merge resultset branch through revision 378
David Kamholz [Sun, 11 Dec 2005 00:16:11 +0000 (00:16 +0000)]
19 files changed:
lib/DBIx/Class.pm
lib/DBIx/Class/AccessorGroup.pm
lib/DBIx/Class/CDBICompat.pm
lib/DBIx/Class/DB.pm
lib/DBIx/Class/Exception.pm
lib/DBIx/Class/Manual.pod
lib/DBIx/Class/Manual/Cookbook.pod
lib/DBIx/Class/Manual/FAQ.pod
lib/DBIx/Class/Manual/Troubleshooting.pod
lib/DBIx/Class/ObjectCache.pm
lib/DBIx/Class/PK.pm
lib/DBIx/Class/PK/Auto.pm
lib/DBIx/Class/Relationship.pm
lib/DBIx/Class/Relationship/Base.pm
lib/DBIx/Class/Row.pm
lib/DBIx/Class/Schema.pm
lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Table.pm
lib/DBIx/Class/UUIDColumns.pm

index e2deaf5..f0d7a7a 100644 (file)
@@ -10,7 +10,6 @@ sub mk_classdata { shift->mk_classaccessor(@_); }
 
 $VERSION = '0.0499_01';
 
-
 1;
 
 =head1 NAME 
@@ -21,14 +20,14 @@ DBIx::Class - Extensible and flexible object <-> relational mapper.
 
 =head1 DESCRIPTION
 
-This is a sql to oop mapper, inspired by the L<Class::DBI> framework, 
+This is an SQL to OO mapper, inspired by the L<Class::DBI> framework, 
 and meant to support compability with it, while restructuring the 
-insides, and making it possible to support some new features like 
+internals and making it possible to support some new features like 
 self-joins, distinct, group bys and more.
 
-This project is still at an early stage so the maintainers don't make
+This project is still at an early stage, so the maintainers don't make
 any absolute promise that full backwards-compatibility will be supported;
-however if we can without compromising the improvements we're trying to
+however, if we can without compromising the improvements we're trying to
 make, we will, and any non-compatible changes will merit a full justification
 on the mailing list and a CPAN developer release for people to test against.
 
@@ -44,13 +43,12 @@ The community can be found via -
 
 =head1 QUICKSTART
 
-If you're using Class::DBI, and want an easy and fast way of migrating to
-DBIx::Class look at L<DBIx::Class::CDBICompat>.
-
-There are two ways of using DBIx::Class, the 'simple' and the 'schema' one.
+If you're using L<Class::DBI>, and want an easy and fast way of migrating to
+DBIx::Class, take a look at L<DBIx::Class::CDBICompat>.
 
-The 'simple' way of using DBIx::Class needs less classes than the 'schema'
-way but doesn't give you the ability to use different database connections.
+There are two ways of using DBIx::Class, the "simple" way and the "schema" way.
+The "simple" way of using DBIx::Class needs less classes than the "schema"
+way but doesn't give you the ability to easily use different database connections.
 
 Some examples where different database connections are useful are:
 
@@ -59,40 +57,42 @@ different databases with the same schema.
 
 =head1 Simple
 
-First you need to create a base class all other classes inherit from.
-
-Look at L<DBIx::Class::DB> how to do this
-
-Next you need to create a class for every table you want to use with
-DBIx::Class.
-
-Look at L<DBIx::Class::Table> how to do this.
+First you need to create a base class which all other classes will inherit from.
+See L<DBIx::Class::DB> for information on how to do this.
 
+Then you need to create a class for every table you want to use with DBIx::Class.
+See L<DBIx::Class::Table> for information on how to do this.
 
 =head2 Schema
 
-With this approach the table classes inherit directly from DBIx::Class::Core,
-although it might be a good idea to create a 'parent' class for all table
-classes which inherits from DBIx::Class::Core and adds additional methods
-needed by all table classes, e.g. reading a config file, loading auto primary
+With this approach, the table classes inherit directly from DBIx::Class::Core,
+although it might be a good idea to create a "parent" class for all table
+classes that inherits from DBIx::Class::Core and adds additional methods
+needed by all table classes, e.g. reading a config file or loading auto primary
 key support.
 
-Look at L<DBIx::Class::Schema> how to do this.
+Look at L<DBIx::Class::Schema> for information on how to do this.
 
-If you need more hand-holding, check out the introduction in the 
+If you need more help, check out the introduction in the 
 manual below.
 
 =head1 SEE ALSO
 
