ObjectStore C++ Release Notes

Chapter 2

Changes and Additions to Existing Features

In general, ObjectStore Release 5.1 is drop-in compatible with Release 4. It is, however, not compatible with applications that use Versions or other features eliminated from Release 5. If you are upgrading from Release 3, you must upgrade your databases with Release 4 before using Release 5.

This chapter includes information about changes to Release 5.1 ObjectStore C++ behavior, and specific conditions that apply independent of platform. The information is organized by specific compatibility with earlier releases. Topics covered include

Compilation Compatibility

ObjectStore programs built with Release 5.0.x can be compiled without source-level modifications and will continue to work with ObjectStore Release 5.1.

Link Compatibility

ObjectStore programs built using Release 5.0.x can be relinked using ObjectStore Release 5.1 libraries without the need to recompile source modules.

Drop-In Compatibility

ObjectStore programs built using Release 5.0.x can be pointed at ObjectStore Release 5.1 shared libraries without having to be rebuilt. In other words, ObjectStore Release 5.1 maintains drop-in compatibility with Release 5.0.x of ObjectStore. A result of this is that ObjectStore Release 5.1 is an acceptable replacement for the 5.0.x patch release stream.

Note: Applications compiled using ObjectStore Release 5.1 are not backward compatible with previous versions of ObjectStore.

Behavior Compatibility

With the following exceptions, ObjectStore programs from Release 5.0.x behave similarly:

This environment variable has been renamed to OS_INBOUND_RELOPT_THRESH. OS_OUTBOUND_RELOPT_THRESH has been added also for symmetry and is synonymous with OS_RELOPT_THRESH.

This environment variable is no longer being used.

Database Compatibility

There are two areas in which ObjectStore Release 5.1 is incompatible with Release 5.0.x.

PRM format
The first is that in order to use ObjectStore Release 5.1, a database must have been upgraded to use the enhanced PRM format. The earlier standard format PRMs are no longer supported. This also means that you cannot upgrade directly from Release 4.0 to ObjectStore Release 5.1 without first upgrading to ObjectStore Release 5.0.x enhanced PRM format. In fact, if you have ObjectStore Release 5.0.x databases that used the earlier standard prm format, you must upgrade them using the ObjectStore Release 5.0.x utility osupgprm.

Server transaction log change
In order to support XA, it was necessary to update slightly the format of the Server's transaction log. The result of this change is that existing Release 5.0.x ObjectStore Server logs cannot be propagated using an ObjectStore Release 5.1 Server.

Utility Compatibility: ossg

Changes to ossg Default

Object Design has changed the default behavior of ossg so that weak importing of vtables done on Solaris and other UNIX platforms is no longer supported by the default. The implication is that when you are building an application you might see unresolved symbols that are new.

Object Design recommends that the most portable method of dealing with this is to create a force_vft() function in your executable that will cause the vfts to be instantiated. See Symbols Missing When Linking ObjectStore Applications in ObjectStore Building C++ Interface Applications for more information.

The other (not recommended) way to deal with this is to use the -weak_symbols flag to ossg to revert ossg to ObjectStore Release 5.1 behavior. The -no_weak_symbols flag still exists in ossg but does emit a warning stating that no_weak_symbols is the default behavior.

-weak_symbols Option

In earlier releases, the schema info linked into an application schema used weak import references on some platforms to link to virtual function tables and union discriminant functions. This was the default behavior. It could be changed with the -no_weak_symbols option to the schema generation utility, ossg

In Release 5.1, default behavior has been changed so that weak import references are never used by default. This was done because using weak import references with DLL schema can cause unpredictable effects. The affected platforms are versions of UNIX. If the weak import feature is needed for some reason, you can restore it by using the -weak_symbols command-line argument to ossg.

ossg Limitations

Note the following limitations and their solutions for ossg in ObjectStore Release 5.1.

Explicit Template Specializations

ossg does not permit explicit template specializations. For example:

template <class A> class B { ... };
template <> class B<char> { ... };  // not accepted 
Ossg: error message: "<file>":LINE <number>, syntax error on input ">" 
Workaround
Instead, use the following to specialize class template B:

class B<char> { ... }; 
  
 Forward Declarations

Forward declarations, including friend declarations, that involve template instantiations can cause problems if the same instantiation appears later in the code. For example:

Example
template <class A> class B { ... }; 
class D { 
      class B<int>; // or friend class B<int>; 
}; 
class B<int> { ... }; 
Ossg: error message: "<file>":LINE <number> *** Defining a previously 
defined class <class>
Workaround
The solution is to eliminate the forward reference. In the previous example, for instance, move class B<int> { ... }; upward to a place before its use.

Class Declarations in Templates

Class declarations in templates can produce link errors if the class is derived from another class that defines virtual functions. For example:

Example
struct C { virtual void f(){} }; 
template< class T > struct A  { 
      struct B  : public C { ... }; 
}; 
Ossg: ossg does not break but generates incorrect names
Workaround
The workaround for this is to move inner declarations to outside the template. In the previous example, for instance, use the following instead to specialize class template B:

class B<char> { ... };

Changes from the Previous Release

Deprecated Features and Interfaces

NETBIOS support
Support for NETBIOS is removed.

os_database::alloc() and os_segment::alloc()
The entrypoints os_database::alloc() and os_segment::alloc() will be removed from the next major release of ObjectStore.

C Library Interface
The C library interface to ObjectStore is deprecated in this release. Support for it will be removed in the next major release of ObjectStore.

Persistent Relocation Maps
The following functions related to persistent relocation maps are deprecated in this release and will be removed in the next major release of ObjectStore.

This signals an exception in ObjectStore Release 5.1 and is deprecated. It will be removed in the next major release of ObjectStore.

