Using DAME With C++ Classes

DAME will not be useful if it returns single values from select statements. In most cases we will be required to select one or more rows from the database tables. For example, we might want to get an employee record given an employee ID. The next example shows how we can achieve this.

The DAME Source

example2.dame
                options {
                    header_suffix = ".hpp",
                    source_suffix = ".cpp",
                    strip_first_char = "false",
                    lower_case_file_names = "false",
                    use_namespace = "Dame::Example"
                }

                header {
                    #include "emp.hpp"
                }

                class SelectDB (Dame::ExampleDb::emp)
                {
                    int         Empno ;
                    char        Name[11] ;
                    char        Job[10] ;
                    int         Manager ;
                    double      Salary ;
                    double      Commission ;
                    int         Deptno ;
                    int         Count ;
                    date        Hiredate ;

                    /*
                    * Simplest form of select statement can be used as follows
                    */

                    Dame::ExampleDb::emp GetByEmpno (Empno) {
                        select empno, ename, job, coalesce(mgr,0), sal, coalesce(comm, 0), deptno, to_char(hiredate, 'dd/mm/yyyy hh24:mi:ss')
                        into :Empno, :Name, :Job, :Manager, :Salary, :Commission, :Deptno, :Hiredate
                        from emp
                        where empno = :Empno
                    } ;
                    ...
                } ;
            

The options section in the above example is selfexplanatory. The strip_first_char option exists, so that we can name our classes like CEmployee and still able to get file names like Employee. DAME has support for namespaces. The emp is expected to be in Dame::ExampleDb namespace. The SelectDB class will be generated in the namespace Dame::Example. Note the into to collect the column values into the local variables. The into-list is not needed when we are selecting a single column value using the SQL statement as in earlier examples.

DAME expects the Dame::ExampleDb::emp to be defined. The definition should have setters/getters in the form of Get<variable> and Set<variable> for all the member variables that need to be accessed from the defined database access class Dame::Example::SelectDB.

Since the generated code now needs to access to the definition of emp, we include the definition using the header directive. All the text within the '{' and '}' of the header directive will be copied verbatim into the resulting Header files.

Note the declaration for the SelectDB class. Now we tell DAME to make use of the emp declaration while generating the code. Besides this, the only change is in the return value of the function GetByEmpno. We are now informing DAME that we need an emp record to be returned.

Accessing the emp record

Whenever the GetByEmpno is called, the function in-turns calls the Iterator object that is passed. The Iterator object will be passed a pointer to an emp record. When the call returns, the pointer is deleted unless and otherwise told not to do so.

We can pass a function pointer using std::ptr_fun if some function definition is similar to:

            int SomeFunction (Dame::ExampleDb::emp*) ;
            

The following code stores the pointer in a variable and prints the details using that variable.

example2.cpp

                Dame::Example::SelectDB                 edb (&db) ;
                Dame::ExampleDb::emp*                   ep ;
                edb.GetByEmpno (7369, Dame::make_single(&ep)) ;
                if (ep)
                    ep->Print() ;
                else
                    std::cout << "Record does not exist" << std::endl ;