-=over 4
+=head2 L<DBIx::Class::Core> - DBIC Core Classes
+
+=head2 L<DBIx::Class::Manual> - User's manual
+
+=head2 L<DBIx::Class::CDBICompat> - L<Class::DBI> Compat layer
+
+=head2 L<DBIx::Class::DB> - database-level methods
 
-=item L<DBIx::Class::Core> - DBIC Core Classes
+=head2 L<DBIx::Class::Table> - table-level methods
 
-=item L<DBIx::Class::CDBICompat> - L<Class::DBI> Compat layer.
+=head2 L<DBIx::Class::Row> - row-level methods
 
-=item L<DBIx::Class::Manual> - User's manual.
+=head2 L<DBIx::Class::PK> - primary key methods
 
-=back
+=head2 L<DBIx::Class::Relationship> - relationships between tables
 
 =head1 AUTHOR
 
index 03ec899..9a2dd11 100644 (file)
@@ -16,8 +16,6 @@ getters and setters.
 
 =head1 METHODS
 
-=over 4
-
 =cut
 
 sub mk_group_accessors {
@@ -146,8 +144,6 @@ sub set_simple {
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 5fb1af4..4d0d412 100644 (file)
@@ -124,7 +124,6 @@ This class implements the trigger functionality.
 
 =back
 
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 03c0985..fed7507 100644 (file)
@@ -5,6 +5,9 @@ use DBIx::Class::Storage::DBI;
 use DBIx::Class::ClassResolver::PassThrough;
 use DBI;
 
+*dbi_commit = \&txn_commit;
+*dbi_rollback = \&txn_rollback;
+
 =head1 NAME 
 
 DBIx::Class::DB - Simple DBIx::Class Database connection by class inheritance
@@ -21,7 +24,7 @@ DBIx::Class::DB - Simple DBIx::Class Database connection by class inheritance
   package MyDB::MyTable;
 
   use base qw/MyDB/;
-  __PACKAGE__->load_components('Core');
+  __PACKAGE__->load_components('Core'); # just load this in MyDB if it will always be there
 
   ...
 
@@ -31,18 +34,15 @@ This class provides a simple way of specifying a database connection.
 
 =head1 METHODS
 
-=over 4
-
-
-=item storage
+=head2 storage
 
-Which storage backend to be used. Defaults to L<DBIx::Class::Storage::DBI>
+Sets or gets the storage backend. Defaults to L<DBIx::Class::Storage::DBI>.
 
-=item class_resolver
+=head2 class_resolver
 
-Which class to use for resolving a class. Defaults to 
-L<DBIx::Class::ClassResolver::Passthrough>, which returns whatever you throw
-at it. See resolve_class below.
+Sets or gets the class to use for resolving a class. Defaults to 
+L<DBIx::Class::ClassResolver::Passthrough>, which returns whatever you give
+it. See resolve_class below.
 
 =cut
 
@@ -50,7 +50,7 @@ __PACKAGE__->mk_classdata('storage');
 __PACKAGE__->mk_classdata('class_resolver' =>
                             'DBIx::Class::ClassResolver::PassThrough');
 
-=item connection
+=head2 connection
 
   __PACKAGE__->connection($dsn, $user, $pass, $attrs);
 
@@ -66,32 +66,34 @@ sub connection {
   $class->storage($storage);
 }
 
-=item dbi_commit
+=head2 txn_begin
 
-  $class->dbi_commit;
-
-Issues a commit again the current dbh
+Begins a transaction (does nothing if AutoCommit is off).
 
 =cut
 
-sub dbi_commit { $_[0]->storage->commit; }
+sub txn_begin { $_[0]->storage->txn_begin }
 
-=item dbi_rollback
+=head2 txn_commit
 
-  $class->dbi_rollback;
+Commits the current transaction.
 
-Issues a rollback again the current dbh
+=cut
+
+sub txn_commit { $_[0]->storage->txn_commit }
+
+=head2 txn_rollback
+
+Rolls back the current transaction.
 
 =cut
 
-sub dbi_rollback { $_[0]->storage->rollback; }
+sub txn_rollback { $_[0]->storage->txn_rollback }
 
 sub resolve_class { return shift->class_resolver->class(@_); }
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 40426ad..0580202 100644 (file)
@@ -31,13 +31,11 @@ $DBix::Class::Exception::DBIC_EXCEPTION_CLASS
 
 =head1 METHODS
 
-=over 4
+=head2 throw( $message )
 
-=item throw( $message )
+=head2 throw( message => $message )
 
-=item throw( message => $message )
-
-=item throw( error => $error )
+=head2 throw( error => $error )
 
 Throws a fatal exception.
 
@@ -54,8 +52,6 @@ sub throw {
     Carp::croak($message);
 }
 
-=back
-
 =head1 AUTHOR
 
 Marcus Ramberg <mramberg@cpan.org>
index f95b8aa..0b6c556 100644 (file)
@@ -11,26 +11,22 @@ from your SQL database.
 
 =head1 SECTIONS
 
-=over 4
-
-=item L<DBIx::Class::Manual::Intro>
+=head2 L<DBIx::Class::Manual::Intro>
 
 A beginner's introduction to using the native DBIx::Class interface
 
-=item L<DBIx::Class::Manual::Cookbook>
+=head2 L<DBIx::Class::Manual::Cookbook>
 
 Convenient reciepes for DBIC usage.
 
-=item L<DBIx::Class::Manual::FAQ>
+=head2 L<DBIx::Class::Manual::FAQ>
 
 Frequently asked questions about DBIC.
 
-=item L<DBIx::Class::Manual::Troubleshooting>
+=head2 L<DBIx::Class::Manual::Troubleshooting>
 
 Got trouble? Let us shoot it for you.
 
-=back
-
 If you're using the CDBI Compat layer, we suggest reading the L<Class::DBI>
 documentation. It should behave the same way.
 
index c168ba4..48edc40 100644 (file)
@@ -8,11 +8,43 @@ Things that could be handy
 
 =head1 RECIPES
 
-=item Input validation.
+=head2 Disconnecting cleanly
 
-=item Using joins
+If you find yourself quitting an app with Control-C a lot during development,
+you might like to put the following signal handler in your main database
+class to make sure it disconnects cleanly:
 
-=item Many-to-many relationships
+    $SIG{INT} = sub {
+        __PACKAGE__->storage->dbh->disconnect;
+    };
+
+=head2 Using joins and prefetch
+
+See L<DBIx::Class::ResultSet/Attributes>.
+
+=head2 Transactions
+
+As of version 0.04001, there is improved transaction support in
+L<DBIx::Class::Storage::DBI>. Here is an example of the recommended way to use it:
+
+    my $obj = Genus->find(12);
+    eval {
+        MyDB->txn_begin;
+        $obj->add_to_species({ name => 'troglodyte' });
+        $obj->wings(2);
+        $obj->update;
+        cromulate($obj); # can have a nested transation
+        MyDB->txn_commit;
+    };
+    if ($@) { eval { MyDB->txn_rollback } } # rollback might fail, too
+
+Currently, a nested commit will do nothing and a nested rollback will die.
+The code at each level must be sure to call rollback in the case of an error,
+to ensure that the rollback will propagate to the top level and be issued.
+Support for savepoints and for true nested transactions (for databases that
+support them) will hopefully be added in the future.
+
+=head2 Many-to-many relationships
 
 This is not as easy as it could be, but it's possible. Here's an example to 
 illustrate:
@@ -78,8 +110,4 @@ illustrate:
        # book2author table equals the bookID of the books (using the bookID 
        # relationship table
 
-=item Advanced Exception handling
-
-=item Transactions
-
 =back
index b20eded..5da03cc 100644 (file)
@@ -4,21 +4,17 @@ DBIx::Class::Manual::FAQ - Frequently Asked Questions
 
 =head1 QUESTIONS 
 
-=over 4
+=head2 What is the point of this module? Is it a fork of Class::DBI?
 
-=item What is the point of this module? Is it a fork of Class::DBI?
+=head2 Who's the intended audience for this module?
 
-=item Who's the intended audience for this module?
+=head2 What databases does it support?
 
-=item What databases does it support?
+=head2 What's the current status of this module?
 
-=item What's the current status of this module?
+=head2 What's planned in the future?
 
-=item What's planned in the future?
-
-=item Where can I go for support?
-
-=back
+=head2 Where can I go for support?
 
 =cut
 
index 029eb81..5dd88a7 100644 (file)
@@ -2,11 +2,7 @@
 
 DBIx::Class::Manual::Troubleshooting - Got a problem? Shoot it.
 
-=over 4
-
-=item  "Can't locate storage blabla"
-
-=back
+=head2  "Can't locate storage blabla"
 
 =cut
 
index f37d439..3dd8ec0 100644 (file)
@@ -14,7 +14,7 @@ __PACKAGE__->mk_classdata('cache');
 =head1 SYNOPSIS
 
     # in your class definition
-    use Cache::FastMmmap;
+    use Cache::FastMmap;
     __PACKAGE__->cache(Cache::FastMmap->new);
 
 =head1 DESCRIPTION
@@ -99,7 +99,7 @@ sub _insert_into_cache {
 
 =head1 AUTHORS
 
-David Kamholz <davekam@pobox.com>
+David Kamholz <dkamholz@cpan.org>
 
 =head1 LICENSE
 
index b532a33..eb2540d 100644 (file)
@@ -16,13 +16,11 @@ DBIx::Class::PK - Primary Key class
 
 =head1 DESCRIPTION
 
-This class represents methods handling primary keys
-and depending on them.
+This class contains methods for handling primary keys and methods 
+depending on them.
 
 =head1 METHODS
 
-=over 4
-
 =cut
 
 sub _ident_cond {
@@ -35,9 +33,10 @@ sub _ident_values {
   return (map { $self->{_column_data}{$_} } keys %{$self->_primaries});
 }
 
-=item set_primary_key <@cols>
+=head2 set_primary_key(@cols)
 
-define one or more columns as primary key for this class
+Defines one or more columns as primary key for this class. Should be
+called after C<columns>.
 
 =cut
 
@@ -53,9 +52,9 @@ sub set_primary_key {
   $class->_primaries(\%pri);
 }
 
-=item find
+=head2 find(@colvalues), find(\%cols)
 
-Finds columns based on the primary key(s).
+Finds a row based on its primary key(s).
 
 =cut
 
@@ -86,9 +85,10 @@ sub find {
   return (@row ? $class->_row_to_object(\@cols, \@row) : ());
 }
 
-=item discard_changes
+=head2 discard_changes
 
-Roll back changes that hasn't been comitted to the database.
+Re-selects the row from the database, losing any changes that had
+been made.
 
 =cut
 
@@ -106,9 +106,9 @@ sub discard_changes {
   return $self;
 }
 
-=item id
+=head2 id
 
-returns the primary key(s) for the current row. Can't be called as
+Returns the primary key(s) for a row. Can't be called as
 a class method.
 
 =cut
@@ -120,9 +120,10 @@ sub id {
   return (wantarray ? @pk : $pk[0]);
 }
 
-=item  primary_columns
+=head2 primary_columns
 
-read-only accessor which returns a list of primary keys.
+Read-only accessor which returns the list of primary keys for a class
+(in scalar context, only returns the first primary key).
 
 =cut
 
@@ -130,6 +131,14 @@ sub primary_columns {
   return keys %{shift->_primaries};
 }
 
+=head2 ID
+
+Returns a unique id string identifying a row object by primary key.
+Used by L<DBIx::Class::CDBICompat::LiveObjectIndex> and 
+L<DBIx::Class::ObjectCache>.
+
+=cut
+
 sub ID {
   my ($self) = @_;
   $self->throw( "Can't call ID() as a class method" ) unless ref $self;
@@ -153,8 +162,6 @@ sub ident_condition {
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 6928ba7..ce745aa 100644 (file)
@@ -21,9 +21,7 @@ one for your database, e.g. PK::Auto::SQLite
 
 =head1 METHODS
 
-=over 4
-
-=item insert
+=head2 insert
 
 Overrides insert so that it will get the value of autoincremented
 primary keys.
@@ -55,7 +53,7 @@ sub insert {
   return $ret;
 }
 
-=item sequence
+=head2 sequence
 
 Manually define the correct sequence for your table, to avoid the overhead
 associated with looking up the sequence automatically.
@@ -66,8 +64,6 @@ __PACKAGE__->mk_classdata('sequence');
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 65d646e..15f1bc6 100644 (file)
@@ -36,67 +36,69 @@ L<DBIx::Class::Relationship::Base>.
 
 All helper methods take the following arguments:
 
-  __PACKAGE__>method_name('relname', 'Foreign::Class', $cond, $attrs);
+  __PACKAGE__>$method_name('relname', 'Foreign::Class', $cond, $attrs);
   
 Both C<$cond> and C<$attrs> are optional. Pass C<undef> for C<$cond> if
 you want to use the default value for it, but still want to set C<$attrs>.
-The following attributes are recognize:
-
-=over 4
-
-=item join_type
-
-Explicitly specifies the type of join to use in the relationship. Any SQL
-join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL
-command immediately before C<JOIN>.
-
-=item proxy
-
-An arrayref containing a list of accessors in the foreign class to proxy in
-the main class. If, for example, you do the following:
-  
-  __PACKAGE__->might_have(bar => 'Bar', undef, { proxy => qw[/ margle /] });
-  
-Then, assuming Bar has an accessor named margle, you can do:
-
-  my $obj = Foo->find(1);
-  $obj->margle(10); # set margle; Bar object is created if it doesn't exist
-
-=back
+See L<DBIx::Class::Relationship::Base> for a list of valid attributes.
 
 =head2 belongs_to
 
-  my $f_obj = $obj->relname;
+  # in a Bar class (where Foo has many Bars)
+  __PACKAGE__->belongs_to(foo => Foo);
+  my $f_obj = $obj->foo;
+  $obj->foo($new_f_obj);
 
-  $obj->relname($new_f_obj);
+Creates a relationship where the calling class stores the foreign class's 
+primary key in one (or more) of its columns. If $cond is a column name
+instead of a join condition hash, that is used as the name of the column
+holding the foreign key. If $cond is not given, the relname is used as
+the column name.
 
-Creates a relationship where we store the foreign class' PK; if $join is a
-column name instead of a condition that is assumed to be the FK, if not
-has_many assumes the FK is the relname is that is a column on the current
-class.
+NOTE: If you are used to L<Class::DBI> relationships, this is the equivalent
+of C<has_a>.
 
 =head2 has_many
 
-  my @f_obj = $obj->relname($cond?, $attrs?);
-  my $f_result_set = $obj->relname($cond?, $attrs?);
+  # in a Foo class (where Foo has many Bars)
+  __PACKAGE__->has_many(bar => Bar, 'foo');
+  my $f_resultset = $obj->foo;
+  my $f_resultset = $obj->foo({ name => { LIKE => '%macaroni%' }, { prefetch => [qw/bar/] });
+  my @f_obj = $obj->foo;
 
-  $obj->add_to_relname(\%col_data);
+  $obj->add_to_foo(\%col_data);
 
-Creates a one-many relationship with another class; 
+Creates a one-to-many relationship, where the corresponding elements of the
+foreign class store the calling class's primary key in one (or more) of its
+columns. You should pass the name of the column in the foreign class as the
+$cond argument, or specify a complete join condition.
+
+If you delete an object in a class with a C<has_many> relationship, all
+related objects will be deleted as well. However, any database-level
+cascade or restrict will take precedence.
 
 =head2 might_have
 
-  my $f_obj = $obj->relname;
+  __PACKAGE__->might_have(baz => Baz);
+  my $f_obj = $obj->baz; # to get the baz object
+
+Creates an optional one-to-one relationship with a class, where the foreign class 
+stores our primary key in one of its columns. Defaults to the primary key of the
+foreign class unless $cond specifies a column or join condition.
 
-Creates an optional one-one relationship with another class; defaults to PK-PK
-for the join condition unless a condition is specified.
+If you update or delete an object in a class with a C<might_have> relationship, 
+the related object will be updated or deleted as well. Any database-level update
+or delete constraints will override this behavior.
 
 =head2 has_one
 
-  my $f_obj = $obj->relname;
+  __PACKAGE__->has_one(gorch => Gorch);
+  my $f_obj = $obj->gorch;
 
-Creates a one-one relationship with another class; defaults to PK-PK for
-the join condition unless a condition is specified.
+Creates a one-to-one relationship with another class. This is just like C<might_have>,
+except the implication is that the other object is always present. The only different
+between C<has_one> and C<might_have> is that C<has_one> uses an (ordinary) inner join,
+whereas C<might_have> uses a left join.
 
 =cut
 
index 4590985..ba44f0f 100644 (file)
@@ -21,21 +21,54 @@ on searches.
 
 =head1 METHODS
 
-=over 4
-
-=item add_relationship
+=head2 add_relationship
 
   __PACKAGE__->add_relationship('relname', 'Foreign::Class', $cond, $attrs);
 
 The condition needs to be an SQL::Abstract-style representation of the
-join between the tables - for example if you're creating a rel from Foo to Bar
+join between the tables. For example, if you're creating a rel from Foo to Bar,
 
   { 'foreign.foo_id' => 'self.id' }
 
-will result in a JOIN clause like
+will result in the JOIN clause
 
   foo me JOIN bar bar ON bar.foo_id = me.id
 
+You can specify as many foreign => self mappings as necessary.
+
+Valid attributes are as follows:
+
+=over 4
+
+=item join_type
+
+Explicitly specifies the type of join to use in the relationship. Any SQL
+join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL
+command immediately before C<JOIN>.
+
+=item proxy
+
+An arrayref containing a list of accessors in the foreign class to proxy in
+the main class. If, for example, you do the following:
+  
+  __PACKAGE__->might_have(bar => 'Bar', undef, { proxy => qw[/ margle /] });
+  
+Then, assuming Bar has an accessor named margle, you can do:
+
+  my $obj = Foo->find(1);
+  $obj->margle(10); # set margle; Bar object is created if it doesn't exist
+  
+=item accessor
+
+Specifies the type of accessor that should be created for the relationship.
+Valid values are C<single> (for when there is only a single related object),
+C<multi> (when there can be many), and C<filter> (for when there is a single
+related object, but you also want the relationship accessor to double as
+a column accessor). For C<multi> accessors, an add_to_* method is also
+created, which calls C<create_related> for the relationship.
+
+=back
+
 =cut
 
 sub add_relationship {
@@ -157,7 +190,7 @@ sub _cond_value {
   return $self->next::method($attrs, $key, $value)
 }
 
-=item search_related
+=head2 search_related
 
   My::Table->search_related('relname', $cond, $attrs);
 
@@ -168,7 +201,7 @@ sub search_related {
   return $self->_query_related('search', @_);
 }
 
-=item count_related
+=head2 count_related
 
   My::Table->count_related('relname', $cond, $attrs);
 
@@ -205,7 +238,7 @@ sub _query_related {
            )->$meth($query, $attrs);
 }
 
-=item create_related
+=head2 create_related
 
   My::Table->create_related('relname', \%col_data);
 
@@ -216,7 +249,7 @@ sub create_related {
   return $class->new_related(@_)->insert;
 }
 
-=item new_related
+=head2 new_related
 
   My::Table->new_related('relname', \%col_data);
 
@@ -240,7 +273,7 @@ sub new_related {
   return $self->resolve_class($rel_obj->{class})->new(\%fields);
 }
 
-=item find_related
+=head2 find_related
 
   My::Table->find_related('relname', @pri_vals | \%pri_vals);
 
@@ -262,7 +295,7 @@ sub find_related {
   return $self->resolve_class($rel_obj->{class})->find($query);
 }
 
-=item find_or_create_related
+=head2 find_or_create_related
 
   My::Table->find_or_create_related('relname', \%col_data);
 
@@ -273,7 +306,7 @@ sub find_or_create_related {
   return $self->find_related(@_) || $self->create_related(@_);
 }
 
-=item set_from_related
+=head2 set_from_related
 
   My::Table->set_from_related('relname', $rel_obj);
 
@@ -302,7 +335,7 @@ sub set_from_related {
   return 1;
 }
 
-=item update_from_related
+=head2 update_from_related
 
   My::Table->update_from_related('relname', $rel_obj);
 
@@ -314,7 +347,7 @@ sub update_from_related {
   $self->update;
 }
 
-=item delete_related
+=head2 delete_related
 
   My::Table->delete_related('relname', $cond, $attrs);
 
@@ -327,8 +360,6 @@ sub delete_related {
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 061184d..2354a7a 100644 (file)
@@ -18,9 +18,7 @@ derived from L<DBIx::Class::Table> objects.
 
 =head1 METHODS
 
-=over 4
-
-=item new
+=head2 new
 
   my $obj = My::Class->new($attrs);
 
@@ -42,7 +40,7 @@ sub new {
   return $new;
 }
 
-=item insert
+=head2 insert
 
   $obj->insert;
 
@@ -66,7 +64,7 @@ sub insert {
   return $self;
 }
 
-=item in_storage
+=head2 in_storage
 
   $obj->in_storage; # Get value
   $obj->in_storage(1); # Set value
@@ -81,7 +79,7 @@ sub in_storage {
   return $self->{_in_storage};
 }
 
-=item create
+=head2 create
 
   my $new = My::Class->create($attrs);
 
@@ -95,7 +93,7 @@ sub create {
   return $class->new($attrs)->insert;
 }
 
-=item update
+=head2 update
 
   $obj->update;
 
@@ -124,7 +122,7 @@ sub update {
   return $self;
 }
 
-=item delete
+=head2 delete
 
   $obj->delete
 
@@ -155,11 +153,13 @@ sub delete {
   return $self;
 }
 
-=item get_column
+=head2 get_column
 
   my $val = $obj->get_column($col);
 
-Fetches a column value
+Gets a column value from a row object. Currently, does not do
+any queries; the column must have already been fetched from
+the database and stored in the object.
 
 =cut
 
@@ -172,11 +172,11 @@ sub get_column {
   return undef;
 }
 
-=item get_columns
+=head2 get_columns
 
   my %data = $obj->get_columns;
 
-Fetch all column values at once.
+Does C<get_column>, for all column values at once.
 
 =cut
 
@@ -185,12 +185,12 @@ sub get_columns {
   return map { $_ => $self->get_column($_) } $self->columns;
 }
 
-=item set_column
+=head2 set_column
 
   $obj->set_column($col => $val);
 
-Sets a column value; if the new value is different to the old the column
-is marked as dirty for when you next call $obj->update
+Sets a column value. If the new value is different from the old one,
+the column is marked as dirty for when you next call $obj->update.
 
 =cut
 
@@ -203,11 +203,11 @@ sub set_column {
   return $ret;
 }
 
-=item set_columns
+=head2 set_columns
 
   my $copy = $orig->set_columns({ $col => $val, ... });
 
-Set more than one column value at once.
+Sets more than one column value at once.
 
 =cut
 
@@ -218,19 +218,19 @@ sub set_columns {
   }
 }
 
-=item copy
+=head2 copy
 
   my $copy = $orig->copy({ change => $to, ... });
 
-Insert a new row with the specified changes.
+Inserts a new row with the specified changes.
 
 =cut
 
-=item store_column
+=head2 store_column
 
   $obj->store_column($col => $val);
 
-Sets a column value without marking it as dirty
+Sets a column value without marking it as dirty.
 
 =cut
 
@@ -259,11 +259,11 @@ sub copy {
   return $new->insert;
 }
 
-=item insert_or_update
+=head2 insert_or_update
 
   $obj->insert_or_update
 
-Updates the object if it's already in the db, else inserts it
+Updates the object if it's already in the db, else inserts it.
 
 =cut
 
@@ -272,7 +272,7 @@ sub insert_or_update {
   return ($self->in_storage ? $self->update : $self->insert);
 }
 
-=item is_changed
+=head2 is_changed
 
   my @changed_col_names = $obj->is_changed
 
@@ -284,8 +284,6 @@ sub is_changed {
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 85c2db6..7bbc2f1 100644 (file)
@@ -56,9 +56,7 @@ particular which module inherits off which.
 
 =head1 METHODS
 
-=over 4
-
-=item register_class <component> <component_class>
+=head2 register_class <component> <component_class>
 
 Registers the class in the schema's class_registrations. This is a hash
 containing database classes, keyed by their monikers. It's used by
@@ -73,7 +71,7 @@ sub register_class {
   $class->class_registrations(\%reg);
 }
 
-=item registered_classes
+=head2 registered_classes
 
 Simple read-only accessor for the schema's registered classes. See 
 register_class above if you want to modify it.
@@ -85,7 +83,7 @@ sub registered_classes {
   return values %{shift->class_registrations};
 }
 
-=item  load_classes [<classes>, (<class>, <class>), {<namespace> => [<classes>]}]
+=head2  load_classes [<classes>, (<class>, <class>), {<namespace> => [<classes>]}]
 
 Uses L<Module::Find> to find all classes under the database class' namespace,
 or uses the classes you select.  Then it loads the component (using L<use>), 
@@ -142,7 +140,7 @@ sub load_classes {
   }
 }
 
-=item compose_connection <target> <@db_info>
+=head2 compose_connection <target> <@db_info>
 
 This is the most important method in this class. it takes a target namespace,
 as well as dbh connection info, and creates a L<DBIx::Class::DB> class as
@@ -185,7 +183,7 @@ sub compose_connection {
   $conn_class->class_resolver($target);
 }
 
-=item setup_connection_class <$target> <@info>
+=head2 setup_connection_class <$target> <@info>
 
 Sets up a database connection class to inject between the schema
 and the subclasses the schema creates.
@@ -201,8 +199,6 @@ sub setup_connection_class {
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 8a3a361..7e41fb2 100644 (file)
@@ -86,6 +86,8 @@ __PACKAGE__->load_components(qw/Exception AccessorGroup/);
 __PACKAGE__->mk_group_accessors('simple' =>
   qw/connect_info _dbh _sql_maker debug cursor/);
 
+our $TRANSACTION = 0;
+
 sub new {
   my $new = bless({}, ref $_[0] || $_[0]);
   $new->cursor("DBIx::Class::Storage::DBI::Cursor");
@@ -105,8 +107,6 @@ This class represents the connection to the database
 
 =head1 METHODS
 
-=over 4
-
 =cut
 
 sub dbh {
@@ -137,25 +137,45 @@ sub _connect {
   return DBI->connect(@info);
 }
 
-=item commit
+=head2 txn_begin
 
-  $class->commit;
-
-Issues a commit again the current dbh
+Calls begin_work on the current dbh.
 
 =cut
 
-sub commit { $_[0]->dbh->commit; }
+sub txn_begin {
+  $_[0]->dbh->begin_work if $TRANSACTION++ == 0 and $_[0]->dbh->{AutoCommit};
+}
 
-=item rollback
+=head2 txn_commit
 
-  $class->rollback;
+Issues a commit against the current dbh.
 
-Issues a rollback again the current dbh
+=cut
+
+sub txn_commit {
+  if ($TRANSACTION == 0) {
+    $_[0]->dbh->commit;
+  }
+  else {
+    $_[0]->dbh->commit if --$TRANSACTION == 0;    
+  }
+}
+
+=head2 txn_rollback
+
+Issues a rollback against the current dbh.
 
 =cut
 
-sub rollback { $_[0]->dbh->rollback; }
+sub txn_rollback {
+  if ($TRANSACTION == 0) {
+    $_[0]->dbh->rollback;
+  }
+  else {
+    --$TRANSACTION == 0 ? $_[0]->dbh->rollback : die $@;    
+  }
+}
 
 sub _execute {
   my ($self, $op, $extra_bind, $ident, @args) = @_;
@@ -220,8 +240,6 @@ sub sth {
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index fa8ecc0..cce20ef 100644 (file)
@@ -25,13 +25,11 @@ DBIx::Class::Table - Basic table methods
 
 =head1 DESCRIPTION
 
-This class is responsible for defining and doing basic operations on 
-L<DBIx::Class> objects.
+This class is responsible for defining and doing table-level operations on 
+L<DBIx::Class> classes.
 
 =head1 METHODS
 
-=over 4
-
 =cut
 
 sub _register_columns {
@@ -48,11 +46,11 @@ sub _mk_column_accessors {
   $class->mk_group_accessors('column' => @cols);
 }
 
-=item add_columns
+=head2 add_columns
 
   __PACKAGE__->add_columns(qw/col1 col2 col3/);
 
-Adds columns to the current package, and creates accessors for them
+Adds columns to the current class and creates accessors for them.
 
 =cut
 
@@ -78,9 +76,11 @@ sub _select_columns {
   return keys %{$_[0]->_columns};
 }
 
-=item table
+=head2 table
 
   __PACKAGE__->table('tbl_name');
+  
+Gets or sets the table name.
 
 =cut
 
@@ -88,12 +88,12 @@ sub table {
   shift->_table_name(@_);
 }
 
-=item find_or_create
+=head2 find_or_create
 
   $class->find_or_create({ key => $val, ... });
 
 Searches for a record matching the search condition; if it doesn't find one,
-creates one and returns that instead
+creates one and returns that instead.
 
 =cut
 
@@ -104,11 +104,11 @@ sub find_or_create {
   return defined($exists) ? $exists : $class->create($hash);
 }
 
-=item has_column                                                                
+=head2 has_column                                                                
                                                                                 
   if ($obj->has_column($col)) { ... }                                           
                                                                                 
-Returns 1 if the object has a column of this name, 0 otherwise                  
+Returns 1 if the class has a column of this name, 0 otherwise.                  
                                                                                 
 =cut                                                                            
 
@@ -117,11 +117,11 @@ sub has_column {
   return exists $self->_columns->{$column};
 }
 
-=item column_info                                                               
+=head2 column_info                                                               
                                                                                 
   my $info = $obj->column_info($col);                                           
                                                                                 
-Returns the column metadata hashref for the column                              
+Returns the column metadata hashref for a column.
                                                                                 
 =cut                                                                            
 
@@ -131,7 +131,7 @@ sub column_info {
   return $self->_columns->{$column};
 }
 
-=item columns                                                                   
+=head2 columns                                                                   
                                                                                 
   my @column_names = $obj->columns;                                             
                                                                                 
@@ -144,8 +144,6 @@ sub columns {
 
 1;
 
-=back
-
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
index 63df67b..dca0c58 100644 (file)
@@ -24,9 +24,7 @@ Note that the component needs to be loaded before Core.
 
 =head1 METHODS
 
-=over 4
-
-=item uuid_columns
+=head2 uuid_columns
 
 =cut
 
@@ -52,8 +50,6 @@ sub get_uuid {
     return Data::UUID->new->to_string(Data::UUID->new->create),
 }
 
-=back
-
 =head1 AUTHORS
 
 Chia-liang Kao <clkao@clkao.org>