Class-AutoDB
view release on metacpan or search on metacpan
lib/Class/AutoDB.pm view on Meta::CPAN
=head3 UNIVERSAL methods
UNIVERSAL, the base class of everything, defines four methods: isa,
DOES, can, and VERSION. Logically these are class methods, because
they return the same answer for all objects of a given class. In
practice, programmers frequently invoke these on objects.
When invoked on an oid, the system intercepts the call and
redispatches the method to the oid's real class. The system does not
retrieve the object from the database.
When invoked on a deleted-oid, the system intercepts the call and
generates an error to be consistent with how all other method
invocations are handled. See L<"Object deletion details">.
=head3 Data::Dumper details
We rely on "freezer" and "toaster" methods to convert references to
persistent objects into oids when objects are stored, and convert oids
back to references when objects are fetched. The native support for
"freezer" and "toaster" methods in L<Data::Dumper> (as of version
2.125) falls short of our needs in two respects:
=over 2
=item 1. Data::Dumper requires that the "freezer" method modify the
object being dumped, rather than letting the method return a modified
copy of the object.
=item 2. If any class has a "toaster" method, Data::Dumper assumes all
classes do and emits a call to the method even if the object in
question can't do it.
=back
We modified Data::Dumper to fix these problems. To avoid any confusion
with the official version of the code, we renamed the modified version
Class::AutoDB::Dumper and include it in our code tree.
Data::Dumper provides both pure Perl and much faster C (.xs)
implementations. We modified both implementations.
B<Caveat>: The build process automatically compiles the C
implementation I<if your system has a C compiler>. We see a few
compiler warnings in this process. These seem benign and can be
ignored. The Data::Dumper docs claim that the code will fall back to
the pure Perl implementation if the C version is not available. We
haven't checked this claim.
=head3 Object deletion details
Object deletion is a bit messy, since it is not a Perl concept. In
standard Perl, an object exists until all references to the object
cease to exist. As a result, the programmer never has to worry about
stale references. The situation changes when we introduce object
deletion: it is now possible for a variable to contain a reference
pointing to an object that has been deleted; likewise, an object can
contain a reference (technically an Oid) pointing to a deleted object.
The closest Perl analog is L<weak
references|Scalar::Util/"weaken_REF">. The standard Perl rule stated
above -- "an object exists until all references to the object cease to
exist" -- does not apply to weak references. A weak reference can go
stale (in other words, point to an object that no longer exists). When
this happens, Perl sets the reference to undef, and any attempt to
access the object via the stale reference generates an error.
We adopt similar semantics for object deletion. We do not convert
stale references to undef (would require delving into Perl internals
-- doable but not worth the effort), but we detect attempts to invoke
methods on deleted objects and 'confess' with appropriate error
messages. This complicates the application, but there seems to be no
better choice.
An application that uses object deletion extensively has to guard
against attempts to invoke methods on deleted objects. One way to
do this is to test the object before accessing it. For example, if
$object contains a reference to an object that might be deleted,
you might use this code snippet:
if ($object) { # $object will test 'true' if it still exists
# okay to invoke methods on $object here
} else { # 'else' $object has been deleted
# deal with deleted object here
}
To avoid such complications, we recommend using object deletion only
in situations where you can confidently remove all references to the
deleted objects. For example, we use it when re-initializing entire
data structures.
The 'del' method operates on the in-memory and database
representations of the objects being deleted.
It converts the in-memory representation to an OidDeleted, which is a
special kind of Oid. Any attempt to invoke application methods on an
OidDeleted confesses.
On the database, 'del' updates the object table (_AutoDB) and all
tables implementing collections that contain the object. In _AutoDB,
'del' sets the 'object' column to NULL thereby removing the object's
BLOB representation from the database; it leaves the object's oid in
_AutoDB so we can detect future attempts to access the deleted object
and generate an appropriate error message. (If we were to delete the
oid, it would look like the object was never stored, and future
accesses would generate a misleading error message). In collection
tables, 'del' removes all rows representing the object; the code
basically deletes the object from any table that 'put' would have put
it in.
'del' does B<not> remove references to the deleted object as this
would require scanning the entire database.
Queries ('get', 'find') will never retrieve a deleted object (although
they may retrieve objects containing references to deleted object),
and 'count' will not include deleted objects in its count.
=head1 METHODS AND FUNCTIONS
=head2 'new' and manage database connections
( run in 0.670 second using v1.01-cache-2.11-cpan-39bf76dae61 )