NAME

DBIx::Simple::Class - Advanced object construction for DBIx::Simple!

DESCRIPTION

This module is writen to replace most of the abstraction stuff from the base model class in the MYDLjE project on github, but can be used independently as well.

The class provides some useful methods which simplify representing rows from tables as Perl objects and modifying them. It is not intended to be a full featured ORM at all. It does not support relational mapping. This is left to the developer. It is rather a database table/row abstraction. At the same time it is not just a fancy representation of a table row like DBIx::Simple::Result::RowObject. See below for details. Last but not least, this module has no other non-CORE dependencies besides DBIx::Simple.

SYNOPSIS

#1. In your class representing a template for a row in a database table or view
package My::Model::AdminUser;
use base qw(DBIx::Simple::Class);

#sql to be used as table
sub TABLE { 'users' }
#alternative syntax: use constant TABLE =>'users';

sub COLUMNS {[qw(id group_id login_name login_password first_name last_name)]}

#used to validate params to field-setters
my $_CHECKS = {
  id => { allow => qr/^\d+$/x },
  group_id => { allow => qr/^\d+$/x },
  login_name => {required => 1, allow => qr/^\p{IsAlnum}{4,12}$/x},
  #...
};
sub CHECKS{$_CHECKS}
1;#end of My::Model::AdminUser

#2. In a startup script or subroutine
$app->{dbix} = DBIx::Simple->connect(...);
#and/or
DBIx::Simple::Class->dbix( $app->{dbix} );

#3. usage 
use My::Model::AdminUser;
my $user = $dbix->select(
  My::Model::AdminUser->TABLE, '*', {login_name => 'fred'}
)->object('My::Model::AdminUser')
#or better (if SQL::Abstract is installed)
my $user = My::Model::AdminUser->select(login_name => 'fred'); #this is cleaner

$user->first_name('Fred')->last_name('Flintstone');#chainable setters
$user->save; #update row
#....
my $user = My::Model::AdminUser->new(
  login_name => 'fred',
  first_name => 'Fred',
  last_name =>'Flintstone'
);
$user->save();#insert new user
print "new user has id:".$user->id;
#...
#select many
my $class = 'My::Model::AdminUser';
my @admins = $dbix->select(
  $class->TABLE,
  $class->COLUMNS,
  $class->WHERE
)->objects($class);
#or
my @admins = $dbix->query(
  $VERY_COMPLEX_SQL, @bind_variables
)->objects($class);

CONSTANTS

TABLE

You must define it in your subclass. This is the table where your object will store its data. Must return a string - the table name. It is used internally in "select" "update" and "insert" when saving object data.

sub TABLE { 'users' }
#using DBIx::Simple select() or query()
$self->data($self->dbix->select($self->TABLE, $self->COLUMNS, $self->WHERE)->hash);

WHERE

A HASHREF suitable for passing to "select" in DBIx::Simple. It is also used internally in "select". Default WHERE clause for your class. Empty "{}" by default. This constant is optional.

package My::PublishedNote;
sub WHERE { {data_type => 'note',published=>1 } };
#...
use My::PublishedNote;
#somwhere in your app
my $note = My::PublishedNote->select(id=>12345);
                                                    

COLUMNS

You must define it in your subclass. It must return an ARRAYREF with table columns to which the data is written. It is used in "select" in DBIx::Simple when retreiving a row from the database and when saving object data. This list is also used to generate specific getters and setters for each data-field.

sub COLUMNS { [qw(id cid user_id tstamp sessiondata)] };
# in select()
$self->data(
  $self->dbix->select($self->TABLE, $self->COLUMNS, $self->WHERE)->hash);

CHECKS

You must define this soubroutine/constant in your class and put in it your $_CHECKS. $_CHECKS must conform to the syntax supported by "Template" in Params::Check.

sub CHECKS{$_CHECKS}

PRIMARY_KEY

The column that will be used to uniquely recognise your object from others in the same table. Default: 'id'.

use constant PRIMARY_KEY => 'product_id';
#or simply
sub PRIMARY_KEY {'product_id'}

ATTRIBUTES

dbix

