c-core/07_core/core07Example_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 "core07_structs.h"
 
/* Generated catalog definition to be used with the RDM rdm_dbSetCatalog() API
 */
#include "core07_cat.h"
 
const char *const description = "Demonstrates using an index for ordering";
const RDM_CMDLINE_OPT opts[] = {{NULL, NULL, NULL, NULL}};
 
RDM_RETCODE insertStudents (RDM_DB hDB)
{
    RDM_RETCODE rc;
    STUDENT student_rec;
 
    rc = rdm_dbStartUpdate (hDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
    print_error (rc);
    if (rc == sOKAY)
    {
        /* Create a few student records */
        strcpy (student_rec.name, "Jeff");
        rc = rdm_dbInsertRow (
            hDB, TABLE_STUDENT, &student_rec, sizeof (student_rec), NULL);
        print_error (rc);
 
        if (rc == sOKAY)
        {
            strcpy (student_rec.name, "Brooke");
            rc = rdm_dbInsertRow (
                hDB, TABLE_STUDENT, &student_rec, sizeof (student_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            strcpy (student_rec.name, "Jonah");
            rc = rdm_dbInsertRow (
                hDB, TABLE_STUDENT, &student_rec, sizeof (student_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            strcpy (student_rec.name, "Norah");
            rc = rdm_dbInsertRow (
                hDB, TABLE_STUDENT, &student_rec, sizeof (student_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            strcpy (student_rec.name, "Micah");
            rc = rdm_dbInsertRow (
                hDB, TABLE_STUDENT, &student_rec, sizeof (student_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
            rc = rdm_dbEnd (hDB);
        else
            rc = rdm_dbEndRollback (hDB);
 
        print_error (rc);
    }
    return rc;
}
 
RDM_RETCODE insertClasses (RDM_DB hDB)
{
    RDM_RETCODE rc;
    CLASS course_rec;
 
    rc = rdm_dbStartUpdate (hDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
    print_error (rc);
    if (rc == sOKAY)
    {
        /* Create a few classes */
        if (rc == sOKAY)
        {
            strcpy (course_rec.id, "ACCTG1A");
            strcpy (course_rec.title, "Principles of Accounting");
            rc = rdm_dbInsertRow (
                hDB, TABLE_CLASS, &course_rec, sizeof (course_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            strcpy (course_rec.id, "MATH037");
            strcpy (course_rec.title, "Finite Mathematics");
            rc = rdm_dbInsertRow (
                hDB, TABLE_CLASS, &course_rec, sizeof (course_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            strcpy (course_rec.id, "CAOTO15");
            strcpy (course_rec.title, "Business Communications");
            rc = rdm_dbInsertRow (
                hDB, TABLE_CLASS, &course_rec, sizeof (course_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            strcpy (course_rec.id, "CBIS36");
            strcpy (course_rec.title, "Systems Analysis and Design");
            rc = rdm_dbInsertRow (
                hDB, TABLE_CLASS, &course_rec, sizeof (course_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            strcpy (course_rec.id, "IBUS1");
            strcpy (course_rec.title, "Introduction to International Business");
            rc = rdm_dbInsertRow (
                hDB, TABLE_CLASS, &course_rec, sizeof (course_rec), NULL);
            print_error (rc);
        }
 
        if (rc == sOKAY)
            rc = rdm_dbEnd (hDB);
        else
            rc = rdm_dbEndRollback (hDB);
 
        print_error (rc);
    }
    return rc;
}
 
RDM_RETCODE register_for_course (
    const char *student_name, 
    const char *course_id,    
    RDM_DB hDB)               
{
    RDM_RETCODE rc;
    RDM_CURSOR studentCursor = NULL;
    RDM_CURSOR classCursor = NULL;
    RDM_CURSOR enrollmentCursor = NULL;
    CLASS_ID_KEY classKey;
    STUDENT_NAME_KEY studentKey;
    ENROLLMENT enroll_rec;
 
    rc = rdm_dbStartUpdate (hDB, RDM_LOCK_ALL, 0, NULL, 0, NULL);
    print_error (rc);
    if (rc == sOKAY)
    {
        /* Find the student record and setup a cursor pointing to it */
        strcpy (studentKey.name, student_name);
        rc = rdm_dbGetRowsByKeyAtKey (
            hDB, KEY_STUDENT_NAME, &studentKey, sizeof (studentKey),
            &studentCursor);
        print_error (rc);
 
        if (rc == sOKAY)
        {
            /* Find the course record and setup a cursor pointing to it */
            strcpy (classKey.id, course_id);
            rc = rdm_dbGetRowsByKeyAtKey (
                hDB, KEY_CLASS_ID, &classKey, sizeof (classKey), &classCursor);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            /* Create the enrollment record */
            /* Set the enrollment date to today and mark the column that it
             * contains a value */
            rdm_dateToday (0, &enroll_rec.begin_date);
            enroll_rec._begin_date_has_value = RDM_TRUE;
 
            /* Set the status to enrolled and mark the column that it contains a
             * value
             */
            strcpy (enroll_rec.status, "enrolled");
            enroll_rec._status_has_value = RDM_TRUE;
 
            /* mark the rest of the data columns empty */
            enroll_rec._end_date_has_value = RDM_FALSE;
            enroll_rec._current_grade_has_value = RDM_FALSE;
 
            /* mark the set relationships as not-linked */
            enroll_rec._class_students_has_value = RDM_FALSE;
            enroll_rec._student_classes_has_value = RDM_FALSE;
 
            /* create a new course_registration record */
            rc = rdm_dbInsertRow (
                hDB, TABLE_ENROLLMENT, &enroll_rec, sizeof (enroll_rec),
                &enrollmentCursor);
            print_error (rc);
        }
 
        if (rc == sOKAY)
        {
            /* Associate the student and the course via the course_registartion
             * sets */
            rc = rdm_cursorLinkRow (
                enrollmentCursor, REF_ENROLLMENT_CLASS_STUDENTS, classCursor);
            print_error (rc);
        }
        if (rc == sOKAY)
        {
            rc = rdm_cursorLinkRow (
                enrollmentCursor, REF_ENROLLMENT_STUDENT_CLASSES,
                studentCursor);
            print_error (rc);
        }
 
        if (rc == sOKAY)
            rc = rdm_dbEnd (hDB);
        else
            rc = rdm_dbEndRollback (hDB);
 
        print_error (rc);
    }
    return rc;
}
 
RDM_RETCODE registerForClasses (RDM_DB hDB)
{
    RDM_RETCODE rc;
 
    rc = register_for_course ("Jeff""IBUS1", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Jeff""CAOTO15", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Jeff""ACCTG1A", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Brooke""CBIS36", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Brooke""IBUS1", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Jonah""MATH037", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Jonah""CBIS36", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Norah""IBUS1", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Norah""ACCTG1A", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Norah""MATH037", hDB);
    if (rc == sOKAY)
        rc = register_for_course ("Micah""ACCTG1A", hDB);
 
    return rc;
}
 
RDM_RETCODE displayClassRoster (RDM_DB hDB)
{
    RDM_RETCODE rc;
    STUDENT student_rec;
    CLASS course_rec;
 
    rc = rdm_dbStartRead (hDB, RDM_LOCK_ALL, 0, NULL);
    print_error (rc);
    if (rc == sOKAY)
    {
        RDM_CURSOR studentCursor = NULL;
        RDM_CURSOR classCursor = NULL;
        RDM_CURSOR enrollmentCursor = NULL;
 
        printf ("\nList of courses each student is registered for\n");
 
        /* Read each student name from the STUDENT table */
        rc = rdm_dbGetRows (hDB, TABLE_STUDENT, &studentCursor);
        print_error (rc);
        for (rc = rdm_cursorMoveToFirst (studentCursor); rc == sOKAY;
             rc = rdm_cursorMoveToNext (studentCursor))
        {
            rc = rdm_cursorReadRow (
                studentCursor, &student_rec, sizeof (student_rec), NULL);
            print_error (rc);
            printf ("%s\n", student_rec.name);
 
            /* For each enrollment record associated with the STUDENT */
            rc = rdm_cursorGetMemberRows (
                studentCursor, REF_ENROLLMENT_STUDENT_CLASSES,
                &enrollmentCursor);
            print_error (rc);
            for (rc = rdm_cursorMoveToFirst (enrollmentCursor); rc == sOKAY;
                 rc = rdm_cursorMoveToNext (enrollmentCursor))
            {
                ENROLLMENT enroll_rec;
                char begin_date[100];
 
                rc = rdm_cursorReadRow (
                    enrollmentCursor, &enroll_rec, sizeof (enroll_rec), NULL);
                print_error (rc);
                rc = rdm_dateToString (
                    enroll_rec.begin_date, RDM_YYYYMMDD'-', begin_date,
                    sizeof (begin_date), NULL);
                print_error (rc);
 
                /* Find the COURSE name associated with the enrollment record
                 * read */
                rc = rdm_cursorGetOwnerRow (
                    enrollmentCursor, REF_ENROLLMENT_CLASS_STUDENTS,
                    &classCursor);
                rc = rdm_cursorReadRow (
                    classCursor, &course_rec, sizeof (course_rec), NULL);
                print_error (rc);
                printf (
                    "\t%s: %s\t%s\n", begin_date, course_rec.id,
                    course_rec.title);
            }
            /* a successful navigation of the cursor list for ENROLLMENT will
             * return sENDOFCURSOR */
            if (rc == sENDOFCURSOR)
                rc = sOKAY;
        }
        /* a successful navigation of the cursor list for STUDENT will return
         * sENDOFCURSOR */
        if (rc == sENDOFCURSOR)
            rc = sOKAY;
 
        /* free the cursor resources that were allocated */
        if (classCursor)
            rdm_cursorFree (classCursor);
        if (studentCursor)
            rdm_cursorFree (studentCursor);
        if (enrollmentCursor)
            rdm_cursorFree (enrollmentCursor);
 
        rdm_dbEnd (hDB);
    }
    return rc;
}
 
int main_core07 (int argc, const char *const *argv)
{
    RDM_TFS hTFS;
    RDM_DB hDB;
    RDM_RETCODE rc;
 
    rc = rdm_cmdlineInit (&cmd, argc, argv, description, opts);
    if (rc != sCMD_USAGE)
        print_error (rc);
    if (rc == sOKAY)
    {
        rc = exampleOpenEmptyDatabase (&hTFS, &hDB, "core07", core07_cat);
        if (rc == sOKAY)
        {
            rc = insertStudents (hDB);
            if (rc == sOKAY)
            {
                rc = insertClasses (hDB);
            }
            if (rc == sOKAY)
            {
                rc = registerForClasses (hDB);
            }
            if (rc == sOKAY)
            {
                rc = displayClassRoster (hDB);
            }
            exampleCleanup (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_dateToString(RDM_PACKED_DATE_T dateVal, RDM_DATE_FORMAT date_fmt, char date_sep, char *buf, size_t bufSize, size_t *puSize)
Convert a date to a string.
@ RDM_FALSE
Definition: psptypes.h:59
RDM_RETCODE rdm_dbEnd(RDM_DB db)
End a transactional operation.
@ sCMD_USAGE
Definition: rdmretcodetypes.h:71
struct RDM_CURSOR_S * RDM_CURSOR
Definition: rdmtypes.h:304
RDM_RETCODE rdm_dbStartRead(RDM_DB db, const RDM_TABLE_ID *tableIds, uint32_t numTableIds, RDM_TRANS *pTrans)
Get read locks.
RDM_RETCODE rdm_cursorReadRow(RDM_CURSOR cursor, void *colValues, size_t bytesIn, size_t *bytesOut)
Read all columns from a row.
The buffer used by the command line parser to hold state information.
Definition: rdmcmdlinetypes.h:85
RDM_RETCODE rdm_cursorLinkRow(RDM_CURSOR cursor, RDM_REF_ID refId, RDM_CURSOR cursorOwner)
Link a row to an owner.
@ sOKAY
Definition: rdmretcodetypes.h:95
@ RDM_TRUE
Definition: psptypes.h:60
RDM_RETCODE rdm_dbGetRowsByKeyAtKey(RDM_DB db, RDM_KEY_ID keyId, const void *keyValue, size_t len, RDM_CURSOR *pCursor)
Associate an RDM_CURSOR with a row set that is ordered by key value and is initially positioned at th...
Generic usage function option record.
Definition: rdmcmdlinetypes.h:32
@ RDM_YYYYMMDD
Definition: rdmdatetimetypes.h:148
RDM_RETCODE rdm_cursorFree(RDM_CURSOR cursor)
Free an RDM_CURSOR.
#define RDM_STARTUP_EXAMPLE(name)
Definition: rdmstartuptypes.h:73
RDM_RETCODE rdm_dateToday(int16_t time_zone, RDM_PACKED_DATE_T *pdt)
Get the current date.
RDM_RETCODE rdm_dbGetRows(RDM_DB db, RDM_TABLE_ID tableId, RDM_CURSOR *pCursor)
Associate an RDM_CURSOR with rows based on a table id.
RDM_RETCODE rdm_dbEndRollback(RDM_DB db)
End and rollback a transactional operation.
RDM_RETCODE rdm_cursorGetMemberRows(RDM_CURSOR ownerCursor, RDM_REF_ID refId, RDM_CURSOR *pCursor)
Associate an RDM_CURSOR with members.
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_cursorGetOwnerRow(RDM_CURSOR memberCursor, RDM_REF_ID refId, RDM_CURSOR *pCursor)
Associate an RDM_CURSOR with a set owner.
#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