//server

#ifdef _WIN32_WCE
#undef UNICODE
#undef _UNICODE
#define main my_main
#endif

/* Preprocessor definitions and includes */

#include "ctdbsdk.h" /* c-tree headers */
#include <string.h>
#include <stdio.h>

#define LOCK_SUPPORT

#ifndef ctCLIENT
#ifdef NOTFORCE
#undef LOCK_SUPPORT
#endif
#endif

#define END_OF_FILE INOT_ERR   /* INOT_ERR is ctree's 101 error. See cterrc.h */


/* Global declarations */

CTHANDLE hSession;
CTHANDLE hDatabase;
CTHANDLE hTable;
CTHANDLE hRecord;


/* Function declarations */

#ifdef PROTOTYPE
VOID Initialize(VOID), Define(VOID), Manage(VOID), Done(VOID);
VOID Add_CustomerMaster_Records(VOID), Display_Records(VOID);
VOID Update_CustomerMaster_Record(VOID), Create_CustomerMaster_Table(VOID),Search_CustomerMaster_Record(VOID);
VOID Delete_Records(CTHANDLE), Check_Table_Mode(CTHANDLE);
VOID Handle_Error(CTSTRING);
VOID Myfunction(VOID),display_main(VOID),fun1(VOID),fun2(VOID);
#else
VOID Initialize(), Define(), Manage(), Done();
VOID Add_CustomerMaster_Records(), Display_Records();
VOID Delete_Records(), Check_Table_Mode();
VOID Update_CustomerMaster_Record(), Create_CustomerMaster_Table(),Search_CustomerMaster_Record();
VOID Handle_Error();
VOID Myfunction(),display_main(),fun1(),fun2();
#endif


/*
 * main()
 *
 * The main() function implements the concept of "init, define, manage
 * and you're done..."
 */

#ifdef PROTOTYPE
NINT main (NINT argc, pTEXT argv[])
#else
NINT main (argc, argv)
NINT argc;
TEXT argv[];
#endif
{
#ifdef LOCK_SUPPORT
   Initialize();

   Define();

   Manage();
   //Myfunction();

   Done();
#else
   printf("\nserver");
   printf("\nserver");
   printf("\nserver");
#endif

   printf("\nPress <ENTER> key to exit . . .\n");
#ifndef ctPortWINCE
   getchar();
#endif

   return(0);
}


/*
 * Initialize()
 *
 * Perform the minimum requirement of logging onto the c-tree Server
 */

#ifdef PROTOTYPE
VOID Initialize(VOID)
#else
VOID Initialize()
#endif
{
   CTDBRET  retval;

   printf("INIT\n");

   if ((retval = ctdbStartDatabaseEngine())) 				/* This function is required when you are using the Server DLL model to start the underlying Server. */
	Handle_Error("Initialize(): ctdbStartDatabaseEngine()"); 	/* It does nothing in all other c-tree models */

   /* allocate session handle */
   if ((hSession = ctdbAllocSession(CTSESSION_CTREE)) == NULL)
      Handle_Error("Initialize(): ctdbAllocSession()");

   hDatabase = hSession; /* database not used in this tutorial */

   /* connect to server */
   printf("\tLogon to server...\n");
   if (ctdbLogon(hSession, "FAIRCOMS", "ADMIN", "ADMIN"))
      Handle_Error("Initialize(): ctdbLogon()");
}


/*
 * Define()
 *
 * Open the table, if they exist. Otherwise create and open the table
 */

#ifdef PROTOTYPE
VOID Define(VOID)
#else
VOID Define()
#endif
{
   printf("DEFINE\n");

   Create_CustomerMaster_Table();
}


/*
 * Manage()
 *
 * This function performs record adds and updates using locking
 */

#ifdef PROTOTYPE
VOID Manage(VOID)
#else
VOID Manage()
#endif
{
   printf("MANAGE\n");

   /* allocate a record handle */
   if ((hRecord = ctdbAllocRecord(hTable)) == NULL)
      Handle_Error("Manage(): ctdbAllocRecord()");

   /* delete any existing records */
   Delete_Records(hRecord);

   /* populate the table with data */
   Add_CustomerMaster_Records();

   /* display contents of table */
   Display_Records();

   /* update a record under locking control */
   //Update_CustomerMaster_Record();

   /* display again after update and effects of lock */
   //Display_Records();
}


