Product Documentation

c-treeDB API API for C

Previous Topic

Next Topic

Multi-Record Table Tutorial

To demonstrate the utility of the c-treeDB API Virtual Table support, this section contains a full working example based on the standard c-treeDB API tutorial 2 exercise.

This tutorial will introduce the most basic FairCom DB API to accomplish creating and manipulating a table through FairCom DB. You will create and populate four tables and then it will create the MRT HOST table, which will host your Virtual Table. Functionally, the application you will build in this application will perform the following:

  1. Create a database.
  2. Create four tables each with an index.
  3. Populate each table with a few records.
  4. Build a query utilizing the advantage of indexes.
  5. Output the results of the query.

c-treeDB API MRTTable Example

/*

* MRTTable_tutorial.c

*

* Public domain FairCom DB C example

*

* FairCom Corporation, 6300 West Sugar Creek Drive, Columbia, MO 65203 USA

* FairCom Corporation, 6300 West Sugar Creek Drive, Columbia, MO 65203

*

* The goal of this tutorial is to introduce the most basic FairCom DB API

* to accomplish creating and manipulating a table through FairCom DB

*

* Functionally, this application will perform the following:

* 1. Create a database

* 2. Create 4 tables each with an index

* 3. Populate each table with a few records

* 4. Build a query utilizing the advantage of indexes

* 5. Output the results of the query

*/


#ifdef _WIN32_WCE

#undef UNICODE

#undef _UNICODE

#define main my_main

#endif


/* Preprocessor definitions and includes */

#include "ctdbsdk.h" /* c-tree headers */

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


/* Global declarations */


/* Session handle */

CTHANDLE hSession;


/* Database handle */

CTHANDLE hDatabase;


/* Table handles */

CTHANDLE hTableCustMast;

CTHANDLE hTableCustOrdr;

CTHANDLE hTableOrdrItem;

CTHANDLE hTableItemMast;


/* Record handles */

CTHANDLE hRecordCustMast;

CTHANDLE hRecordCustOrdr;

CTHANDLE hRecordOrdrItem;

CTHANDLE hRecordItemMast;


/* Function declarations */

#ifdef PROTOTYPE

VOID Initialize(VOID), Define(VOID), Manage(VOID), Done(VOID);


VOID Create_HOST_Table(VOID);

VOID Create_CustomerMaster_Table(VOID), Create_ItemMaster_Table(VOID);

VOID Create_OrderItems_Table(VOID), Create_CustomerOrders_Table(VOID);


VOID Add_CustomerMaster_Records(VOID), Add_ItemMaster_Records(VOID);

VOID Add_CustomerOrders_Records(VOID), Add_OrderItems_Records(VOID);

VOID Delete_Records(CTHANDLE hRecord);

VOID Check_Table_Mode(CTHANDLE hTable);


VOID Handle_Error(CTSTRING);

#else

VOID Initialize(), Define(), Manage(), Done();


VOID Create_HOST_Table();

VOID Create_CustomerMaster_Table(), Create_ItemMaster_Table();

VOID Create_OrderItems_Table(), Create_CustomerOrders_Table();


VOID Add_CustomerMaster_Records(), Add_ItemMaster_Records();

VOID Add_CustomerOrders_Records(), Add_OrderItems_Records();

VOID Delete_Records();

VOID Check_Table_Mode();


VOID Handle_Error();

#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

{

Initialize();


Define();


Manage();


Done();


printf("\nPress <ENTER> key to exit . . .\n");

getchar();


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_CTDB)) == NULL)

Handle_Error("Initialize(): ctdbAllocSession()");


if ((hDatabase = ctdbAllocDatabase(hSession)) == NULL)

Handle_Error("Initialize(): ctdbAllocDatabase()");


/* connect to server */

printf("\tLogon to server...\n");

if (ctdbLogon(hSession, "FAIRCOMS", "", ""))

Handle_Error("Initialize(): ctdbLogon()");

if (ctdbConnect(hDatabase, "ctreeSQL"))

Handle_Error("Initialize(): ctdbConnect()");

}


/*

* Define()

*

* Open the tables, if they exist. Otherwise create and open the tables

*/


#ifdef PROTOTYPE

VOID Define(VOID)

#else

VOID Define()

#endif

