gendb_syntax.hlp: (update in case/gen/gendb and in case/94s204) This note lists some syntactic requirements on gendb.cc schema files which will help avoid runtime errors: Many errors cause gendb to report ERR_ messages whose string argument "ERR_..." or numeric code (10xx) can be grepped-for in gendb.hpp; this locates the gendb method that passes the parameter string. Use grep -n or 'alias grep 'grep -n' to print the source file line number. -------------------------------------------------- 1.In a schema file, "parent(x,y,z)" can NOT have spaces around commas or BEFORE "(". (DO NOT INSERT ANY SPACES within this statement). Reason: (A) gendb's parser looks for "parent(". It does not complain about "parent (", but the result is a runtime error. (B) After "parent(" is recognized, gendb copies every byte between "(" and "," or between two "," separators, or between "," and ")" into argument strings. Although the integer arguments may be correctly converted by atoi or its equivalent (I didn't check), the Table and field name arguments will be stored with a leading or trailing blank inside: This will cause runtime errors (failure to match a table name during schema read-in, failure to match the field name during other gendb library functions). The same constraint may apply to the path statement (I didn't check). --------------------------------------------------- 2. Comments in the schema must be single lines and end at the newline: /*............*/ or //.............. and possibly /*............. but NOT multiline comments such as /* ............. ............. */ ------------------------------------------------- 3. One g++ error was fixed by initializiing static UserTypes::object_count immediately after the closing "}" of its class definition, instead of inside it. It must be at file scope, i.e. outside the definition of gendb.cc's or the application's main() and functions. This worked fine as long as you #include gendb.cc which #includes gendb.hpp only once. However, if you #include only gendb.hpp and link your application to a separately compiled gendb.o, ld fails with a multiply-defined warning (.hpp is included twice). The latest version of gendb.cc (2/23) initializes object_count once in gendb.cc to avoid this error. gendb now compiles together with or can be linked to your application. -------------------------------------------------- 4. One g++ error was fixed by adding the base class name (from which list inherits) after the ":" in the following: list(char *tname, int tsize) : (tname,tsize){} The following compiler message was eliminated by this fix: gendb.cc:2425: warning: ANSI C++ forbids old style base class initialization (this is a constructor defaulting to a call to the base class constructor, which must be identified now that multiple inheritance is supported by g++.) ----------------------------------------------------- 5. The format values for int field declarations in the schema must be i and not i(4) or i4 (as in gendb). Similarly, declare float fields as f not f4 or f8 as in gendb or f(4) or f(8). There are no 8-byte double-precision field options in gendb. -------------------------------------------------- 6. Tables should be declared in top-down order in the schema. This makes db.Unloads save parent records before any of their children. Without this constraint, there may be forward references to non-existent parents in each child. Their foreign keys (and chain pointers) cannot be assigned values until the parent is loaded. This requires a search to find the (potential) children of a parent every time a parent is loaded. You can call gendb's TopDownOnly method to avoid this overhead at runtime (Ref: gendb report 94/2/4 section 2.6). If TopDownOnly is falsely asserted, db.Load may fail and abort your program. To make TopDownOnly true, define your schema tables in top-down order (parents before children). Prepare your test data in this order as well. ----------------------------------------------------------- 7. Help on accessing a parent from a child and setting an iterator to refer to this parent: The proper syntax to make an iterator refer to the same row of a parent table that is referenced by a child-to-parent relation field in a child is: parent_iter.FindPKey(child_iter.ParentVal("child_to_parent_fieldname") E.g., TR.FindPKey( PA.ParentVal("trip")); (Thanks to DCalkin) (94/2/25) The reason for this is that the relation field "trip" has a string type with a c(8) value like the foreign key fields that db.Dump puts in db.dat files. Iterators on the other hand have an object identifier type and these identify table tuples - they do not point to char strings. ---------------------------------------------------- =========================================================== Help on specific runtime error messages: (Rev. 94/2/22-RJL) main() undefined: This is a Link-time error: Compiling and linking gendb.cc alone into a.out results in this error. The program gendb_test.cc un-comments gendb's main() to avoid this error. err-num 1044 (ERR_SCHEMA_EXPECT_CREATE): The program gendb_test.cc generates this runtime error from the schema parser. Test.dat is no longer compatible with (is incorrect for) test.sch, but test.sch is read before test.dat, so a faulty test.dat is not the likely cause. cs(170)> a.out STATE NULL ERROR: err_num = 1044, routine = Define, table = , info = 29 ------------------------------------------------------------