/*
 * Done()
 *
 * This function handles the housekeeping of closing tables and
 * freeing of associated memory
 */

#ifdef PROTOTYPE
VOID Done(VOID)
#else
VOID Done()
#endif
{
   printf("DONE\n");

   /* close table */
   printf("\tClose table\n");
   if (ctdbCloseTable(hTable))
      Handle_Error("Done(): ctdbCloseTable()");

   /* logout */
   printf("\tLogout...\n");
   if (ctdbLogout(hSession))
      Handle_Error("Done(): ctdbLogout()");

   /* free handles */
   ctdbFreeRecord(hRecord);
   ctdbFreeTable(hTable);
   ctdbFreeSession(hSession);

   /* If you are linked to the Server DLL, then we should stop our Server at the end of the program.   */
   /* It does nothing in all other c-tree models */
   ctdbStopDatabaseEngine();
}


/*
 * Create_CustomerMaster_Table()
 *
 * Open table CustomerMaster, if it exists. Otherwise create it
 * along with its indices and open it
 */

#ifdef PROTOTYPE
VOID Create_CustomerMaster_Table(VOID)
#else
VOID Create_CustomerMaster_Table()
#endif
{
   CTHANDLE pField1, pField2, pField3, pField4;
   CTHANDLE pField5, pField6, pField7;
   CTHANDLE pIndex;
   CTHANDLE pIseg;

   /* define table CustomerMaster */
   printf("\ttable CustomerMaster\n");

   /* allocate a table handle */
   if ((hTable = ctdbAllocTable(hDatabase)) == NULL)
      Handle_Error("Create_CustomerMaster_Table(): ctdbAllocTable()");

   /* open table */
   if (ctdbOpenTable(hTable, "custmast", CTOPEN_NORMAL))
   {
      /* define table fields */
      pField1 = ctdbAddField(hTable, "cm_custnumb", CT_FSTRING, 4);
      pField2 = ctdbAddField(hTable, "cm_custzipc", CT_FSTRING, 9);
      pField3 = ctdbAddField(hTable, "cm_custstat", CT_FSTRING, 2);
      pField4 = ctdbAddField(hTable, "cm_custflag", CT_STRING, 1);
      pField5 = ctdbAddField(hTable, "cm_custname", CT_STRING, 47);
      pField6 = ctdbAddField(hTable, "cm_custaddr", CT_STRING, 47);
      pField7 = ctdbAddField(hTable, "cm_custphon", CT_STRING, 47);

      if (!pField1 || !pField2 || !pField3 || !pField4 ||
          !pField5 || !pField6|| !pField7)
         Handle_Error("Create_CustomerMaster_Table(): ctdbAddField()");

      /* define index */
      pIndex = ctdbAddIndex(hTable, "cm_custnumb_idx", CTINDEX_FIXED, NO, NO);
      pIseg = ctdbAddSegment(pIndex, pField1, CTSEG_SCHSEG);
      if (!pIndex || !pIseg)
         Handle_Error("Create_CustomerMaster_Table(): ctdbAddIndex()|ctdbAddSegment()");

      /* create table */
      if (ctdbCreateTable(hTable, "custmast", CTCREATE_NORMAL))
         Handle_Error("Create_CustomerMaster_Table(): ctdbCreateTable()");

      /* open table */
      if (ctdbOpenTable(hTable, "custmast", CTOPEN_NORMAL))
         Handle_Error("Create_CustomerMaster_Table(): ctdbOpenTable()");
   }
   else
   {
      Check_Table_Mode(hTable);

      /* confirm the index exists, if not then add the index
       *
       * this scenario arises out of the fact that this table was created in tutorial 1
       * without indexes. The index is now created by the call to ctdbAlterTable
       */

      if (ctdbGetIndexByName(hTable, "cm_custnumb_idx") == NULL)
      {
         pField1 = ctdbGetFieldByName(hTable, "cm_custnumb");
         pIndex = ctdbAddIndex(hTable, "cm_custnumb_idx", CTINDEX_FIXED, NO, NO);
         pIseg = ctdbAddSegment(pIndex, pField1, CTSEG_SCHSEG);
         if (!pIndex || !pIseg)
            Handle_Error("Create_CustomerMaster_Table(): ctdbAddIndex()|ctdbAddSegment()");

         if (ctdbAlterTable(hTable, CTDB_ALTER_NORMAL) != CTDBRET_OK)
            Handle_Error("Create_CustomerMaster_Table(): ctdbAlterTable()");
      }
   }
}