{

printf("DEFINE\n");


Create_HOST_Table();

Create_CustomerMaster_Table();

Create_CustomerOrders_Table();

Create_OrderItems_Table();

Create_ItemMaster_Table();


if (ctdbOpenTable(hTableCustMast, "custmast", CTOPEN_NORMAL))

Handle_Error("Create_CustomerMaster_Table(): ctdbOpenTable()");

if (ctdbOpenTable(hTableCustOrdr, "custordr", CTOPEN_NORMAL))

Handle_Error("Create_CustomerOrders_Table(): ctdbOpenTable()");

if (ctdbOpenTable(hTableOrdrItem, "ordritem", CTOPEN_NORMAL))

Handle_Error("Create_OrderItems_Table(): ctdbOpenTable()");

if (ctdbOpenTable(hTableItemMast, "itemmast", CTOPEN_NORMAL))

Handle_Error("Create_ItemMaster_Table(): ctdbOpenTable()");

}


/*

* Manage()

*

* Populates table and perform a simple query

*

*/


#ifdef PROTOTYPE

VOID Manage(VOID)

#else

VOID Manage()

#endif

{

CTDBRET retval;

CTSIGNED quantity;

CTFLOAT price, total;

TEXT itemnumb[5+1], custnumb[4+1], ordrnumb[6+1], custname[47+1];

CTBOOL isOrderFound, isItemFound;


printf("MANAGE\n");


/* populate the tables with data */

Add_CustomerMaster_Records();

Add_CustomerOrders_Records();

Add_OrderItems_Records();

Add_ItemMaster_Records();


/* perform a query:

list customer name and total amount per order


name total

@@@@@@@@@@@@@ $xx.xx


for each order in the CustomerOrders table

fetch order number

fetch customer number

fetch name from CustomerMaster table based on customer number

for each order item in OrderItems table

fetch item quantity

fetch item number

fetch item price from ItemMaster table based on item number

next

next

*/

printf("\n\tQuery Results\n");


/* get the first order */

if (ctdbFirstRecord(hRecordCustOrdr))

Handle_Error("Manage(): ctdbFirstRecord()");


isOrderFound = YES;

while (isOrderFound) /* for each order in the CustomerOrders table */

{

/* fetch order number */

retval = ctdbGetFieldAsString(hRecordCustOrdr, 1, ordrnumb, sizeof(ordrnumb));

/* fetch customer number */

retval |= ctdbGetFieldAsString(hRecordCustOrdr, 4, custnumb, sizeof(custnumb));

if (retval)

Handle_Error("Manage(): ctdbGetFieldAsString()");


/* fetch name from CustomerMaster table based on customer number */

if (ctdbClearRecord(hRecordCustMast))

Handle_Error("Manage(): ctdbClearRecord()");

if (ctdbSetFieldAsString(hRecordCustMast, 1, custnumb))

Handle_Error("Manage(): ctdbSetFieldAsString()");

if (ctdbFindRecord(hRecordCustMast, CTFIND_EQ))

Handle_Error("Manage(): ctdbFindRecord()");

if (ctdbGetFieldAsString(hRecordCustMast, 5, custname, sizeof(custname)))

Handle_Error("Manage(): ctdbGetFieldAsString()");


/* fetch item price from OrderItems table */

if (ctdbClearRecord(hRecordOrdrItem))

Handle_Error("Manage(): ctdbClearRecord()");

if (ctdbSetFieldAsString(hRecordOrdrItem, 1, ordrnumb))

Handle_Error("Manage(): ctdbSetFieldAsString()");

/* define a recordset to scan only items applicable to this order */

if (ctdbRecordSetOn(hRecordOrdrItem, 4))

Handle_Error("Manage(): ctdbRecordSetOn()");

if (ctdbFirstRecord(hRecordOrdrItem))

Handle_Error("Manage(): ctdbFirstRecord()");

isItemFound = YES;


total = 0;

while (isItemFound) /* for each order item in OrderItems table */

{

/* fetch item quantity */

if (ctdbGetFieldAsSigned(hRecordOrdrItem, 3, &quantity))

Handle_Error("Manage(): ctdbGetFieldAsSigned()");

/* fetch item number */

if (ctdbGetFieldAsString(hRecordOrdrItem, 4, itemnumb, sizeof(itemnumb)))

Handle_Error("Manage(): ctdbGetFieldAsString()");


/* fetch item price from ItemMaster table based on item number */

if (ctdbClearRecord(hRecordItemMast))

Handle_Error("Manage(): ctdbClearRecord()");

if (ctdbSetFieldAsString(hRecordItemMast, 1, itemnumb))

Handle_Error("Manage(): ctdbSetFieldAsString()");

if (ctdbFindRecord(hRecordItemMast, CTFIND_EQ))

Handle_Error("Manage(): ctdbFindRecord()");

if (ctdbGetFieldAsFloat(hRecordItemMast, 3, &price))

Handle_Error("Manage(): ctdbGetFieldAsFloat()");


/* calculate order total */

total += (price * quantity);

/* read next record */

retval = ctdbNextRecord(hRecordOrdrItem);

if (retval != CTDBRET_OK)

{

if (retval == END_OF_FILE)

isItemFound = NO;

else

Handle_Error("Manage(): ctdbNextRecord()");

}

}


ctdbRecordSetOff(hRecordOrdrItem);


/* output data to stdout */

printf("\t\t%-20s %.2f\n", custname, total);


/* read next order */

retval = ctdbNextRecord(hRecordCustOrdr);

if (retval != CTDBRET_OK)

{

if (retval == END_OF_FILE)

isOrderFound = NO;

else

Handle_Error("Manage(): ctdbNextRecord()");

}

}

}


