=head1 NAME DBIx::DataModel::Doc::Reference - All methods of DBIx::DataModel =head1 DOCUMENTATION CONTEXT This chapter is part of the C manual. =over =item * L =item * L =item * L =item * REFERENCE =item * L =item * L =item * L =back =head1 DESCRIPTION This chapter is the detailed description of C methods for creating and using schemas. Automatic schema generation from external sources is not covered here; see L. Detailed use of B is not covered here either, because explicit programming of the various statement phases (sqlize, prepare, bind, execute, etc.) is seldom needed. If you want to finely tune these operations, read the L section of the manual (purpose, lifecycle, etc.), and the L page. =head1 GENERAL CONVENTION Method names starting with an B are meant to be B. These methods will typically be called when loading a module like 'MySchema.pm', and therefore will be executed during the BEGIN phase of the Perl compiler. They instruct the compiler to create classes, methods and datastructures for representing the elements of a database schema. For those methods, the return value is the classname again, so that they can be chained : MySchema->Table(...) ->Table(...) ->Association(...); Method names starting with a B are meant to be usual B, either for classes or for instances; usually these methods do not return the classname and therefore cannot be chained. =head1 SCHEMA CREATION =head2 Schema DBIx::DataModel->Schema($schemaName, %options) Creates a new Perl class of name C<$schemaName> that represents a database schema. That class inherits from C. Possible options are : =over =item C<< dbh => $dbh >> Connects the schema to a DBI database handle. This can also be set or reset later via the L method. =item C<< sqlAbstract => $sql_abstract_instance >> Specifies an instance of L to be used by this schema. If none is given, a default instance will be created automatically, with no specific option. =item C<< sqlDialect => $dialect >> SQL has no standard syntax for performing joins, so if your database wants a particular syntax you will need to declare it. Current builtin dialects are either C<'MsAccess'>, C<'BasisODBC'>, C<'BasisJDBC'> or C<'Default'> (contributions to enrich this list are welcome). Otherwise C<$dialect> can also be a hashref in which you supply the following information : =over =item innerJoin a string in L format, with placeholders for the left table, the right table and the join criteria. Default is C<%s INNER JOIN %s ON %s>. If your database does not support inner joins, set this to C and the generated SQL will be in the form C. =item leftJoin a string for left outer joins. Default is C<%s LEFT OUTER JOIN %s ON %s>. =item joinAssociativity either C or C =item columnAlias a string for generating column aliases. Default is C<%s AS %s>. =back =item C<< tableParent => 'My::Parent::Class::For::Tables' >> Specifies a parent class from which table classes will inherit. The default is C. The argument may also be an arrayref of several parent class names. =item C<< viewParent => 'My::Parent::Class::For::Views' >> Specifies a parent class from which table classes will inherit. The default is C. The argument may also be an arrayref of several parent class names. =item C<< statementClass => 'My::Statement::Class' >> Specifies a class to be used for statements returned by the L method, instead of the default L. The specified class should of course implement the same API. It may be useful to override it for performing driver-specific operations on the underlying C (see for example L, with added methods for scrolling the result set). =item C<< placeholderPrefix => $string >> Specifies a prefix to distinguish named placeholders from ordinary values in parameters to L. The default is the question mark C. =back =head1 SCHEMA POPULATION (CREATING TABLES, VIEWS AND ASSOCIATIONS) =head2 Table MySchema->Table($pckName, $dbTable, @primKey); Creates a new Perl class of name C<$pckName> that represents a database table. That class inherits from C. If C<< $pckName >> contains no C<::>, then the schema name is prepended to it (so the new table class is created in the namespace of the schema). C<< $dbTable >> should contain the name of the table in the database. C<< @primKey >> should contain the name of the column (or names of columns) holding the primary key for that table. =head2 View MySchema->View($viewName, $columns, $dbTables, \%where, @parentTables); Creates a new Perl class of name C<$viewName> that represents a SQL SELECT request of shape SELECT $columns FROM $dbTables [ WHERE %where ] Therefore arguments C<$columns> and C<$dbTables> should be strings; the optional C<\%where> argument should be a hashref, as explained below. If C<< $viewName >> or any parent table name contains no C<::>, then the schema name is prepended to it. C is seldom called explicitly from client code; it is mainly useful internally for implementing the L method. However, it could also be used to build queries with specific SQL clauses like for example MySchema->View(MyView => "DISTINCT column1 AS c1, t2.column2 AS c2", "Table1 AS t1 LEFT OUTER JOIN Table2 AS t2 ON t1.fk=t2.pk", {c1 => 'foo', c2 => {-like => 'bar%'}}, qw/Table1 Table2/); The class generated by C has a L method, which will =over =item * select records from the database according to the criteria of the view, merged with the criteria of the request; =item * apply the 'fromDB' handlers of the parent tables to those records; =item * bless the results into objects of C<$viewName>. =back See L for a complete description of what to put in the C<\%where> argument. For the moment, just consider the following example: my $lst = MySchema::MyView->select(-where => {c3 => 22}); This would generate the SQL statement: SELECT DISTINCT column1 AS c1, t2.column2 AS c2 FROM Table1 AS t1 LEFT OUTER JOIN Table2 AS t2 ON t1.fk=t2.pk WHERE (c1 = 'foo' AND c2 LIKE 'bar%' AND c3 = 22) The C<\%where> argument can of course be C. The optional list of C<< @parentTables >> contains names of Perl table classes from which the view will also inherit. If the SQL code in C<$dbTables> is a join between several tables, then it is a good idea to mention these tables in C<< @parentTables >>, so that their role methods become available to instances of C<>MySchema::MyView>. Be careful about table names : the SQL code in C<$dbTables> should contain database table names, whereas the members of C<< @parentTables >> should be Perl table classes (might be the same, but not necessarily). Perl views as defined here have nothing to do with views declared in the database itself. Perl views are totally unknown to the database, they are just abstractions of SQL statements. If you need to access I, just use the C declaration, like for a regular table. =head2 Association MySchema->Association([$class1, $role1, $multiplicity1, @columns1], [$class2, $role2, $multiplicity2, @columns2]); Declares an association between two tables (or even two instances of the same table), in a UML-like fashion. Each side of the association specifies its table, the "rolename" of of this table in the association, the multiplicity, and the name of the column or list of columns that technically implement the association as a database join. Role names should preferably be chosen so as to avoid conflicts with column names in the same table. Multiplicities should be written in the UML form '0..*', '1..*', '0..1', etc. (minimum .. maximum number of occurrences); this will influence how role methods and views are implemented, as explained below. The '*' for "infinite" may also be written 'n', i.e. '1..n'. Multiplicity '*' is a shortcut for '0..*', and multiplicity '1' is a shortcut for '1..1'. Other numbers may be given as multiplicity bounds, but this will be just documentary : technically, all that matters is =over =item * whether the lower bound is 0 or more (if 0, generated joins will be left joins, otherwise inner joins) =item * whether the upper bound is 1 or more (if 1, the associated method returns a single object, otherwise it returns an arrayref) =back If C<@columns1> or C<@columns2> are omitted, they are guessed as follows : for the table with multiplicity C<1> or C<0..1>, the default is the primary key; for the other table, the default is to take the same column names as the other side of the association. This default behaviour is convenient for data models where primary keys and foreign keys are identical (for example C both as primary key in C and as foreign key in C). Some data models have a different policy, where primary keys are always named the same (for example C), and foreign keys are named after the related table name : in such models, the default does not work, and you have to specify the join columns explicitly. =head3 Roles as additional methods in table classes As a result of the association declaration, the Perl class C<< $table1 >> will get an additional method named C<< $role2 >> for accessing the associated object(s) in C<< $table2 >>; that method normally returns an arrayref, unless C<< $multiplicity2 >> has maximum '1' (in that case the return value is a single object ref). Of course, C<< $table2 >> conversely gets a method named C<< $role1 >>. To understand why tables and roles are crossed, look at the UML picture : +--------+ +--------+ | | * 0..1 | | | Table1 +---------------------+ Table2 | | | role1 role2 | | +--------+ +--------+ so from an object of C, you need a method C to access the associated object of C. In your diagrams, be careful to get the role names correctly according to the UML specification. Sometimes we see UML diagrams where role names are on the wrong side, mainly because modelers have a background in Entity-Relationship or Merise methods, where it is the other way around. Role methods perform joins within Perl (as opposed to joins directly performed within the database). That is, given a declaration MySchema->Association([qw/Employee employee 1 /], [qw/Activity activities 0..*/]); we can call my activities = $anEmployee->activities which will implicitly perform a SELECT * FROM Activity WHERE emp_id = $anEmployee->{emp_id} The role method can also accept additional parameters in L format, exactly like the L method. So for example my $activities = $anEmployee->activities(-columns => [qw/act_name salary/], -where => {is_active => 'Y'}); would perform the following SQL request : SELECT act_name, salary FROM Activity WHERE emp_id = $anEmployee->{emp_id} AND is_active = 'Y' If the role method is called without any parameters, and if that role was previously expanded (see L method), i.e. if the object hash contains an entry C<< $obj->{$role} >>, then this data is reused instead of calling the database again (this is a primitive form of caching). To force a new call to the database, supply some parameters : $emp->expand('activities'); # stores result in $emp->{activities} $list = $emp->activities; # returns cached $emp->{activities} $list = $emp->activities(-columns => '*'); # default columns, but # forces a new call to the DB Sometimes associations are unidirectional (it does not make sense to traverse the association in both directions). In such cases, just supply 0 or an empty string (or even the string C<"0"> or C<'""'> or C<--> or C<"none">) to one of the role names : then the corresponding role method is not generated. =head3 Methods C When a role has multiplicity '*', another method named C is also installed, that will create new objects of the associated class, taking care of the linking automatically : $anEmployee->insert_into_activities({d_begin => $today, dpt_id => $dpt}); This is equivalent to MySchema::Activity->insert({d_begin => $today, dpt_id => $dpt, emp_id => $anEmployee->{emp_id}}); =head3 Many-to-many associations UML conceptual models may contain associations where both roles have multiplicity '*' (so-called B associations). However, when it comes to actual database implementation, such associations need an intermediate linking table to collect couples of identifiers from both tables. C supports many-to-many associations as a kind of syntactic sugar, translated into low-level associations with the linking table. The linking table needs to be declared first : MySchema->Table(qw/link_table link_table prim_key1 prim_key2/); MySchema->Association([qw/table1 role1 0..1/], [qw/link_table links * /]); MySchema->Association([qw/table2 role2 0..1/], [qw/link_table links * /]); This describes a diagram like this : +--------+ +-------+ +--------+ | | 0..1 * | Link | * 0..1 | | | Table1 +---------------+ -- +-----------------+ Table2 | | | role1 linksA | Table | linksB role2 | | +--------+ +-------+ +--------+ Then we can declare the many-to-many association, very much like ordinary associations, except that the last items in the argument lists are names of roles to follow, instead of names of columns to join. In the diagram above, we must follow roles C and C in order to obtain the rows of C related to an instance of C; so we write MySchema->Association([qw/table1 roles1 * linksB role1/], [qw/table2 roles2 * linksA role2/]); which describes a diagram like this : +--------+ +--------+ | | * * | | | Table1 +--------------------+ Table2 | | | roles1 roles2 | | +--------+ +--------+ The declaration has created a new method C in C; that method is implemented by following roles C and C. So for an object C of C, the call my $obj2_arrayref = $obj1->roles2(); will generate the following SQL : SELECT * FROM link_table INNER JOIN table2 ON link_table.prim_key2=table2.prim_key2 WHERE link_table.prim_key1 = $obj->{prim_key1} Observe that C returns rows from a I, so these rows will belong both to C I to C. Many-to-many associations do not have an automatic C method : you must explicitly insert into the link table. =head3 Following multiple associations In the previous section we were following two roles at once in order to implement a many-to-many association. More generally, it may be useful to follow several roles at once, joining the tables in a single SQL query. This can be done through the following methods : =over =item * L (invoked on a Schema) : create a new C that selects from several tables, filling the joins automatically =item * L (invoked on an instance of Table or View) : from a given object, follow a list of roles to get information from associated tables. =item * L : add a new method in a table, that will follow a list of roles (shortcut for repeated calls to C). =back =head2 Composition MySchema->Composition([$class1, $role1, $multiplicity1, @columns1], [$class2, $role2, $multiplicity2, @columns2]); Declares a composition between two tables, i.e an association with some additional semantics. In UML class diagrams, compositions are pictured with a black diamond on one side : this side will be called the I class, while the other side will be called the I class. In C, the diamond (the composite class) corresponds to the first arrayref argument, and the component class corresponds to the second arrayref argument, so the order of both arguments is important (while for associations the order makes no difference). The UML intended meaning of a composition is that objects of the component classes cannot exist outside of their composite class. Within C, the additional semantics for compositions is to support cascaded insertions and deletions and auto-expansion : =over =item * the argument to an C may contain references to subrecords. The main record will be inserted in the composite class, and within the same operation, subrecords will be inserted into the component classes, with foreign keys automatically filled with appropriate values. =item * the argument to a C may contain lists of component records to be deleted together with the main record of the composite class. =item * roles declared through a Composition may then be supplied to L so that the composite class can automatically fetch its component parts. =back See the documentation of L, L and L methods below for more details. Note that compositions add nothing to the semantics of update operations. Even though the arguments to a C look exactly like for C, there are some more constraints : the maximum C<$multiplicity1> must be 1 (which is coherent with the notion of composition), and the maximum C<$multiplicity2> must be greater than 1 (because one-to-one compositions are not common and we don't know exactly how to implement cascaded inserts or deletes in such a case). Furthermore, a class cannot be component of several composite classes, unless the corresponding multiplicities are all C<0..1> instead of the usual C<1>. =head2 join =head3 join as class method within a Schema my $view = MySchema->join($table, $role1, $role2, ..); Creates a C class, starting from a given table class and following one or several associations through their role names. It calls the L method, with a collection of parameters automatically inferred from the associations. So for example MySchema->join(qw/Department activities employee/); is equivalent to my $sql = <<_EOSQL_ Department LEFT OUTER JOIN Activity ON Department.dpt_id = Activity.dpt_id LEFT OUTER JOIN Employee ON Activity.emp_id = Employee.emp_id _EOSQL_ MySchema->View(DepartmentActivitiesEmployee => '*', $sql, qw/Department Activity Employee/); For each pair of tables, the kind of join is chosen according to the multiplicity declared with the role : if the minimum multiplicity is 0, the join will be LEFT OUTER JOIN; otherwise it will be a usual inner join (exception : after a first left join, all remaining tables are also connected through additional left joins). The default kind of join chosen by this rule may be overriden by inserting pseudo-roles in the list, namely C<< '<=>' >> or C<< INNER >> for inner joins and C<< '=>' >> or C<< LEFT >> for left joins. So for example MySchema->join(qw/Department <=> activities <=> employee/); becomes equivalent to my $sql = <<_EOSQL_ Department INNER JOIN Activity ON Department.dpt_id = Activity.dpt_id INNER JOIN Employee ON Activity.emp_id = Employee.emp_id _EOSQL_ Table names in the SQL statement correspond to what was defined in the C<< MySchema->Table(...) >> declarations. However, tables may be aliased using C<|> as a separator : MySchema->join(qw/Department|dpt activities|act employee|emp/) ->select(-columns => qw/dpt.name act.d_begin emp.lastname/, -where => {"dpt.dpt_name" => {-like => "A%"}}); which generates SELECT dpt.name, act.d_begin, emp.lastname FROM Department AS dpt LEFT OUTER JOIN Activity AS act ON dpt.dpt_id = act.dpt_id LEFT OUTER JOIN Employee AS emp ON act.emp_id = emp.emp_id WHERE dtp.dpt_name like 'A%' All tables participating in a C are stacked, and further roles are found by walking up the stack. So in ..->join(qw/FirstTable role1 role2 role3/) we must find a C in C, from which we know what will be the C. Then, we must find a C in in C, or otherwise in C, in order to know C. In turn, C must be found either in C, or in C, or in C, etc. To resolve ambiguities, prefix the role by the role name or alias of the targeted source, such as : ..->join(qw/FirstTable role1|r1 FirstTable.role2 r1.role3|r3 role2.role4/) The resulting view name will be composed by concatenating the table and the capitalized role names. If join kinds were explicitly set, these also belong to the view name, like C<< Department_INNER_Activities >>. Since such names might be long and uncomfortable to use, the view name is also returned as result of the method call, so that the client code can store it in a variable and use it as an alias. The main purpose of C is to gain efficiency in interacting with the database. If we write foreach my $dpt (@{MySchema::Department->select}) { foreach my $act ($dpt->activities) { my $emp = $act->employee; printf "%s works in %s since %s\n", $emp->{lastname}, $dpt->{dpt_name}, $act->{d_begin}; } } many database calls are generated behind the scene. Instead we could write my $view = MySchema->join(qw/MySchema::Department activities employee/); foreach my $row (@{$view->select}) { printf "%s works in %s since %s\n", $row->{lastname}, $row->{dpt_name}, $row->{d_begin}; } which generates one single call to the database. =head3 join as class method within a Table or View my $statement = My::Table->join(qw/role1 role2 .../)->prepare; Starting from a given table, returns a reference to a L that selects a collection of data rows from associated tables, performing the appropriate joins. Internally this is implemented throught the C method, with an additional join criteria to constrain on the primary key(s) of C. That statement cannot be executed yet, because the values of the primary key are not known until we have an instance of C; but the statement can already be Ld. Later on, we can L the statement by binding it to an instance of C : my $obj = My::Table->fetch(...); my $rows = $statement->execute($obj)->all; =head3 join as instance method within a Table or View Creates a statement as just explained above, and immediately binds it to the current object. So for example if C<< $emp->{emp_id} == 987 >>, then $emp->join(qw/activities department/) ->select(-where => {d_end => undef}) will generate SELECT * FROM Activity INNER JOIN Department ON Activity.dpt_id = Department.dpt_id WHERE emp_id = 987 AND d_end IS NULL =head2 MethodFromJoin $table->MethodFromJoin($meth_name => qw/role1 role2 .../, \%options); Inserts into the table class a new method named C<$meth_name>, that will automatically call L and then L, passing its arguments to the C call. =head1 SCHEMA OR TABLE PARAMETERIZATION =head2 DefaultColumns My::Table->DefaultColumns($columns); Sets the default value for the C<-columns> argument to L. If nothing else is stated, the default value for all tables is 'C<*>'. =head2 ColumnHandlers My::Table->ColumnHandlers($columnName => handlerName1 => coderef1, handlerName2 => coderef2, ...); Associates some handlers to a given column in the current table class. Then, when you call C<< $obj->applyColumnHandler('someHandler') >>, each column having a handler of the corresponding name will execute the associated code. This can be useful for all sorts of data manipulation : =over =item * converting dates between internal database format and user presentation format =item * converting empty strings into null values =item * inflating scalar values into objects =item * column data validation =back Handlers receive the column value as usual through C<< $_[0] >>. If the value is to be modified (for example for scalar conversions or while inflating values into objects), the result should be put back into C<< $_[0] >>. In addition to the column value, other info is passed to the handler : sub myHandler { my ($columnValue, $obj, $columnName, $handlerName) = @_; my $newVal = $obj->computeNewVal($columnValue, ...); $columnValue = $newVal; # WRONG : will be a no-op $_[0] = $newVal; # OK : value is converted } The second argument C<< $obj >> is the object from where C<< $columnValue >> was taken -- most probably an instance of a Table or View class. Use this if you need to read some contextual information, but avoid modifying C<< $obj >> : you would most probably get unexpected results, since the collection of available columns may vary from one call to the other. Other arguments C<< $columnName >> and C<< $handlerName >> are obvious. Handler names B and B have a special meaning : they are called automatically just after reading data from the database, or just before writing into the database. Handler name B is used by the method L. =head2 ColumnType MySchema->ColumnType(type_name => handler_name1 => coderef1, handler_name2 => coderef2, ...); When invoked on a schema, declares a collection of column handlers under name C. My::Table->ColumnType(type_name => qw/column1 column2 .../); When invoked on a table, retrieves all column handlers defined under C in the schema and calls L to register those handlers to C<< column1 >>, C<< column2 >>, etc. =head2 Autoload MySchema->Autoload(1); # turn on AUTOLOAD My::Table ->Autoload(1); # turn it on, just for one table If C is turned on, then columns have implicit read accessors through Perl's AUTOLOAD mechanism. So instead of C<< $record->{column} >> you can write C<< $record->column >>. This feature is off by default, because the hashref API C<< $record->{column} >> is the recommended way to access data when using C. B : AUTOLOAD is a global feature, so if there are several schemas, C<< MySchema->Autoload(1) >> actually turns it on for all of them. =head2 AutoInsertColumns MySchema->AutoInsertColumns( columnName1 => sub{...}, ... ); My::Table->AutoInsertColumns( columnName1 => sub{...}, ... ); Declares handler code that will automatically fill column names C, etc. at each insert, either for a single table, or (if declared at the Schema level), for every table. For example, each record could remember who created it and when with something like MySchema->AutoInsertColumns( created_by => sub{$ENV{REMOTE_USER} . ", " . localtime} ); The handler code will be called as $handler->(\%record, $table) so that it can know something about its calling context. In most cases, however, the handler will not need these parameters, because it just returns global information such as current user or current date/time. =head2 AutoUpdateColumns MySchema->AutoUpdateColumns( columnName1 => sub{...}, ... ); My::Table->AutoUpdateColumns( columnName1 => sub{...}, ... ); Just like C, but will be called automatically at each update B each insert. This is typically used to remember the author and/or date and time of the last modification of a record. If you use both C and C, make sure that the column names are not the same. When doing an I (i.e. not an insert), the handler code will be called as $handler->(\%record, $table, \%where) where C<%record> contains the columns to be updated and C<%where> contains the primary key (column name(s) and value(s)). =head2 NoUpdateColumns MySchema->NoUpdateColumns(@columns); My::Table->NoUpdateColumns(@columns); Defines an array of column names that will be excluded from INSERT/UPDATE statements. This is useful for example when some column are set up automatically by the database (like automatic time stamps or user identification). It can also be useful if you want to temporarily add information to memory objects, without passing it back to the database. NoUpdate columns can be set for a whole Schema, or for a specific Table class. =head2 AutoExpand My::Table->AutoExpand(qw/role1 role2 .../) Generates an L method for the class, that will autoexpand on the roles listed (i.e. will call the appropriate method and store the result in a local slot within the object). In other words, the object knows how to expand itself, fetching information from associated tables, in order to build a data tree in memory. Only roles declared as L may be auto-expanded. Be careful about performance issues: when an object uses auto-expansion through a call to L, every auto-expanded role will generate an additional call to the database. This might be slow, especially if there are recursive auto-expansions; so in some cases it will be more appropriate to flatten the tree and use database joins, typically through the method L. =head1 RUNTIME PROPERTIES OR PARAMETERIZATION =head2 dbh my $dbh = DBI::connect(...); MySchema->dbh($dbh, %options); # set MySchema->dbh([$dbh, %options]); # set, alternative syntax my $dbh = MySchema->dbh; # get back just the dbh my ($dbh, %options) = MySchema->dbh; # get back all Returns or sets the handle to a DBI database handle (see L). This handle is schema-specific. C expects the handle to be opened with C<< RaiseError => 1 >> (see L). In C<%options> you may pass any key-value pairs, and retrieve them later by calling C in a list context. C will look in those options to try to find the "catalog" and "schema" arguments for C's L. Changing the database handle through the C method is forbidden while a transaction is in course. However, a nested transaction may temporarily change the database handle by supplying it as argument to the L method. =head2 schema $schema = $class->schema; $schema = $object->schema; Returns the name of the schema class for the given object or class (table or view). =head2 db_table $db_table = $class->db_table; $db_table = $object->db_table; Returns the database table name registered via C<< Schema->Table(..) >> or collection of joined tables registered via C<< Schema->View(..) >>. =head2 debug Schema->debug( 1 ); # will warn for each SQL statement Schema->debug( $debugObject ); # will call $debugObject->debug($sql) Schema->debug( 0 ); # turn off debugging Debug mode is useful for seeing SQL statements generated by C. Enabling debugging with a C<$debugObject> will typically be useful in conjunction with something like L or L. There is also another way to see the SQL code : my $spy_sql = sub {my ($sql, @bind) = @_; print STDERR join "\n", $sql, @bind; return ($sql, @bind);}; my $result = $myClassOrObj->$someSelectMethod(-columns => \@columns, -where => \%criteria, -postSQL => $spy_sql); =head2 classData my $val = $someClass ->classData->{someKey}; my $val = $someObject->classData->{someKey}; Returns a ref to a hash for storing class-specific data. Each subclass has its own hashref, so class data is NOT propagated along the inheritance tree. Class data should be mainly for reading; if you write into it, make sure you know what you are doing. =head2 primKey my @primKeyColumns = My::Table->primKey; my @primKeyValues = $obj->primKey; If called as a class method, returns the list of columns registered as primary key for that table (via C<< Schema->Table(..) >>). If called as an instance method, returns the list of values in those columns. When called in scalar context and the primary key has only one column, returns that column (so you can call C<< $my k = $obj->primKey >>). =head2 componentRoles my @roles = My::Table->componentRoles; Returns the list of roles declared through L. =head2 noUpdateColumns my @cols = MySchema->noUpdateColumns; Returns the array of column names declared as noUpdate through L. my @cols = $obj->noUpdateColumns; Returns the array of column names declared as noUpdate, either in the Schema or in the Table class of the invocant. =head2 autoUpdateColumns my @cols = MySchema->autoUpdateColumns; Returns the array of column names declared as autoUpdate through L. my @cols = $obj->autoUpdateColumns; Returns the array of column names declared as autoUpdate, either in the Schema or in the Table class of the invocant. =head2 selectImplicitlyFor MySchema->selectImplicitlyFor('read only'); # will be added to SQL selects MySchema->selectImplicitlyFor(''); # turn it off Gets or sets a default value for the C<-for> argument to L. Here it is set at the C level, so it will be applied to all tables. $tableClass->selectImplicitlyFor('read only'); $viewClass->selectImplicitlyFor(''); Same thing, but at a Table or View level. my $string = $object->selectImplicitlyFor; Retrieves whatever whas set in the table or in the schema. =head2 dbiPrepareMethod MySchema->dbiPrepareMethod('prepare_cached'); DBI statement handles will be created using L. =head2 tables my @tables = MySchema->tables; Returns an array of names of C
subclasses declared in this schema. =head2 views my @views = MySchema->views; Returns an array of names of C subclasses declared in this schema. =head2 localizeState { my $scope_guard = MySchema->localizeState; # or.. my $scope_guard = MySchema->localizeState(qw/dbh dbh_options selectImplicitlyFor/); ... # do some work, possibly change state } # $scope_guard out of scope : previous state of MySchema is restored Schema classes hold some global state (database connection, current debug mode, current value of C, etc.). Like for other global resources (for example C or C<%ENV>), this could create interferences if the global state is simultaneously modified by several independent components. The usual Perl solution to this kind of problem is I through C (see L). Here however, since C is not perfectly suited for private class data, we provide a solution which is similar in spirit, but slightly different in implementation. The C method internally takes a copy of the current state, and returns a handle to it. The handle should be stored in a C variable; when that variable goes out of scope (at block exit), then the previous state is restored. If called without arguments, C localizes the following state components by default : C, C, C, C, C, C. Otherwise, the list of specific components to localize can be passed in the argument list. =head2 statementClass MySchema->statementClass($classname); Dynamically sets the statement class. It is quite uncommon to change it after schema initialization, but may nevertheless be useful in specific cases like for example if the C switches from one kind of database to another. =head1 DATA RETRIEVAL AND MANIPULATION =head2 doTransaction my $coderef = sub {Table1->insert(...); Table2->update(...); ...}; MySchema->doTransaction($coderef); Evaluates the code within a transaction. In case of failure, the transaction is rolled back, and an exception is raised, with a message containing the initial error and the status of the rollback (because the rollback itself may also fail). If you need finer details, you can treat the as an object with two methods C and C: eval {MySchema->doTransaction($coderef); 1} or do {my $err = $@; explain($err->initial_error, $err->rollback_errors)}; Usually the coderef passed as argument will be a closure that may refer to variables local to the environment where the closure was created. Nested calls to C are supported : only the top-level call will actually initiate and then commit the transaction, while an exception at any level will abort and rollback the whole thing. If the nested transaction needs to work on a different database handle, it may do so by supplying the dbh and its options as additional arguments : MySchema->doTransaction($coderef, $new_dbh, %new_dbh_options); When called in this form, C will temporarily set the dbh to the supplied value, and then return to the previous value when the nested transaction is finished. Commits on all involved database handles are delayed until the top-level transaction is finished. =head2 fetch my $record = My::Table->fetch(@keyValues, \%options); Fetches a single record from a table, from its primary key value. C<%options> may specify things like C<-for>, C<-preExec>, C<-postExec>, etc. This method is just syntactic sugar for my $record = My::Table->select(-fetch => \@keyValues, %options); (see below). =head2 fetch_cached my $record = My::Table->fetch_cached(@keyValues, \%options); Like C, except that the result is stored in a cache, and further calls to the same methods with the same parameters will return the cached record instead of going back to the database. The cache does not know about any updates to the database, so this is mainly useful for readonly data. The cache is stored internally in C<< MyTable->classData->{fetch_cached}{$dbh_addr}{$freeze_args} >> (where C<$dbh_addr> is C<< Scalar::Util::refaddr(MyTable->dbh) >> and C<$freeze_args> is C<< Storable::freeze(@keyValues, \%options) >>). Using these arguments, the cache can be cleared or tied to a caching module. =head2 createStatement my $statement = My::Table->createStatement; Creates a statement that will search the target table (or view). The statement can then be refined, sqlized, prepared and finally executed (see L). =head2 select Given a C<$target>, which could be either a L, a L or a L : $records = $target->select(\@columns, \%where, \@order); $records = $target->select(-columns => \@columns, # OR : -distinct => \@columns, -where => \%where, # OR : -fetch => $key, # OR : -fetch => \@key, -groupBy => \@groupings, -having => \%criteria, -orderBy => \@order, -for => 'read only', -postSQL => \&postSQL_callback, -preExec => \&preExec_callback, -postExec => \&preExec_callback, -postFetch => \&postFetch_callback, -limit => $limit, -offset => $offset, -pageSize => $pageSize, -pageIndex => $pageIndex, -columnTypes => \%columnTypes, -resultAs => 'rows' || 'firstrow' || 'subquery' || 'flat_arrayref' || 'sth' || 'sql' || 'statement' || 'fast_statement'); $all_records = $target->select(); Applies a SQL SELECT to the C<$target>, and returns a result as specified by the C<-resultAs> argument (see below). If C<$target> is a table or a view, C