This now always return false and is deprecated. It will be removed in the next major release of ObjectStore.

This now always return false and is deprecated. It will be removed in the next major release of ObjectStore.

This now always return false and is deprecated. It will be removed in the next major release of ObjectStore.

Support for these functions has been removed. Use objectstore::get_unassigned_address_space() instead.

IP Addresses in UNC Pathnames

You can use IP addresses in UNC pathnames when opening a database. For example:

//198.316.17/top/dbs/db1

New Documentation for -O option to osrestore

The osrestore utility takes an option, -O, that restores the database image specified with the -f flag and then exits. There is no prompt for additional volumes.

Incompatible Changes to os_CString

To fix several reported problems, os_CString was substantially rewritten in Release 5.1. Applications that use os_CString must be recompiled.

The following changes were made:

  1. The use of a common empty string was eliminated to avoid cross-segment pointers. The default constructor provides each os_CString object with its own empty string.

  2. Like regular CStrings, os_CStrings share data when copied, by default. This can lead to undesirable cross-segment pointers. To avoid this, Object Design recommends that you call os_CString::LockBuffer() on persistent os_CStrings. Copying a transient os_CString to a persistent location, or copying a persistent os_CString from one database to another will copy the data instead of sharing it.

  3. Internal operations on os_CString use _ODI_strlen instead of lstrlen. If a persistent string is not currently mapped into memory, _ODI_strlen causes it to be mapped and returns the correct length, unlike lstrlen, which returns 0.

Documentation Enhancements

Use of Change-Record Files with osbackup

For every set of databases you plan to back up, you need one change record file. Only one level 0 backup can be recorded in a change-record file. Subsequent level 0 backups refresh the change records, so you will lose information about the prior databases' backup status.

For example, the following will work and is the recommended usage:

osbackup -f ./test1.db.back0 -i test1.db.record -l 0 -a test1.db
osbackup -f ./test2.db.back0 -i test2.db.record -l 0 -a test2.db
osbackup -f ./test1.db.back4 -i test1.db.record -l 4 -a test1.db
osbackup -f ./test2.db.back4 -i test2.db.record -l 4 -a test2.db
However, using the default incremental record file for two backups like this will result in lost information about the backup level of test1.db:

osbackup -f ./test1.db.back0 -l 0 -a test1.db
osbackup -f ./test2.db.back0 -l 0 -a test2.db
osbackup -f ./test1.db.back4 -l 4 -a test1.db
osbackup -f ./test2.db.back4 -l 4 -a test2.db
In general, Object Design advises against using the default record file because it is easy to make this kind of mistake. You should always specify a unique record file for each set of databases backed up with the -i option.

Correction to Some Examples in the ObjectStore C++ API User Guide

Examples in the following section of the ObjectStore C++ API User Guide have some incorrect lines. They should appear as described in this section.

Using Nonparameterized References

If your compiler does not support class templates, you can use the nonparameterized reference class os_reference. You also should use os_reference if you need a reference to an instance of a built-in type like int or char; the referent type of an os_Reference must be a class.

os_reference is just like os_Reference, except the conversion constructor used is os_reference(void*) instead of os_Reference(T*). In addition, the conversion operator used is operator void*() instead of operator T*(), which means that you should use a cast to pointer-to-referent type when dereferencing an os_reference.

Corrections to Nonparameterized example 1
Nonparameterized example 1

Here are some examples:

      #include <ostore/ostore.hh>
      #include <stdio.h>
      class employee {
The following line was omitted:

public:
      static os_typespec *get_os_typespec();
      . . . 
The following line was omitted:

int emp_id;
      };
      class part {
The following line was omitted:

public:
      static os_typespec *get_os_typespec();
      . . . 
      os_reference responsible_engineer;
      . . . 
      };
      f() {
      objectstore::initialize();
      static os_database *db1 = os_database::open("/thx/parts");
      static os_database *db2 = os_database::open("/thx/parts");
      OS_BEGIN_TXN(tx1, 0, os_transaction::update)
            part *a_part = new(db1, part::get_os_typespec()) part;
            employee *an_emp = 
                  new(db2, employee::get_os_typespec()) employee;
            a_part->responsible_engineer = an_emp;
This line is incorrect:

            printf("%d\n", 
            (employee*) (a_part->responsible_engineer)->emp_id);
It should be

            printf("%d\n", 
                  ((employee*) (void*)
                  (a_part->responsible_engineer))->emp_id);
      OS_END_TXN(tx1)
      db1->close();
      }
Corrections to Nonparameterized example 2
Nonparameterized example 2

      #include <ostore/ostore.hh>
      #include <ostore/coll.hh>
      #include "part.hh"
      main() {
      objectstore::initialize();
      part *a_part; 
      os_database *db1 = os_database::open("/thx/parts");
      os_reference part_set_ref;
      OS_BEGIN_TXN(tx1, 0, os_transaction::update)
            part_set_ref = (os_set*) (
                  db1->find_root("part_set")->get_value()
            ); /* retrieval */
            . . . 
      OS_END_TXN(tx1)
      OS_BEGIN_TXN(tx2, 0, os_transaction::update)
This line is incorrect:

            a_part = (part*) (
                  ((os_set*) (part_set_ref))->query_pick(
                  "part", "part_number==123456", db1
                  )
            ) ; /* OK */
It should be

a_part = (part*) (
            ((os_set*)(void*) (part_set_ref))->query_pick(
                  "part", "part_number==123456", db1
            )
            ) ; /* OK */
            . . . 
      OS_END_TXN(tx2)
      db1->close();
      }



[previous] [next]

Copyright © 1998 Object Design, Inc. All rights reserved.

Updated: 04/02/98 12:47:30