/*

* 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 tables */

printf("\tClose tables...\n");

if (ctdbCloseTable(hTableCustMast))

Handle_Error("Done(): ctdbCloseTable()");

if (ctdbCloseTable(hTableOrdrItem))

Handle_Error("Done(): ctdbCloseTable()");

if (ctdbCloseTable(hTableCustOrdr))

Handle_Error("Done(): ctdbCloseTable()");

if (ctdbCloseTable(hTableItemMast))

Handle_Error("Done(): ctdbCloseTable()");


/* logout */

printf("\tLogout...\n");

if (ctdbLogout(hSession))

Handle_Error("Done(): ctdbLogout()");


/* free handles */

ctdbFreeRecord(hRecordCustMast);

ctdbFreeRecord(hRecordItemMast);

ctdbFreeRecord(hRecordOrdrItem);

ctdbFreeRecord(hRecordCustOrdr);


ctdbFreeTable(hTableCustMast);

ctdbFreeTable(hTableItemMast);

ctdbFreeTable(hTableOrdrItem);

ctdbFreeTable(hTableCustOrdr);


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_HOST_Table()

*

* Open the MRT HOST table, if it exists. Otherwise create it

*/


#ifdef PROTOTYPE

VOID Create_HOST_Table(VOID)

#else

VOID Create_HOST_Table()

#endif

{

CTHANDLE pField0, pField1, pField2;

CTHANDLE pIndex;

CTHANDLE pIseg;

CTHANDLE hosttable;


/* define table CustomerMaster */

printf("\ttable HOST\n");


/* allocate a table handle */

if ((hosttable = ctdbAllocTable(hDatabase)) == NULL)

Handle_Error("Create_HOST_Table(): ctdbAllocTable()");


/* open table */

if (ctdbOpenTable(hosttable, "tutorial_host", CTOPEN_NORMAL))

{

/* define table fields */

pField0 = ctdbAddField(hosttable, "rectype", CT_FSTRING, 1);

pField1 = ctdbAddField(hosttable, "rec_numb", CT_FSTRING, 4);

pField2 = ctdbAddField(hosttable, "variablepart", CT_STRING, 1);


if (!pField0 || !pField1 || !pField2)

Handle_Error("Create_HOST_Table(): ctdbAddField()");


/* define index */

pIndex = ctdbAddIndex(hosttable, "rec_numb", CTINDEX_FIXED, YES, NO);

pIseg = ctdbAddSegment(pIndex, pField1, CTSEG_SCHSEG);


if (!pIndex || !pIseg)

Handle_Error("Create_HOST_Table(): ctdbAddIndex()|ctdbAddSegment()");


/* create table */

if (ctdbCreateTable(hosttable, "tutorial_host", CTCREATE_NORMAL|CTCREATE_NONULFLD)) /*CTCREATE_NONULFLD because NULFLD may case troubles in case different schemas have different number of fields */

Handle_Error("Create_HOST_Table(): ctdbCreateTable()");

}

else

{

Check_Table_Mode(hosttable);

ctdbCloseTable(hosttable);

}

}


/*

* Create_CustomerMaster_Table()

*

* Open table CustomerMaster, if it exists. Otherwise create it

* along with its indexes and open it

*/


#ifdef PROTOTYPE

