Documentation: cookbook, resultset/create and some other bits
Jess Robinson [Sun, 12 Aug 2007 14:27:38 +0000 (14:27 +0000)]
lib/DBIx/Class.pm
lib/DBIx/Class/Manual/Cookbook.pod
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/Row.pm

index 0934c55..cde7f79 100644 (file)
@@ -123,6 +123,8 @@ Then you can use these classes in your application's code:
   my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
   my $cd_artist_name = $cd->artist->name; # Already has the data so no query
 
+  # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
+  # create() is the same as new() then insert().
   my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
   $new_cd->artist($cd->artist);
   $new_cd->insert; # Auto-increment primary key filled in after INSERT
@@ -161,9 +163,9 @@ APIs, since DBIx::Class is used in production in many organisations,
 and even backwards incompatible changes to non-published APIs will be fixed
 if they're reported and doing so doesn't cost the codebase anything.
 
-The test suite is quite substantial, and several developer releases are
-generally made to CPAN before the -current branch is merged back to trunk for
-a major release.
+The test suite is quite substantial, and several developer releases
+are generally made to CPAN before the branch for the next release is
+merged back to trunk for a major release.
 
 The community can be found via:
 
index fbe9e0a..9a96f34 100644 (file)
@@ -9,7 +9,7 @@ DBIx::Class::Manual::Cookbook - Miscellaneous recipes
 =head3 Paged results
 
 When you expect a large number of results, you can ask L<DBIx::Class> for a
-paged resultset, which will fetch only a small number of records at a time:
+paged resultset, which will fetch only a defined number of records at a time:
 
   my $rs = $schema->resultset('Artist')->search(
     undef,
@@ -32,7 +32,7 @@ The C<page> attribute does not have to be specified in your search:
 
   return $rs->page(1); # DBIx::Class::ResultSet containing first 10 records
 
-In either of the above cases, you can return a L<Data::Page> object for the
+In either of the above cases, you can get a L<Data::Page> object for the
 resultset (suitable for use in e.g. a template) using the C<pager> method:
 
   return $rs->pager();
@@ -668,25 +668,50 @@ your main database class to make sure it disconnects cleanly:
 
 =head2 Schema import/export
 
-This functionality requires you to have L<SQL::Translator> (also known as
-"SQL Fairy") installed.
+To create a DBIx::Class schema from an existing database, use
+L<DBIx::Class::Schema::Loader>'s C<make_schema_at>:
 
-To create a DBIx::Class schema from an existing database:
+  perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at("My::Schema", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])'
 
- sqlt --from DBI
-      --to DBIx::Class::File
-      --prefix "MySchema" > MySchema.pm
+The following functionality requires you to have L<SQL::Translator>
+(also known as "SQL Fairy") installed.
 
-To create a MySQL database from an existing L<DBIx::Class> schema, convert the
-schema to MySQL's dialect of SQL:
+To create a set of database-specific .sql files for the above schema:
 
-  sqlt --from SQL::Translator::Parser::DBIx::Class 
-       --to MySQL 
-       --DBIx::Class "MySchema.pm" > Schema1.sql
-  
-And import using the mysql client:
+ my $schema = My::Schema->connect($dsn);
+ $schema->create_ddl_dir(['MySQL', 'SQLite', 'PostgreSQL'],
+                        '0.1',
+                        '/dbscriptdir/'
+                        );
+
+By default this will create schema files in the current directory, for
+MySQL, SQLite and PostgreSQL, using the $VERSION from your Schema.pm.
+
+To create a new database using the schema:
+
+ my $schema = My::Schema->connect($dsn);
+ $schema->deploy({ add_drop_tables => 1});
+
+To import created .sql files using the mysql client:
+
+  mysql -h "host" -D "database" -u "user" -p < My_Schema_1.0_MySQL.sql
+
+To create C<ALTER TABLE> conversion scripts to update a database to a
+newer version of your schema at a later point, first set a new
+$VERSION in your Schema file, then:
+
+ my $schema = My::Schema->connect($dsn);
+ $schema->create_ddl_dir(['MySQL', 'SQLite', 'PostgreSQL'],
+                         '0.2',
+                         '/dbscriptdir/',
+                         '0.1'
+                         );
+
+This will produce new database-specific .sql files for the new version
+of the schema, plus scripts to convert from version 0.1 to 0.2. This
+requires that the files for 0.1 as created above are available in the
+given directory to diff against.
 
-  mysql -h "host" -D "database" -u "user" -p < Schema1.sql
 
 =head2 Easy migration from class-based to schema-based setup
 
@@ -762,19 +787,8 @@ described under C<Schema import/export>.
 
 =head3 Save the schema
 
-Use C<sqlt> to transform your schema into an SQL script suitable for your
-customer's database. E.g. for MySQL:
-
-  sqlt --from SQL::Translator::Parser::DBIx::Class
-       --to MySQL
-       --DBIx::Class "MySchema.pm" > Schema1.mysql.sql
-
-If you need to target databases from multiple vendors, just generate an SQL
-script suitable for each. To support PostgreSQL too:
-
-  sqlt --from SQL::Translator::DBIx::Class
-       --to PostgreSQL
-       --DBIx::Class "MySchema.pm" > Schema1.pgsql.sql
+Call L<DBIx::Class::Schema/create_ddl_dir> as above under L<Schema
+import/export>.
 
 =head3 Deploy to customers
 