This is a class attribute, shared among all subclasses of DBIx::Simple::Class. This is an DBIx::Simple instance and (as you guessed) provides direct access to the current DBIx::Simple instance (with SQL::Abstract support eventually :)).

DBIx::Simple::Class->dbix( $app->{dbix} );
#later in My::Note
$self->dbix->query(...);#same instance
#or
__PACKAGE__->dbix->query(...);#same instance

DEBUG

Flag to enable debug warnings. Influencess all DBIx::Simple::Class subclasses.

DBIx::Simple::Class->DEBUG(1);

METHODS

new

Constructor. Generates getters and setters (if needed) for the fields described in "COLUMNS". Sets the eventually passed parameters as fields if they exists as column names.

My::User->new($session->{user_data});

new_from_dbix_simple

A constructor called in "object" in DBIx::Simple and "objects" in DBIx::Simple. Basically makes the same as new() without checking the validity of the field values since they come from the database and should be valid. See "Advanced_object_construction" in DBIx::Simple.

#This should be quicker than DBIx::Simple::Result::RowObject
my $class = 'My::Model::AdminUser';
my @admins = $dbix->select(
  $class->TABLE,
  $class->COLUMNS,
  $class->WHERE
)->objects($class);

select

A convenient wrapper for $dbix->select($table,$columns,$where)->object($class) and constructor. Note that SQL::Abstract must be installed. Instantiates an object from a saved in the database row by constructing and executing an SQL query based on the parameters. These parameters are used to construct the WHERE clause for the SQL SELECT statement. Prepends the "WHERE" clause defined by you to the parameters. If a row is found puts it in "data". Returns an instance of your class on success or undef otherwise.

my $user = MYDLjE::M::User->select(id => $user_id);

query

A convenient wrapper for $dbix->query($SQL,@bind)->object($class) and constructor. Accepts exacttly the same arguments as "query" in DBIx::Simple. Returns an instance of your class on success or undef otherwise.

my $user = My::User->query(
  'SELECT ' . join (',',My::User->COLUMNS)
  . ' FROM ' . My::User->TABLE.' WHERE id=? and disabled=?', 12345, 0);

data

Common getter/setter for all "COLUMNS". Uses internally the specific field getter/setter for each field. Returns a HASHREF - name/value pairs of the fields.

$self->data(title=>'My Title', description =>'This is a great story.');
my $hash = $self->data;
#or
$self->data($self->dbix->select(TABLE, COLUMNS, $where)->hash);

save

DWIM saver. If the object is fresh ( not instantiated via "new_from_dbix_simple" and "select") prepares and executes an INSERT statment, otherwise preforms an UPDATE. "TABLE" and "COLUMNS" are used to construct the SQL. "data" is stored as a row in "TABLE".

my $note = MyNote->new(title=>'My Title', description =>'This is a great story.');
#do something more...
$note->save;

insert

Used internally in "save". Can be used when you are sure your object is new. Returns the object "PRIMARY_KEY" on success.

my $note = MyNote->new(title=>'My Title', description =>'This is a great story.');
#do something more...
my $last_insert_id = $note->insert;

update

Used internally in "save". Can be used when you are sure your object is retreived from the database. Returns true on success.

use My::Model::AdminUser;
my $user = $dbix->query(
  'SELECT * FROM users WHERE login_name=?', 'fred'
)->object('My::Model::AdminUser')
$user->first_name('Fred')->last_name('Flintstone');
$user->update;

AUTHOR

Красимир Беров, <berov at cpan.org>

CREDITS

Jos Boumans for Params::Check

Juerd Waalboer for DBIx::Simple

Nate Wiger and all contributors for SQL::Abstract

BUGS

Please report any bugs or feature requests to https://github.com/kberov/DBIx--Simple--Class/issues. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc DBIx::Simple::Class

You can also look for information at:

SEE ALSO

DBIx::Simple, DBIx::Simple::Result::RowObject, DBIx::Simple::OO SQL::Abstract, Params::Check https://github.com/kberov/MYDLjE

LICENSE AND COPYRIGHT

Copyright 2012 Красимир Беров.

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.