Data-ObjectDriver
view release on metacpan or search on metacpan
Optional.
- offset
The offset to start at when limiting the result set.
Optional.
- fetchonly
A reference to an array of column names to fetch in the _SELECT_ statement.
Optional; the default is to fetch the values of all of the columns.
- for\_update
If set to a true value, the _SELECT_ statement generated will include a
_FOR UPDATE_ clause.
- comment
A sql comment to watermark the SQL query.
- window\_size
Used when requesting an iterator for the search method and selecting
a large result set or a result set of unknown size. In such a case,
no LIMIT clause is assigned, which can load all available objects into
memory. Specifying `window_size` will load objects in manageable chunks.
This will also cause any caching driver to be bypassed for issuing
the search itself. Objects are still placed into the cache upon load.
This attribute is ignored when the search method is invoked in an array
context, or if a `limit` attribute is also specified that is smaller than
the `window_size`.
## Class->search(\\@terms \[, \\%options \])
This is an alternative calling signature for the search method documented
above. When providing an array of terms, it allows for constructing complex
expressions that mix 'and' and 'or' clauses. For example:
my $iter = Ingredient->search([ { recipe_id => 5 },
-or => { calories => { value => 300, op => '<' } } ]);
while (my $ingredient = $iter->()) {
...
}
Supported logic operators are: '-and', '-or', '-and\_not', '-or\_not'.
## Class->add\_trigger($trigger, \\&callback)
Adds a trigger to all objects of class _Class_, such that when the event
_$trigger_ occurs to any of the objects, subroutine `&callback` is run. Note
that triggers will not occur for instances of _subclasses_ of _Class_, only
of _Class_ itself. See TRIGGERS for the available triggers.
## Class->call\_trigger($trigger, \[@callback\_params\])
Invokes the triggers watching class _Class_. The parameters to send to the
callbacks (in addition to _Class_) are specified in _@callback\_params_. See
TRIGGERS for the available triggers.
## $obj->save
Saves the object _$obj_ to the database.
If the object is not yet in the database, _save_ will automatically
generate a primary key and insert the record into the database table.
Otherwise, it will update the existing record.
If an error occurs, _save_ will _croak_.
Internally, _save_ calls _update_ for records that already exist in the
database, and _insert_ for those that don't.
## $obj->remove
Removes the object _$obj_ from the database.
If an error occurs, _remove_ will _croak_.
## Class->remove(\\%terms, \\%args)
Removes objects found with the _%terms_. So it's a shortcut of:
my @obj = Class->search(\%terms, \%args);
for my $obj (@obj) {
$obj->remove;
}
However, when you pass `nofetch` option set to `%args`, it won't
create objects with `search`, but issues _DELETE_ SQL directly to
the database.
## issues "DELETE FROM tbl WHERE user_id = 2"
Class->remove({ user_id => 2 }, { nofetch => 1 });
This might be much faster and useful for tables without Primary Key,
but beware that in this case **Triggers won't be fired** because no
objects are instantiated.
## Class->bulk\_insert(\[col1, col2\], \[\[d1,d2\], \[d1,d2\]\]);
Bulk inserts data into the underlying table. The first argument
is an array reference of columns names as specified in install\_properties
## $obj->add\_trigger($trigger, \\&callback)
Adds a trigger to the object _$obj_, such that when the event _$trigger_
occurs to the object, subroutine `&callback` is run. See TRIGGERS for the
available triggers. Triggers are invoked in the order in which they are added.
## $obj->call\_trigger($trigger, \[@callback\_params\])
Invokes the triggers watching all objects of _$obj_'s class and the object
_$obj_ specifically for trigger event _$trigger_. The additional parameters
besides _$obj_, if any, are passed as _@callback\_params_. See TRIGGERS for
the available triggers.
# TRIGGERS
_Data::ObjectDriver_ provides a trigger mechanism by which callbacks can be
called at certain points in the life cycle of an object. These can be set on a
class as a whole or individual objects (see USAGE).
Triggers can be added and called for these events:
- pre\_save -> ($obj, $orig\_obj)
Callbacks on the _pre\_save_ trigger are called when the object is about to be
saved to the database. For example, use this callback to translate special code
strings into numbers for storage in an integer column in the database. Note that this hook is also called when you `remove` the object.
Modifications to _$obj_ will affect the values passed to subsequent triggers
and saved in the database, but not the original object on which the _save_
method was invoked.
- post\_save -> ($obj, $orig\_obj)
Callbaks on the _post\_save_ triggers are called after the object is
saved to the database. Use this trigger when your hook needs primary
key which is automatically assigned (like auto\_increment and
sequence). Note that this hooks is **NOT** called when you remove the
object.
- pre\_insert/post\_insert/pre\_update/post\_update/pre\_remove/post\_remove -> ($obj, $orig\_obj)
Those triggers are fired before and after $obj is created, updated and
deleted.
- post\_load -> ($obj)
Callbacks on the _post\_load_ trigger are called when an object is being
created from a database query, such as with the _lookup_ and _search_ class
methods. For example, use this callback to translate the numbers your
_pre\_save_ callback caused to be saved _back_ into string codes.
Modifications to _$obj_ will affect the object passed to subsequent triggers
and returned from the loading method.
Note _pre\_load_ should only be used as a trigger on a class, as the object to
which the load is occurring was not previously available for triggers to be
added.
- pre\_search -> ($class, $terms, $args)
Callbacks on the _pre\_search_ trigger are called when a content addressed
query for objects of class _$class_ is performed with the _search_ method.
For example, use this callback to translate the entry in _$terms_ for your
code string field to its appropriate integer value.
Modifications to _$terms_ and _$args_ will affect the parameters to
subsequent triggers and what objects are loaded, but not the original hash
references used in the _search_ query.
Note _pre\_search_ should only be used as a trigger on a class, as _search_ is
never invoked on specific objects.
> The return values from your callbacks are ignored.
>
> Note that the invocation of callbacks is the responsibility of the object
> driver. If you implement a driver that does not delegate to
> _Data::ObjectDriver::Driver::DBI_, it is _your_ responsibility to invoke the
> appropriate callbacks with the _call\_trigger_ method.
# PROFILING
For performance tuning, you can turn on query profiling by setting
_$Data::ObjectDriver::PROFILE_ to a true value. Or, alternatively, you can
set the _DOD\_PROFILE_ environment variable to a true value before starting
your application.
To obtain the profile statistics, get the global
_Data::ObjectDriver::Profiler_ instance:
my $profiler = Data::ObjectDriver->profiler;
Then see the documentation for _Data::ObjectDriver::Profiler_ to see the
methods on that class.
In some applications there are phases of execution in which no I/O
operations should occur, but sometimes it's difficult to tell when,
where, or if those I/O operations are happening. One approach to
surfacing these situations is to set, either globally or locally,
the $Data::ObjectDriver::RESTRICT\_IO flag. If set, this will tell
Data::ObjectDriver to die with some context rather than executing
network calls for data.
# TRANSACTIONS
Transactions are supported by Data::ObjectDriver's default drivers. So each
Driver is capable to deal with transactional state independently. Additionally
<Data::ObjectDriver::BaseObject> class know how to turn transactions switch on
for all objects.
In the case of a global transaction all drivers used during this time are put
in a transactional state until the end of the transaction.
## Example
## start a transaction
Data::ObjectDriver::BaseObject->begin_work;
$recipe = Recipe->new;
$recipe->title('lasagnes');
$recipe->save;
my $ingredient = Ingredient->new;
$ingredient->recipe_id($recipe->recipe_id);
$ingredient->name("more layers");
$ingredient->insert;
$ingredient->remove;
if ($you_are_sure) {
Data::ObjectDriver::BaseObject->commit;
}
else {
## erase all trace of the above
Data::ObjectDriver::BaseObject->rollback;
}
## Driver implementation
Drivers have to implement the following methods:
( run in 0.942 second using v1.01-cache-2.11-cpan-39bf76dae61 )