/*
 * Check_Table_Mode()
 *
 * Check if existing table has transaction processing flag enabled.
 * If a table is under transaction processing control, modify the
 * table mode to disable transaction processing
 */

#ifdef PROTOTYPE
VOID Check_Table_Mode(CTHANDLE hTable)
#else
VOID Check_Table_Mode(hTable)
CTHANDLE hTable;
#endif
{
   CTCREATE_MODE mode;

   /* get table create mode */
   mode = ctdbGetTableCreateMode(hTable);

   /* check if table is under transaction processing control */
   if ((mode & CTCREATE_TRNLOG))
   {
      /* change file mode to disable transaction processing */
      mode ^= CTCREATE_TRNLOG;
      if (ctdbUpdateCreateMode(hTable, mode) != CTDBRET_OK)
         Handle_Error("Check_Table_Mode(); ctdbUpdateCreateMode");
   }
}


/*
 * Delete_Records()
 *
 * This function deletes all the records in the table
 */

#ifdef PROTOTYPE
VOID Delete_Records(CTHANDLE hRecord)
#else
VOID Delete_Records(hRecord)
CTHANDLE hRecord;
#endif
{
   CTDBRET  retval;
   CTBOOL   empty;

   printf("\tDelete records...\n");

   /* enable session-wide lock flag */
   if (ctdbLock(hSession, CTLOCK_WRITE_BLOCK))
      Handle_Error("Delete_Records(): ctdbLock()");

   empty = NO;
   retval = ctdbFirstRecord(hRecord);
   if (retval != CTDBRET_OK)
   {
      if (retval == END_OF_FILE)
         empty = YES;
      else
         Handle_Error("Delete_Records(): ctdbFirstRecord()");
   }

   while (empty == NO) /* while table is not empty */
   {
      /* delete record */
      if (ctdbDeleteRecord(hRecord))
         Handle_Error("Delete_Records(): ctdbDeleteRecord()");

      /* read next record */
      retval = ctdbNextRecord(hRecord);
      if (retval != CTDBRET_OK)
      {
         if (retval == END_OF_FILE)
            empty = YES;
         else
            Handle_Error("Delete_Records(): ctdbNextRecord()");
      }
   }
   if (ctdbUnlock(hSession))
      Handle_Error("Delete_Records(): ctdbUnlock()");
}


/*
 * Add_CustomerMaster_Records()
 *
 * This function adds records to table CustomerMaster from an
 * array of strings
 */

typedef struct {
   CTSTRING number, zipcode, state, flag, name, address, phone;
} CUSTOMER_DATA;

CUSTOMER_DATA data[] = {
   "1000", "92867", "CA", "1", "Bryan Williams", "2999 Regency,Orange","1234567890",
   "1001", "61434", "CT", "1", "Joshua Brown", "13 Main,Harford",      "3123452423",
   "1002", "73677", "GA", "1", "Wenqiang Bo",   "4356 Cambridge,Atlanta","7145781667",
   "1003", "10034", "MO", "1", "Keyon Dooling",  "19771 Park Avenue,Columbi", "3225564377",
   "1004", "42155", "NY", "1", "Jack sparrow",  "1600 Rolling hill,New york", "4425575446",
   "1005", "87765", "MO", "1", "Kimberly Plwell",  "19771 Park Avenue,Columbia", "6644333455",
   "1006", "33245", "MO", "1", "Randel Archibold",  "19771 Park Avenue,Columbia", "3333333333",
   "1007", "65201", "MO", "1", "Jonathan Weisman",  "19771 Park Avenue,Columbia", "4533464754",
   "1008", "35543", "MO", "1", "Julia Barrd",  "19771 Park Avenue,Columbia", "8754324552",
   "1009", "44567", "MO", "1", "Henry Fountain",  "19771 Park Avenue,Columbia", "5544766995",
   "1020", "44567", "MO", "1", "Andrea Elliott",  "19771 Park Avenue,Columbia", "5544766995",

};

