X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FManual%2FFAQ.pod;h=426233c0664162b691b3772d5b5f4232147b114d;hb=b83736a7d3235d2f50fe5695550eb3637432d960;hp=102c4e90ecda9ae08593182553edd2282ad619d4;hpb=e66002835945589b7174d524ba5add64e714abd2;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/Manual/FAQ.pod b/lib/DBIx/Class/Manual/FAQ.pod index 102c4e9..426233c 100644 --- a/lib/DBIx/Class/Manual/FAQ.pod +++ b/lib/DBIx/Class/Manual/FAQ.pod @@ -20,7 +20,7 @@ How Do I: =item .. create a database to use? -First, choose a database. For testing/experimenting, we reccommend +First, choose a database. For testing/experimenting, we recommend L, which is a self-contained small database (i.e. all you need to do is to install L from CPAN, and it works). @@ -58,7 +58,7 @@ L. =item .. store/retrieve Unicode data in my database? -Make sure you database supports Unicode and set the connect +Make sure your database supports Unicode and set the connect attributes appropriately - see L @@ -75,22 +75,22 @@ lot later. =item .. use DBIx::Class across multiple databases? -If your database server allows you to run querys across multiple +If your database server allows you to run queries across multiple databases at once, then so can DBIx::Class. All you need to do is make sure you write the database name as part of the -L call. Eg: +L call. Eg: __PACKAGE__->table('mydb.mytablename'); -And load all the Result classes for both / all databases using one -L call. +And load all the Result classes for both / all databases by calling +L. =item .. use DBIx::Class across PostgreSQL/DB2/Oracle schemas? -Add the name of the schema to the L -as part of the name, and make sure you give the one user you are going -to connect with has permissions to read/write all the schemas/tables as -necessary. +Add the name of the schema to the table name, when invoking +L, and make sure the user +you are about to connect as has permissions to read/write all the +schemas/tables as necessary. =back @@ -132,9 +132,10 @@ allow you to supply a hashref containing the condition across which the tables are to be joined. The condition may contain as many fields as you like. See L. -=item .. define a relationship across an intermediate table? (many-to-many) +=item .. define a relationship bridge across an intermediate table? (many-to-many) -Read the documentation on L. +The term 'relationship' is used loosely with many_to_many as it is not considered a +relationship in the fullest sense. For more info, read the documentation on L. =item .. stop DBIx::Class from attempting to cascade deletes on my has_many and might_have relationships? @@ -153,7 +154,7 @@ See L. =item .. use a relationship? Use its name. An accessor is created using the name. See examples in -L. +L. =back @@ -238,19 +239,10 @@ documentation for details. =item .. search with an SQL function on the left hand side? -To use an SQL function on the left hand side of a comparison: +To use an SQL function on the left hand side of a comparison you currently need +to resort to literal SQL: - ->search({ -nest => \[ 'YEAR(date_of_birth) = ?', [ plain_value => 1979 ] ] }); - -Note: the C string in the C<< [ plain_value => 1979 ] >> part -should be either the same as the name of the column (do this if the type of the -return value of the function is the same as the type of the column) or -otherwise it's essentially a dummy string currently (use C as a -habit). It is used by L to handle special column types. - -Or, if you have quoting off: - - ->search({ 'YEAR(date_of_birth)' => 1979 }); + ->search( \[ 'YEAR(date_of_birth) = ?', 1979 ] ); =item .. find more help on constructing searches? @@ -270,6 +262,39 @@ alter session statements on database connection establishment: ->on_connect_do("ALTER SESSION SET NLS_SORT = 'BINARY_CI'"); ->on_connect_do("ALTER SESSION SET NLS_SORT = 'GERMAN_CI'"); +=item .. format a DateTime object for searching? + +L and L +do not take L into account, and so your L +object will not be correctly deflated into a format your RDBMS expects. + +The L method on your +storage object can be used to return the object that would normally do this, so +it's easy to do it manually: + + my $dtf = $schema->storage->datetime_parser; + my $rs = $schema->resultset('users')->search( + { + signup_date => { + -between => [ + $dtf->format_datetime($dt_start), + $dtf->format_datetime($dt_end), + ], + } + }, + ); + +With in a Result Class method, you can get this from the +L|DBIx::Class::Row/result_source>. + + my $dtf = $self->result_source->storage->datetime_parser; + +This kludge is necessary only for conditions passed to +L and L, +whereas L and L +(but not L) are +L-aware and will do the right thing when supplied +an inflated L object. =back @@ -304,7 +329,7 @@ Use the L and L attributes to order your data and pick off a single row. -See also L. +See also L. A less readable way is to ask a regular search to return 1 row, using L: @@ -320,9 +345,9 @@ in the cookbook can do the same if you pass a C attribute to the search. Use L. - $row->discard_changes + $result->discard_changes -Discarding changes and refreshing from storage are two sides fo the same coin. When you +Discarding changes and refreshing from storage are two sides of the same coin. When you want to discard your local changes, just re-fetch the row from storage. When you want to get a new, fresh copy of the row, just re-fetch the row from storage. L does just that by re-fetching the row from storage @@ -351,7 +376,7 @@ C on the resultset will only return the total number in the page. =item .. insert a row with an auto incrementing primary key? This happens automatically. After -L a row object, the primary +L a result object, the primary key value created by your database can be fetched by calling C (or the access of your primary key column) on the object. @@ -382,7 +407,7 @@ the rows at once. =item .. update a column using data from another column? To stop the column name from being quoted, you'll need to tell DBIC -that the right hand side is an SQL identity (it will be quoted +that the right hand side is an SQL identifier (it will be quoted properly if you have quoting enabled): ->update({ somecolumn => { -ident => 'othercolumn' } }) @@ -392,17 +417,17 @@ object. To fetch the new value, use the C method on the Row. # will return the scalar reference: - $row->somecolumn() + $result->somecolumn() # issue a select using the PK to re-fetch the row data: - $row->discard_changes(); + $result->discard_changes(); # Now returns the correct new value: - $row->somecolumn() + $result->somecolumn() To update and refresh at once, chain your calls: - $row->update({ 'somecolumn' => { -ident => 'othercolumn' } })->discard_changes; + $result->update({ 'somecolumn' => { -ident => 'othercolumn' } })->discard_changes; =item .. store JSON/YAML in a column and have it deflate/inflate automatically? @@ -437,8 +462,8 @@ data out. =head2 Custom methods in Result classes -You can add custom methods that do arbitrary things, even to unrelated tables. -For example, to provide a C<< $book->foo() >> method which searches the +You can add custom methods that do arbitrary things, even to unrelated tables. +For example, to provide a C<< $book->foo() >> method which searches the cd table, you'd could add this to Book.pm: sub foo { @@ -455,12 +480,12 @@ methods to find or create data in related tables for you. But if you want to write your own methods, you can. For example, to provide a C<< $book->foo() >> method to manually implement -what create_related() from L does, you could +what create_related() from L does, you could add this to Book.pm: sub foo { - my ($self, $relname, $col_data) = @_; - return $self->related_resultset($relname)->create($col_data); + my ($self, $rel_name, $col_data) = @_; + return $self->related_resultset($rel_name)->create($col_data); } Invoked like this: @@ -473,41 +498,41 @@ Invoked like this: =item How do I store my own (non-db) data in my DBIx::Class objects? -You can add your own data accessors to your classes. +You can add your own data accessors to your Result classes. One method is to use the built in mk_group_accessors (via L) - package MyTable; + package App::Schema::Result::MyTable; - use parent 'DBIx::Class'; + use parent 'DBIx::Class::Core'; __PACKAGE__->table('foo'); #etc __PACKAGE__->mk_group_accessors('simple' => qw/non_column_data/); # must use simple group An another method is to use L with your L package. - package MyTable; + package App::Schema::Result::MyTable; use Moose; # import Moose use Moose::Util::TypeConstraint; # import Moose accessor type constraints - extends 'DBIx::Class'; # Moose changes the way we define our parent (base) package + extends 'DBIx::Class::Core'; # Moose changes the way we define our parent (base) package has 'non_column_data' => ( is => 'rw', isa => 'Str' ); # define a simple attribute __PACKAGE__->table('foo'); # etc -With either of these methods the resulting use of the accesssor would be +With either of these methods the resulting use of the accessor would be - my $row; + my $result; - # assume that somewhere in here $row will get assigned to a MyTable row + # assume that somewhere in here $result will get assigned to a MyTable row - $row->non_column_data('some string'); # would set the non_column_data accessor + $result->non_column_data('some string'); # would set the non_column_data accessor # some other stuff happens here - $row->update(); # would not inline the non_column_data accessor into the update + $result->update(); # would not inline the non_column_data accessor into the update =item How do I use DBIx::Class objects in my TT templates? @@ -536,7 +561,7 @@ L runs the actual SQL statement as late as possible, thus if you create a resultset using C in scalar context, no query is executed. You can create further resultset refinements by calling search again or relationship accessors. The SQL query is only run when -you ask the resultset for an actual row object. +you ask the resultset for an actual result object. =item How do I deal with tables that lack a primary key? @@ -556,7 +581,7 @@ Look at the tips in L =item How do I reduce the overhead of database queries? You can reduce the overhead of object creation within L -using the tips in L +using the tips in L and L =item How do I override a run time method (e.g. a relationship accessor)? @@ -567,12 +592,12 @@ The code example works for both modules: package Your::Schema::Group; use Class::Method::Modifiers; - + # ... declare columns ... - + __PACKAGE__->has_many('group_servers', 'Your::Schema::GroupServer', 'group_id'); __PACKAGE__->many_to_many('servers', 'group_servers', 'server'); - + # if the server group is a "super group", then return all servers # otherwise return only servers that belongs to the given group around 'servers' => sub { @@ -592,12 +617,12 @@ L way: package Your::Schema::Group; use Method::Signatures::Simple; - + # ... declare columns ... - + __PACKAGE__->has_many('group_servers', 'Your::Schema::GroupServer', 'group_id'); __PACKAGE__->many_to_many('servers', 'group_servers', 'server'); - + # The method keyword automatically injects the annoying my $self = shift; for you. method servers { return $self->result_source->schema->resultset('Server')->search({ ... }); @@ -607,17 +632,17 @@ The dirty way: package Your::Schema::Group; use Sub::Name; - + # ... declare columns ... - + __PACKAGE__->has_many('group_servers', 'Your::Schema::GroupServer', 'group_id'); __PACKAGE__->many_to_many('servers', 'group_servers', 'server'); - + *servers = subname servers => sub { my $self = shift; return $self->result_source->schema->resultset('Server')->search({ ... }); }; - + =back =head2 Notes for CDBI users @@ -666,3 +691,14 @@ Taken from: L. =back + +=head1 FURTHER QUESTIONS? + +Check the list of L. + +=head1 COPYRIGHT AND LICENSE + +This module is free software L +by the L. You can +redistribute it and/or modify it under the same terms as the +L.