c-core/12_core/core12Example_main.c
/*
 * Raima Database Manager
 *
 * Copyright (c) 2019 Raima Inc.,  All rights reserved.
 *
 * Use of this software, whether in source code format, or in executable,
 * binary object code form, is governed by the Raima LICENSE which
 * is fully described in the LICENSE.TXT file, included within this
 * distribution of files.
 */
 
#include <stdio.h>
#include <string.h>
#include "example_fcns.h"
#include "rdm.h"
#include "rdmstartupapi.h"
 
/* Generated \c struct and \c typedef definitions to be used with the RDM APIs
 */
#include "core12_structs.h"
 
/* Generated catalog definition to be used with the RDM rdm_dbSetCatalog() API
 */
#include "core12_cat.h"
 
const char *const description = "Demonstrates transaction commit/rollback";
const RDM_CMDLINE_OPT opts[] = {{NULL, NULL, NULL, NULL}};
 
RDM_RETCODE openEmptyDatabase (
    RDM_TFS *pTFS, 
    RDM_DB *pDB)   
{
    RDM_RETCODE rc;
 
    rc = rdm_rdmAllocTFS (pTFS);
    print_error (rc);
    if (rc == sOKAY)
    {
        rc = rdm_tfsInitialize (*pTFS);
        print_error (rc);
        if (rc == sOKAY)
        {
            rc = rdm_tfsAllocDatabase (*pTFS, pDB);
            print_error (rc);
 
            if (rc == sOKAY)
            {
                /*
                 *  Associate the compiled catalog with the DB handle.
                 *  If the database does not exist on open, it will be created
                 *  in the default DOCROOT directory.
                 */
                rc = rdm_dbSetCatalog (*pDB, core12_cat);
                print_error (rc);
 
                if (rc == sOKAY)
                {
                    rc = rdm_dbOpen (*pDB, "core12"RDM_OPEN_EXCLUSIVE);
                    print_error (rc);
                }
 
                if (rc == sOKAY)
                {
                    rc = rdm_dbStartUpdate (
                        *pDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
                    print_error (rc);
                }
                if (rc == sOKAY)
                {
                    rc = rdm_dbDeleteAllRowsFromDatabase (*pDB);
                    print_error (rc);
                    rdm_dbEnd (*pDB);
                }
 
                /* If any of the above DB operations failed, free the DB handle
                 */
                if (rc != sOKAY)
                {
                    rdm_dbFree (*pDB);
                }
            }
        }
 
        /* If any of the above DB operations failed, free the TFS handle */
        if (rc != sOKAY)
        {
            rdm_tfsFree (*pTFS);
        }
    }
 
    return rc;
}
 
void cleanup (
    RDM_TFS hTFS, 
    RDM_DB hDB)   
{
    /* close the database */
    rdm_dbClose (hDB);
 
    /* free the database handle */
    rdm_dbFree (hDB);
 
    /* free the TFS handle */
    rdm_tfsFree (hTFS);
}
 
RDM_RETCODE display_offices (RDM_DB hDB) 
{
    RDM_RETCODE rc;
    OFFICE office_rec;
    RDM_CURSOR cursor = NULL;
 
    /* The following cursor association call will allocate the cursor
     *  if the cursor is set to NULL. This short-cut can eliminate the
     *  requirement to call rdm_dbAllocCursor() before using the cursor
     *  in this function */
    rc = rdm_dbGetRowsByKey (hDB, KEY_OFFICE_NAME, &cursor);
    print_error (rc);
 
    for (rc = rdm_cursorMoveToFirst (cursor); rc == sOKAY;
         rc = rdm_cursorMoveToNext (cursor))
    {
        /* Read and display the current person record */
        rc = rdm_cursorReadRow (cursor, &office_rec, sizeof (office_rec), NULL);
        print_error (rc);
        printf ("%s\n", office_rec.name);
    }
 
    /* free the cursor if it was allocated */
    if (cursor)
        rdm_cursorFree (cursor);
 
    /* Expect rc to be sENDOFCURSOR when we exit the loop */
    if (rc == sENDOFCURSOR)
    {
        rc = sOKAY;
    }
    return rc;
}
 
RDM_RETCODE insertOffices (RDM_DB hDB, const char **officeList, size_t listSize)
{
    RDM_RETCODE rc;
    OFFICE office_rec;
    int ii;
 
    for (ii = 0; ii < (int) listSize; ii++)
    {
        strncpy (office_rec.name, officeList[ii], sizeof (office_rec.name));
        rc = rdm_dbInsertRow (
            hDB, TABLE_OFFICE, &office_rec, sizeof (office_rec), NULL);
        print_error (rc);
    }
    return rc;
}
 
static const char *na_office_names[] = {"Seattle""Boise""San Francisco",
                                        "Dallas"};
static const char *emea_office_names[] = {"Paris""London""Dublin""Zurich",
                                          "Madrid"};
 
#define RLEN(x) (sizeof (x) / sizeof (x[0]))
 
int main_core12 (int argc, const char *const *argv)
{
    RDM_RETCODE rc;
    RDM_TFS hTFS;
    RDM_DB hDB;
 
    rc = rdm_cmdlineInit (&cmd, argc, argv, description, opts);
    if (rc != sCMD_USAGE)
        print_error (rc);
 
    if (rc == sOKAY)
    {
        rc = openEmptyDatabase (&hTFS, &hDB);
        if (rc == sOKAY)
        {
            rc = rdm_dbStartUpdate (hDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
            print_error (rc);
 
            if (rc == sOKAY)
            {
                insertOffices (hDB, na_office_names, RLEN (na_office_names));
                printf ("\nAll Offices before transaction commit.\n");
                display_offices (hDB);
 
                rdm_dbEnd (hDB);
                print_error (rc);
 
                if (rc == sOKAY)
                {
                    /* Display all offices */
                    printf ("\nAll Offices after transaction commit.\n");
                    display_offices (hDB);
                }
            }
            if (rc == sOKAY)
            {
                rc = rdm_dbStartUpdate (hDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
                print_error (rc);
 
                if (rc == sOKAY)
                {
                    insertOffices (
                        hDB, emea_office_names, RLEN (emea_office_names));
 
                    printf ("\nAll Offices before transaction commit.\n");
                    display_offices (hDB);
 
                    rc = rdm_dbEndRollback (hDB);
                    print_error (rc);
 
                    /* Display all offices */
                    printf ("\nAll Offices after transaction rollback.\n");
                    display_offices (hDB);
                }
            }
        }
        cleanup (hTFS, hDB);
    }
    return (int) rc;
}
 
RDM_RETCODE rdm_cursorMoveToFirst(RDM_CURSOR cursor)
Position a cursor to the first row in the collection.
RDM_RETCODE rdm_cursorMoveToNext(RDM_CURSOR cursor)
Position a cursor to the next row in the collection.
Header for the native RDM Runtime API.
RDM_RETCODE rdm_rdmAllocTFS(RDM_TFS *phTFS)
Allocate a TFS handle.
RDM_RETCODE rdm_dbEnd(RDM_DB db)
End a transactional operation.
@ sCMD_USAGE
Definition: rdmretcodetypes.h:71
RDM_RETCODE rdm_dbDeleteAllRowsFromDatabase(RDM_DB db)
Remove all rows from a database.
struct RDM_CURSOR_S * RDM_CURSOR
Definition: rdmtypes.h:304
RDM_RETCODE rdm_cursorReadRow(RDM_CURSOR cursor, void *colValues, size_t bytesIn, size_t *bytesOut)
Read all columns from a row.
@ RDM_OPEN_EXCLUSIVE
Definition: rdmtypes.h:254
The buffer used by the command line parser to hold state information.
Definition: rdmcmdlinetypes.h:85
RDM_RETCODE rdm_dbClose(RDM_DB db)
Close the database associated with a database handle.
RDM_RETCODE rdm_dbGetRowsByKey(RDM_DB db, RDM_KEY_ID keyId, RDM_CURSOR *pCursor)
Associate an RDM_CURSOR with a row set based on a key.
RDM_RETCODE rdm_dbSetCatalog(RDM_DB db, const char *catalog)
Associate a catalog with an allocated database.
RDM_RETCODE rdm_dbFree(RDM_DB db)
Free a database handle.
RDM_RETCODE rdm_dbOpen(RDM_DB db, const char *dbNameSpec, RDM_OPEN_MODE mode)
Open an existing RDM database using the specified database handle.
@ sOKAY
Definition: rdmretcodetypes.h:95
Generic usage function option record.
Definition: rdmcmdlinetypes.h:32
RDM_RETCODE rdm_cursorFree(RDM_CURSOR cursor)
Free an RDM_CURSOR.
RDM_RETCODE rdm_tfsAllocDatabase(RDM_TFS tfs, RDM_DB *pDb)
Allocate memory for a new RDM db.
#define RDM_STARTUP_EXAMPLE(name)
Definition: rdmstartuptypes.h:73
RDM_RETCODE rdm_dbEndRollback(RDM_DB db)
End and rollback a transactional operation.
RDM_RETCODE rdm_dbInsertRow(RDM_DB db, RDM_TABLE_ID tableId, const void *colValues, size_t bytesIn, RDM_CURSOR *pCursor)
Insert a new row into a table at the specified rowId.
struct RDM_TFS_S * RDM_TFS
RDM TFS Handle.
Definition: rdmtfstypes.h:21
RDM_RETCODE rdm_cmdlineInit(RDM_CMDLINE *cmd, int32_t argc, const char *const argv[], const char *description, const RDM_CMDLINE_OPT *opts)
Initialize an RDM_CMDLINE buffer and validate the command line.
struct RDM_DB_S * RDM_DB
Definition: rdmtypes.h:303
RDM_RETCODE rdm_tfsFree(RDM_TFS hTFS)
Terminate a TFS service.
#define RDM_LOCK_ALL
Definition: rdmtypes.h:170
RDM_RETCODE rdm_dbStartUpdate(RDM_DB db, const RDM_TABLE_ID *writeTableIds, uint32_t numWriteTableIds, const RDM_TABLE_ID *readTableIds, uint32_t numReadTableIds, RDM_TRANS *pTrans)
Get write locks.
@ sENDOFCURSOR
Definition: rdmretcodetypes.h:58
Internal RDM Startup API used by startup macros.
RDM_RETCODE
RDM status and error return codes.
Definition: rdmretcodetypes.h:43
RDM_RETCODE rdm_tfsInitialize(RDM_TFS tfs)
Initialize a RDM_TFS instance.