#ifdef PROTOTYPE
VOID Add_CustomerMaster_Records(VOID)
#else
VOID Add_CustomerMaster_Records()
#endif
{
   CTDBRET  retval;
   CTSIGNED i;
   CTSIGNED nRecords = sizeof(data) / sizeof(CUSTOMER_DATA);

   printf("\tAdd records...\n");

   /* add data to table */
   for (i = 0; i < nRecords; i++)
   {
      /* clear record buffer */
      ctdbClearRecord(hRecord);

      retval = 0;
      /* populate record buffer with data */
      retval |= ctdbSetFieldAsString(hRecord, 0, data[i].number);
      retval |= ctdbSetFieldAsString(hRecord, 1, data[i].zipcode);
      retval |= ctdbSetFieldAsString(hRecord, 2, data[i].state);
      retval |= ctdbSetFieldAsString(hRecord, 3, data[i].flag);
      retval |= ctdbSetFieldAsString(hRecord, 4, data[i].name);
      retval |= ctdbSetFieldAsString(hRecord, 5, data[i].address);
      retval |= ctdbSetFieldAsString(hRecord, 6, data[i].phone);

      if (retval)
         Handle_Error("Add_CustomerMaster_Records(): ctdbSetFieldAsString()");

      /* add record */
      if (ctdbWriteRecord(hRecord))
         Handle_Error("Add_CustomerMaster_Records(): ctdbWriteRecord()");
   }
}


/*
 * Display_Records()
 *
 * This function displays the contents of a table. ctdbFirstRecord() and
 * ctdbNextRecord() fetch the record. Then each field is parsed and displayed
 */

#ifdef PROTOTYPE
VOID Display_Records(VOID)
#else
VOID Display_Records()
#endif
{
   CTDBRET  retval;
   TEXT     custnumb[4+1];
   TEXT		custzipc[9+1];
   TEXT		custphon[47+1];
   TEXT		custname[47+1];
   TEXT		custaddr[47+1];
   TEXT		custcity[47+1];

   printf("\tDisplay records...");

   /* read first record */
   retval = ctdbFirstRecord(hRecord);
   if (retval == END_OF_FILE)
      return;

   while (retval == CTDBRET_OK)
   {
      retval = 0;
      retval |= ctdbGetFieldAsString(hRecord, 0, custnumb, sizeof(custnumb));
      retval |= ctdbGetFieldAsString(hRecord, 1, custzipc, sizeof(custzipc));
      //retval |= ctdbGetFieldAsString(hRecord, 3, custphon, sizeof(custphon));
      retval |= ctdbGetFieldAsString(hRecord, 4, custname, sizeof(custname));
      retval |= ctdbGetFieldAsString(hRecord, 5, custaddr, sizeof(custaddr));
      retval |= ctdbGetFieldAsString(hRecord, 6, custphon, sizeof(custphon));
      if (retval)
         Handle_Error("Display_Records(): ctdbGetFieldAsString()");

      printf("\n%-7s%-8s%-18s%-25s%15s\n",custnumb,custzipc,custname,custaddr,custphon);

      /* read next record */
      retval = ctdbNextRecord(hRecord);
      if (retval == END_OF_FILE)
         break;   /* reached end of file */

      if (retval != CTDBRET_OK)
         Handle_Error("Display_Records(): ctdbNextRecord()");
   }
}


/*
 * Update_CustomerMaster_Records()
 *
 * Update one record under locking control to demonstrate the effects
 * of locking
 */

