If you are creating a new application and have selected c-treeDB as the API of choice to access your data, there may be situations where you need to place calls directly into the ISAM or even low-level layers while remaining in your c-treeDB code. This may be to obtain certain specific services that are not directly supported by c-treeDB, or you may want to rewrite certain c-treeDB functionality to better suit your specific requirements.
It may also be common to find situations were you have an existing application written using the ISAM or Low-Level API and wish to develop new modules using the c-treeDB API and migrate the existing modules over time to c-treeDB. In either case you will need c-treeDB to support the mix of ISAM or low-level function calls with your c-treeDB code, specifically when you must work with a table's data and index files and record data.
Functionality has been added to more easily support using c-treeDB with multiple APIs.
c-treeDB, short for c-tree DataBase, is a high-level, easy-to-use API abstracting the c-tree ISAM and Low-Level APIs. c-treeDB is intended as the standard for c-tree programming.
The C functions and C++ methods described below present new functionality supplementing the c-treeDB C and C++ APIs.
If a c-treeDB application has multiple sessions, it may be necessary to force a c-tree instance switch before directing calls to ISAM and low-level functions to ensure those calls are made in the correct context.
This is particularly important in LOCLIB applications were you have one session connected to a c-tree Server, the remote session, and another session performing local I/O. In this case, it is very important to closely control which c-tree instance you require before making calls into the ISAM and low-level function layers.
Almost all c-treeDB functions automatically perform a c-tree instance switch for you; you need only take concern with c-tree instance switching in the case where you make ISAM or low-level calls within c-treeDB code.
The following c-treeDB C function performs a c-tree instance switch:
CTDBRET ctdbSwitchInstance(CTHANDLE Handle)
This call will force a switch to the c-tree Plus instance indicated by the Session handle. Each session handle has a unique c-tree instance id. When most c-treeDB functions are called, they automatically perform a c-tree instance switch. ctdbSwitchInstance is used before a call to a specific c-tree ISAM or low level function to ensure the correct instance is active before instantiating the call. You may pass any c-treeDB handle to ctdbSwitchInstance. CTDBRET_OK is returned on success.
Similarly, the following c-treeDB C++ method performs a c-tree instance switch:
void CTBase::SwitchInstance()
This method will force a switch to the c-tree instance indicated by the Session object. Each session object has a unique c-tree instance id. When most c-treeDB C++ methods are called, they automatically perform a c-tree instance switch. If any errors are detected, a CTException is thrown.
The following is an example demonstrating a server administration logon in a LOCLIB implementation then forcing a c-tree instance switch to the remote instance and calling some ctreeUserOperation function.
/* declare and allocate the remote and local session handles */
CTHANDLE hRemote = ctdbAllocSession(CTSESSION_CTREE);
CTHANDLE hLocal = ctdbAllocSession(CTSESSION_CTREE);
/* logon to c-tree server using the remote session handle */
if (ctdbLogon(hRemote, "FAIRCOMS", "ADMIN", "ADMIN") != CTDBRET_OK)
printf("Remote ctdbLogon failed\n");
/* logon to local session using the local session handle */
if (ctdbLogon(hLocal, "local", "ADMIN", "ADMIN") != CTDBRET_OK)
printf("Local ctdbLogon failed\n");
/* perform a c-tree instance switch and call ctreeUserOperation function */
if (ctdbSwitchInstance(hRemote) != CTDBRET_OK)
printf("ctdbSwitchInstance failed\n");
else
CtreeUserOperation("!mkdir faircom", buffer, sizeof(buffer));
Each time a record handle is allocated with ctdbAllocRecord, the allocated record handle acquires its own ISAM context, which means each record position operates independently from the other records. Record operations that move the current record position of one record handle will not interfere with other record handles.
If a c-treeDB application requires a call to the ISAM or low-level functions, it should ensure those calls are made in the correct ISAM context. All c-treeDB record handling functions automatically perform an ISAM context switch.
The following c-treeDB C function is used to perform a context switch:
CTDBRET ctdbSwitchContext(CTHANDLE Handle)
This call will force a switch to the c-tree ISAM context indicated by the record handle. Each record handle has a c-tree ISAM context id associated with it. When most c-treeDB record handling functions are called, they will automatically perform a c-tree ISAM context switch. ctdbSwitchContext is called before specific c-tree ISAM or low level calls to make sure the correct ISAM context is active before making those calls. The handle must be a record handle. No other handle is acceptable. CTDBRET_OK is returned on success.
Similarly, the following c-treeDB C++ method should be used to perform a context switch:
void CTRecord::SwitchContext()
This method will force a switch to the c-tree ISAM context indicated by the record object. Each record object may have its own c-tree ISAM context id. If any errors are detected, a CTException is thrown.
The following code snippet demonstrates use of the ctdbSwitchContext function to call the c-tree ISAM function ResetRecord.
/* force a context switch */
if (ctdbSwitchContext(hRecord) != CTDBRET_OK)
printf("ctdbSwitchContext failed\n");
/* call ResetRecord */
if (ResetRecord((COUNT)ctdbGetDatno(hRecord), SWTCURI))
printf("ResetRecord failed\n");
Most c-tree ISAM and low-level functions require a data or index file number to operate correctly. Data file operations may require a data file number while all index operations will require an index file number.
The c-treeDB C and C++ APIs provide several functions and methods to extract the data and index file numbers from c-treeDB record or table handles.
The following c-treeDB function will retrieve a data file number (or datno) from a table handle or any handle that can be converted into a table handle such as a record, segment, index and field handles:
NINT ctdbGetDatno(CTHANDLE Handle)
Retrieve the table datno. Handle must be a table handle, or a handle that can be converted into a table handle. Return the table datno on success or -1 on failure. If ctdbGetDatno() returns -1, the error code can be retrieved by calling the ctdbGetError() function.
The following c-treeDB method will similarly retrieve a data file number from a table object:
NINT CTTable::GetDatno()
If the GetDatno() method fails, a CTException is thrown.
An example using the c-treeDB C API:
CTDBRET DeleteTable(CTHANDLE hSession, pTEXT tablename)
{
CTDBRET Retval = CTDBRET_OK;
CTHANDLE hTable = ctdbAllocTable(hSession);
if (hTable)
{
/* open the table exclusive */
if ((Retval = ctdbOpenTable(hTable, tablename, CTOPEN_EXCLUSIVE)) != CTDBRET_OK)
return Retval;
/* delete a file */
if ((Retval = (CTDBRET)DeleteRFile((COUNT)ctdbGetDatno(hTable)) != CTDBRET_OK)
return Retval;
}
else
Retval = CTDBRET_NOMEMORY;
return Retval;
}
Three c-treeDB functions have been added to the c-treeDB API, which allow the retrieval of an index file number from a c-treeDB handle.
ctdbGetIdxno(), will retrieve an index file number from a c-treeDB handle and is declared as follows:
NINT ctdbGetIdxno(CTHANDLE Handle)
ctdbGetIdxnoByName() will retrieve an index file number given an index name and is declared as follows:
NINT ctdbGetIdxnoByName(CTHANDLE Handle, pTEXT indexname)
To retrieve the index file number by index number, call the c-treeDB function ctdbGetIdxnoByNumber() declared as follows:
NINT ctdbGetIdxnoByNumber(CTHANDLE Handle, NINT index)
These c-treeDB functions will return the index number on success or -1 on failure. If -1 is returned, the error code is retrieved with a call to the ctdbGetError() function.
Corresponding methods re available in the c-treeDB C++ API. The following method is used to retrieve the data file number from a CTTable object:
NINT CTTable::GetDatno()
This retrieves the table datno. A CTException is thrown if an error occurs.
The following methods are used to retrieve the index file number:
NINT CTIndex::GetIdxno()
This method retrieves the index file number from the index object.
NINT CTTable::GetIdxno(const CTString& IndexName)
This method retrieves the index file number from the table object, given the index name.
NINT CTTable::GetIdxno(NINT index)
This method retrieves the index file number from the table object, given the c-treeDB index number.
In all cases, if the GetIdxno() method fails, a CTException is thrown.
Below is a snippet demonstrating the c-treeDB C API function:
/* retrieve the first key of first index */
TEXT keyval[256];
if (FirstKey(ctdbGetIdxnoByNumber(hTable, 0)), keyval)
printf("FirstKey failed\n");