VOID Create_CustomerMaster_Table(VOID)

#else

VOID Create_CustomerMaster_Table()

#endif

{

CTHANDLE pField0, pField1, pField2, pField3, pField4;

CTHANDLE pField5, pField6, pField7;


/* define table CustomerMaster */

printf("\ttable CustomerMaster\n");


/* allocate a table handle */

if ((hTableCustMast = ctdbAllocTable(hDatabase)) == NULL)

Handle_Error("Create_CustomerMaster_Table(): ctdbAllocTable()");


/* open table */

if (ctdbOpenTable(hTableCustMast, "custmast", CTOPEN_NORMAL))

{

/* define table fields */

pField0 = ctdbAddField(hTableCustMast, "rectype", CT_FSTRING, 1);

pField1 = ctdbAddField(hTableCustMast, "cm_custnumb", CT_FSTRING, 4);

pField2 = ctdbAddField(hTableCustMast, "cm_custzipc", CT_FSTRING, 9);

pField3 = ctdbAddField(hTableCustMast, "cm_custstat", CT_FSTRING, 2);

pField4 = ctdbAddField(hTableCustMast, "cm_custratg", CT_FSTRING, 1);

pField5 = ctdbAddField(hTableCustMast, "cm_custname", CT_STRING, 47);

pField6 = ctdbAddField(hTableCustMast, "cm_custaddr", CT_STRING, 47);

pField7 = ctdbAddField(hTableCustMast, "cm_custcity", CT_STRING, 47);


if (!pField0 || !pField1 || !pField2 || !pField3 || !pField4 ||

!pField5 || !pField6|| !pField7)

Handle_Error("Create_CustomerMaster_Table(): ctdbAddField()");

/* create table */

if (ctdbCreateMRTTable(hTableCustMast, "custmast","tutorial_host", CTCREATE_NORMAL|CTCREATE_NONULFLD,"rectype==\"C\""))

Handle_Error("Create_CustomerMaster_Table(): ctdbCreateTable()");


}

else

ctdbCloseTable(hTableCustMast);

}


/*

* Create_CustomerOrders_Table()

*

* Open table CustomerOrders, if it exists. Otherwise create it

* along with its indexes and open it

*/


#ifdef PROTOTYPE

VOID Create_CustomerOrders_Table(VOID)

#else

VOID Create_CustomerOrders_Table()

#endif

{

CTHANDLE pField0, pField1, pField2, pField3, pField4;


/* define table CustomerOrders */

printf("\ttable CustomerOrders\n");


/* allocate a table handle */

if ((hTableCustOrdr = ctdbAllocTable(hDatabase)) == NULL)

Handle_Error("Create_CustomerOrders_Table(): ctdbAllocTable()");


/* open table */

if (ctdbOpenTable(hTableCustOrdr, "custordr", CTOPEN_NORMAL))

{

/* define table fields */

pField0 = ctdbAddField(hTableCustOrdr, "rectype", CT_FSTRING, 1);

pField1 = ctdbAddField(hTableCustOrdr, "co_ordrnumb", CT_FSTRING, 4);

pField2 = ctdbAddField(hTableCustOrdr, "co_ordrdate", CT_DATE, 4);

pField3 = ctdbAddField(hTableCustOrdr, "co_promdate", CT_DATE, 4);

pField4 = ctdbAddField(hTableCustOrdr, "co_custnumb", CT_FSTRING, 4);


if (!pField0 || !pField1 || !pField2 || !pField3 || !pField4)

Handle_Error("Define(): ctdbAddField()");


/* create table */

if (ctdbCreateMRTTable(hTableCustOrdr, "custordr","tutorial_host", CTCREATE_NORMAL|CTCREATE_NONULFLD,"rectype==\"O\""))

Handle_Error("Create_CustomerOrders_Table(): ctdbCreateTable()");

}

else

ctdbCloseTable(hTableCustOrdr);

}


/*

* Create_OrderItems_Table()

*

* Open table OrderItems, if it exists. Otherwise create it

* along with its indexes and open it

*/


#ifdef PROTOTYPE

VOID Create_OrderItems_Table(VOID)

#else

VOID Create_OrderItems_Table()

#endif

