Database Schema Definition in C

For C projects, the database schema is specified in the eXtremeDB Data Definition Language (DDL) which identifies the database, defines each data class, its elements, its relationship to other data classes, and data access methods. The DDL syntax, keywords and preprocessor are designed to be similar to elements of the C language to simplify learning and understanding.

Whether intended for access from the C, C++, Java, Python or C# APIs or from embedded SQL statements, the schema is defined in a text file (commonly with extension .mco) using eXtremeDB Data Definition Language.

The DDL compiler mcocomp is then run to generate two header files (<database_name>.h and <database_name>.c) that are included into the C or C++ application source code and project. These generated files constitute the application specific Generated API used within the application to manage database objects.

For example, the following file schema.mco would define a simple database c_apidb consisting of a single class Person:

 
    declare database  c_apidb;
     
    class Person
    {
        string name;
        string address;
        string position;
        unsigned<4>  salary;
        float  rating;
         
        autoid_t<Person> manager;
        autoid[1000];
        tree<name> pk;
    };
     

As can be seen here, the eXtremeDB DDL uses a C-like syntax for defining the type and name of the fields within the database class. Please see the DDL pages for a complete definition of the DDL syntax.

Compiling the schema

The schema file is compiled by the mcocomp utility found in the eXtremeDB/host/bin directory of the eXtremeDB installation. For example, the following command will compile the example schema defined above when run from the directory containing schema.mco:

 
    eXtremeDB/host/bin/mcocomp schema.mco 
 

If the schema definition is syntactically correct, mcocomp will emit output like the following:

 
    eXtremeDB Data Definition Language Processor version 7.0 (Build 1792)
    Copyright (c) 2001-2016 McObject LLC.  All Rights Reserved.
     
    Compiled successfully: Mon Jan 23 15:40:42 2017
     

(Note that the first line of output indicates the eXtremeDBbuild number (in this case 1792) which can be useful if ever it is necessary to contact McObject Support for technical assistance.)

When successful, two C source code files (c_apidb.h and c_apidb.c in this case) will be generated that comprise the schema-specific API for this database. The header file c_apidb.h must be included in all C source files that will use the generated API. And the source file c_apidb.c must be included in the project to be compiled and linked with the application code.

Note that the generated .h and .c files must be included also in eXtremeSQL applications - even if all access to the eXtremeDB database will be through SQL only.

The following sample DDL specification illustrates many of the data types and declarations. (Please see the detailed description of eXtremeDB DDL syntax here and view other examples in the schema.mco files in SDK Samples.)

 
    #define int1	signed<1>
    #define int2	signed<2>
    #define int4	signed<4>
    #define uint4	unsigned<4>
    #define uint2	unsigned<2>
    #define uint1	unsigned<1>
     
    struct SampleStruct 
    {
        uint2	s1;
        char<20>	s2;
    };
    struct BigStruct 
    {
        string      str;
        uint2       u2;
        uint4       u4;
        vector     <SampleStruct> vss;
    };
     
    declare database	simple;
     
    /* Declare an OID - the estimated number of class instances is in square brackets */
    declare OID	SampleStruct[20000];
     
    /*
     * “compact” keyword: Total object size, including overhead is less than 64K.
     * Size calculation does NOT count size of blob(s) fields
    * embedded in the class
    */
    compact class SampleClass {
        /* basic data types */
        uint1 a = 0;
        uint2 b;
        uint4 c;
         
        /* oid reference */
        ref	  d;
         
        /* vectors - could be made of any type */
        vector <uint2>        numbers;
        vector <SampleStruct> ss;
         
        /* strings are limited to 64K */
        string                str;
         
        /* blobs are unlimited */
        blob                  blo;
         
        /* optional structure, the value could be missing */
        optional BigStruct	big_struct;
         
        /* voluntary means could be initiated and dropped at runtime
        * unique    means unique
        * tree      means tree-based index (sort order is supported)
        * hash      means hash-based index
        */
        voluntary unique tree< a,b,ss.s2> SAM;
         
        /* for hash indexes the estimated number of class instances is in square brackets */
        hash <a>     AAAA[10000];
        hash <ss.s2> SSS2[10000];
        hash <numbers> NNNN[10000];
         
        /* events can be defined for NEW, and DELETE operations 
        * and for UPDATE of the class-object or any field
        */
        event <new>	new;
        event <delete> delete;
        event <a update> update;
         
        /* declare an autoid and oid (internally managed hash indexes) for this class */
        autoid;
        oid;
         
        /*  list      means the objects could be sequentially scanned */
        list;
    };
     

The database dictionary

The generated header file (c_apidb.h in this case) contains struct, typedef and function prototype definitions for each class, field and index defined in the schema. The source code file (c_apidb.c in this case) contains the implementation of the functions defined in the header file. It may be interesting to examine these function implementations. Most of them call lower level "wrapper" functions with prefix "mco_w_". But one function, the "_get_dictionary()" function, is of particular importance. It has a name composed of the database name followed by suffix "_get_dictionary(void)". When compiled, this function contains the binary form of the schema that is loaded by the eXtremeDB runtime when the database open function mco_db_open_dev() is called with argument _get_dictionary(). This binary dictionary is used internally for all database access by the runtime.

Persistent Databases

For persistent database applications the schema is specified in the eXtremeDB Data Definition Language (DDL) exactly as for in-memory databases except for the declaration persistent for all classes that will be stored on persistent media. For example:

 
    persistent class Record 
    {
        unsigned<4> key;
        unsigned<4> value;
 
        unique tree<key> tkey;
    };
     

If all classes in the schema are persistent, an alternative is to use the -persistent option when compiling the schema with mcocomp. For example:

 
    mcocomp -persistent schema.mco