NAME
Backed_Objects - Create static files from a database.
VERSION
Version 1.0
SYNOPSIS
Create static files from a database. Update the files every time when you update the database.
It can be used with any kind of database, for example SQL databases, Berkeley databases, data stored in .ini files, etc.
USAGE OF THE CLASS
The class Backed_Objects
is an abstract base class and you need to derive your class from it. For further suppose you developed a class HTML_DB
derived from Backed_Objects
. We will call HTML (for example) files which are updated by this module the view.
All methods can be called either as object methods or as class methods.
Calling these as class methods may be convienient when you do not need to specify additional parameters to be put into an object.
Thus the following alternatives are possible:
HTML_DB->output_all_and_order;
or
my $obj = new HTML_DB;
$obj->output_all_and_order;
Examples below assume that you are familiar with SQL and DBI
module.
Database update methods
The class Backed_Objects
offers you flexibility on the way how you update your database.
One variant is to override do_insert
, do_update
, do_delete
methods, so that they will update your database when insert
, update
, delete
methods are called.
The other variant is to update the database yourself and afterward to call insert
, update
, delete
which will call the default do-nothing do_insert
, do_update
, do_delete
methods.
The object and the ID
A database stores objects, every object stored in a database has an ID. An object may be without an ID when it is not yet stored into the DB, but you must assign an ID to an object when you store it in the DB, either by overriding do_insert
method which should set the object ID or yourself in your own code (without overriding do_insert
). HTML_DB
must have id
method which receives an object and return its ID.
The interface of this module does not specify what objects are. Objects may be hashes or any other data structures.
Every object inserted into the database has ID (which may be a natural number, but is not required to be a number).
Sometimes you may want the objects and IDs to be the same. For example, it is often OK for an object and an ID to be a row ID in a SQL database. Or you may want an object to be a hash representing a row in an SQL DB.
Sometimes a middle solution is fit: Store an object as a hash with some values from the database and read the rest values from the DB when needed, using the ID stored in the object.
An other possibililty for an object is to be a hash based on user input in a HTML form.
METHODS
id
This abstract (not defined in Backed_Objects
method) must be defined to return the ID of an object.
Examples:
sub id {
my ($self, $obj) = @_;
return $obj->{id};
}
or
# Objects are simple IDs
sub id {
my ($self, $obj) = @_;
return $obj;
}
all_ids
This abstract (not defined in Backed_Objects
method) must return a list of all IDs in the database.
sub all_ids {
my ($self) = @_;
return @{ $dbh->selectcol_arrayref("SELECT id FROM table") };
}
do_select
This abstract method should return an object from the DB having a given ID.
sub do_select {
my ($self, $id) = @_;
return $dbh->selectcol_arrayref("SELECT * FROM table WHERE id=?", undef, $id);
}
or
# Objects are simple IDs
sub do_select {
my ($self, $id) = @_;
return $id;
}
select
This method returns an object from the DB or undef
if the ID is absent (undefined or zero).
See its implementation:
sub select {
my ($self, $id) = @_;
return undef unless $id;
return $self->do_select($id);
}
do_insert, do_update, do_delete
By default these methods do nothing. (In this case you need to update database yourself, before calling insert
, update
, or delete
methods.)
You may override these methods to do database updates:
sub do_insert {
my ($self, $obj) = @_;
my @keys = keys @$obj;
my @values = values @$obj;
my $set = join ', ', map { "$_=?" } @keys;
$dbh->do("INSERT table SET $set", undef, @values);
}
sub do_update {
my ($self, $obj) = @_;
my @keys = keys @$obj;
my @values = values @$obj;
my $set = join ', ', map { "$_=?" } @keys;
$dbh->do("UPDATE table SET $set WHERE id=?", undef, @values, $obj->{id});
}
sub do_delete {
my ($self, $id) = @_;
$dbh->do("DELETE FROM table WHERE id=?", undef, @values, $id);
}
outputter
This method should return a value used to output a view of the DB (for example it may be used to output HTML files and be a hash whose values are HTML templates).
Example:
use File::Slurp;
sub outputter {
my ($self) = @_;
my $template_dir = "$ENV{DOCUMENT_ROOT}/templates";
return { main_tmpl => read_file("$template_dir/main.html"),
announce_tmpl => read_file("$template_dir/announce.html") };
}
The default implementation returns undef
.
insert, update, delete
HTML_DB->insert($obj);
HTML_DB->update($obj);
HTML_DB->delete($id);
These functions update the view based on the value $obj
from the DB. They are to be called when an object is inserted, updated, or deleted in the DB.
If you've overridden the do_insert
, do_update
, or do_delete
methods, then insert
, update
, or delete
methods update the database before updating the view.
Note that insert
methods calls both on_update
and on_insert
methods (as well as some other methods, see the source).
on_update
on_update
method it called when an object in the database is updated or after a new object is inserted.
By default on_update
calls the output
method to update the view of the object.
on_insert, on_delete, on_order_change
sub on_insert {
my ($self, $obj) = @_;
...
}
sub on_delete {
my ($self, $id) = @_;
...
}
sub on_order_change {
my ($self) = @_;
...
}
These methods (doing nothing by default) are called correspondingly when:
- inserting a new object into the database;
- deleting an object from the database;
- changing order of objects in the database (including the case of inserting a new object).
By default these methods do nothing.
You may update your view in your overrides of these methods.
on_any_change
sub on_any_change {
my ($self) = @_;
...
}
This method is called after every change of the database, for example, after insertion, deletion, update, etc.
do_output
sub do_output {
my ($self, $outputter, $obj) = @_;
...
}
This is the main method to output your files (the view).
It receives the object and the outputter returned by the outputter
method.
order_change
HTML_DB->order_change;
Call order_change
after you changed the order of objects in the database (but not after calling insert
or delete
method which call order_change
automatically).
output_by_id
An internal function.
output_all
HTML_DB->output_all;
HTML_DB->output_all_and_order;
output_all
updates the entire set of your files based on the data in the DB.
output_all_and_order
additionally updates data dependent on the order of objects in the DB.
Use these methods to update your all files (for example, after your template changed).
save
HTML_DB->save($obj);
This saves an object into the DB: updates it if it is already in the DB (has an ID) or inserts it into the DB if it has an undefined ID.
The actual code:
sub save {
my ($self, $obj) = @_;
if($self->id($obj)) {
$self->update($obj);
} else {
$self->insert($obj);
}
}
output
An internal function.
AUTHOR
Victor Porton, <porton@narod.ru>
BUGS
Please report any bugs or feature requests to bug-backed_objects at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Backed_Objects. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
In the current version of Backed_Objects
there are no provision for passing file handles for example got from a HTML form with a file
control. A complexity is that usually to upload a file we need to already know the ID of a row in a database what is possible only after inserting into the DB. Your suggestions how to deal with this problem are welcome.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Backed_Objects
You can also look for information at:
RT: CPAN's request tracker
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
LICENSE AND COPYRIGHT
Copyright 2011 Victor Porton.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.