{

CTHANDLE pField0, pField1, pField2, pField3, pField4;


/* define table OrderItems */

printf("\ttable OrderItems\n");


/* allocate a table handle */

if ((hTableOrdrItem = ctdbAllocTable(hDatabase)) == NULL)

Handle_Error("Create_OrderItems_Table(): ctdbAllocTable()");


if (ctdbOpenTable(hTableOrdrItem, "ordritem", CTOPEN_NORMAL))

{

/* define table fields */

pField0 = ctdbAddField(hTableOrdrItem,"rectype", CT_FSTRING, 1);

pField1 = ctdbAddField(hTableOrdrItem,"oi_ordrnumb", CT_FSTRING, 4);

pField2 = ctdbAddField(hTableOrdrItem,"oi_sequnumb", CT_INT2, 2);

pField3 = ctdbAddField(hTableOrdrItem,"oi_quantity", CT_INT2, 2);

pField4 = ctdbAddField(hTableOrdrItem,"oi_itemnumb", CT_FSTRING, 5);

if (!pField0 || !pField1 || !pField2 || !pField3 || !pField4)

Handle_Error("Create_OrderItems_Table(): ctdbAddField()");


/* create table */

if (ctdbCreateMRTTable(hTableOrdrItem, "ordritem","tutorial_host", CTCREATE_NORMAL|CTCREATE_NONULFLD,"rectype==\"I\""))

Handle_Error("Create_OrderItems_Table(): ctdbCreateTable()");

}

else

ctdbCloseTable(hTableOrdrItem);

}


/*

* Create_ItemMaster_Table()

*

* Open table ItemMaster, if it exists. Otherwise create it

* along with its indexes and open it

*/


#ifdef PROTOTYPE

VOID Create_ItemMaster_Table(VOID)

#else

VOID Create_ItemMaster_Table()

#endif

{

CTHANDLE pField0, pField1, pField2, pField3, pField4;


/* define table ItemMaster */

printf("\ttable ItemMaster\n");


/* allocate a table handle */

if ((hTableItemMast = ctdbAllocTable(hDatabase)) == NULL)

Handle_Error("Create_ItemMaster_Table(): ctdbAllocTable()");


/* open table */

if (ctdbOpenTable(hTableItemMast, "itemmast", CTOPEN_NORMAL))

{

/* define table fields */

pField0 = ctdbAddField(hTableItemMast,"rectype", CT_FSTRING, 1);

pField1 = ctdbAddField(hTableItemMast, "im_itemnumb", CT_FSTRING, 4);

pField2 = ctdbAddField(hTableItemMast, "im_itemwght", CT_INT4, 4);

pField3 = ctdbAddField(hTableItemMast, "im_itempric", CT_MONEY, 4);

pField4 = ctdbAddField(hTableItemMast, "im_itemdesc", CT_STRING, 47);

if (!pField0 || !pField1 || !pField2 || !pField3 || !pField4)

Handle_Error("Create_ItemMaster_Table(): ctdbAddField()");


/* create table */

if (ctdbCreateMRTTable(hTableItemMast, "itemmast","tutorial_host", CTCREATE_NORMAL|CTCREATE_NONULFLD,"rectype==\"M\""))

Handle_Error("Create_ItemMaster_Table(); ctdbCreateTable()");

}

else

ctdbCloseTable(hTableItemMast);

}


/*

* 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");

}

}


/*

* Add_CustomerMaster_Records()

*

* This function adds records to table CustomerMaster from an

* array of strings

*/


typedef struct {

CTSTRING type, number, zipcode, state, rating, name, address, city;

} CUSTOMER_DATA;


CUSTOMER_DATA data4[] = {

"C", "1000", "92867", "CA", "1", "Bryan Williams", "2999 Regency", "Orange",

"C","1001", "61434", "CT", "1", "Michael Jordan", "13 Main", "Harford",

"C","1002", "73677", "GA", "1", "Joshua Brown", "4356 Cambridge", "Atlanta",

"C","1003", "10034", "MO", "1", "Keyon Dooling", "19771 Park Avenue", "Columbia"

};


#ifdef PROTOTYPE

VOID Add_CustomerMaster_Records(VOID)

#else

VOID Add_CustomerMaster_Records()

#endif

