ObjectStore Building C++ Interface Applications
Chapter 3
Generating Schemas
This chapter provides instructions for using the schema generator to generate application, component, library, and compilation schemas.
Caution
Be sure you can successfully compile your code before you generate a schema. You should not use the schema generator to validate your code.
The topics discussed in this chapter are
Overview of Schema Generation
A schema contains information about a set of classes. ObjectStore defines these kinds of schemas:
You use the ObjectStore schema generator to generate application, component, library, and compilation schemas. ObjectStore creates database schemas.
ObjectStore stores each application, component, library, and compilation schema in its own ObjectStore database. ObjectStore stores database schemas in the associated database or in a separate database that you specify.
Each schema database must be accessible to an ObjectStore Server.
Application Schemas
An application schema contains descriptions of
ObjectStore uses the application schema during run time to
For simple applications, you can use a single invocation of ossg to generate an application schema. In more complex applications, you might need to use library schemas to store schema information before constructing the application schema.
Component Schemas
A component schema is a type of application schema that can be loaded and unloaded dynamically at run time. Typically, a component schema is also a self-contained schema associated with a DLL.
The rules for generating component schemas are identical to those for generating application schema, with these differences:
Library Schemas
If your application uses a library that stores or retrieves persistent data, and the library does not supply its own component schema, use the schema generator to create a library schema for that library. When you generate the application schema, you specify the library schema. This allows the schema generator to generate an application schema that contains information for all persistently used types.
It is particularly important that a library schema contain definitions of persistently allocated types that users of the library do not have access to.
In addition to the library schemas you create, ObjectStore provides library schemas for its libraries that use persistent data. If you link your application with an ObjectStore library that has a library schema, you must specify that library schema when you generate the application schema. See Specifying ObjectStore Library Schemas.
Compilation Schemas
A compilation schema works like a library schema. A compilation schema contains information about the application's persistent types, but does not contain information about any persistent types used by any libraries that the application links with. Earlier releases of ObjectStore on some platforms required a compilation schema before you could generate an application schema. With ObjectStore Release 5.0 and later, you still can create a compilation schema and generate the application schema from the compilation schema, but it is no longer required.
Database Schemas
ObjectStore creates a database schema from the application and component schemas of all applications that allocate objects in the database. The database schema consists of the definitions of all types of objects that have ever been stored, or are expected to be stored, in the database.
Normally, ObjectStore stores a database schema in segment 0 of the database. (In each database, segment 0 is a special segment that is reserved for ObjectStore use.)
You can, however, specify an alternative database to contain the database schema. You do this when you create the database. The database whose schema is stored in another database is referred to as a remote schema database. The database that contains the schema belonging to the remote schema database is referred to as the schema database. The schema for a remote schema database resides in segment 0 of the schema database.
An application augments a database schema through batch (the default) or incremental schema installation.
With batch schema installation, the first time an application accesses a database, each class in the application's schema that can be persistently allocated is added to the database's schema (if it is not already present in the database schema). Subsequent execution of the application does not install schema in that database unless the application's schema changes (as evidenced by a change in the internally stored date of the application schema database).
With incremental schema installation, a class is added to a database's schema only when the first instance of that class is allocated in the database. You can specify incremental schema installation for a particular database in your source code.
The following table is a simple comparison of batch and incremental schema installation:
Keeping Database Schemas and Application Schemas Compatible
Each ObjectStore database has its own database schema. Each With the exception of component schema, anObjectStore application is associated with one application schema or multiple component schemas. Many users can share an application schema and use it with different applications. When an application opens a database, the application's schema must be compatible with the database's schema. Compatibility means that if a class exists in both schemas,
ObjectStore flags differences as schema validation exceptions.
Multiple Component Schemas
Multiple component schemas can be used in one application.
If two program schemata that are loaded into the same complete program schema define types with the same name, the type definitions must be identical.
This is only checked for types that appear in the schema of a database that is in use. An error will show up as a schema validation error.
When a new type is installed into a database schema, it will be validated against all program schemata and a schema validation error will be signaled if there are multiple inconsistent definitions.
Schemas Are Platform Specific
After you generate a schema, you can use it only on the platform on which you generated it. If you try to generate an application schema from one or more schemas that were built on other platforms, ossg aborts the process and displays a message indicating why. If you want to use a library schema on multiple platforms, you must generate it on each platform on which you want to use it.
Consider that an application schema corresponds to an executable, a component schema corresponds to a DLL, a library schema corresponds to a library, and a compilation schema corresponds to an object file. Just as executables, libraries, and object files are platform specific, so are their accompanying schema databases.
Generating an Application or Component Schema
Input
To generate an application schema, specify your schema source file as input to ossg. If you are linking with libraries that have library schemas, you must also specify those library schemas as input to ossg. This procedure is also true for component schema.
Output
The output from ossg is
You must compile this file and then link the resulting object file with your application. (Chapter 4, Compiling, Linking, and Debugging Programs, provides the details for linking.)
When you use ossg on Windows platforms, the schema generator creates the application schema object file directly.
Following is an illustration of the application schema generation process, extending to just before the link step.
Invoking ossg to Generate an Application Schema
The ossg command syntax for generating application, library, and compilation schemas appears below. Portions of the command line are on different lines only to make them more understandable.
ossg [ neutralizer_options] [ additional_app_options] [{-assf
app_schema_source_file | -asof app_schema_object_file.obj}]
-asdb app_schema_db schema_source_file [ lib_schema_db1 ... lib_
schema_dbn]-cd class_definition_file
ossg [ neutralizer_options] [ additional_options] -lsdb lib_schema_db
schema_source_file
ossg [ neutralizer_options] [ additional_options] -csdb comp_schema_db
schema_source_file
neutralizer_options: [-arch setn...] [{-padm | -padc}] [-ostyp]
[-nout file_name][{-showd | -showw}] [-nor] [-sopt]
additional_app_options: [{ -mrlcp | -mrscp }] [-rtdp]
[-no_weak_symbols] [ additional_options]
additional_options: [-no_default_includes] [-mrscp]
additional_options: [-smf] [{-sfbp | -pfb}]
ossg [ compilation_options] [ neutralizer_options] [-cpp_fixup]
[-final_asdb final_app_schema_db]
[-E schema_source_file]
compilation_options
| Specifies any options that would be passed to the compiler if you were compiling a schema source file instead of generating schema from it. You should include any preprocessor options such as include file paths and macro definitions, as well as compiler options that might affect object layout, such as packing options (for example, /Zp4 for Visual C++). Optional.
If you specify the /I, -I (uppercase I), /D, or -D option, do not include a space between the option and the argument. For example, on OS/2 the following is correct:
ossg /I$(OS_ROOTDIR)\include ...
On UNIX, do not specify the -o option on the ossg command line.
On Windows, do not specify /Tp on the ossg command line.
On OS/2, when you specify any option that takes an argument do not put a space between the option and the argument.
|
neutralizer_options
| Include any of the options in ossg Neutralization Options. These options allow you to neutralize a schema for a heterogeneous application. You can include them in any order.
Optional. The default is that neutralization is not done.
|
-arch set n
| The schema that is generated or updated will be neutralized to be compatible with the architectures in the specified set. See ossg Neutralization Options for explanations of the set options.
Required when you are neutralizing schema. No default.
|
-cpp_fixup
| Allows preprocessor output to contain spaces inside C++ tokens. Specify this option if your preprocessor inserts a space between consecutive characters that form C++ tokens. For example, if your preprocessor changes :: to : :, you can specify this option so that the schema generator allows the inserted space and correctly reads the preprocessor output.
You might generate an application schema from a compilation schema and library schemas. In this case, you do not need this option because there is no source code input to the schema generator, which means that the preprocessor is not involved.
Optional. The default is that ossg does not allow a space in a C++ token such as :: or .*.
|
-E schema_source_file
| The -E option causes ossg to preprocess the input file and send the preprocessed output to standard output.
This option is useful for debugging ossg parsing problems, because it allows you to see the results of any preprocessing that might have occurred without generating the schema. It is also useful when you report ossg problems to Technical Support because it allows the problem to be reproduced by Object Design without the need to package all your application's include files.
When specifying the -E argument, you cannot specify schema databases on the same command line. Only the schema source file and preprocessor switches, such as macro definitions and include paths, should be specified.
|
-final_asdb final_app_schema_db
| Specifies a location for the application schema database that is different from the location you specify with the -asdb option. The schema generator writes the location you specify with the -final_asdb option into the application schema source file (application schema object file for Visual C++). Use this option when you cannot specify the desired location with the -asdb option. The -asdb option is still required and that is where the schema generator places the application schema.
This option is useful when you plan to store the application schema database as a derived object in a ClearCase versioned object base (VOB). The schema generator cannot place the application schema database directly in a ClearCase VOB. If you specify the -final_asdb option with the desired location, you avoid the need to run the ossetasp utility, which patches an executable so that it looks for its application schema in a database that you specify.
You can also use this option to specify a relative path.
After you run ossg with the -final_asdb option, remember to move the application schema to the database you specify with -final_asdb.
You must specify an absolute pathname with -final_asdb.
Optional. The default is that the schema generator writes the pathname that you specify for -asdb in the application schema source file (object file for Visual C++).
|
-mrlcp or -make_reachable_library_classes_persistent
| Causes every class in the application schema that is reachable from a persistently marked class to be persistently allocatable and accessible.
This option is supplied for compatibility purposes only. The use of the -mrlcp option is discouraged. Specify -mrscp instead.
When you specify this option, you cannot neutralize the schema for use with a heterogeneous application. If you are building a heterogeneous application, you must either mark every persistent class in the schema source file or specify the -mrscp option.
If you do not mark any types in the schema source file and you specify -mrlcp when you run ossg, then the application schema does not include any types. You must mark at least one type for there to be any reachable types.
Optional. The default is that only marked classes are persistently allocatable and accessible.
See also Determining the Types in a Schema.
|
-mrscp or -make_reachable_source_ classes_persistent
| Causes every class that is both
|
-no_default_includes or -I-
| When you specify this option, ossg does not automatically specify any include directories to the C++ preprocessor. However, the preprocessor can have default include directories built in. If there are any directories that are built into the preprocessor, ossg does check these built-in directories. Typically, the preprocessor uses built-in include paths to find standard include files such as stdio.h.
When you specify this option, you must explicitly specify directories that contain included files.
For example, on some UNIX systems, when you do not specify this option, the C++ preprocessor looks for include files in the /usr/include directory.
Note that if you want the schema generator to pass the ObjectStore include directory to the preprocessor as a directory for finding included files, you must always specify it. For example:
UNIX: -I$OS_ROOTDIR/include
Windows and OS/2: -I%OS_ROOTDIR%\include
The -I- option is the letter I as in Include. Specifying -I- is the same as specifying -no_default_includes.
Optional. The default is that the preprocessor checks default directories for included files.
|
-nor
| A neutralizer option that prevents the schema generator from instructing you to reorganize your code as part of neutralization. This is useful for minimizing changes outside your header file, working with unfamiliar classes, or simply padding formats.
See ossg Neutralization Options for more information.
|
-neutral_info_output filename or -nout filename
| A neutralizer option that indicates the name of the file to which neutralization instructions are directed.
Optional. Default is that the schema generator sends output to stderr.
|
-no_weak_symbols
| Default. Notifies you of missing vftbls and discriminants, allowing you to check whether a referenced vtbl or discriminant function symbol is undefined.
If you specify -rtdp maximal -no_weak_symbols, the linker outputs messages about what is missing. You can use this information to determine which additional classes you need to mark. These missing symbols are only a hint about what you might consider marking. They might also be the result of a link line error.
Specify the option -weak_symbols to suppress this behavior.
|
-pad_maximal or -padm | -pad_consistent or -padc
| Neutralizer options that indicate the type of padding requested. See ossg Neutralization Options for additional information.
Optional. Default is -padc.
|
-parse_function_bodies or -pfb
| This option ensures that any types that are marked inside a function are parsed by ossg. If you do not explicitly use this option and you have any types marked inside functions, an error is reported. See ossg Troubleshooting Tips for further information.
Optional. The default is that the -sfbp option is set.
|
-runtime_dispatch or -rtdp {minimal | derived | full | maximal}
| Specifies the classes for which the schema generator makes vftbls and discriminant functions available.
minimal specifies marked classes, classes embedded in marked classes, and base classes of marked classes.
derived specifies the minimal set plus classes that derive from marked classes and classes embedded in the derived classes.
full specifies the derived set plus the transitive closure over base classes, derived classes, and classes that are the targets of pointers or references. The full specification does not include nested classes or enclosing classes unless they meet one of the previous criteria.
maximal specifies the full set plus nested types. In previous ObjectStore releases, this was the default. If your application used an earlier release of ObjectStore and you do not specify this option, you might need to mark classes that you did not previously mark.
See Example of Using the -runtime_dispatch Option.
Optional. The default is derived.
|
-show_difference or -showd | -show_whole or -showw
| Neutralizer options that indicate the description level of the schema neutralization instructions. Optional. Default is -show_whole.
|
-skip_function_body_parsing or -sfbp
| Optional. Specifies that code within function bodies is not parsed. By default this option is in effect.
|
-schema_options option_file or -sopt
| A neutralizer function that specifies a file in which you list compiler options being used on platforms other than the current platform. See Listing Nondefault Object Layout Compiler Options for further information.
|
-store_member_functions or -smf
| Causes ossg to create an instance of os_member_function for each member function in each class in the schema source file. It then puts these instances in the list of class members, which includes member types and member variables.
This is useful when you intend to use the MOP to inspect the member functions. If you are not planning to inspect member functions, you should not specify this option, because it wastes disk space.
This also means that additions and deletions of member functions are schema changes and affect validation.
When you generate an application schema, you might specify a library or compilation schema. If you want to capture the member functions from the library or compilation schema, you must have specified the -store_member_functions option when you generated the library or compilation schema. You must also specify the -store_member_functions option when you generate the application schema.
Optional. The default is that ossg generates a schema that includes member types and member variables, but not member functions.
|
-weak_symbols
| Suppresses notification about missing vftbls and discriminants. This option overrides the default behavior described at -no_weak_symbols.
|
-assf app_schema_source_file or -asof app_schema_object_file.obj
| Specifies the name of the application schema source file or application schema object file to be produced by ossg. For all compilers except Visual C++, the schema generator produces a source file that you must compile. When you use Visual C++, the schema generator directly produces the object file.
Required. No default.
|
-asdb app_schema_db.adb
| Specifies the name of the application schema database to be produced by ossg. If the schema database exists and is compatible with the type information in the input files, the database is not modified.
This pathname must be local to a host running an ObjectStore Server.
The pathname should have the extension . If you want to specify an existing application schema database with ossg, the application schema must have .adb as its extension.
Required. No default.
|
schema_source_file
| Specifies the C++ source file that designates all the types you want to include in the schema. It should include all classes that the application uses in a persistent context.
No default. Required except in two cases:
|
lib_schema.ldb ...
| Specifies the pathname of a library schema database. The name must end in .ldb. This can be an ObjectStore-provided library schema or a library schema that you created with ossg.
The schema generator reads schema information from the library schema database specified and modifies the application schema database to include the library schema information. You can specify zero or more library schema databases.
Optional. The default is that library schemas are not included.
|
Changing the Default Preprocessor
Except on OS/2, you can use the OS_OSSG_CPP environment variable to specify a C preprocessor other than the configured default. The following table shows the default preprocessor on each platform:
OS/2 Platforms Have an Additional ossg Option
On OS/2 platforms, when you invoke ossg, you must specify the
-cd option with the name of the class definition file for the application. The class definition file, also called the schema header file, contains the definitions for all classes that you want in the schema. While only one class definition file is allowed, it can contain #include statements for files that actually contain the class definitions. You must include the class definition file in the schema source file.
The reason for this option is that the icc compiler does not make public a number of symbols that ObjectStore needs to link your persistent data to your program at run time. However, these symbols are available to any file that includes your class definitions. Consequently, the application schema source file produced by the schema generator must include the class definitions for all persistent classes your application might need. For example:
ossg -assf osschema.cpp -cd schmdefs.hh -asdb myschema.adb \
myschema $(OS_ROOTDIR)\lib\os_coll.ldb
Using a Temporary File to Send Arguments to ossg
You can specify the following option on an ossg command line:
@ filename
It does not matter what kind of schema you are generating.
When the schema generator encounters this option, it reads additional options and arguments from filename. Note that the command line passed to the compiler for preprocessing is the fully expanded command line, so those options that are passed to the compiler must still meet command-line length restrictions.
Be sure that you do not insert a space between @ and filename. You can specify this option on any platform.
On OS/2 and Windows NT, this is commonly used to avoid problems with the length of a command line in Microsoft's nmake program. The usual nmake syntax is
ossg -other-args @<<
$(LONG_ARGS1)
$(LONG_ARGS2)
<<
Specifying ObjectStore Library Schemas
ObjectStore provides library schemas for the ObjectStore libraries that store or retrieve persistent data. If you will be linking your application with an ObjectStore library that has a schema, you must specify that library schema when you generate the application schema. The following table shows when to specify an ObjectStore-provided library schema. When you specify a library schema, you must always specify the full path. For example, $(OS_ROOTDIR)/lib/liboscol.ldb on UNIX and $(OS_ROOTDIR)\lib\os_coll.ldb on Windows and OS/2.
Specifying Remote Library Schemas
A client that uses a remote Server uses ObjectStore library schemas that are stored on the remote Server. Consequently, when generating the application schema, be sure to specify absolute pathnames for library schemas.
How Long Does Schema Generation Take?
The time it takes to generate an application schema is difficult to predict. There are many variables that affect how long schema generation takes, such as the platform and the size of the schema. Usually, the time to generate your schema is comparable to the time to compile the equivalent source code.
If You Omit a Required Library Schema
If you generate an application schema without specifying a required library schema, you might not notice the omission until the application fails with a message indicating that classes are missing from the application schema.
If the collections library schema is required, and you omit it, the linker typically displays a message indicating that there are missing get_os_typespec functions. If os_tinyarray::get_os_typespec() is among them, this probably indicates that you failed to include the collections library schema while building the application schema.
If the types in a library are not persistently used,
Missing collections class library example
Here is an example that shows what happens when there is a missing collections library schema. The exact mode of failure differs on each platform. This example was generated on Sun using the ProCompiler.
Here is a trivial application:
#include <ostore/ostore.hh>
#include <ostore/coll.hh>
main ()
{
OS_ESTABLISH_FAULT_HANDLER
objectstore::initialize();
os_collection::initialize();
OS_END_FAULT_HANDLER
return 0;
}
As you can see, it does not do much, but it does make a reference to the collections library. Because this application does not persistently create or access any types, the schema source file is trivial:
Schema source file
#include <ostore/ostore.hh>
#include <ostore/manschem.hh>
Build the application schema with the usual command (forgetting to explicitly include the collections library schema):
ossg -assf os_nullschm.cc -asdb nullschm.adb nullschema.cc
Compile the application (test.cc) and the application schema source file (os_nullschm.cc) and link the application as shown. As you can see, there are a large number of undefined get_os_typespec functions that are missing (about 100 lines of messages are not shown) because the collections library schema was not included while ossg was building the application schema.
Running the ProCompiler
CC -pta -vdelx -mt -o test test.o os_nullschm.o -loscol -los -losthr
Undefined first referenced
symbol in file
static _RH_ref<_RH_ref_slot_SHV>::get_os_typespec(void)
...
...
The exact message varies depending on which compiler you are using, but the elements common among the messages are the undefined get_os_typespec functions.
Example of Using the -runtime_dispatch Option
The -runtime_dispatch (-rtdp) option specifies the set of classes for which the schema generator makes vftbls and discriminant functions available. For example, suppose you define the following classes:
class A {
public:
class B { public: G* gp; };
E* ep;
};
class C : public A { };
class D : public A { };
class E { };
class F : public D { public: E e; };
class G { public: E e; }
class H { };
If you mark class D, the following classes are in the set (that is, their vftbls and discriminant functions are available). Note that class H is not reachable from class D and consequently is not in the set unless you explicitly mark it.
Option Specified | Classes in the Set
|
---|
Minimal
| A and D
|
Derived
| A, D, E and F
|
Full
| A, C, D, E and F
|
Maximal
| A, B, C, D, E, F and G
|
Using the Same Application Schema for Multiple Applications
Multiple applications can share a single application schema. You can set this up by following these steps:
- Generate the application schema that you want the applications to share.
- Compile the application schema source file produced by the schema generator. (If you are using Visual C++, the compiler directly produces the application schema object file.)
- Link the application schema object file into each application that you want to use this schema. When applications share an application schema object file, they consequently share the application schema.
When the first application accesses the database, ObjectStore validates the application schema. When subsequent applications access the database, ObjectStore does not need to perform validation and access is faster.
Examples of Generating an Application Schema
UNIX
ossg -assf myschema.cc -asdb myschema.adb schema_source.cc
The -assf option indicates the name of the application schema source, myschema.cc. You must specify a name for the application schema source file. There is no default. The -asdb option indicates the name of the database (myschema.adb) to contain the application schema. The schema source file is schema_source.cc.
ossg -mrscp -assf myassf.c -asdb my.adb mine.c my.ldb your.ldb
The -mrscp option is included, so all classes that are defined in the schema source file and that are reachable from marked classes are persistently allocatable and accessible. This is true even if they are not marked in the schema source file. The -assf option indicates that myassf.c is the name of the application schema source file to be produced by ossg. The -asdb option indicates that my.adb is the name of the application schema database to be generated. The schema source file is mine.c. The application schema is generated with the my.ldb and your.ldb library schema databases and consequently will include the types in those libraries.
Windows
ossg -asof jetsch.obj -asdb jetsch.adb jetsch.cc \ %OS_
ROOTDIR%\lib\os_coll.ldb
Since this is a Windows platform, the schema generator directly produces the application schema object file. The -asof option indicates the name of the application schema object file, jetsch.obj. The -asdb option indicates that the application schema database to be generated by ossg is jetsch.adb. The schema source file is jetsch.cc. Because this application uses ObjectStore collections, the collections library schema, lib\os_coll.ldb, is specified.
OS/2
ossg -assf paris.cc -asdb paris.adb paris_sch_source.cc\
-cd paris.hh %OS_ROOTDIR%\lib\oscmpct.ldb
On OS/2, you must specify the -cd option with the name of the class definition file. The application schema source file that ossg produces will be named paris.cc. The application schema database will be in paris.adb. The schema source file is paris_sch_source.cc. The class definition file is paris.hh. The application uses the compactor feature, so you must specify the library schema for the compactor library, oscmpct.ldb.
Generating a Library Schema
If you create a library that allocates or reads persistent data, you should create a library schema. A library schema contains descriptions of the types that the library stores or retrieves in a persistent context.
You specify the library schema when you generate the application schema for applications that use the library. ObjectStore adds the types defined in the library schema to the application schema.
In addition to the library schemas you create, there are library schemas that ObjectStore provides. Specifying ObjectStore Library Schemas describes library schemas provided with ObjectStore.
Makefiles
A makefile that generates a library schema is almost the same as a makefile that generates an application schema. The major differences are that when you want to generate a library schema you
For an example of a makefile that generates an application schema, see the section discussing your platform in Chapter 4, Compiling, Linking, and Debugging Programs.
Invoking ossg to Generate a Library Schema
Refer to Invoking ossg to Generate an Application Schema for the forms of the ossg command to generate a library schema. On OS/2, the -cd option is only required when you generate an application schema.
Using Multiple Schema Source Files to Create a Library Schema
You can create a library schema from multiple schema source files. To do this, you incrementally build the library schema from one schema source file at a time. For example, to include information from the schema source files s1.cc and s2.cc in the library schema foo.ldb, you would use two commands:
ossg -lsdb foo.ldb s1.cc
ossg -lsdb foo.ldb s2.cc
This creates the foo.ldb library schema. It contains the types marked in each of the schema source files s1.cc and s2.cc.
If you modify a source file from which you created a library schema and run ossg again, the schema generator adds to the library schema. It does not overwrite the existing library schema. If you do not want to add to the existing library schema, you must remove the old schema or specify a name for a new library schema.
For example, if you modify s1.cc after you create foo.ldb and then you run ossg again, ossg adds to foo.ldb. It does not overwrite foo.ldb.
Example
ossg -lsdb part.ldb partschm.cc
This command creates the part.ldb library schema and stores it in an ObjectStore database. The part.ldb library schema contains descriptions of the types marked in the partschm.cc schema source file. When you generate an application schema for an application that will link with the part library, you must specify the part.ldb library schema.
If you specify neutralization arguments when you generate a library schema, you must specify the same neutralization arguments each time you run ossg to update that library schema.
If Not Creating a Library Schema
Your application needs access to all types that are persistently allocated. These should be marked either in the application schema or the library schema. If they are not marked in one or the other, providing access to the necessary header files can be quite complex.
Generating a Compilation Schema
When the schema generator generates an application schema, it internally creates a compilation schema first and then builds the application schema from the compilation schema.
A compilation schema contains information about the classes in your application's source files that are read from or written to persistent memory. A compilation schema differs from an application schema in that the compilation schema does not include information about the classes used by libraries your application links with.
You can use ossg to explicitly generate a compilation schema before you generate the application schema.
A makefile that generates a compilation schema is almost the same as a makefile that generates an application schema. The major differences are that when you want to generate a compilation schema you
For an example of a makefile that generates an application schema, see the section for your platform in Chapter 4, Compiling, Linking, and Debugging Programs.
Why Generate a Compilation Schema?
There is no requirement for you to generate a compilation schema. However, you might want to generate a compilation schema in the following situations:
Invoking ossg to Generate a Compilation Schema
Use the syntax described in Invoking ossg to Generate an Application Schema to create a compilation schema. On OS/2, the -cd option is not required when you generate a compilation schema.
Example
ossg -csdb my.cdb myschema.cc
The name of the compilation schema that ossg produces is my.cdb. The schema source file is myschema.cc.
Using a Compilation Schema to Generate an Application Schema
To generate an application schema from a compilation schema, specify the name of a compilation schema in place of the schema source file when you invoke ossg. For example:
ossg -assf engine_schema.cc -asdb engine.adb libmine.cdb
On Windows, you would enter
ossg -asof engine_schema.obj -asdb engine.adb libmine.cdb
OS/2
On OS/2, you must specify the -cd option when you generate an application schema from a compilation schema. See OS/2 Platforms Have an Additional ossg Option.
Hiding Code from the Schema Generator
You can use the _ODI_OSSG_ cpp macro to hide code from the schema generator. This is useful
Specify the _ODI_OSSG_ macro in a directive in your source code. For example:
#ifndef _ODI_OSSG_
/* code you do not want the schema generator to see */
#endif
When you run the schema generator, ossg passes your code to the C preprocessor (cpp) before it generates the schema. When ossg does this, it also passes a definition for _ODI_OSSG_ to cpp. Consequently, _ODI_OSSG_ is always defined. The result is that cpp removes the code between the two directives (#ifndef _ODI_OSSG_ and #endif) from the code that it passes back to the schema generator. The schema generator never operates on the code between the directives.
Unsupported Types
The following paragraphs describe types unsupported in ObjectStore Release 5.1.
Limited Support for long long Data Type
A long long is an int type with a length of 64 bits. DEC C++ , SPARCompiler C++, and SGI C++ treat long long as a new type.
On platforms that support long long, the schema generator recognizes this type in a source fed through it. On platforms that do not support long long, the schema generator signals an error when it encounters this type.
However, you cannot perform a persistent new for an object that includes the long long type. In other words, you cannot mark a type in the schema source file that includes a long long member. An error occurs during schema generation if you do.
Support for wchar_t Types
The schema generator does not fully support the wchar_t type. Consequently, Object Design discourages the use of this type.
You can persistently store an object that has a wchar_t member type. However, code that requires implicit conversions or type promotions that involve wchar_t is not guaranteed to be recognized by the schema generator. You might need to conditionalize such code so that the schema generator ignores it.
You cannot neutralize a schema that includes the wchar_t type. The schema generator treats wchar_t types in the same manner as the architecture/compiler platform for which it is generating schema. Different platforms treat this type in different ways.
Schema evolution and queries of classes containing wchar_t types are not supported.
Restricting Use of Template Classes and Collections
There are two ObjectStore preprocessor macros that you can pass to ossg to restrict the use of ObjectStore template classes and collections.
ObjectStore header files contain numerous definitions and uses of template classes. Specify one of these macros on the ossg command line when you do not want ObjectStore to define class templates.
The use of these macros does not affect your ability to define and use your own template classes. These macros hide only the definitions of ObjectStore templates.
__NO_TEMPLATES__
When you specify __NO_TEMPLATES__ on the ossg command line, before the specification of any ObjectStore include files, template classes normally defined by ObjectStore are not available for use by your application. These templates include collection templates, reference templates, and relationship templates. The advantage of this is that compilation time is faster. The disadvantage is that you need to use the generic versions of the classes, which do not provide the security of type safety.
OS_NO_COLLECTION_TEMPLATES
When you specify OS_NO_COLLECTION_TEMPLATES on the ossg command line, your application can use parameterized references and relationships but not parameterized collections.
It is not possible to allow the use of collections without allowing the use of template classes.
Caution
The mop.hh and schmevol.hh header files use template classes unconditionally. Do not specify the __NO_TEMPLATES__ macro or the OS_NO_COLLECTION_TEMPLATES macro when your application uses the MOP or schema evolution.
Correcting Schema-Related Errors
This section presents information about schema-related errors that you might need to resolve:
Type Mismatch Errors
The most common schema-related error can occur when an attempt is made to reconcile type definitions from different sources. This can happen when ObjectStore builds any kind of schema.
Similarly, you might get an exception when an application is run against a database, if the class definitions in the application schema are incompatible with class definitions already present in the database schema. When this happens, you might have to either change the application to match the database or evolve the schema database.
When an error occurs due to a type mismatch, the easiest way to get more information about the mismatch is to use the osexschm utility. See ObjectStore Management, Chapter 4, osexschm: Displaying Class Names in a Schema.
Persistent Allocation Errors
The following exceptions might occur at run time:
<err-0025-0022> Persistent new requested for type "XXX", which has not
been marked as a legitimate type for persistent new.
<err-0025-0021> Persistent new requested for type "XXX", which was not
found in the application schema.
ObjectStore detects these errors when the application attempts to persistently allocate a class that was not part of its application schema or a class that was not marked. Common sources of this error are
Use the osexschm utility to establish the absence of the class in the appropriate schema. See ObjectStore Management, Chapter 4, osexschm: Displaying Class Names in a Schema.
ossg Run-Time Errors
When the schema generator builds an application schema, errors can occur at link time if the class definitions present in the compilation and library schemas are not compatible.
When the schema generator builds a compilation schema, errors can occur because a class definition used in a persistent context in one file differs from the class definition of a class with the same name in another file. This situation normally causes a compile-time error.
For library and compilation schemas, you can determine how ossg handles type-mismatch errors during schema generation. Set the environment variable OS_COMP_SCHEMA_CHANGE_ACTION to one of the following values:
Metaschema Mismatch Errors
The metaschema consists of class definitions internal to ObjectStore that are used to describe user classes. A metaschema mismatch usually indicates an incorrectly built program or database, where the program, libraries, and databases do not correspond to the same ObjectStore release of the software. For this reason, you are most likely to see these errors at ObjectStore release boundaries.
Schema Neutralization Errors
For information about handling schema neutralization errors, see ossg Neutralization Options.
Missing Virtual Function Table Pointer Problems
For information about missing virtual function tables, see Run-Time Errors from Missing VTBLs.
Handling Pragma Statements in Source Code
The schema generator recognizes the #pragma statements that it encounters in your schema source files and interprets them as the compiler would in most cases. However, for pragma statements that occur inside a class definition, ossg does not usually treat them as the compiler would.
In particular, a #pragma statement that is nested in a class does not take effect until the start of the next nonnested class. For nonpersistent classes, this might not be a problem. For persistent classes, be sure that all #pragma statements that affect structure layout occur outside the class. Otherwise, the object layout defined by the compiler and the ObjectStore schema might be inconsistent.
Utilities for Working with Schemas
The following ObjectStore utilities help you manage schemas:
Information about all these utilities appears in ObjectStore Management, Chapter 4, Utilities.
Comparison of ossg Command Lines
Each time you run ossg, you can generate one kind of schema.
After you generate a compilation schema, you can use the compilation schema to generate the application schema. In this scenario, the name of the compilation schema replaces the name of the schema source file in the ossg command syntax for generating an application schema. The syntax is
ossg {-assf app_schema_source_file | -asof app_schema_object_
file.obj}
-asdb app_schema_database.adb comp_schema.cdb
Conventions for application schema source file names
In previous releases of ObjectStore, .os_schema.cc and .os_schema.o were often used as the names for the application schema source file and the application schema object file. This was always a convention and not a requirement. The initial dot hid the files from directory listings.
This convention is not observed in Release 5.1. The Release 5.1 convention is to use names without the initial dot. Again, this is a convention and not a requirement.
Comparison of Kinds of Schemas
1 If you want to specify an existing application schema database with ossg, Object Design recommends that the application schema have .adb as its extension.
Deploying Products with Protected Databases
If you want to restrict access to a database's data and metadata, you can use ObjectStore's schema protection facility. This facility allows you to associate a schema key (a pair of integers) with a database. After you associate a database with a schema key, an application must supply the key to access data in the database. A database with a schema key is considered to be a protected database. See ObjectStore C++ API User Guide, Chapter 7, Database Access Control, Schema Keys.
When you deploy a product that generates a schema for a protected database, you must write an application that does the following:
- Programmatically sets the environment variables OS_SCHEMA_KEY_LOW and OS_SCHEMA_KEY_HIGH to the correct schema key. See ObjectStore Management, OS_SCHEMA_KEY_LOW
.
- Spawns a child process that
The reason your application must include these characteristics is that the schema generator is not a database utility that you can call programmatically.
Using Rogue Wave with Solaris Sun C++
When you use Sun C++ on a Solaris 2 system, you might encounter the following problem when you try to generate a schema and your schema source file includes Rogue Wave header files.
ossg -csdb fiddle:/home/bow/aa.cdb -I$OS_ROOTDIR/include
a.cc"/opt/SUNWspro/SC3.0.1/include/CC/rw/tislist.h", line 216: Error:
Trying to open encrypted file
"/opt/SUNWspro/SC3.0.1/include/CC/rw/tislist.cc" while
preprocessing."/opt/SUNWspro/SC3.0.1/include/CC/rw/tislist.h", line
216: Error: Could not open include file "
rw/tislist.cc"."/opt/SUNWspro/SC3.0.1/include/CC/rw/tpslist.h", line 244:
Error: Trying to open encrypted file
"/opt/SUNWspro/SC3.0.1/include/CC/rw/tpslist.cc" while
preprocessing."/opt/SUNWspro/SC3.0.1/include/CC/rw/tpslist.h", line
244: Error: Could not open include file "
rw/tpslist.cc".
The Sun C++ 4.0.1 package includes Rogue Wave header files. However, the template functions are in encrypted form in accompanying .cc files. If you include the .hh file in a compilation, everything works fine. If you include the .hh file in a schema source file, the schema generator tries to preprocess the source file using CC. But if you do not have a source license, the encrypted source file causes an error.
There are two work arounds for this:
#include <rw/compiler.h>
#undef RW_COMPILE_INSTANTIATE
These two lines cause only the class declarations to be seen and not the member functions.
ossg Troubleshooting Tips
The following information provides guidelines for avoiding problems when using ossg.
Precompile
Do not use ossg to find syntax and semantic errors in your source files. Compile your sources with the compiler before running ossg over your source files.
Member function declarations
Function declarations can be complex. For example, are template functions instantiated using inheritance or nesting? ossg never needs to see nonmember functions. There are only three circumstances requiring ossg to see and process member function declarations:
If none of these conditions apply, functions (including member functions) can be hidden from ossg using conditional compilation or exclusion.
Skip function body parsing
In ObjectStore 5.0, by default ossg skips all function body parsing and processing (the -sfbp option is the default). If function bodies are not parsed, ossg's process time and use of heap storage during execution will decrease from previous releases. The only reason to process function bodies is if a user has marked types for persistent new inside function bodies. If a user has done so, ossg will not see those types and will issue the following warning:
<warn-0038-0003>One or more types have been marked in a function
body, but function bodies are not being parsed. These types will not be
marked in the schema. Please move the marking of all types outside of
function bodies (preferred) or specify -parse_function_bodies.
The two options available to the user in this case are to move the OS_MARK_SCHEMA_TYPE macros outside function bodies or to specify the -parse_function_bodies option.
Modularize schema information
Just as it is good programming practice to modularize code, it is preferable to separate schema information into separate compilation or library schemas that can be combined as needed to create application schemas for specific applications.
Swap space
Parsing and analysis of C++ code can be very complex. For generation of schema, ossg sometimes uses large amounts of swap space, so Object Design recommends that you make a large amount of swap space available when running ossg.
What to send to Technical Support
When a problem occurs during schema generation (such as syntax errors, semantic errors, or any other errors), you should send the following to Object Design Technical Support :
This information will probably be needed to diagnose the problem. To produce the preprocessed source, run ossg over the source (as if you were generating schema), using the following options:
For example:
ossg -E -D... -I... source.cc > source.ii
[previous] [next]
Copyright © 1998 Object Design, Inc. All rights
reserved.
Updated: 03/26/98 19:57:53