#ifdef PROTOTYPE
VOID Search_CustomerMaster_Record(VOID)
#else
VOID Search_CustomerMaster_Record()
#endif
{
   TEXT num[10];
   TEXT		custzipc[9+1];
   TEXT		custphon[10+1];
   TEXT		custname[47+1];
   TEXT		custaddr[47+1];
   TEXT		custcity[47+1];
   CTDBRET  retval;
   printf("\tUpdate record...\n");
   printf("input your Security ID\n");
   gets(num);

   /* enable session-wide lock flag */
   if (ctdbLock(hSession, CTLOCK_WRITE_BLOCK))
      Handle_Error("Update_CustomerMaster_Record(): ctdbLock()");

   /* find record by customer number */
   if (ctdbClearRecord(hRecord))
      Handle_Error("Update_CustomerMaster_Record(): ctdbClearRecord()");
   if (ctdbSetFieldAsString(hRecord, 0, num))
      Handle_Error("Update_CustomerMaster_Record(): ctdbSetFieldAsString()");
   if (ctdbFindRecord(hRecord, CTFIND_EQ))
      Handle_Error("Update_CustomerMaster_Record(): ctdbFindRecord()");

   //retval |= ctdbGetFieldAsString(hRecord, 0, custnumb, sizeof(custnumb));
   retval |= ctdbGetFieldAsString(hRecord, 1, custzipc, sizeof(custzipc));
   retval |= ctdbGetFieldAsString(hRecord, 3, custphon, sizeof(custphon));
   retval |= ctdbGetFieldAsString(hRecord, 4, custname, sizeof(custname));
   retval |= ctdbGetFieldAsString(hRecord, 5, custaddr, sizeof(custaddr));
   retval |= ctdbGetFieldAsString(hRecord, 6, custcity, sizeof(custcity));

   printf("\n%-8s%-14s%-13s%-18s%-8s\n",custzipc,custphon,custname,custaddr,custcity);

   //ctdbSetFieldAsString(hRecord, 4, &name);
   //puts(name);

   //if (ctdbSetFieldAsString(hRecord, 4, "KEYON DOOLING"))
    //  Handle_Error("Update_CustomerMaster_Record(): ctdbSetFieldAsString()");
   /* rewrite record */
   //if (ctdbWriteRecord(hRecord))
    //  Handle_Error("Update_CustomerMaster_Record(): ctdbWriteRecord()");

   /*
   else
   {
      printf("\tPress <ENTER> key to unlock\n");
      getchar();
   }*/

   if (ctdbUnlock(hSession))
      Handle_Error("Update_CustomerMaster_Record(): ctdbUnlock()");
}

/*
 * Handle_Error()
 *
 * This function is a common bailout routine. It displays an error message
 * allowing the user to acknowledge before terminating the application
 */

#ifdef PROTOTYPE
VOID Handle_Error(CTSTRING errmsg)
#else
VOID Handle_Error(errmsg)
CTSTRING errmsg;
#endif
{
   printf("\nERROR: [%d] - %s \n", ctdbGetError(hSession), errmsg);
   printf("*** Execution aborted *** \nPress <ENTER> key to exit...");

   ctdbLogout(hSession);

   ctdbFreeRecord(hRecord);
   ctdbFreeTable(hTable);
   ctdbFreeSession(hSession);

   getchar();

   exit(1);
}

#ifdef PROTOTYPE
VOID Myfunction(VOID)
#else
VOID Myfunction()
#endif
{
	int choice,n=0;
   printf("Myfunction\n");
   while(1)
   {
      display_main();
      do
      {
   	   n=scanf("%d",&choice);
      }while(choice<1 ||choice>2);
      switch(choice)
      {
      case 1:fun1();break;
      case 2:fun2();break;
      }
      //getchar();
   }

}

#ifdef PROTOTYPE
VOID display_main(VOID)
#else
VOID display_main()
#endif
{
	printf("******************************\n");
	printf("Welcome to use parking system!\n");
	printf("1.I want to park a car!\n");
	printf("2.I want to get my car back!\n");
	printf("******************************\n");
}

#ifdef PROTOTYPE
VOID fun1(VOID)
#else
VOID fun1()
#endif
{

   printf("Myfunction1\n");
   getchar();
   /* update a record under locking control */
   Search_CustomerMaster_Record();

   /* display again after update and effects of lock */
   //Display_Records();

}