@@ -796,22 +810,21 @@ all part of your install.
 
 =head3 Modify the schema to change functionality
 
-As your application evolves, it may be necessary to modify your schema to
-change functionality. Once the changes are made to your schema in DBIx::Class,
-export the modified schema as before, taking care not to overwrite the original:
-
-  sqlt --from SQL::Translator::DBIx::Class
-       --to MySQL
-       --DBIx::Class "Anything.pm" > Schema2.mysql.sql
-
-Next, use sqlt-diff to create an SQL script that will update the customer's
-database schema:
-
-  sqlt-diff --to MySQL Schema1=MySQL Schema2=MySQL > SchemaUpdate.mysql.sql
+As your application evolves, it may be necessary to modify your schema
+to change functionality. Once the changes are made to your schema in
+DBIx::Class, export the modified schema and the conversion scripts as
+in L<Schema import/export>.
 
 =head3 Deploy update to customers
 
-The schema update can be deployed to customers using the same method as before.
+Add the L<DBIx::Class::Schema::Versioned> schema component to your
+Schema class. This will add a new table to your database called
+C<SchemaVersions> which will keep track of which version is installed
+and warn if the user trys to run a newer schema version than the
+database thinks it has.
+
+Alternatively, you can send the conversion sql scripts to your
+customers as above.
 
 =head2 Setting limit dialect for SQL::Abstract::Limit
 
index b421944..a56166f 100644 (file)
@@ -1422,7 +1422,12 @@ sub page {
 
 =back
 
-Creates an object in the resultset's result class and returns it.
+Creates a new row object in the resultset's result class and returns
+it. The row is not inserted into the database at this point, call
+L<DBIx::Class::Row/insert> to do that. Calling L<DBIx::Class::Row/in_storage>
+will tell you whether the row object has been inserted or not.
+
+Passes the hashref of input on to L<DBIx::Class::Row/new>.
 
 =cut
 
@@ -1540,10 +1545,38 @@ sub find_or_new {
 
 =back
 
-Inserts a record into the resultset and returns the object representing it.
+Attempt to create a single new row or a row with multiple related rows
+in the table represented by the resultset (and related tables). This
+will not check for duplicate rows before inserting, use
+L</find_or_create> to do that.
+
+To create one row for this resultset, pass a hashref of key/value
+pairs representing the columns of the table and the values you wish to
+store. If the appropriate relationships are set up, foreign key fields
+can also be passed an object representing the foreign row, and the
+value will be set to it's primary key.
+
+To create related objects, pass a hashref for the value if the related
+item is a foreign key relationship (L<DBIx::Class::Relationship/belongs_to>),
+and use the name of the relationship as the key. (NOT the name of the field,
+necessarily). For C<has_many> and C<has_one> relationships, pass an arrayref
+of hashrefs containing the data for each of the rows to create in the foreign
+tables, again using the relationship name as the key.
+
+Instead of hashrefs of plain related data (key/value pairs), you may
+also pass new or inserted objects. New objects (not inserted yet, see
+L</new>), will be inserted into their appropriate tables.
 
 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
 
+  $artist_rs->create(
+     { artistid => 4, name => 'Manufactured Crap', cds => [ 
+        { title => 'My First CD', year => 2006 },
+        { title => 'Yet More Tweeny-Pop crap', year => 2007 },
+      ],
+     },
+  );
+
 =cut
 
 sub create {
@@ -2153,7 +2186,7 @@ C<get_column> method (or via the object accessor, B<if one already
 exists>).  It has nothing to do with the SQL code C< SELECT foo AS bar
 >.
 
-The C< as > attribute is used in conjunction with C<select>,
+The C<as> attribute is used in conjunction with C<select>,
 usually when C<select> contains one or more function or stored
 procedure names:
 
@@ -2265,10 +2298,11 @@ below.
 
 =back
 
-Contains one or more relationships that should be fetched along with the main
-query (when they are accessed afterwards they will have already been
-"prefetched").  This is useful for when you know you will need the related
-objects, because it saves at least one query:
+Contains one or more relationships that should be fetched along with
+the main query (when they are accessed afterwards the data will
+already be available, without extra queries to the database).  This is
+useful for when you know you will need the related objects, because it
+saves at least one query:
 
   my $rs = $schema->resultset('Tag')->search(
     undef,
index 897ddf1..41c804e 100644 (file)
@@ -35,6 +35,8 @@ passed a hashref or an arrayref of hashrefs as the value, these will
 be turned into objects via new_related, and treated as if you had
 passed objects.
 
+For a more involved explanation, see L<DBIx::Class::ResultSet/create>.
+
 =cut
 
 ## It needs to store the new objects somewhere, and call insert on that list later when insert is called on this object. We may need an accessor for these so the user can retrieve them, if just doing ->new().
@@ -137,6 +139,9 @@ be set, or the class to have a result_source_instance method. To insert
 an entirely new object into the database, use C<create> (see
 L<DBIx::Class::ResultSet/create>).
 
+This will also insert any uninserted, related objects held inside this
+one, see L<DBIx::Class::ResultSet/create> for more details.
+
 =cut
 
 sub insert {
@@ -258,7 +263,7 @@ sub insert {
   $obj->in_storage; # Get value
   $obj->in_storage(1); # Set value
 
-Indicated whether the object exists as a row in the database or not
+Indicates whether the object exists as a row in the database or not
 
 =cut