{

CTDBRET retval;

CTSIGNED i;

CTSIGNED nRecords = sizeof(data4) / sizeof(CUSTOMER_DATA);


if ((hRecordCustMast = ctdbAllocRecord(hTableCustMast)) == NULL)

Handle_Error("Add_Customer_Records(): ctdbAllocRecord()");


Delete_Records(hRecordCustMast);


printf("\tAdd records in table CustomerMaster...\n");


/* add records to table */

for (i = 0; i < nRecords; i++)

{

/* clear record buffer */

ctdbClearRecord(hRecordCustMast);


retval = 0;

/* populate record buffer with data */

retval |= ctdbSetFieldAsString(hRecordCustMast, 0, data4[i].type);

retval |= ctdbSetFieldAsString(hRecordCustMast, 1, data4[i].number);

retval |= ctdbSetFieldAsString(hRecordCustMast, 2, data4[i].zipcode);

retval |= ctdbSetFieldAsString(hRecordCustMast, 3, data4[i].state);

retval |= ctdbSetFieldAsString(hRecordCustMast, 4, data4[i].rating);

retval |= ctdbSetFieldAsString(hRecordCustMast, 5, data4[i].name);

retval |= ctdbSetFieldAsString(hRecordCustMast, 6, data4[i].address);

retval |= ctdbSetFieldAsString(hRecordCustMast, 7, data4[i].city);


if(retval)

Handle_Error("Add_Customer_Records(): ctdbSetFieldAsString()");


/* add record */

if (ctdbWriteRecord(hRecordCustMast))

Handle_Error("Add_Customer_Records(): ctdbWriteRecord()");

}

}


/*

* Add_CustomerOrders_Records()

*

* This function adds records to table CustomerOrders from an

* array of strings

*/


typedef struct {

CTSTRING type, orderdate, promisedate, ordernum, customernum;

} ORDER_DATA;


ORDER_DATA data1[] = {

{"O", "09/01/2002", "09/05/2002", "1", "1001"},

{"O", "09/02/2002", "09/06/2002", "2", "1002"}

};


#ifdef PROTOTYPE

VOID Add_CustomerOrders_Records(VOID)

#else

VOID Add_CustomerOrders_Records()

#endif

{

CTDBRET retval;

CTSIGNED i;

CTSIGNED nRecords = sizeof(data1) / sizeof(ORDER_DATA);

CTDATE orderdate;

CTDATE promisedate;


if ((hRecordCustOrdr = ctdbAllocRecord(hTableCustOrdr)) == NULL)

Handle_Error("Add_CustomerOrders_Records(): ctdbAllocRecord()");


Delete_Records(hRecordCustOrdr);


printf("\tAdd records in table CustomerOrders...\n");


/* add records to table */

for (i = 0; i < nRecords; i++)

{

/* clear record buffer */

ctdbClearRecord(hRecordCustOrdr);


retval = 0;

retval |= ctdbStringToDate(data1[i].orderdate, CTDATE_MDCY ,&orderdate);

retval |= ctdbStringToDate(data1[i].promisedate, CTDATE_MDCY, &promisedate);

/* populate record buffer with data */

retval |= ctdbSetFieldAsString(hRecordCustOrdr, 0, data1[i].type);

retval |= ctdbSetFieldAsString(hRecordCustOrdr, 1, data1[i].ordernum);

retval |= ctdbSetFieldAsDate(hRecordCustOrdr, 2, orderdate);

retval |= ctdbSetFieldAsDate(hRecordCustOrdr, 3, promisedate);

retval |= ctdbSetFieldAsString(hRecordCustOrdr, 4, data1[i].customernum);


if (retval)

Handle_Error("Add_CustomerOrders_Records(): ctdbSetFieldAsString()|ctdbSetFieldAsDate()");


/* add record */

if (ctdbWriteRecord(hRecordCustOrdr))

Handle_Error("Add_CustomerOrders_Records(): ctdbWriteRecord()");

}

}


/*

* Add_OrderItems_Records()

*

* This function adds records to table OrderItems from an

* array of strings

*/


typedef struct {

CTSTRING type;

COUNT sequencenum, quantity;

CTSTRING ordernum, itemnum;

} ORDERITEM_DATA;


ORDERITEM_DATA data2[] = {

{"I", 1, 2, "1", "1"},

{"I", 2, 1, "1", "2"},

{"I", 3, 1, "1", "3"},

{"I", 1, 3, "2", "3"}

};


#ifdef PROTOTYPE

VOID Add_OrderItems_Records(VOID)

#else

VOID Add_OrderItems_Records()

#endif

