PCustomizeFundamental
, VSession
. See also the init()
method on PVirtual.
Redefinable Mechanisms
The following C++/VERSANT mechanisms can be redefined.
Create object |
|
Read object |
|
Write object |
|
Delete object |
|
Set data type |
Internal operation |
Activate object |
Internal operation |
These mechanisms can be redefined because they operate through relay methods. The relay methods are defined in the PCustomizeFundamental
and VSession classes, and their behavior can be altered with other methods in PCustomizeFundamental
and VSession
.
By default, the above C++/VERSANT mechanisms that create, read, write, and delete objects are relayed to the following C/VERSANT functions:
Create object |
o_makeobj() |
Read object |
o_locateobj() |
Write object |
o_preptochange() |
Delete object |
o_deleteobj() |
PCustomizeFundamental
and VSession
methods.
To override default behavior for the redefinable C++/VERSANT mechanisms, do the following.
1. Create new functions that create, read, write, delete, and/or activate objects.
Typically, you will use the default functions and add additional code that performs the tasks you desire.
PCustomizeFundamental
and VSession
to redefine the relay methods that create, read, write, delete, and activate objects.
Some customization methods use the data type PHandle
.
The PHandle
type is typedef
as LinkAny
.
You can use PHandle
as you would LinkAny
. However, to delete it, you must use deleteobj()
, rather than operator delete
.
Example: Fixing a Class
The following subroutine illustrates how to fix a class. The function defined can be used in place of o_locateobj()
and activateWSlots()
calls.
After calling o_makeobj()
, o_createobj()
, or make_object()
, instead of calling o_locateobj()
and PClassObject<CheatClass>.activateWSlots()
, call this function. It will do the work of both, plus fix an address in an internal header properly.
Pass to this function the o_object
link returned from o_makeobj()
. It will return the top of the object, just as o_locateobj()
does.
In the following, you can substitute proper error handling for the assert()
function.
void*
fix_and_locate_new_object( o_object obj )
{
PResult pr;
void* top= ((PHandle)obj)->getObject(pr, RLOCK);
assert ( pr.is_ok() );
return top;
}
Following is a reference to the relay methods on PCustomizeFundamental
and VSession
that redefine default behavior.
static o_4b get_call_user_init_flag(PDOM *dom) const;
Return the current status of the flag used in set_call_user_init_flag()
in PCustomizeFundamental
.
If this method returns 1
, then objects will be initialized with the init()
method when they are brought into memory. If this method returns 0, then init()
will not be called.
See also:
init()
in PVirtual
set_call_user_init_flag()
static vpp_makeobj_thrower_t *get_makeobj_thrower(PDOM *dom) const;
Get the currently defined object creation exception handler.
See also:
set_makeobj_thrower()
set_object_maker()
static vpp_object_activater_t *get_object_activater(PDOM *dom) const;
Get the object activation function currently in use.
See also:
set_object_activater()
Note — The word "activator" is consistently misspelled as "activater" in PCustomizeFundamental
methods.
static vpp_object_deleter_t *get_object_deleter(PDOM *dom) const;
Get the currently defined object deletion function.
See also:
set_object_deleter()
static vpp_object_dirtier_t *get_object_dirtier(PDOM *dom) const;
Get the object dirty function currently in use.
See also:
set_object_dirtier()
static vpp_object_locater_t *get_object_locater(PDOM *dom) const;
Get the instance object locator function currently in use.
See also:
set_object_locater()
Note — The word "locator" is consistently misspelled as "locater" in PCustomizeFundamental
methods.
static vpp_object_maker_t *get_object_maker(PDOM *dom) const;
Get the currently defined object creation function.
See also:
set_object_maker()
static vpp_pclass_fixer_t *get_PClass_fixer(PDOM *dom) const;
Get the class fixer function for this thread.
See also:
set_pclass_fixer()
static vpp_schema_locater_t* get_schema_locater() const;
Get the schema locator function for this
VSession
object.
See also:
set_schema_locater()
Note — The word "locator" is consistently misspelled as "locater" in PCustomizeFundamental
methods.
static void reset(PDOM *dom);
Restore default behavior for all redefined relays.
void set_call_user_init_flag(PDOM *dom, o_4b flag );
Specify whether the init()
method in PVirtual
is called as objects are brought into memory.
To cause init()
to be called, specify flag
as 1
; to
restore default behavior, specify flag as 0
.
The init()
method in PVirtual
allows you to initialize objects with transient data when they are first brought into memory. (See init()
in PVirtual
.)
For example, suppose the Employee
class is defined as the following.
class Employee : public PVirtual {
void *transient_data;
public:
void init() {
// initialize transient_data
}
};
To cause init()
to be called when an instance of Employee
is dereferenced:
dom -> beginsession();
PCustomizeFundamental::set_call_user_init_flag( dom, 1 );
Afterwards, dereferencing a link will load the object into the object memory cache and call Employee::init()
to initialize transient_data
:
Link<Employee> lp = ...;
Employee *ep = lp;
See also set_call_user_init_flag()
void set_object_activater(
PDOM *dom,
vpp_object_activater_t *activate_object);
Redefine object activation.
When it is brought into memory, a C++ object must be activated (laid out in memory) before it can be used as a C++ object.
The information needed to activate an instance is contained in its class object, which is an instance of PClassObject<type>
. Some activation also occurs when an object is created.
Before a C++ object is brought into memory, VERSANT calls the object_activater()
method in PCustomizeFundamental
.
By default, the object_activater()
function sets the __what
, __vtbl
, and __vbase
pointers per information defined in the VERSANT implementation of the class object, which is an instance of PClassObject<type>
.
You can redefine object_activater()
, perhaps if you have your own kind of What/Class mechanism, but you probably don't need to. If you do want to define an activation function, you may want to inspect VERSANT's implementation in the file cxxcls/customiz.h
.
If the class object for a class has not been found, the PClass_fixer()
function will leave the pointer to the class object as NULL
. In this case, the default object_activater()
function returns the following error:
8040, CXX_NO_CXXCLS: C++ interface does not know about class %s
If you define an object_activater()
method, there should be three parameters.
Link
o_object
to the instance .
char*
to the class name.
PClass*
to the desired class object.
o_errno
and return NULL
if an error occurs. If defined to throw an exception, the exception will not be caught by C++ error handling mechanisms.
To use your activation function, start a session and redefine the calling relay with set_object_activator()
.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call PCustomizeFundamental::reset()
.
To restore default behavior for just the relay that activates objects:
PCustomizeFundamental::set_object_activater(dom, NULL);
See also:
get_object_activater(),
set_object_activater() in VSession.
Note — The word "activator" is consistently misspelled as "activater" in PCustomizeFundamental
methods.
void set_object_deleter(
PDOM *dom,
vpp_object_deleter_t *delete_function );
Redefine C++/VERSANT mechanisms that delete objects from a database.
To delete an object, the delete
operator and deleteobj()
method call the C/VERSANT o_deleteobj()
function.
To redefine what happens when an object is deleted, define a delete function and call this method with your function substituted for the delete_function
parameter.
The syntax of o_deleteobj()
is:
o_err o_deleteobj( o_object object );
Your redefined function should pass the same arguments and return the same value. Errors will be handled by normal C++ error handling mechanisms. See o_deleteobj()
in C/VERSANT Manual for more information.
For example, suppose that you want to redefine the delete mechanisms so that you print the logical object identifier for each deleted object. To do this, you could create the following delete function.
extern "C" {
o_err my_deleter( o_object x)
{
char buf[O_PRINTLOID_SIZE];
o_err e= o_deleteobj(x);
if (e!=O_OK) return e;
o_err ok= o_printloid( x, buf );
assert(ok==O_OK);
printf( "Deleted: %s\n", buf );
return e;
}
};
Then, after starting a session, redefine the delete relay:
main() {
....
dom->beginsession(...);
....
PCustomizeFundamental::set_object_deleter(dom, my_deleter);
....
}
To restore default behavior for all redefined relays, you can end the current session and start a new one or call PCustomizeFundamental::reset()
.
To restore default behavior for just the delete relay:
PCustomizeFundamental::set_object_maker(dom, o_deleteobj);
See also:
set_object_deleter() in VSession.
void set_object_dirtier(
PDOM *dom,
vpp_set_object_dirtier_t *dirty_function );
Redefine the default C++/VERSANT mechanism that marks an object for update.
This method changes what happens when the following are called:
dirty()
PObject
.
preptochange()
Link<type>
and LinkAny
.
o_preptochange()
, which sets a short write lock, marks the object as dirty, and returns O_OK
if successful.
The syntax of o_preptochange()
is:
o_err o_preptochange( o_object object );
Your redefined function should pass the same arguments and return the same value. Errors will be handled by normal C++ error handling mechanisms. See o_preptochange()
in C/VERSANT Manual for more information.
To use your object write function, start a session and redefine the calling relay with the set_object_dirtier()
.
For example, suppose that you want to redefine the dirty mechanisms so that you print the logical object identifier for each object marked as dirty.
First, create the new dirty function:
extern "C" {
o_err my_dirty(o_object x)
{
char buf[O_PRINTLOID_SIZE];
o_err e= o_preptochange(x);
if (e!=O_OK) return e;
o_err ok= o_printloid( x, buf );
assert(ok==O_OK);
printf( "Dirtied: %s\n", buf );
return e;
}
};
Then, after starting a session, redefine the dirty relay:
main() {
....
dom->beginsession(...);
....
PCustomizeFundamental::set_object_dirtier(dom, my_dirty);
....
}
To restore default behavior for all redefined relays, you can end the current session and start a new one or call PCustomizeFundamental::reset()
.
To restore default behavior for just the dirty relay:
PCustomizeFundamental::set_object_maker(dom, o_preptochange);
void set_object_locater(
PDOM *dom,
vpp_object_locater_t *locator_function);
Redefine the C++/VERSANT mechanism that fetches instance objects from a database.
By default, to read an instance object, the dereference operator ->()
and the locateobj()
method call the C/VERSANT function o_locateobj()
, which finds a specified instance object, sets a specified short lock, pins the object in memory, and returns a pointer to the top of the object.
To redefine this behavior, redefine the locator function and then call this method.
The syntax for o_locateobj()
is:
o_u1b* o_locateobj(
o_object object,
o_lockmode lockmode );
Your redefined function should pass the same arguments and return the same value. See o_locateobj()
in the C/VERSANT Manual for more information.
If an error occurs, this function should set o_errno
and return NULL
. The error will be handled by normal C++ error handling mechanisms.
For example, suppose that you want to redefine read mechanisms so that you print the logical object identifier for each object read.
First, create a new locator function:
extern "C" {
o_u1b* my_locator(o_object x, o_lockmode lm)
{
char buf[O_PRINTLOID_SIZE];
o_u1b *p= o_locateobj(x, lm);
if (!p) return p;
o_err ok= o_printloid( x, buf );
assert(ok==O_OK);
printf( "Located: %s\n", buf );
return p;
}
};
Then, after starting a session, redefine the object locator relay:
main() {
....
dom->beginsession(...);
PCustomizeFundamental::set_object_locater(dom,my_locator);
....
}
To restore default behavior for all redefined relays, you can end the current session and start a new one or call PCustomizeFundamental::reset()
.
To restore default behavior for just the object locator:
PCustomizeFundamental::set_object_locater(dom, o_locateobj);
To redefine the locator function for a thread, use the set_object_locater()
method in VSession
.
Note — The word "locator" is consistently misspelled as "locater" in PCustomizeFundamental
methods.
void set_object_maker(
PDOM *dom,
vpp_object_maker_t *create_function);
Redefine C++/VERSANT mechanisms that create objects.
This method changes what happens when the following are called:
O_NEW_PERSISTENT()
O_NEW_PERSISTENT1()
O_NEW_PERSISTENT2()
PObject
.
make_copy()
Link<type>
and LinkAny
.
o_makeobj()
, which will create a persistent object of a specified class in the default database, optionally set initial attribute values, optionally pin the new object, and return a link to the new object.
The syntax of o_makeobj()
is:
o_object o_makeobj(
o_object clsobj,
o_bufdesc * initvals,
o_bool topin );
Your redefined function should pass the same arguments and return the same value. See o_makeobj()
in C/VERSANT Manual for more information.
If an error occurs, this function should set o_errno
and return NULL
. The error will be handled by normal C++ error handling mechanisms.
To use your object creation function, start a session and then redefine the calling relay with set_object_maker()
.
For example, suppose you want to redefine the create object mechanisms so that you print the logical object identifier for each new object.
First, create the new object creation function:
extern "C" {
o_object my_creator( o_object cls, o_bufdesc *bd, o_bool to_pin )
{
char buf[O_PRINTLOID_SIZE];
o_object p = o_makeobj(cls, bd, to_pin);
if (!p) return p;
o_err ok = o_printloid( p, buf );
assert(ok == O_OK);
printf( "Made: %s\n", buf );
return p;
}
};
Then, to use your object creation function, start a session and redefine the object creation relay:
main() {
....
dom->beginsession(...);
....
PCustomizeFundamental::set_object_maker(dom, my_creator);
....
}
To restore default behavior for all redefined relays, you can end the current session and start a new one or call PCustomizeFundamental::reset()
.
To restore default behavior for just the object creator relay:
PCustomizeFundamental::set_object_maker(dom, o_makeobj);
void set_PClass_fixer(PDOM *dom, vpp_pclass_fixer_t *fix_class)
Assign a data type to a non-C++ object.
C++ objects must have a data type. Normally, a data type is defined by compiling a class definition, stored by loading it into a database as a class object, and made known to an application by linking. In the following cases, a class definition may not have been compiled, stored in a database, and/or linked to an application:
Runtime object
In this case, you need to specify to your application both the class and also define PWhat
and other things to mimic elements normally defined during schema capture.
In this case, you can cheat and activate non-C++ objects as if there were the closest C++ class to their true class. This has its limitations. For example, you can use only simple inheritence.
PClass_fixer()
method in PCustomizeFundamental
.
The default is for PClass_fixer()
to do nothing.
If you define a PClass_fixer()
method, there should be three parameters.
Link
o_object
to the instance .
const
char*
to the class name.
PClass**
to the desired class object.
PClass_fixer()
, make the class object parameter point to the desired instance of PClass
.
If an error occurs, this function should set o_errno
and return NULL
. If defined to throw an exception, the exception will not be caught by C++ error handling mechanisms.
To use your function that defines a class, start a session and then redefine the calling relay with set_PClass_fixer()
.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call PCustomizeFundamental::reset()
.
To restore default behavior for just the relay that defines a class:
PCustomizeFundamental::set_PClass_fixer(dom, NULL);
See also:
set_pclass_fixer() in VSession.
void set_schema_locater(
PDOM * dom,
vpp_schema_locater_t* locator_function);
Redefine the C++/VERSANT mechanism that fetches class objects from a database.
By default, to read a class object, the dereference operator ->()
and the locateobj()
method call the C/VERSANT function o_locateobj()
, which finds a specified instance object, sets a specified short lock, pins the object in memory, and returns a pointer to the top of the object.
To redefine locator behavior for class objects, redefine the locator function and then call this method. Otherwise, all steps are the same as for redefining the locator function for instance objects. See set_object_locater()
in VSession
for an explanation of object location.
To restore default behavior, call this method and specify o_locateobj()
for the locator_function
parameter:
PCustomizeFundamental::set_schema_locater(
dom, o_locateobj);
See also:
set_schema_locater()
Note — The word "locator" is consistently misspelled as "locater" in PCustomizeFundamental
methods.
static o_4b get_call_user_init_flag() const;
Return the current status of the flag used in set_call_user_init_flag()
in VSession
.
If this method returns 1
, then objects will be initialized with the init()
method when they are brought into memory. If this method returns 0, then init()
will not be called.
See also:
init()
in PVirtual
set_call_user_init_flag()
in VSession
.
static vpp_makeobj_thrower_t* get_makeobj_thrower() const;
Get the currently defined object creation exception handler.
See also:
set_makeobj_thrower()
set_object_maker().
static vpp_object_activater_t* get_object_activater() const;
Get the object activation function currently in use.
See also:
set_object_activater()
Note — The word "activator" is consistently misspelled as "activater" in PCustomizeFundamental
methods.
static vpp_object_deleter_t* get_object_deleter() const;
Get the currently defined object deletion function.
See also:
set_object_deleter()
static vpp_object_dirtier_t* get_object_dirtier() const;
Get the object dirty function currently in use.
See also:
set_object_dirtier()
static vpp_object_locater_t* get_object_locater() const;
Get the instance object locator function currently in use.
See also:
set_object_locater()
Note — The word "locator" is consistently misspelled as "locater" in PCustomizeFundamental
methods.
static vpp_object_maker_t* get_object_maker() const;
Get the currently defined object creation function.
See also:
set_object_maker()
static vpp_pclass_fixer_t* get_PClass_fixer() const;
Get the class fixer function for this thread.
See also:
set_pclass_fixer()
static vpp_schema_locater_t* get_schema_locater() const;
Get the schema locator function for this
VSession
object.
See also:
set_schema_locater()
Note — The word "locator" is consistently misspelled as "locater" in PCustomizeFundamental
methods.
static void set_call_user_init_flag(o_4b flag);
Specify whether the init()
method in PVirtual
is called as objects are brought into memory.
To cause init()
to be called, specify flag
as 1
; to
restore default behavior, specify flag as 0
.
The init()
method in PVirtual
allows you to initialize objects with transient data when they are first brought into memory.
For example, suppose the Employee
class is defined as the following.
class Employee : public PVirtual
{
void *transient_data;
public:
void init() {
// initialize transient_data
}
};
To cause init()
to be called when an instance of Employee
is dereferenced:
VSession::set_call_user_init_flag(1);
Afterwards, dereferencing a link will load the object into the object memory cache and call Employee::init()
to initialize transient_data
:
Link<Employee> lp = ...;
Employee *ep = lp;
This method is the same as set_call_user_init_flag()
in PCustomizeFundamental
, except that you can call it for an individual thread.
See also:
init() in PVirtual.
static void set_makeobj_thrower( vpp_makeobj_thrower_t *f );
To redefine the object creation exception handler, call this method with your redefined function specified as the f
parameter.
To restore the default, call this method and specify NULL
for the f
parameter.
See also:
set_object_maker()
static void set_object_activater(
vpp_object_activater_t *activator_function );
Redefine object activation.
When it is brought into memory, a C++ object must be activated (laid out in memory) before it can be used as a C++ object.
The information needed to activate an instance is contained in its class object, which is an instance of PClassObject<type>
. Some activation also occurs when an object is created.
Before a C++ object is brought into memory, VERSANT calls the object_activater()
method.
By default, the object_activater()
function sets the __what
, __vtbl
, and __vbase
pointers per information defined in the VERSANT implementation of the class object, which is an instance of PClassObject<type>
.
You can redefine object_activater()
, perhaps if you have your own kind of What/Class mechanism, but you probably don't need to. If you do want to define an activation function, you may want to inspect VERSANT's implementation in the file cxxcls/customiz.h
.
If the class object for a class has not been found, the PClass_fixer()
function will leave the pointer to the class object as NULL
. In this case, the default object_activater()
function returns the following error:
8040, CXX_NO_CXXCLS: C++ interface does not know about class %s
If you define an object activator function, there should be three parameters.
Link
o_object
to the instance .
char*
to the class name.
PClass*
to the desired class object.
o_errno
and return NULL
if an error occurs. If defined to throw an exception, the exception will not be caught by C++ error handling mechanisms.
To use your activation function, call this method in a session and specify your activator function in the activator_function
parameter.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call the reset()
method in VSession
.
To restore default behavior for just the relay that activates objects, call this method and specify NULL for the activator_function
parameter.
This method is the same as set_object_activater()
in PCustomizeFundamental
, except for the ability to call it for an individual thread.
Note — The word "activator" is consistently misspelled as "activater" in PCustomizeFundamental
methods.
static void set_object_deleter(
vpp_object_deleter_t *delete_function );
Redefine C++/VERSANT mechanisms that delete objects from a database.
To delete an object, the delete
operator and deleteobj()
method call the C/VERSANT o_deleteobj()
function.
To redefine what happens when an object is deleted, define a delete function and call this method with your function substituted for the delete_function
parameter.
To redefine what happens when an object is deleted, define a delete function and call this method with your function substituted for the delete_function
parameter.
The syntax of o_deleteobj()
is:
o_err o_deleteobj( o_object object );
Your redefined function should pass the same arguments and return the same value. Errors will be handled by normal C++ error handling mechanisms. See o_deleteobj()
in C/VERSANT Manual for more information.
For example, suppose that you want to redefine the delete mechanisms so that you print the logical object identifier for each deleted object. To do this, you could create the following delete function.
extern "C" {
o_err my_deleter( o_object x)
{
char buf[O_PRINTLOID_SIZE];
o_err e= o_deleteobj(x);
if (e!=O_OK) return e;
o_err ok= o_printloid( x, buf );
assert(ok==O_OK);
printf( "Deleted: %s\n", buf );
return e;
}
};
To restore default behavior for all redefined functions, call reset()
in VSession
. To restore default behavior for just the delete function, call this method and substitute o_deleteobj
for the delete_function
parameter.
This method is the same as the set_object_deleter()
method in PCustomizeFundamental
, except that you can call it for an individual thread.
static void set_object_dirtier(
vpp_object_dirtier_t *dirty_function );
This method changes what happens when the following are called:
dirty()
PObject
.
preptochange()
Link<type>
and LinkAny
.
o_preptochange()
, which sets a short write lock, marks the object as dirty, and returns O_OK
if successful.To change the default behavior, define an object dirty function and call this method in a session.
The syntax of o_preptochange()
is:
o_err o_preptochange( o_object object );
o_preptochange()
in C/VERSANT Manual for more information.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call reset()
.
To restore default behavior for just the dirty relay, call this method and specify o_preptochange
for the dirty_function
parameter.
This method is the same as set_object_dirtier()
in PCustomizeFundamental
, except for the ability to call it for an individual thread.
See also:
dirty()
preptochange()
static void set_object_locater(
vpp_object_locater_t *locator_function);
Redefine the C++/VERSANT mechanism that fetches instance objects from a database.
By default, to read an instance object, the dereference operator ->()
and the locateobj()
method call the C/VERSANT function o_locateobj()
, which finds a specified instance object, sets a specified short lock, pins the object in memory, and returns a pointer to the top of the object.
To redefine this behavior, redefine the locator function and then call this method.
The syntax for o_locateobj()
is:
o_u1b *o_locateobj(
o_object object,
o_lockmode lockmode );
Your redefined function should pass the same arguments and return the same value. See o_locateobj()
in the C/VERSANT Manual for more information.
If an error occurs, this function should set o_errno
and return NULL
. The error will be handled by normal C++ error handling mechanisms.
To restore default behavior, you can end the current session and start a new one or call VSession::reset()
.
To restore default behavior for just the object locator, call this method and set the locator_function
to o_locateobj()
.
This method is the same as set_object_locater()
in PCustomizeFundamental
, except that you can call it for an individual thread.
Note — The word "locator" is consistently misspelled as "locater" in PCustomizeFundamental
methods.
static void set_object_maker(
vpp_object_maker_t *create_function );
Redefine C++/VERSANT mechanisms that create objects.
This method changes what happens when the following are called:
Macros defined in PObject:
O_NEW_PERSISTENT()
O_NEW_PERSISTENT1()
O_NEW_PERSISTENT2()
Link<type>
and LinkAny
.
make_copy()
o_makeobj()
, which will create a persistent object of a specified class in the default database, optionally set initial attribute values, optionally pin the new object, and return a link to the new object.
The syntax of o_makeobj()
is:
o_object o_makeobj(
o_object clsobj,
o_bufdesc * initvals,
o_bool topin );
Your redefined function should pass the same arguments and return the same value. See o_makeobj()
in C/VERSANT Manual for more information.
If an error occurs, this function should set o_errno
and return NULL
. The error will be handled by normal C++ error handling mechanisms.
To use your object creation function, start a session and then redefine the calling relay with set_object_maker()
.
For example, suppose you want to redefine the create object mechanisms so that you print the logical object identifier for each new object.
First, create the new object creation function:
extern "C" {
o_object my_creator( o_object cls, o_bufdesc *bd, o_bool to_pin )
{
char buf[O_PRINTLOID_SIZE];
o_object p = o_makeobj(cls, bd, to_pin);
if (!p) return p;
o_err ok = o_printloid( p, buf );
assert(ok == O_OK);
printf( "Made: %s\n", buf );
return p;
}
};
Then, to use your object creation function, start a session and redefine the object creation relay by specifying your object creation function in the create_function
parameter of this method.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call reset()
.
To restore default behavior for just the object creator relay, call this method and specify o_makeobj
for the create_function
parameter.
This method is the same as the set_object_maker()
method in PCustomizeFundamental
, except that you can call it for an individual thread.
static void set_pclass_fixer(
vpp_pclass_fixer_t *class_fixer );
Assign a data type to a non-C++ object.
C++ objects must have a data type. Normally, a data type is defined by compiling a class definition, stored by loading it into a database as a class object, and made known to an application by linking. In the following cases, a class definition may not have been compiled, stored in a database, and/or linked to an application:
Runtime object
In this case, you need to specify to your application both the class and also define PWhat
and other things to mimic elements normally defined during schema capture.
In this case, you can cheat and activate non-C++ objects as if there were the closest C++ class to their true class. This has its limitations. For example, you can use only simple inheritence.
PClass_fixer()
method in VSession
. The default is for PClass_fixer()
to do nothing.To redefine the default behavior, create a class fixer method and then call this method.
If you define a PClass_fixer()
method and substitute it for the class_fixer
parameter in this method, there should be three parameters:
Link
o_object
to the instance .
const
char*
to the class name.
PClass**
to the desired class object.
PClass
.
If an error occurs, this function should set o_errno
and return NULL
. If defined to throw an exception, the exception will not be caught by C++ error handling mechanisms.
To use your function that defines a class, start a session and then redefine the calling relay with set_PClass_fixer()
.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call reset()
.
To restore default behavior for just the relay that defines a class, you can call this method and specify NULL
for the class_fixer
parameter.
This method is the same as set_PClass_fixer()
in PCustomizeFundamental
, except for a different use of capital letters and the ability to call it for an individual thread.
static void set_schema_locater(
vpp_schema_locater_t *locator_function );
Redefine the C++/VERSANT mechanism that fetches class objects from a database.
By default, to read a class object, the dereference operator ->()
and the locateobj()
method call the C/VERSANT function o_locateobj()
, which finds a specified instance object, sets a specified short lock, pins the object in memory, and returns a pointer to the top of the object.
To redefine locator behavior for class objects, redefine the locator function and then call this method. Otherwise, all steps are the same as for redefining the locator function for instance objects. See set_object_locater()
in VSession
for an explanation of object location.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call reset()
.
To restore default behavior, call this method and specify o_locateobj()
for the locator_function
parameter.
This method is the same as set_schema_locater()
in PCustomizeFundamental
, except that you can call it for an individual thread.
Note — The word "locator" is consistently misspelled as "locater" in PCustomizeFundamental
methods.
VThread
class is now obsolete.
The functions described in this section have been moved to the VSession
section in this chapter. Although VThread
class and methods are still supported by VERSANT, the usage of this class is not ODMG compliant, and is not recommended for new applications.
o_4b get_call_user_init_flag() const;
Return the current status of the flag used in set_call_user_init_flag()
in VThread
.
If this method returns 1
, then objects will be initialized with the init()
method when they are brought into memory. If this method returns 0, then init()
will not be called.
See also:
init() in PVirtual
set_call_user_init_flag() in VThread.
vpp_makeobj_thrower_t *get_makeobj_thrower() const;
Get the currently defined object creation exception handler.
See also set_makeobj_thrower()
and set_object_maker()
in VThread
.
vpp_object_activater_t *get_object_activater() const;
Get the object activation function currently in use.
See set_object_activater()
in VThread
for an explanation.
Note: the word "activator" is consistently misspelled as "activater" in VThread
methods.
vpp_object_deleter_t *get_object_deleter() const;
Get the currently defined object deletion function.
See set_object_deleter()
in VThread
for an explanation.
vpp_object_dirtier_t *get_object_dirtier() const;
Get the object dirty function currently in use.
See set_object_dirtier()
in VThread
for an explanation.
vpp_object_locater_t *get_object_locater() const;
Get the instance object locator function currently in use.
See set_object_locater()
in VThread
for an explanation of the object locator function.
Note: the word "locator" is consistently misspelled as "locater" in VThread
methods.
vpp_object_maker_t *get_object_maker() const;
Get the currently defined object creation function.
See set_object_maker()
in VThread
for an explanation.
vpp_pclass_fixer_t *get_PClass_fixer() const;
Get the class fixer function for this thread.
See set_pclass_fixer()
in VThread for an explanation.
void reset();
Restore default behavior for C++/VERSANT mechanisms for creating, reading, writing, deleting, and activating objects.
This method is similar to the reset()
method in PCustomizeFundamental
, except that it can be used on individual threads.
void set_call_user_init_flag(o_4b flag);
Specify whether the init()
method in PVirtual
is called as objects are brought into memory.
To cause init()
to be called, specify flag
as 1
; to
restore default behavior, specify flag as 0
.
The init()
method in PVirtual
allows you to initialize objects with transient data when they are first brought into memory.
For example, suppose the Employee
class is defined as the following.
class Employee : public PVirtual {
void *transient_data;
public:
void init() {
// initialize transient_data
}
};
To cause init()
to be called when an instance of Employee
is dereferenced:
VThread mythread;
mythread.set_call_user_init_flag(1);
Afterwards, dereferencing a link will load the object into the object memory cache and call Employee::init()
to initialize transient_data
:
Link<Employee> lp = ...;
Employee *ep = lp;
This method is the same as set_call_user_init_flag()
in PCustomizeFundamental
, except that you can call it for an individual thread.
See also:
init() in PVirtual.
void set_makeobj_thrower( vpp_makeobj_thrower_t *f );
To redefine the object creation exception handler, call this method with your redefined function specified as the f
parameter.
To restore the default, call this method and specify NULL
for the f
parameter.
See also:
set_object_maker() in VThread.
void set_object_activater(
vpp_object_activater_t *activator_function );
Redefine object activation.
When it is brought into memory, a C++ object must be activated (laid out in memory) before it can be used as a C++ object.
The information needed to activate an instance is contained in its class object, which is an instance of PClassObject<type>
. Some activation also occurs when an object is created.
Before a C++ object is brought into memory, VERSANT calls the object_activater()
method.
By default, the object_activater()
function sets the __what
, __vtbl
, and __vbase
pointers per information defined in the VERSANT implementation of the class object, which is an instance of PClassObject<type>
.
You can redefine object_activater()
, perhaps if you have your own kind of What/Class mechanism, but you probably don't need to. If you do want to define an activation function, you may want to inspect VERSANT's implementation in the file cxxcls/customiz.h
.
If the class object for a class has not been found, the PClass_fixer()
function will leave the pointer to the class object as NULL
. In this case, the default object_activater()
function returns the following error:
8040, CXX_NO_CXXCLS: C++ interface does not know about class %s
If you define an object activator function, there should be three parameters.
Link
o_object
to the instance .
char*
to the class name.
PClass*
to the desired class object.
o_errno
and return NULL
if an error occurs. If defined to throw an exception, the exception will not be caught by C++ error handling mechanisms.
To use your activation function, call this method in a session and specify your activator function in the activator_function
parameter.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call the reset()
method in VThread
.
To restore default behavior for just the relay that activates objects, call this method and specify NULL for the activator_function
parameter.
This method is the same as set_object_activater()
in PCustomizeFundamental
, except for the ability to call it for an individual thread.
Note: the word "activator" is consistently misspelled as "activater" in VThread
methods.
void set_object_deleter(
vpp_object_deleter_t *delete_function );
Redefine C++/VERSANT mechanisms that delete objects from a database.
To delete an object, the delete
operator and deleteobj()
method call the C/VERSANT o_deleteobj()
function.
To redefine what happens when an object is deleted, define a delete function and call this method with your function substituted for the delete_function
parameter.
To redefine what happens when an object is deleted, define a delete function and call this method with your function substituted for the delete_function
parameter.
The syntax of o_deleteobj()
is:
o_err o_deleteobj( o_object object );
Your redefined function should pass the same arguments and return the same value. Errors will be handled by normal C++ error handling mechanisms. See o_deleteobj()
in C/VERSANT Manual for more information.
For example, suppose that you want to redefine the delete mechanisms so that you print the logical object identifier for each deleted object. To do this, you could create the following delete function.
extern "C" {
o_err my_deleter( o_object x)
{
char buf[O_PRINTLOID_SIZE];
o_err e= o_deleteobj(x);
if (e!=O_OK) return e;
o_err ok= o_printloid( x, buf );
assert(ok==O_OK);
printf( "Deleted: %s\n", buf );
return e;
}
};
To restore default behavior for all redefined functions, call reset()
in VThread
. To restore default behavior for just the delete function, call this method and substitute o_deleteobj
for the delete_function
parameter.
This method is the same as the set_object_deleter()
method in PCustomizeFundamental
, except that you can call it for an individual thread.
void set_object_dirtier(
vpp_object_dirtier_t *dirty_function );
This method changes what happens when the following are called:
dirty()
PObject
.
preptochange()
Link<type>
and LinkAny
.
o_preptochange()
, which sets a short write lock, marks the object as dirty, and returns O_OK
if successful.To change the default behavior, define an object dirty function and call this method in a session.
The syntax of o_preptochange()
is:
o_err o_preptochange( o_object object );
Your redefined function should pass the same arguments and return the same value. Errors will be handled by normal C++ error handling mechanisms. See o_preptochange()
in C/VERSANT Manual for more information.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call the reset()
method in VThread
.
To restore default behavior for just the dirty relay, call this method and specify o_preptochange for the dirty_function
parameter.
This method is the same as set_object_dirtier()
in PCustomizeFundamental
, except for the ability to call it for an individual thread.
void set_object_locater(
vpp_object_locater_t *locator_function);
Redefine the C++/VERSANT mechanism that fetches instance objects from a database.
By default, to read an instance object, the dereference operator ->()
and the locateobj()
method call the C/VERSANT function o_locateobj()
, which finds a specified instance object, sets a specified short lock, pins the object in memory, and returns a pointer to the top of the object.
To redefine this behavior, redefine the locator function and then call this method.
The syntax for o_locateobj()
is:
o_u1b* o_locateobj(
o_object object,
o_lockmode lockmode );
Your redefined function should pass the same arguments and return the same value. See o_locateobj()
in the C/VERSANT Manual for more information.
If an error occurs, this function should set o_errno
and return NULL
. The error will be handled by normal C++ error handling mechanisms.
To restore default behavior, you can end the current session and start a new one or call VThread::reset()
.
To restore default behavior for just the object locator, call this method and set the locator_function
to o_locateobj()
:
This method is the same as set_object_locater()
in PCustomizeFundamental
, except that you can call it for an individual thread.
Note: the word "locator" is consistently misspelled as "locater" in VThread
methods.
void set_object_maker(
vpp_object_maker_t *create_function );
Redefine C++/VERSANT mechanisms that create objects.
This method changes what happens when the following are called:
O_NEW_PERSISTENT()
O_NEW_PERSISTENT1()
O_NEW_PERSISTENT2()
PObject
.
make_copy()
Link<type>
and LinkAny
.
o_makeobj()
, which will create a persistent object of a specified class in the default database, optionally set initial attribute values, optionally pin the new object, and return a link to the new object.
The syntax of o_makeobj()
is:
o_object o_makeobj(
o_object clsobj,
o_bufdesc * initvals,
o_bool topin );
Your redefined function should pass the same arguments and return the same value. See o_makeobj()
in C/VERSANT Manual for more information.
If an error occurs, this function should set o_errno
and return NULL
. The error will be handled by normal C++ error handling mechanisms.
To use your object creation function, start a session and then redefine the calling relay with set_object_maker()
.
For example, suppose you want to redefine the create object mechanisms so that you print the logical object identifier for each new object.
First, create the new object creation function:
extern "C" {
o_object my_creator( o_object cls, o_bufdesc *bd, o_bool to_pin )
{
char buf[O_PRINTLOID_SIZE];
o_object p = o_makeobj(cls, bd, to_pin);
if (!p) return p;
o_err ok = o_printloid( p, buf );
assert(ok == O_OK);
printf( "Made: %s\n", buf );
return p;
}
};
Then, to use your object creation function, start a session and redefine the object creation relay by specifying your object creation function in the create_function
parameter of this method.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call reset()
.
To restore default behavior for just the object creator relay, call this method and specify o_makeobj
for the create_function
parameter.
This method is the same as the set_object_maker()
method in PCustomizeFundamental
, except that you can call it for an individual thread.
void set_pclass_fixer(
vpp_pclass_fixer_t *class_fixer );
Assign a data type to a non-C++ object.
C++ objects must have a data type. Normally, a data type is defined by compiling a class definition, stored by loading it into a database as a class object, and made known to an application by linking. In the following cases, a class definition may not have been compiled, stored in a database, and/or linked to an application:
Runtime object
In this case, you need to specify to your application both the class and also define PWhat
and other things to mimic elements normally defined during schema capture.
In this case, you can cheat and activate non-C++ objects as if there were the closest C++ class to their true class. This has its limitations. For example, you can use only simple inheritance.
PClass_fixer()
method in VThread
. The default is for PClass_fixer()
to do nothing.To redefine the default behavior, create a class fixer method and then call this method.
If you define a PClass_fixer()
method and substitute it for the class_fixer
parameter in this method, there should be three parameters:
Link
o_object
to the instance .
const
char*
to the class name.
PClass**
to the desired class object.
PClass
.
If an error occurs, this function should set o_errno
and return NULL
. If defined to throw an exception, the exception will not be caught by C++ error handling mechanisms.
To use your function that defines a class, start a session and then redefine the calling relay with set_PClass_fixer()
.
To restore default behavior for all redefined relays, you can end the current session and start a new one or call reset()
.
To restore default behavior for just the relay that defines a class, you can call this method and specify NULL
for the class_fixer
parameter.
This method is the same as set_PClass_fixer()
in PCustomizeFundamental
, except for a different use of capital letters and the ability to call it for an individual thread.
void set_schema_locater(
vpp_schema_locater_t *locator_function );
Redefine the C++/VERSANT mechanism that fetches class objects from a database.
By default, to read a class object, the dereference operator ->()
and the locateobj()
method call the C/VERSANT function o_locateobj()
, which finds a specified instance object, sets a specified short lock, pins the object in memory, and returns a pointer to the top of the object.
To redefine locator behavior for class objects, redefine the locator function and then call this method. Otherwise, all steps are the same as for redefining the locator function for instance objects. See set_object_locater()
in VThread
for an explanation of object location.
To restore default behavior, call this method and specify o_locateobj()
for the locator_function
parameter.
This method is the same as set_schema_locater()
in PCustomizeFundamental
, except that you can call it for an individual thread.
Note: the word "locator" is consistently misspelled as "locater" in VThread
methods.
This online documentation is confidential and proprietary to Versant Corporation and is licensed to you, or to your organization, pursuant to the terms of an agreement between you and Versant that restricts the use of this documentation. Please refer to the agreement for more information or call Versant at 510-789-1500 with any questions.