I'd like to get some feedback on a new module in the DBIx hierarchy. It
is another DBI wrapper, or a lightweight object-relational mapping if you
prefer to look at it that way. The main goal is ease of writing a simple
database app. I have a lot of the code ready and working, it doesn't
quite do everything described below but it's been used in a few projects

In particular...

1) Is there another module that does the same thing? (DBIx::Simple and
DBIx::Wrapper for example help but definitely leave you to do manually a
lot of the things this module takes care of; Class::DBI, Alzabo and
Tangram do a whole lot more than this but are much harder to do a simple
app in)

2) What would be a good name? Some ideas are DBIx::Flexible,
DBIx::RapidPrototype, DBIx::VerySimple, DBIx::SimpleORDB, ... ?

3) Any suggestions for additions or changes to the interface? Some areas
that are not completely fleshed out are error handling (die/global error
variable/stderr), inheritance to create a database-stored object (how is
it instantiated from the database), etc. I'd like to somehow borrow the
map_* idea from DBIx::Simple as well.

-Alex Izvorski


$db = DBIx::Flexible->connect(...); # stuff gets passed to DBI

$people = $db->table('people'); # create a people table if it doesn't

$people->insert(+{ name => 'John Smith', phone => '000 000 0000', height =>
5.75 }); # adds name, phone, height columns to the people table, and then
inserts a row with the data we gave

$person = $people->select(+{ name => 'John Smith' }); # indexes people by
name if not already indexed, then fetches the row we just put in (this
will return array of rows if requested)

print $person->{phone};
print $person->get_phone(); # this also works, the method is autoloaded

$person->{phone} = '800 000 000'; # this actually changes the phone column in
the database
$person->set_phone('800 000 000'); # so does this

$people->set_condition('phone', sub { return ($_[0] =~ m/\d\d\d \d\d\d
\d\d\d\d/); }); # set a perl subroutine to check phone values

$person->set_phone('0'); # this fails (with a die or an error message)

$person->{hobbies} = [ 'Swimming', 'Jogging' ]; # this adds a new column
'hobbies', packs the data using Storable, and puts it there

$schema = $people->get_schema(); # this returns something like the
# $schema = +{
# fields =>
# +{
# _id => +{ ftype => 'id' },
# name => +{ ftype => 'text' },
# phone => +{ ftype => 'text', fconditions => [ CODE(...) ] },
# height => +{ ftype => 'float' },
# hobbies => +{ ftype => 'storable' },
# },
# keys => [ '_id', 'name' ]
# };

push(@{$schema->{keys}}, 'phone');
$people->set_schema($schema); # this creates a new index for the phone column

delete $schema->{fields}->{hobbies};
$people->set_schema($schema); # this deletes the hobbies column

# creating a database-stored object
package MyPerson;
@ISA = qw(DBIx::Flexible::Row);

$schema->{package} = 'MyPerson';
$people->set_schema($schema); # any rows returned by select from this point
on are instances of MyPerson that also inherit the tied-hashref and get/set
method behaviour of normal rows


DBIx::Flexible is a module that would help with using a database for
simple, rapid-prototyping applications that would otherwise use Storable,
Data::Dumper, a DBM or something else like that to store their data. In
the typical case, there is just one table for each kind of entity in the
application (usually just one table), tables are never joined (i.e. we
never do a select from multiple tables, although tables may have columns
that refer to keys in other tables), there are essentially no constraints
on the data imposed in the database itself (although there may be
constraints in the application code), and the exact fields and indexes
change all the time as the application is being developed.

The main goal is that it should be almost as easy to use a database as it
is a structure in memory. To that end:

* rows are returned as hashrefs that also have "magic" accessor methods
for each field

* selects take an example hashref with the fields we want to match

* updating a row value should immediately update the database

* the database schema should be updated as needed, on the fly, by adding
and dropping columns and indexes (with an option to freeze the schema)

* values should be packed/unpacked as appropriate

* values should be verified when updating using perl callbacks

* it should not be necessary to write any SQL most of the time

This package is meant to be somewhere between a full object-relational
mapping system (which would require you to subclass it for each object,
and to define schema in advance) and a dbi wrapper (which usually just
saves writing sql by hand). You can still subclass it for each object if
you wish, but you don't really have to define anything.

Limitations (in the interest of simplicity):

* no way to get part of a row, you get an entire row

* no way to iterate over rows, you get the entire result set at the same

* no way to do table joins, or to model a one/many or many/many
relationship (you can do a pseudo-join in perl code)

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupdbi-users @
postedMar 6, '04 at 11:21p
activeMar 6, '04 at 11:21p



site design / logo © 2022 Grokbase