Merge 'trunk' into 'pod_fixes'
Peter Rabbitson [Sat, 6 Mar 2010 18:26:10 +0000 (19:26 +0100)]
r8913@Thesaurus (orig r8900):  ribasushi | 2010-03-06 12:26:10 +0100
More checks for weird usage of _determine_driver (maint/gen-schema)

Changes
lib/DBIx/Class/InflateColumn/File.pm
lib/DBIx/Class/Manual/Cookbook.pod
lib/DBIx/Class/Manual/Intro.pod
lib/DBIx/Class/PK.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Row.pm

diff --git a/Changes b/Changes
index 39a1d13..b07d38c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -41,6 +41,7 @@ Revision history for DBIx::Class
 
 0.08117 2010-02-05 17:10:00 (UTC)
         - Perl 5.8.1 is now the minimum supported version
+        - DBIx::Class::InflateColumn::File entered deprecated state
         - Massive optimization of the join resolution code - now joins
           will be removed from the resulting SQL if DBIC can prove they
           are not referenced by anything
index 3d67914..c1f75ea 100644 (file)
@@ -107,7 +107,15 @@ sub _save_file_column {
 
 =head1 NAME
 
-DBIx::Class::InflateColumn::File -  map files from the Database to the filesystem.
+DBIx::Class::InflateColumn::File -  DEPRECATED (superseded by DBIx::Class::InflateColumn::FS)
+
+=head2 Deprecation Notice
+
+ This component has a number of architectural deficiencies and is not
+ recommended for further use. It will be retained for backwards
+ compatibility, but no new functionality patches will be accepted.
+ Please consider using the much more mature and actively supported
+ DBIx::Class::InflateColumn::FS
 
 =head1 SYNOPSIS
 
index c84df81..16fa647 100644 (file)
@@ -1821,12 +1821,27 @@ You can accomplish this by overriding C<insert> on your objects:
   sub insert {
     my ( $self, @args ) = @_;
     $self->next::method(@args);
-    $self->cds->new({})->fill_from_artist($self)->insert;
+    $self->create_related ('cds', \%initial_cd_data );
     return $self;
   }
 
-where C<fill_from_artist> is a method you specify in C<CD> which sets
-values in C<CD> based on the data in the C<Artist> object you pass in.
+If you want to wrap the two inserts in a transaction (for consistency,
+an excellent idea), you can use the awesome
+L<DBIx::Class::Storage::TxnScopeGuard>:
+
+  sub insert {
+    my ( $self, @args ) = @_;
+
+    my $guard = $self->result_source->schema->txn_scope_guard;
+
+    $self->next::method(@args);
+    $self->create_related ('cds', \%initial_cd_data );
+
+    $guard->commit;
+
+    return $self
+  }
+
 
 =head2 Wrapping/overloading a column accessor
 
index 55a7463..18347d8 100644 (file)
@@ -401,6 +401,53 @@ L<DBIx::Class::ResultSet/ATTRIBUTES>.
 
 =head1 NOTES
 
+=head2 The Significance and Importance of Primary Keys
+
+The concept of a L<primary key|DBIx::Class::ResultSource/set_primary_key> in
+DBIx::Class warrants special discussion. The formal definition (which somewhat
+resembles that of a classic RDBMS) is I<a unique constraint that is least
+likely to change after initial row creation>. However this is where the
+similarity ends. Any time you call a CRUD operation on a row (e.g.
+L<delete|DBIx::Class::Row/delete>,
+L<update|DBIx::Class::Row/update>,
+L<discard_changes|DBIx::Class::Row/discard_changes>,
+etc.) DBIx::Class will use the values of of the
+L<primary key|DBIx::Class::ResultSource/set_primary_key> columns to populate
+the C<WHERE> clause necessary to accomplish the operation. This is why it is
+important to declare a L<primary key|DBIx::Class::ResultSource/set_primary_key>
+on all your result sources B<even if the underlying RDBMS does not have one>.
+In a pinch one can always declare each row identifiable by all its columns:
+
+ __PACKAGE__->set_primary_keys (__PACKAGE__->columns);
+
+Note that DBIx::Class is smart enough to store a copy of the PK values before
+any row-object changes take place, so even if you change the values of PK
+columns the C<WHERE> clause will remain correct.
+
+If you elect not to declare a C<primary key>, DBIx::Class will behave correctly
+by throwing exceptions on any row operation that relies on unique identifiable
+rows. If you inherited datasets with multiple identical rows in them, you can
+still operate with such sets provided you only utilize
+L<DBIx::Class::ResultSet> CRUD methods:
+L<search|DBIx::Class::ResultSet/search>,
+L<update|DBIx::Class::ResultSet/update>,
+L<delete|DBIx::Class::ResultSet/delete>
+
+For example, the following would not work (assuming C<People> does not have
+a declared PK):
+
+ my $row = $schema->resultset('People')
+                   ->search({ last_name => 'Dantes' })
+                    ->next;
+ $row->update({ children => 2 }); # <-- exception thrown because $row isn't
+                                  # necessarily unique
+
+So instead the following should be done:
+
+ $schema->resultset('People')
+         ->search({ last_name => 'Dantes' })
+          ->update({ children => 2 }); # <-- update's ALL Dantes to have children of 2
+
 =head2 Problems on RHEL5/CentOS5
 
 There used to be an issue with the system perl on Red Hat Enterprise
index a25c431..c4d3b93 100644 (file)
@@ -37,6 +37,7 @@ sub id {
 
 sub _ident_values {
   my ($self) = @_;
+
   my (@ids, @missing);
 
   for ($self->_pri_cols) {
index 4b6ec45..da89e0e 100644 (file)
@@ -465,10 +465,11 @@ called after L</add_columns>.
 Additionally, defines a L<unique constraint|add_unique_constraint>
 named C<primary>.
 
-The primary key columns are used by L<DBIx::Class::PK::Auto> to
-retrieve automatically created values from the database. They are also
-used as default joining columns when specifying relationships, see
-L<DBIx::Class::Relationship>.
+Note: you normally do want to define a primary key on your sources
+B<even if the underlying database table does not have a primary key>.
+See
+L<DBIx::Class::Intro/The Significance and Importance of Primary Keys>
+for more info.
 
 =cut
 
index 45cff9b..0819375 100644 (file)
@@ -440,7 +440,11 @@ Throws an exception if the row object is not yet in the database,
 according to L</in_storage>.
 
 This method issues an SQL UPDATE query to commit any changes to the
-object to the database if required.
+object to the database if required (see L</get_dirty_columns>).
+It throws an exception if a proper WHERE clause uniquely identifying
+the database row can not be constructed (see
+L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
+for more details).
 
 Also takes an optional hashref of C<< column_name => value> >> pairs
 to update on the object first. Be aware that the hashref will be
@@ -513,8 +517,10 @@ sub update {
 =back
 
 Throws an exception if the object is not in the database according to
-L</in_storage>. Runs an SQL DELETE statement using the primary key
-values to locate the row.
+L</in_storage>. Also throws an exception if a proper WHERE clause
+uniquely identifying the database row can not be constructed (see
+L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
+for more details).
 
 The object is still perfectly usable, but L</in_storage> will
 now return 0 and the object must be reinserted using L</insert>
@@ -1276,8 +1282,11 @@ sub register_column {
 =back
 
 Fetches a fresh copy of the Row object from the database and returns it.
-
-If passed the \%attrs argument, will first apply these attributes to
+Throws an exception if a proper WHERE clause identifying the database row
+can not be constructed (i.e. if the original object does not contain its
+entire
+ L<primary key|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
+). If passed the \%attrs argument, will first apply these attributes to
 the resultset used to find the row.
 
 This copy can then be used to compare to an existing row object, to
@@ -1312,7 +1321,11 @@ sub get_from_storage {
 =head2 discard_changes ($attrs)
 
 Re-selects the row from the database, losing any changes that had
-been made.
+been made. Throws an exception if a proper WHERE clause identifying
+the database row can not be constructed (i.e. if the original object
+does not contain its entire
+L<primary key|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
+).
 
 This method can also be used to refresh from storage, retrieving any
 changes made since the row was last read from storage.