#ifdef PROTOTYPE
VOID fun2(VOID)
#else
VOID fun2()
#endif
{
   printf("Myfunction2\n");
   getchar();
   Update_CustomerMaster_Record();

}


#ifdef PROTOTYPE
VOID Update_CustomerMaster_Record(VOID)
#else
VOID Update_CustomerMaster_Record()
#endif
{
	int choice,n=0;
   TEXT num[10],name[47],phone[10];
   TEXT		custzipc[9+1];
   TEXT		custphon[10+1];
   TEXT		custname[47+1];
   TEXT		custaddr[47+1];
   TEXT		custcity[47+1];
   CTDBRET  retval;
   printf("\tUpdate record...\n");
   printf("input your Security ID\n");
   gets(num);

   /* enable session-wide lock flag */
   if (ctdbLock(hSession, CTLOCK_WRITE_BLOCK))
      Handle_Error("Update_CustomerMaster_Record(): ctdbLock()");

   /* find record by customer number */
   if (ctdbClearRecord(hRecord))
      Handle_Error("Update_CustomerMaster_Record(): ctdbClearRecord()");
   if (ctdbSetFieldAsString(hRecord, 0, num))
      Handle_Error("Update_CustomerMaster_Record(): ctdbSetFieldAsString()");
   if (ctdbFindRecord(hRecord, CTFIND_EQ))
      Handle_Error("Update_CustomerMaster_Record(): ctdbFindRecord()");

   retval |= ctdbGetFieldAsString(hRecord, 1, custzipc, sizeof(custzipc));
   retval |= ctdbGetFieldAsString(hRecord, 3, custphon, sizeof(custphon));
   retval |= ctdbGetFieldAsString(hRecord, 4, custname, sizeof(custname));
   retval |= ctdbGetFieldAsString(hRecord, 5, custaddr, sizeof(custaddr));
   retval |= ctdbGetFieldAsString(hRecord, 6, custcity, sizeof(custcity));
   printf("\n\t\t%-8s%-14s%-13s%-18s%-8s\n",custzipc,custphon,custname,custaddr,custcity);
   printf("\nWhich record you want to change?\n");
   printf("1.phone number?\n");
   printf("2.name?\n");
   do
   {
	   n=scanf("%d",&choice);
   }while(choice<1 ||choice>2);
   if(choice==1)
   {
	   getchar();
	   printf("Please input your new phone number!\n");
	   gets(phone);
	   if (ctdbSetFieldAsString(hRecord, 3, phone))
	      Handle_Error("Update_CustomerMaster_Record(): ctdbSetFieldAsString()");
	   /* rewrite record */
	   if (ctdbWriteRecord(hRecord))
	      Handle_Error("Update_CustomerMaster_Record(): ctdbWriteRecord()");

   }
   if(choice==2)
   {
	   getchar();
	   printf("Please input your new name!\n");
	   gets(name);
	   if (ctdbSetFieldAsString(hRecord, 4, name))
	      Handle_Error("Update_CustomerMaster_Record(): ctdbSetFieldAsString()");
	   /* rewrite record */
	   if (ctdbWriteRecord(hRecord))
	      Handle_Error("Update_CustomerMaster_Record(): ctdbWriteRecord()");
   }



   //ctdbSetFieldAsString(hRecord, 4, &name);
   //puts(name);






   retval |= ctdbGetFieldAsString(hRecord, 1, custzipc, sizeof(custzipc));
   retval |= ctdbGetFieldAsString(hRecord, 3, custphon, sizeof(custphon));
   retval |= ctdbGetFieldAsString(hRecord, 4, custname, sizeof(custname));
   retval |= ctdbGetFieldAsString(hRecord, 5, custaddr, sizeof(custaddr));
   retval |= ctdbGetFieldAsString(hRecord, 6, custcity, sizeof(custcity));
   printf("\n\t\t%-8s%-14s%-13s%-18s%-8s\n",custzipc,custphon,custname,custaddr,custcity);



   if (ctdbUnlock(hSession))
      Handle_Error("Update_CustomerMaster_Record(): ctdbUnlock()");
}