{

CTDBRET retval;

CTSIGNED i;

CTSIGNED nRecords = sizeof(data2) / sizeof(ORDERITEM_DATA);


if ((hRecordOrdrItem = ctdbAllocRecord(hTableOrdrItem)) == NULL)

Handle_Error("Add_OrderItems_Records(): ctdbAllocRecord()");


Delete_Records(hRecordOrdrItem);


printf("\tAdd records in table OrderItems...\n");


/* add records to table */

for (i = 0; i < nRecords; i++)

{

/* clear record buffer */

ctdbClearRecord(hRecordOrdrItem);


retval = 0;

/* populate record buffer with data */

retval |= ctdbSetFieldAsString(hRecordOrdrItem, 0, data2[i].type);

retval |= ctdbSetFieldAsString(hRecordOrdrItem, 1, data2[i].ordernum);

retval |= ctdbSetFieldAsSigned(hRecordOrdrItem, 2, data2[i].sequencenum);

retval |= ctdbSetFieldAsSigned(hRecordOrdrItem, 3, data2[i].quantity);

retval |= ctdbSetFieldAsString(hRecordOrdrItem, 4, data2[i].itemnum);


if(retval)

Handle_Error("Add_OrderItems_Records(): ctdbSetFieldAsString()");

/* add record */

if (ctdbWriteRecord(hRecordOrdrItem))

Handle_Error("Add_OrderItems_Records(): ctdbWriteRecord()");

}

}


/*

* Add_ItemMaster_Records()

*

* This function adds records to table ItemMaster from an

* array of strings

*/


typedef struct {

CTSTRING type;

CTSIGNED weight;

CTMONEY price;

CTSTRING itemnum, description;

} ITEM_DATA;


ITEM_DATA data3[] = {

{"M", 10, 1995, "1", "Hammer"},

{"M", 3, 999, "2", "Wrench"},

{"M", 4, 1659, "3", "Saw"},

{"M", 1, 398, "4", "Pliers"}

};


#ifdef PROTOTYPE

VOID Add_ItemMaster_Records(VOID)

#else

VOID Add_ItemMaster_Records()

#endif

{

CTDBRET retval;

CTSIGNED i;

CTSIGNED nRecords = sizeof(data3) / sizeof(ITEM_DATA);


if ((hRecordItemMast = ctdbAllocRecord(hTableItemMast)) == NULL)

Handle_Error("Add_ItemMaster_Records(): ctdbAllocRecord()");


Delete_Records(hRecordItemMast);


printf("\tAdd records in table ItemMaster...\n");


/* add records to table */

for (i = 0; i < nRecords; i++)

{

/* clear record buffer */

ctdbClearRecord(hRecordItemMast);


retval = 0;

/* populate record buffer with data */

retval |= ctdbSetFieldAsString(hRecordItemMast, 0, data3[i].type);

retval |= ctdbSetFieldAsString(hRecordItemMast, 1, data3[i].itemnum);

retval |= ctdbSetFieldAsSigned(hRecordItemMast, 2, data3[i].weight);

retval |= ctdbSetFieldAsMoney(hRecordItemMast, 3, data3[i].price);

retval |= ctdbSetFieldAsString(hRecordItemMast, 4, data3[i].description);


if(retval)

Handle_Error("Add_ItemMaster_Records(): ctdbSetFieldAsString()|ctdbSetFieldAsSigned()");


/* add record */

if (ctdbWriteRecord(hRecordItemMast))

Handle_Error("Add_ItemMaster_Records(): ctdbWriteRecord()");

}

}



/*

* Delete_Records()

*

* This function deletes all the records in the table based

* on the input parameter

*/


#ifdef PROTOTYPE

VOID Delete_Records(CTHANDLE hRecord)

#else

VOID Delete_Records(hRecord)

CTHANDLE hRecord;

#endif

{

CTDBRET retval;

CTBOOL empty;


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


if (ctdbClearRecord(hRecord))

Handle_Error("Delete_Records(): ctdbClearRecord()");


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()");

}

}

}


/*

* 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(hRecordCustMast);

ctdbFreeRecord(hRecordItemMast);

ctdbFreeRecord(hRecordOrdrItem);

ctdbFreeRecord(hRecordCustOrdr);


ctdbFreeTable(hTableCustMast);

ctdbFreeTable(hTableItemMast);

ctdbFreeTable(hTableOrdrItem);

ctdbFreeTable(hTableCustOrdr);


ctdbFreeSession(hSession);


getchar();


exit(1);

}

/* end of ctdb_tutorial2.c */

TOCIndex