summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Woodward2005-12-21 06:22:48 +0000
committerJason Woodward2005-12-21 06:22:48 +0000
commit3cabf91c5aefb74d4a5e1facde029812f9db482c (patch)
tree8dab58989a2544985c34046e587f1b5d12426438
parent462102ad01d8cad51d66542e63eea6cef17e4659 (diff)
downloadJaos-DBI-3cabf91c5aefb74d4a5e1facde029812f9db482c.tar.gz
added 04full.t, updated POD, and added additional search methods0.3
-rw-r--r--Changes5
-rw-r--r--MANIFEST2
-rw-r--r--README343
-rw-r--r--lib/Jaos/DBI.pm128
-rw-r--r--t/04full.t69
-rw-r--r--t/lib/Foo.pm10
6 files changed, 374 insertions, 183 deletions
diff --git a/Changes b/Changes
index 6c840bc..be7a3b7 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,9 @@
Revision history for Perl extension Jaos::DBI
+0.3
+ - added 04full.t
+ - updated POD
+ - added additional search methods
+
0.2
- initial release
diff --git a/MANIFEST b/MANIFEST
index db732e1..b3d1532 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -8,3 +8,5 @@ README
t/01use.t
t/02pod.t
t/03podcoverage.t
+t/04full.t
+t/lib/Foo.pm
diff --git a/README b/README
index 9f463bc..61a3a56 100644
--- a/README
+++ b/README
@@ -1,237 +1,248 @@
-
NAME
- Jaos::DBI - Jaos DBI object similar to Class::DBI
+ Jaos::DBI - Jaos DBI object similar to Class::DBI
SYNOPSIS
- # subclassing
- package Users;
- use base qw/Jaos::DBI/;
- use strict;
- use warnings;
-
- __PACKAGE__->db_dsn('dbi:Pg:dbname=foo');
- __PACKAGE__->db_user('you');
- __PACKAGE__->db_password('secret');
- __PACKAGE__->db_options({RaiseError => 0, AutoCommit => 1, PrintError => 0});
-
- __PACKAGE__->table('users');
- __PACKAGE__->columns(qw/id nick password email logged_in/);
- __PACKAGE__->primary_column('id');
- __PACKAGE__->virtual_columns(qw/join_id join_name/);
- __PACKAGE__->sequence('users_id_seq');
- __PACKAGE__->base_select('select a.*,b.join_id,b.join_name from foo a join bar b on a.id=b.foo');
- __PACKAGE__->manual_update(1);
-
- __PACKAGE__->setup(); # initiates database connection and accessors
- 1;
-
- # using subclass
- use Users;
-
- # examine the class properties
- print "table: ", Users->table, "\n";
- print "columns: ", join(',', Users->columns ), "\n";
-
- # retrieve objects
- # by search
- my @objs = Users->search(email => 'foo@bar.com',{ order_by => 'id', limit => '2'});
- my @objs = Users->search(email => 'foo@bar.com',{ order_by => 'id', limit => '2'});
- my @objs = Users->search_like(email => '%@bar.com',{ order_by => 'id', limit => '2'});
- # all
- my $objs_arrayref = Users->retrieve_all();
- # by primary column value (primary key)
- my $obj = Users->retrieve($id);
-
- # insert (or alias create)
- my $user = Users->insert(nick => 'zaphod', email => 'foo@bar.org');
- $user = Users->find_or_create(nick => 'zaphod', email => 'foo@bar.org');
-
- # modify
- $user->email('newaddress@foo.com'); # setting attribute updates the database
- $user->delete();
- $user->update unless $user->manual_update == 1;
- User->delete(nick => 'zaphod', email => 'newaddress@foo.com');
+ # subclassing
+ package Users;
+ use base qw/Jaos::DBI/;
+ use strict;
+ use warnings;
+
+ __PACKAGE__->db_dsn('dbi:Pg:dbname=foo');
+ __PACKAGE__->db_user('you');
+ __PACKAGE__->db_password('secret');
+ __PACKAGE__->db_options({RaiseError => 0, AutoCommit => 1, PrintError => 0});
+
+ __PACKAGE__->table('users');
+ __PACKAGE__->columns(qw/id nick password email logged_in/);
+ __PACKAGE__->primary_column('id');
+ __PACKAGE__->virtual_columns(qw/join_id join_name/);
+ __PACKAGE__->sequence('users_id_seq');
+ __PACKAGE__->base_select('select a.*,b.join_id,b.join_name from foo a join bar b on a.id=b.foo');
+ __PACKAGE__->manual_update(1);
+
+ __PACKAGE__->setup(); # initiates database connection callback and accessors
+ 1;
+
+ # using subclass
+ use Users;
+
+ # examine the class properties
+ print "table: ", Users->table, "\n";
+ print "columns: ", join(',', Users->columns ), "\n";
+
+ # retrieve objects
+ # using various search options
+ my @objs = Users->search(email => 'foo@bar.com',{ order_by => 'id', limit => '2'});
+ my @objs = Users->search_like(email => '%@bar.com',{ order_by => 'id', limit => '2'});
+ my @objs = Users->search_ilike(email => '%@bar.com',{ order_by => 'id', limit => '2'});
+ my @objs = Users->search_or(email => 'john.doe@bar.com', name => 'john');
+ my @objs = Users->search_or_like(email => 'john.doe@%', name => '%john%');
+ my @objs = Users->search_or_ilike(email => 'john.doe@%', name => '%john%');
+ my @objs = Users->search_where('name in (select name from other_user_table)');
+ # all
+ my @objs = Users->retrieve_all();
+ # by primary column value (primary key)
+ my $obj = Users->retrieve($id);
+
+ # insert (or alias create)
+ my $user = Users->insert(nick => 'zaphod', email => 'foo@bar.org');
+ my $user = Users->create(nick => 'zaphod', email => 'foo@bar.org');
+ $user = Users->find_or_create(nick => 'zaphod', email => 'foo@bar.org');
+
+ # modify
+ $user->email('newaddress@foo.com'); # setting attribute updates the database
+ $user->delete();
+ $user->update() unless $user->manual_update == 1;
+ User->delete(nick => 'zaphod', email => 'newaddress@foo.com');
DESCRIPTION
- Some description here.
+ Some description here.
METHODS
- setup
-
- Initializes the Class; creates a database handle callback and sets up the accessors for columns, primary_column, and virtual_columns. Must
- have a table name, dsn, user, and pass specified prior to calling __PACKAGE__->setup().
-
- db_dsn
-
- Get or set the database dsn.
-
- __PACKAGE__->db_dsn('dbi:Pg:dbname=foo');
-
- db_user
-
- Get or set the database user.
-
- __PACKAGE__->db_user('user');
-
- db_password
-
- Get or set the database password.
-
- __PACKAGE__->db_passwd('secret');
-
- db_options
-
- Get or set the database options.
-
- __PACKAGE__->db_options({ Autocommit => 1});
-
- base_select
-
- This sets the basic select statement that is used to retrieve information. This can be used to create complex joins or subselects that
- further where clauses can be built from.
-
- __PACKAGE__->base_select('select a.*,b.field from table a left join table2 b on a.field=b.field');
-
- table
-
- Gets or sets the table name for the subclass or instance.
-
- __PACKAGE__->table('foo');
- my $table = __PACKAGE__->table();
+ setup
+ Initializes the Class; creates a database handle callback and sets up
+ the accessors for columns, primary_column, and virtual_columns. Must
+ have a table name, dsn, user, and pass specified prior to calling
+ __PACKAGE__->setup().
- columns
+ db_dsn
+ Get or set the database dsn.
- Get or set the tables column names.
+ __PACKAGE__->db_dsn('dbi:Pg:dbname=foo');
- __PACKAGE_->columns(qw/one two three/);
- my @columns = __PACKAGE__->columns();
+ db_user
+ Get or set the database user.
- primary_column
+ __PACKAGE__->db_user('user');
- Get or set the tables primary column;
+ db_password
+ Get or set the database password.
- __PACKAGE_->primary_column('id);
+ __PACKAGE__->db_passwd('secret');
- virtual_columns
+ db_options
+ Get or set the database options.
- These are virtual columns that may result from a base_select join. Accessors will be created for them just as if they were columns.
+ __PACKAGE__->db_options({ Autocommit => 1});
- __PACKAGE__->virtual_columns(qw/join_id join_name/);
+ base_select
+ This sets the basic select statement that is used to retrieve
+ information. This can be used to create complex joins or subselects that
+ further where clauses can be built from.
- manual_update
+ __PACKAGE__->base_select('select a.*,b.field from table a left join table2 b on a.field=b.field');
- Get or set the option to stop auto update on modification. Must call __PACKAGE__->update manually.
+ table
+ Gets or sets the table name for the subclass or instance.
- sequence
+ __PACKAGE__->table('foo');
+ my $table = __PACKAGE__->table();
- Get or set the tables sequence. This is used to generate unique primary keys.
+ columns
+ Get or set the tables column names.
- __PACKAGE__->sequence('users_id_seq');
+ __PACKAGE_->columns(qw/one two three/);
+ my @columns = __PACKAGE__->columns();
- dbh
+ primary_column
+ Get or set the tables primary column;
- Retrieve the database handle [not recommended].
+ __PACKAGE_->primary_column('id);
- sequence_nextval
+ virtual_columns
+ These are virtual columns that may result from a base_select join.
+ Accessors will be created for them just as if they were columns.
- Returns the next value for the tables sequence.
+ __PACKAGE__->virtual_columns(qw/join_id join_name/);
- my $new_id = __PACKAGE__->sequence_nextval();
+ manual_update
+ Get or set the option to stop auto update on modification. Must call
+ __PACKAGE__->update manually.
- sequence_currval
+ sequence
+ Get or set the tables sequence. This is used to generate unique primary
+ keys.
- Returns the current value for the tables sequence.
+ __PACKAGE__->sequence('users_id_seq');
- my $current_id = __PACKAGE__->sequence_currval();
+ dbh
+ Retrieve the database handle [not recommended].
- prepare
+ sequence_nextval
+ Returns the next value for the tables sequence.
- Returns a statement handle for the specified sql;
+ my $new_id = __PACKAGE__->sequence_nextval();
- __PACKAGE__->prepare('select * from foo');
+ sequence_currval
+ Returns the current value for the tables sequence.
- insert
+ my $current_id = __PACKAGE__->sequence_currval();
- Inserts a row into the database, returning an object representing that row. This calls __PACKAGE__->sequence_nextval for the primary col-
- umn.
+ prepare
+ Returns a statement handle for the specified sql;
- my $new_obj = __PACKAGE__->insert(column1 => $value1, column2 => $value2);
+ __PACKAGE__->prepare('select * from foo');
- create
+ insert
+ Inserts a row into the database, returning an object representing that
+ row. This calls __PACKAGE__->sequence_nextval for the primary column.
- Alias to insert.
+ my $new_obj = __PACKAGE__->insert(column1 => $value1, column2 => $value2);
- find_or_create
+ create
+ Alias to insert.
- This attempts to find a row with the column values specified, or creates one. Calls __PACKAGE__->search(@_) and __PACKAGE__->insert(@_) if
- search returns undef.
+ find_or_create
+ This attempts to find a row with the column values specified, or creates
+ one. Calls __PACKAGE__->search(@_) and __PACKAGE__->insert(@_) if search
+ returns undef.
- my $obj = __PACKAGE__->find_or_create(column1 => $value, column2 => $value);
- =cut
+ my $obj = __PACKAGE__->find_or_create(column1 => $value, column2 => $value);
+ =cut
- sub find_or_create {
- my $self = shift;
- my $table = $self->table;
+ sub find_or_create { my $self = shift; my $table = $self->table;
- if (my ($r) = $self->search(@_)) {
- return $r;
- }
- return $self->insert(@_);
- }
+ if (my ($r) = $self->search(@_)) {
+ return $r;
+ }
+ return $self->insert(@_);
+ }
- search
+ search
+ Searches the table and returns a list of matching objects.
- Searches the table and returns a list of matching objects.
+ my @objs = __PACKAGE__->search(column1 => $value1, column2 => $value2);
- my @objs = __PACKAGE__->search(column1 => $value1, column2 => $value2);
+ search_like
+ Searches the table and returns a list of matching objects using column
+ like $value rather than column = $value.
- search_like
+ my @objs = __PACKAGE__->search_like(column1 => "%$value1%", column2 => "%$value2%");
- Searches the table and returns a list of matching objects using column like $value rather than column = $value.
+ search_ilike
+ same as search_like but insensitive
- my @objs = __PACKAGE__->search_like(column1 => "%$value1%", column2 => "%$value2%");
+ search_or
+ search where given key/values use or instead of and
- search_where
+ search_or_like
+ search where given like key/values use or instead of and
- Searches the table and returns a list of matching objects using the specified where clause
+ search_or_ilike
+ search insensitive where given ilike key/values use or instead of and
- my @objs = __PACKAGE__->search_where('id = foo');
+ search_where
+ Searches the table and returns a list of matching objects using the
+ specified where clause
- delete
+ my @objs = __PACKAGE__->search_where('id = foo');
- Deletes either the referring object, if called as $obj->delete, or provides a class method to delete all all rows matching the arguments if
- called as __PACKAGE__->delete();
+ delete
+ Deletes either the referring object, if called as $obj->delete, or
+ provides a class method to delete all all rows matching the arguments if
+ called as __PACKAGE__->delete();
- $obj->delete();
- __PACKAGE__->delete(column1 => $value1, column2 => $value2);
+ $obj->delete();
+ __PACKAGE__->delete(column1 => $value1, column2 => $value2);
- get
+ get
+ Get a column value.
- Get a column value.
+ __PACKAGE__->get('column');
- __PACKAGE__->get('column');
+ set
+ Set a column value. This updates the column in the table row represented
+ by the object.
- set
+ __PACKAGE__->set('column',$value);
- Set a column value. This updates the column in the table row represented by the object.
+ update
+ Commit changes to database. Only useful when manual update is set.
- __PACKAGE__->set('column',$value);
+ retrieve_all
+ Return all rows in the table;
- retrieve_all
+ my @objs = __PACKAGE__->retrieve_all();
- Return all rows in the table;
+ retrieve
+ Return row mathing the specified key against the primary column.
- my @objs = __PACKAGE__->retrieve_all();
+ my $obj = __PACKAGE__->retrieve($id);
- retrieve
+ begin_work
+ Start transaction. Calls DBI begin_work().
- Return row mathing the specified key against the primary column.
+ commit
+ Commit transaction. Calls DBI commit().
- my $obj = __PACKAGE__->retrieve($id);
+ rollback
+ Rollback transaction. Calls DBI rollback().
AUTHOR
- Jason Woodward <woodwardj@jaos.org>
+ Jason Woodward <woodwardj@jaos.org>
LICENSE
- This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+ This library is free software; you can redistribute it and/or modify it
+ under the same terms as Perl itself.
diff --git a/lib/Jaos/DBI.pm b/lib/Jaos/DBI.pm
index dc8a70f..6299b44 100644
--- a/lib/Jaos/DBI.pm
+++ b/lib/Jaos/DBI.pm
@@ -4,7 +4,7 @@ use warnings;
use base qw/Class::Data::Inheritable Class::Accessor/;
use DBI ();
-our $VERSION = 0.2;
+our $VERSION = 0.3;
our $if_active = ($DBI::VERSION >= '1.40') ? 3 : 0;
=head1 NAME
@@ -32,7 +32,7 @@ Jaos::DBI - Jaos DBI object similar to Class::DBI
__PACKAGE__->base_select('select a.*,b.join_id,b.join_name from foo a join bar b on a.id=b.foo');
__PACKAGE__->manual_update(1);
- __PACKAGE__->setup(); # initiates database connection and accessors
+ __PACKAGE__->setup(); # initiates database connection callback and accessors
1;
# using subclass
@@ -43,23 +43,28 @@ Jaos::DBI - Jaos DBI object similar to Class::DBI
print "columns: ", join(',', Users->columns ), "\n";
# retrieve objects
- # by search
- my @objs = Users->search(email => 'foo@bar.com',{ order_by => 'id', limit => '2'});
+ # using various search options
my @objs = Users->search(email => 'foo@bar.com',{ order_by => 'id', limit => '2'});
my @objs = Users->search_like(email => '%@bar.com',{ order_by => 'id', limit => '2'});
+ my @objs = Users->search_ilike(email => '%@bar.com',{ order_by => 'id', limit => '2'});
+ my @objs = Users->search_or(email => 'john.doe@bar.com', name => 'john');
+ my @objs = Users->search_or_like(email => 'john.doe@%', name => '%john%');
+ my @objs = Users->search_or_ilike(email => 'john.doe@%', name => '%john%');
+ my @objs = Users->search_where('name in (select name from other_user_table)');
# all
- my $objs_arrayref = Users->retrieve_all();
+ my @objs = Users->retrieve_all();
# by primary column value (primary key)
my $obj = Users->retrieve($id);
# insert (or alias create)
my $user = Users->insert(nick => 'zaphod', email => 'foo@bar.org');
+ my $user = Users->create(nick => 'zaphod', email => 'foo@bar.org');
$user = Users->find_or_create(nick => 'zaphod', email => 'foo@bar.org');
# modify
$user->email('newaddress@foo.com'); # setting attribute updates the database
$user->delete();
- $user->update unless $user->manual_update == 1;
+ $user->update() unless $user->manual_update == 1;
User->delete(nick => 'zaphod', email => 'newaddress@foo.com');
=head1 DESCRIPTION
@@ -381,7 +386,7 @@ sub insert
my $sql = "insert into $table (";
my $seq = undef;
- #$self->_jaos_dbh()->()->begin_work();
+ #$self->begin_work();
$seq = $self->sequence_nextval();
@@ -404,10 +409,9 @@ sub insert
};
$seq = $self->sequence_currval();
- #$self->_jaos_dbh()->()->commit();
+ #$self->commit();
if ($seq) {
- #return ($self->search($self->primary_column => $seq))[0];
return $self->retrieve($seq);
} else {
if (my ($r) = $self->search(%opts)) {
@@ -458,7 +462,7 @@ Searches the table and returns a list of matching objects.
sub search
{
my $self = shift;
- return $self->_do_search('=',undef,@_);
+ return $self->_do_search('and','=',undef,@_);
}
=head2 search_like
@@ -472,7 +476,55 @@ Searches the table and returns a list of matching objects using column like $val
sub search_like
{
my $self = shift;
- return $self->_do_search('like',undef,@_);
+ return $self->_do_search('and','like',undef,@_);
+}
+
+=head2 search_ilike
+
+same as search_like but insensitive
+
+=cut
+
+sub search_ilike
+{
+ my $self = shift;
+ return $self->_do_search('and','ilike',undef,@_);
+}
+
+=head2 search_or
+
+search where given key/values use or instead of and
+
+=cut
+
+sub search_or
+{
+ my $self = shift;
+ return $self->_do_search('or','=',undef,@_);
+}
+
+=head2 search_or_like
+
+search where given like key/values use or instead of and
+
+=cut
+
+sub search_or_like
+{
+ my $self = shift;
+ return $self->_do_search('or','like',undef,@_);
+}
+
+=head2 search_or_ilike
+
+search insensitive where given ilike key/values use or instead of and
+
+=cut
+
+sub search_or_ilike
+{
+ my $self = shift;
+ return $self->_do_search('or','ilike',undef,@_);
}
=head2 search_where
@@ -486,12 +538,12 @@ Searches the table and returns a list of matching objects using the specified wh
sub search_where
{
my $self = shift;
- return $self->_do_search('=',@_);
+ return $self->_do_search(undef,undef,@_);
}
sub _do_search
{
- my ($self,$type,$where,@opts) = @_;
+ my ($self,$join,$type,$where,@opts) = @_;
my $class = ref($self) || $self;
my $table = $self->table;
my $sql = $self->base_select || "select * from $table";
@@ -508,7 +560,7 @@ sub _do_search
$sql .= ' where ' . $where;
} elsif (@columns) {
$sql .= ' where ';
- $sql .= join(' and ',map { "$_ $type ?" } @columns);
+ $sql .= join(" $join ",map { "$_ $type ?" } @columns);
}
if ($search_opts) {
$sql .= " order by $search_opts->{order_by}" if $search_opts->{order_by};
@@ -579,7 +631,7 @@ sub delete
return;
}
- #$self->_jaos_dbh()->()->begin_work();
+ #$self->begin_work();
#print STDERR "delete:$sql [",join(',',@values),"]\n";
eval {
my $stmt = $self->prepare($sql) or die "Failed to prepare [$sql]";
@@ -588,13 +640,13 @@ sub delete
};
if ($@) {
warn $@;
- #$self->_jaos_dbh()->()->rollback();
+ #$self->rollback();
return;
} else {
if ( ref $self ) {
undef %$self;
}
- #$self->_jaos_dbh()->()->commit();
+ #$self->commit();
return 1;
}
@@ -623,6 +675,12 @@ sub set
$self->_update($key) unless ($self->manual_update == 1);
}
+=head2 update
+
+Commit changes to database. Only useful when manual update is set.
+
+=cut
+
sub update
{
my $self = shift;
@@ -704,6 +762,42 @@ sub retrieve
return undef;
}
+=head2 begin_work
+
+Start transaction. Calls DBI begin_work().
+
+=cut
+
+sub begin_work
+{
+ my ($self) = @_;
+ $self->_jaos_dbh()->()->begin_work();
+}
+
+=head2 commit
+
+Commit transaction. Calls DBI commit().
+
+=cut
+
+sub commit
+{
+ my ($self) = @_;
+ $self->_jaos_dbh()->()->commit();
+}
+
+=head2 rollback
+
+Rollback transaction. Calls DBI rollback().
+
+=cut
+
+sub rollback
+{
+ my ($self) = @_;
+ $self->_jaos_dbh()->()->rollback();
+}
+
=head1 AUTHOR
Jason Woodward <woodwardj@jaos.org>
diff --git a/t/04full.t b/t/04full.t
new file mode 100644
index 0000000..8a4343f
--- /dev/null
+++ b/t/04full.t
@@ -0,0 +1,69 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Data::Dumper;
+use FindBin;
+use Test::More;
+use DBI;
+use lib "$FindBin::Bin/lib";
+
+BEGIN
+{
+ eval { require DBD::CSV; }
+ or plan skip_all =>
+ "DBD::CSV is needed for this test";
+
+ plan tests => 23;
+
+ unlink('foo_table') if ( -e 'foo_table' );
+ my $dbh = DBI->connect('DBI:CSV:f_dir=./') or die $DBI::errstr;
+ $dbh->do('create table foo_table (id INTEGER, name CHAR(255), password CHAR(255), email CHAR(255))') or $dbh->errstr;
+ $dbh->disconnect();
+
+ use_ok('Foo');
+}
+
+my @base_class_methods = qw/
+ db_dsn db_user db_password db_options
+ setup base_select
+ table columns primary_column virtual_columns manual_update
+ sequence sequence_nextval sequence_currval
+ insert create find_or_create delete set get update
+ search search_like search_ilike search_or search_or_like search_or_ilike
+ search_where retrieve_all retrieve
+ prepare begin_work commit rollback
+
+/;
+
+can_ok('Foo',@base_class_methods);
+ok(Foo->table eq 'foo_table','checking table class method');
+ok(Foo->columns == 3,'checking columns class method');
+my $obj = Foo->find_or_create( id => 1, name => 'jason', password => 'pass', email => 'woodwardj@jaos.org' );
+isa_ok($obj,'Foo');
+isa_ok(Foo->retrieve(1),'Foo');
+isa_ok(Foo->find_or_create( id => 2, name => 'jason', password => 'pass', email => 'woodwardj@jaos.org' ),'Foo');
+ok(Foo->search(name => 'jason') > 0,'search returns array');
+ok(Foo->search(name => 'jason',{ order_by => 'id'}) > 0,'search with order_by returns array');
+ok(Foo->search_where("name = 'jason'") > 0,'search returns array');
+ok(Foo->search_like(name => 'j%') > 0,'search_like returns array');
+ok(Foo->search_ilike() > 0,'search_ilike returns array');
+ok(Foo->search_or_like() > 0,'search_or_like returns array');
+ok(Foo->search_or_ilike() > 0,'search_or_ilike returns array');
+ok(Foo->retrieve_all() > 0,'search_or_ilike returns array');
+ok($obj->id == 1,'testing generated method');
+ok($obj->name eq 'jason','testing generated method');
+eval{$obj->begin_work;};
+$obj->name('j');
+$obj->commit;
+ok($obj->name eq 'j','testing generated method');
+ok($obj->password eq 'pass','testing generated method');
+ok($obj->email eq 'woodwardj@jaos.org','testing generated method');
+$obj->set('email','foo@bar');
+ok($obj->get('email') eq 'foo@bar','testing get() method');
+ok($obj->update(),'update() method');
+ok($obj->delete(),'delete() method');
+
+END
+{
+ unlink('foo_table');
+}
diff --git a/t/lib/Foo.pm b/t/lib/Foo.pm
new file mode 100644
index 0000000..3810736
--- /dev/null
+++ b/t/lib/Foo.pm
@@ -0,0 +1,10 @@
+package Foo;
+use base qw/ Jaos::DBI /;
+
+__PACKAGE__->db_dsn('DBI:CSV:f_dir=');
+__PACKAGE__->table('foo_table');
+__PACKAGE__->columns(qw/name password email/);
+__PACKAGE__->primary_column('id');
+
+__PACKAGE__->setup();
+1;