From: Jess Robinson Date: Sun, 12 Aug 2007 14:27:38 +0000 (+0000) Subject: Documentation: cookbook, resultset/create and some other bits X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=264f157120a19acb7c265e549f48d1396326aa4f;p=dbsrgits%2FDBIx-Class-Historic.git Documentation: cookbook, resultset/create and some other bits --- diff --git a/lib/DBIx/Class.pm b/lib/DBIx/Class.pm index 0934c55..cde7f79 100644 --- a/lib/DBIx/Class.pm +++ b/lib/DBIx/Class.pm @@ -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: diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index fbe9e0a..9a96f34 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -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 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 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 object for the +In either of the above cases, you can get a L object for the resultset (suitable for use in e.g. a template) using the C 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 (also known as -"SQL Fairy") installed. +To create a DBIx::Class schema from an existing database, use +L's C: -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 +(also known as "SQL Fairy") installed. -To create a MySQL database from an existing L 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 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. =head3 Save the schema -Use C 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 as above under L. =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. =head3 Deploy update to customers -The schema update can be deployed to customers using the same method as before. +Add the L schema component to your +Schema class. This will add a new table to your database called +C 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 diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index b421944..a56166f 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -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 to do that. Calling L +will tell you whether the row object has been inserted or not. + +Passes the hashref of input on to L. =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 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), +and use the name of the relationship as the key. (NOT the name of the field, +necessarily). For C and C 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), 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 method (or via the object accessor, B). It has nothing to do with the SQL code C< SELECT foo AS bar >. -The C< as > attribute is used in conjunction with C, usually when C