Appendix A. Understanding DAME

This chapter gives more details about how DAME is implemented. We use the DAME syntax to walk through the functionalities of the application. This is not a formal syntax for DAME language. It is better to go through the sources and Antlr file src/dame/dame.g to understand the syntax. In this chapter we go through the DAMEs major syntactical elements to understand the semantics better. I hope that whatever information I missed out in the earlier parts of this Primer I will be able to capture here.

DAME Syntax

The DAME Script File

script_file : ( option_list )? ( header )? ( class_definition )*

The dame source file consists a set of options, a header that needs to be output verbatim into the header files generated and zero or more class definitions. According to this syntax an empty file is also a valid DAME source!. However, the source files are generated for each of the class definitions, so even if you have a proper DAME source file without class definitions, DAME can not do anything with it.

Future Additions: Currently with DAME you need to reproduce the options in each of the source files even though they are same. This will soon change and DAME will be able to pick default options from multiple sources (/etc/dameoptions, $HOME/.dameoptions and $CURRENTDIR/.dameoptions).

The options are a comma seperated list of the form variable = value. The value is always enclosed in "". The boolean options should be provided with values "true" or "false". DAME does not process anything in the raw_header. It just strips the initial '{' and '}' and writes it verbatim into the each header files it generates. The following options are supported by DAME

header_suffix and source_suffix

Suffixes to be used while generating C++ source code.

strip_first_char

Some coding standards insist that we prefix a 'C' before every class name. This option when set to true strips the first character from the class names and uses it for file name generation.

lower_case_file_names

Converts all characters in the class name to lower case and uses it as the filename.

use_namespace

This string is a standard C++ namespace string. The classes generated will be put into this namespace. Highly recommended to avoid namespace pollution.

Class Definitions

class_definition: CLASS className ( LPAREN for_class RPAREN )? LCURLY declaration_list function_list RCURLY SEMI

There are two types of classes that can be generated using DAME. One that can be used stand alone and one for which we will be making use of another associated class (for_class in the grammer). When for_class is omitted, you are expected to pass parameters to each of the functions you create - a void is also a valid parameter. When for_class was given a function declaration with no parameters assumes that the parameters are passed through a const for_class pointer.

The for_class is expected to be a regular C++ class. The class should implement accessors (settors and gettors) for each of the variables that are used in the DAME generated class. All getters start with Get and setters with Set.

The declaration list is a semi-colon seperated list of variable declarations. Unlike in C/C++ you can not declare more than a single variable in each statement. DAME supports the following data types:

int

Any integer type that is stored in the database can be used for this type. It includes NUMERIC, NUMBER with zero precision along with INTEGER, SMALLINT. This corresponds to C++ datatype int.

double

Any floating type that is stored in the database can be used for this type. It includes NUMERIC, NUMBER. This corresponds to C++ datatype double.

char

As with any database schema, the size of the character buffer is required when declaring a string. This can be any character string representation supported by the database like VARCHAR2, VARCHAR, char . This corresponds to C++ STL's std::string.

date

This data type represents the datetime field in the database. This corresponds to Posix time structure struct tm . DAME does not support reading date and time columns from the database. The date and time fields are converted into character strings before used by DAME. Hence any access to the date/time fields should convert the fields to/from character strings using the database provided functions like to_char and to_date.

The declaration list is followed by one or more function definitions. The function definitions are the topic of next section.

Function Definitions

function_def: ( for_class | VOID ) IDENTIFIER LPAREN ( param=id_commalist )? RPAREN LCURLY sql_statement RCURLY SEMI

A function definition always has a return type. The return type is either one of the variables that existed in the declaration list or the associated class defined for the DAME class (for_class). DAME will throw up an error, in case the return value is not a valid variable. The return value can also be void. If the sql_statement is a select statement and the return type is void, then DAME will assume that return type is for_class. Do not get confused by the return type of a function in the DAME source. The generated code always create functions that return void. All the errors are propogated using exceptions.

The parameters passed (id_commalist) is either a single word "void" or a comma seperated list of variables that exist in the declaration section of the class definition. If the parameter passed is void, the sql_statement can't make use of any variables from the declaration list. If the parameter list is empty, DAME assumes that the parameters are passed using the associated class (for_class).

The next section describes the sql_statement. The semi-colons at the end of function definitions are noise - but are required.

The SQL Statement

sql_statement: (.*) ( INTO target_comma_list )? FROM (.*)

DAME does not parse the SQL statement. Any syntactical errors or semantic errors (like table does not exist) were returned to the application at run time using exceptions. DAME removes the part from "into" till "from" from the sql_statement before it is passed to the database. DAME parses this part of the statement for a list of variables (prefixed by ':'). As a special case, a select statement that retrieves a single column need not have a INTO part, if the return type is specified in the function definition.

Future: Future versions of DAME will provide for replacements of regular expressions in an sql_statement while generating code. This rewrite engine might help us to write sql_statement for one specific database and use for multiple other databases using a map database. For example, Oracle™ 9i supports COALESCE where as Oracle™ 8i does not. In this case the map database entry can map coalesce into an equivalent using nvl.