Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Rose::DB::Object::ManaUser3Contributed Perl DocumeRose::DB::Object::Manager(3)

NAME
       Rose::DB::Object::Manager - Fetch multiple Rose::DB::Object-derived
       objects from the	database using complex queries.

SYNOPSIS
	 ##
	 ## Given the following	Rose::DB::Object-derived classes...
	 ##

	 package Category;

	 use base 'Rose::DB::Object';

	 __PACKAGE__->meta->setup
	 (
	   table   => 'categories',
	   columns =>
	   [
	     id		 => { type => 'int', primary_key => 1 },
	     name	 => { type => 'varchar', length	=> 255 },
	     description => { type => 'text' },
	   ],

	   unique_key => 'name',
	 );

	 ...

	 package CodeName;

	 use base 'Rose::DB::Object';

	 __PACKAGE__->meta->setup
	 (
	   table   => 'code_names',
	   columns =>
	   [
	     id		 => { type => 'int', primary_key => 1 },
	     product_id	 => { type => 'int' },
	     name	 => { type => 'varchar', length	=> 255 },
	     applied	 => { type => 'date', not_null => 1 },
	   ],

	   foreign_keys	=>
	   [
	     product =>
	     {
	       class	   => 'Product',
	       key_columns => {	product_id => 'id' },
	     },
	   ],
	 );

	 ...

	 package Product;

	 use base 'Rose::DB::Object';

	 __PACKAGE__->meta->setup
	 (
	   table   => 'products',
	   columns =>
	   [
	     id		 => { type => 'int', primary_key => 1 },
	     name	 => { type => 'varchar', length	=> 255 },
	     description => { type => 'text' },
	     category_id => { type => 'int' },
	     region_num	 => { type => 'int' },

	     status =>
	     {
	       type	 => 'varchar',
	       check_in	 => [ 'active',	'inactive' ],
	       default	 => 'inactive',
	     },

	     start_date	 => { type => 'datetime' },
	     end_date	 => { type => 'datetime' },

	     date_created  => {	type =>	'timestamp', default =>	'now' },
	     last_modified => {	type =>	'timestamp', default =>	'now' },
	   ],

	   unique_key => 'name',

	   foreign_keys	=>
	   [
	     category =>
	     {
	       class	   => 'Category',
	       key_columns =>
	       {
		 category_id =>	'id',
	       }
	     },
	   ],

	   relationships =>
	   [
	     code_names	=>
	     {
	       type  =>	'one to	many',
	       class =>	'CodeName',
	       column_map   => { id => 'product_id' },
	       manager_args =>
	       {
		 sort_by => CodeName->meta->table . '.applied DESC',
	       },
	     },
	   ],
	 );

	 ...

	 ##
	 ## Create a manager class
	 ##

	 package Product::Manager;

	 use base 'Rose::DB::Object::Manager';

	 sub object_class { 'Product' }

	 __PACKAGE__->make_manager_methods('products');

	 # The call above creates the methods shown below.  (The actual
	 # method bodies vary slightly,	but this is the	gist of	it...)
	 #
	 # sub get_products
	 # {
	 #   shift->get_objects(@_, object_class => 'Product');
	 # }
	 #
	 # sub get_products_iterator
	 # {
	 #   shift->get_objects_iterator(@_, object_class => 'Product');
	 # }
	 #
	 # sub get_products_count
	 # {
	 #   shift->get_objects_count(@_, object_class => 'Product');
	 # }
	 #
	 # sub update_products
	 # {
	 #   shift->update_objects(@_, object_class => 'Product');
	 # }
	 #
	 # sub delete_products
	 # {
	 #   shift->delete_objects(@_, object_class => 'Product');
	 # }

	 ...

	 ##
	 ## Use	the manager class
	 ##

	 #
	 # Get a reference to an array of objects
	 #

	 $products =
	   Product::Manager->get_products
	   (
	     query =>
	     [
	       category_id => [	5, 7, 22 ],
	       status	   => 'active',
	       start_date  => {	lt => '15/12/2005 6:30 p.m.' },
	       name	   => {	like =>	[ '%foo%', '%bar%' ] },
	     ],
	     sort_by =>	'category_id, start_date DESC',
	     limit   =>	100,
	     offset  =>	80,
	   );

	 foreach my $product (@$products)
	 {
	   print $product->id, ' ', $product->name, "\n";
	 }

	 #
	 # Get objects iterator
	 #

	 $iterator =
	   Product::Manager->get_products_iterator
	   (
	     query =>
	     [
	       category_id => [	5, 7, 22 ],
	       status	   => 'active',
	       start_date  => {	lt => '15/12/2005 6:30 p.m.' },
	       name	   => {	like =>	[ '%foo%', '%bar%' ] },
	     ],
	     sort_by =>	'category_id, start_date DESC',
	     limit   =>	100,
	     offset  =>	80,
	   );

	 while($product	= $iterator->next)
	 {
	   print $product->id, ' ', $product->name, "\n";
	 }

	 print $iterator->total;

	 #
	 # Get objects count
	 #

	 $count	=
	   Product::Manager->get_products_count
	   (
	     query =>
	     [
	       category_id => [	5, 7, 22 ],
	       status	   => 'active',
	       start_date  => {	lt => '15/12/2005 6:30 p.m.' },
	       name	   => {	like =>	[ '%foo%', '%bar%' ] },
	     ],
	   );

	  die Product::Manager->error  unless(defined $count);

	 print $count; # or Product::Manager->total()

	 #
	 # Get objects and sub-objects in a single query
	 #

	 $products =
	   Product::Manager->get_products
	   (
	     with_objects => [ 'category', 'code_names'	],
	     query =>
	     [
	       category_id => [	5, 7, 22 ],
	       status	   => 'active',
	       start_date  => {	lt => '15/12/2005 6:30 p.m.' },

	       # We need to disambiguate the "name" column below since it
	       # appears in more than one table	referenced by this query.
	       # When more than	one table is queried, the tables have numbered
	       # aliases starting from the "main" table	("products").  The
	       # "products" table is t1, "categories" is t2, and "code_names"
	       # is t3.	 You can read more about automatic table aliasing in
	       # the documentation for the get_objects() method	below.
	       #
	       # "category.name" and "categories.name" would work too, since
	       # table and relationship	names are also valid prefixes.

	       't2.name'   => {	like =>	[ '%foo%', '%bar%' ] },
	     ],
	     sort_by =>	'category_id, start_date DESC',
	     limit   =>	100,
	     offset  =>	80,
	   );

	 foreach my $product (@$products)
	 {
	   # The call to $product->category does not hit the database
	   print $product->name, ': ', $product->category->name, "\n";

	   # The call to $product->code_names does not hit the database
	   foreach my $code_name ($product->code_names)
	   {
	     # This call doesn't hit the database either
	     print $code_name->name, "\n";
	   }
	 }

	 #
	 # Update objects
	 #

	 $num_rows_updated =
	   Product::Manager->update_products(
	     set =>
	     {
	       end_date	  => DateTime->now,
	       region_num => { sql => 'region_num * -1'	}
	       status	  => 'defunct',
	     },
	     where =>
	     [
	       start_date => { lt => '1/1/1980'	},
	       status	  => [ 'active', 'pending' ],
	     ]);

	 #
	 # Delete objects
	 #

	 $num_rows_deleted =
	   Product::Manager->delete_products(
	     where =>
	     [
	       status  => [ 'stale', 'old' ],
	       name    => { like => 'Wax%' },
	       or =>
	       [
		 start_date => { gt => '2008-12-30' },
		 end_date   => { gt => 'now' },
	       ],
	     ]);

DESCRIPTION
       Rose::DB::Object::Manager is a base class for classes that select rows
       from tables fronted by Rose::DB::Object-derived classes.	 Each row in
       the table(s) queried is converted into the equivalent
       Rose::DB::Object-derived	object.

       Class methods are provided for fetching objects all at once, one	at a
       time through the	use of an iterator, or just getting the	object count.
       Subclasses are expected to create syntactically pleasing	wrappers for
       Rose::DB::Object::Manager class methods,	either manually	or with	the
       make_manager_methods method.  A very minimal example is shown in	the
       synopsis	above.

CLASS METHODS
       dbi_prepare_cached [BOOL]
	   Get or set a	boolean	value that indicates whether or	not this class
	   will	use DBI's prepare_cached method	by default (instead of the
	   prepare method) when	preparing SQL queries.	The default value is
	   false.

       default_limit_with_subselect [BOOL]
	   Get or set a	boolean	value that determines whether or not this
	   class will consider using a sub-query to express "limit"/"offset"
	   constraints when fetching sub-objects related through one of	the
	   "...-to-many" relationship types.  Not all databases	support	this
	   syntax, and not all queries can use it even in supported databases.
	   If this parameter is	true, the feature will be used when possible,
	   by default.	The default value is true.

       default_manager_method_types [ LIST | ARRAYREF ]
	   Get or set the default list of method types used by the
	   make_manager_methods	method.	 The default list is "objects",
	   "iterator", "count",	"delete", and "update".

       default_nested_joins [BOOL]
	   Get or set a	boolean	value that determines whether or not this
	   class will consider using nested JOIN syntax	when fetching related
	   objects.  Not all databases support this syntax, and	not all
	   queries can use it even in supported	databases.  If this parameter
	   is true, the	feature	will be	used when possible, by default.	 The
	   default value is true.

       default_objects_per_page	[NUM]
	   Get or set the default number of items per page, as returned	by the
	   get_objects method when used	with the "page"	and/or "per_page"
	   parameters.	The default value is 20.

       delete_objects [	PARAMS | ARRAYREF | HASHREF ]
	   Delete rows from a table fronted by a Rose::DB::Object-derived
	   class based on PARAMS, where	PARAMS are name/value pairs.  Returns
	   the number of rows deleted, or undef	if there was an	error.

	   If the first	argument is a reference	to a hash or array, it is
	   converted to	a reference to an array	(if necessary) and taken as
	   the value of	the "where" parameter.

	   Valid parameters are:

	   all BOOL
	       If set to a true	value, this parameter indicates	an explicit
	       request to delete all rows from the table.  If both the "all"
	       and the "where" parameters are passed, a	fatal error will
	       occur.

	   db DB
	       A Rose::DB-derived object used to access	the database.  If
	       omitted,	one will be created by calling the init_db method of
	       the object_class.

	   prepare_cached BOOL
	       If true,	then DBI's prepare_cached method will be used (instead
	       of the prepare method) when preparing the SQL statement that
	       will delete the objects.	 If omitted, the default value is
	       determined by the dbi_prepare_cached class method.

	   object_class	CLASS
	       The name	of the Rose::DB::Object-derived	class that fronts the
	       table from which	rows are to be deleted.	 This parameter	is
	       required; a fatal error will occur if it	is omitted.  Defaults
	       to the value returned by	the object_class class method.

	   where ARRAYREF
	       The query parameters, passed as a reference to an array of
	       name/value pairs.  These	pairs are used to formulate the
	       "where" clause of the SQL query that is used to delete the rows
	       from the	table.	Arbitrarily nested boolean logic is supported.

	       For the complete	list of	valid parameter	names and values, see
	       the documentation for the "query" parameter of the build_select
	       function	in the Rose::DB::Object::QueryBuilder module.

	       If this parameter is omitted, this method will refuse to	delete
	       all rows	from the table and a fatal error will occur.  To
	       delete all rows from a table, you must pass the "all" parameter
	       with a true value.  If both the "all" and the "where"
	       parameters are passed, a	fatal error will occur.

       error
	   Returns the text message associated with the	last error, or false
	   if there was	no error.

       error_mode [MODE]
	   Get or set the error	mode for this class.  The error	mode
	   determines what happens when	a method of this class encounters an
	   error.  The default setting is "fatal", which means that methods
	   will	croak if they encounter	an error.

	   PLEASE NOTE:	The error return values	described in the method
	   documentation in the	rest of	this document are only relevant	when
	   the error mode is set to something "non-fatal."  In other words, if
	   an error occurs, you'll never see any of those return values	if the
	   selected error mode dies or croaks or otherwise throws an exception
	   when	an error occurs.

	   Valid values	of MODE	are:

	   carp
	       Call Carp::carp with the	value of the object error as an
	       argument.

	   cluck
	       Call Carp::cluck	with the value of the object error as an
	       argument.

	   confess
	       Call Carp::confess with the value of the	object error as	an
	       argument.

	   croak
	       Call Carp::croak	with the value of the object error as an
	       argument.

	   fatal
	       An alias	for the	"croak"	mode.

	   return
	       Return a	value that indicates that an error has occurred, as
	       described in the	documentation for each method.

	   In all cases, the class's "error" attribute will also contain the
	   error message.

       get_objects [ PARAMS | HASHREF |	ARRAYREF ]
	   Get Rose::DB::Object-derived	objects	based on PARAMS, where PARAMS
	   are name/value pairs.  Returns a reference to a (possibly empty)
	   array, or undef if there was	an error.

	   If the first	argument is a reference	to a hash or array, it is
	   converted to	a reference to an array	(if necessary) and taken as
	   the value of	the "query" parameter.

	   Each	table that participates	in the query will be aliased.  Each
	   alias is in the form	"tN" where "N" is an ascending number starting
	   with	1.  The	tables are numbered as follows.

	   o   The primary table is always "t1"

	   o   The table(s) that correspond to each relationship or foreign
	       key named in the	"with_objects" parameter are numbered in
	       order, starting with "t2"

	   o   The table(s) that correspond to each relationship or foreign
	       key named in the	"require_objects" parameter are	numbered in
	       order, starting where the "with_objects"	table aliases left
	       off.

	   "Many to many" relationships	have two corresponding tables, and
	   therefore will use two "tN" numbers.	 All other supported of
	   relationship	types only have	just one table and will	therefore use
	   a single "tN" number.

	   For example,	imagine	that the "Product" class shown in the synopsis
	   also	has a "many to many" relationship named	"colors."  Now
	   consider this call:

	       $products =
		 Product::Manager->get_products(
		   require_objects => [	'category' ],
		   with_objects	   => [	'code_names', 'colors' ],
		   multi_many_ok   => 1,
		   query	   => [	status => 'defunct' ],
		   sort_by	   => 't1.name');

	   The "products" table	is "t1"	since it's the primary table--the
	   table behind	the "Product" class that "Product::Manager" manages.
	   Next, the "with_objects" tables are aliased.	 The "code_names"
	   table is "t2".  Since "colors" is a "many to	many" relationship, it
	   gets	two numbers: "t3" and "t4".  Finally, the "require_objects"
	   tables are numbered:	the table behind the foreign key "category" is
	   "t5".  Here's an annotated version of the example above:

	       # Table aliases in the comments
	       $products =
		 Product::Manager->get_products(
				      #	t5
		   require_objects => [	'category' ],
				      #	t2	      t3, t4
		   with_objects	   => [	'code_names', 'colors' ],
		   multi_many_ok   => 1,
		   query	   => [	status => 'defunct' ],
		   sort_by	   => 't1.name'); # "products" is "t1"

	   Also	note that the "multi_many_ok" parameter	was used in order to
	   suppress the	warning	that occurs when more than one "... to many"
	   relationship	is included in the combination of "require_objects"
	   and "with_objects" ("code_names" (one to many) and "colors" (many
	   to many) in this case).  See	the documentation for "multi_many_ok"
	   below.

	   The "tN" table aliases are for convenience, and to isolate end-user
	   code	from the actual	table names.  Ideally, the actual table	names
	   should only exist in	one place in the entire	code base: in the
	   class definitions for each Rose::DB::OBject-derived class.

	   That	said, when using Rose::DB::Object::Manager, the	actual table
	   names can be	used as	well.  But be aware that some databases	don't
	   like	a mix of table aliases and real	table names in some kinds of
	   queries.

	   Valid parameters to get_objects are:

	   allow_empty_lists BOOL
	       If set to true, "query" parameters with empty lists as values
	       are allowed.  For example:

		   @ids	= (); #	empty list

		   Product::Manager->get_products(
		     query =>
		     [
		       id => \@ids,
		       ...
		     ]);

	       By default, passing an empty list as a value will cause a fatal
	       error.

	   db DB
	       A Rose::DB-derived object used to access	the database.  If
	       omitted,	one will be created by calling the init_db method of
	       the "object_class".

	   debug BOOL
	       If true,	print the generated SQL	to STDERR.

	   distinct [ BOOL | ARRAYREF ]
	       If set to any kind of true value, then the "DISTINCT" SQL
	       keyword will be added to	the "SELECT" statement.	 Specific
	       values trigger the behaviors described below.

	       If set to a simple scalar value that is true, then only the
	       columns in the primary table ("t1") are fetched from the
	       database.

	       If set to a reference to	an array of table names, "tN" table
	       aliases,	or relationship	or foreign key names, then only	the
	       columns from the	corresponding tables will be fetched.  In the
	       case of relationships that involve more than one	table, only
	       the "most distant" table	is considered.	(e.g., The map table
	       is ignored in a "many to	many" relationship.)  Columns from the
	       primary table ("t1") are	always selected, regardless of whether
	       or not it appears in the	list.

	       This parameter conflicts	with the "fetch_only" parameter	in the
	       case where both provide a list of table names or	aliases.  In
	       this case, if the value of the "distinct" parameter is also
	       reference to an array table names or aliases, then a fatal
	       error will occur.

	   fetch_only ARRAYREF
	       ARRAYREF	should be a reference to an array of table names or
	       "tN" table aliases. Only	the columns from the corresponding
	       tables will be fetched.	In the case of relationships that
	       involve more than one table, only the "most distant" table is
	       considered.  (e.g., The map table is ignored in a "many to
	       many" relationship.)  Columns from the primary table ("t1") are
	       always selected,	regardless of whether or not it	appears	in the
	       list.

	       This parameter conflicts	with the "distinct" parameter in the
	       case where both provide a list of table names or	aliases.  In
	       this case, then a fatal error will occur.

	   for_update BOOL
	       If true,	this parameter is translated to	be the equivalent of
	       passing the lock	parameter and setting the "type" to "for
	       update".	 For example, this:

		   for_update => 1

	       is equivalent to	this:

		   lock	=> { type => 'for update' }

	       See the lock parameter below for	more information.

	   hints HASHREF
	       A reference to a	hash of	hints that influence the SQL generated
	       to fetch	the objects.  Hints are	just "suggestions" and may be
	       ignored,	depending on the actual	features of the	database being
	       queried.	 Use the debug parameter to see	the generated SQL.
	       Most of the current hints apply to MySQL	only.  See the
	       relevant	documentation for more details:

	       <http://dev.mysql.com/doc/refman/5.0/en/select.html>

	       The hints hash is keyed by tN table aliases or relationship
	       names.  The value of each key is	a reference to a hash of hint
	       directives.  In the absence of any key for "t1" or the name of
	       the primary table, the entire hints hash	is considered
	       applicable to the primary table.

	       Valid hint directives are:

	       all_rows	BOOL
		   If true, direct the database	to choose the query plan that
		   returns all the records as quickly as possible.

	       big_result BOOL
		   If true, indicate to	the database that the result set is
		   expected to be big.

	       buffer_result BOOL
		   If true, force the result to	be put into a temporary	table.

	       cache BOOL
		   If true, ask	the database to	store the result in its	query
		   cache.

	       calc_found_rows BOOL
		   If true, ask	the database to	internally calculate the
		   number of rows found, ignoring any limit or offset
		   arguments.

	       comment TEXT
		   Add a comment after the "SELECT" keyword in the query.
		   TEXT	should not be surrounded by any	comment	delimiters.
		   The appropriate delimiters will be added automatically.

	       first_rows BOOL
		   If true, direct the database	to choose the query plan that
		   returns the first result record as soon as possible.

	       force_index [ INDEX | ARRAYREF ]
		   Force the use of the	named indexes, specified by an index
		   name	or a reference to an array of index names.

	       high_priority BOOL
		   If true, give this query higher priority.

	       ignore_index [ INDEX | ARRAYREF ]
		   Ignore the named indexes, specified by an index name	or a
		   reference to	an array of index names.

	       no_cache	BOOL
		   If true, ask	the database not to store the result in	its
		   query cache.

	       small_result BOOL
		   If true, indicate to	the database that the result set is
		   expected to be small.

	       straight_join BOOL
		   If true, ask	the database to	join the tables	in the order
		   that	they are listed	in the "FROM" clause of	the SQL
		   statement.

	       strict_ops BOOL
		   If true, any	comparison operator used in the	"query"	that
		   is not listed in the	Rose::DB::Object::QueryBuilder
		   documentation will cause a fatal error.  The	default	value
		   is determined by the	strict_ops class method.

	       use_index [ INDEX | ARRAYREF ]
		   Prefer to use the named indexes, specified by an index name
		   or a	reference to an	array of index names.

	   inject_results BOOL
	       If true,	then the data returned from the	database will be
	       directly	"injected" into	the objects returned by	this method,
	       bypassing the constructor and column mutator methods for	each
	       object class.  The default is false.  This parameter is ignored
	       (i.e., treated as if it were false) if the "select" parameter
	       is passed.

	       This parameter is useful	for situations where the performance
	       of get_objects is limited by the	speed at which
	       Rose::DB::Object-derived	objects	can be created.	 It's safe to
	       set this	parameter to true only if the constructor and column
	       mutator methods for all of the classes involved do not have any
	       side-effects (or	if it's	is okay	to bypass any side-effects).

	       The default Rose::DB::Object constructor	and the	column mutator
	       methods created by the column classes included in the
	       Rose::DB::Object	module distribution do not have	any side-
	       effects and should therefore be safe to use with	this
	       parameter.

	   limit NUM
	       Return a	maximum	of NUM objects.

	   limit_with_subselect	BOOL
	       This parameter controls whether or not this method will
	       consider	using a	sub-query to express  "limit"/"offset"
	       constraints when	fetching sub-objects related through one of
	       the "...-to-many" relationship types.  Not all databases
	       support this syntax, and	not all	queries	can use	it even	in
	       supported databases.  If	this parameter is true,	the feature
	       will be used when possible.

	       The default value is determined by the
	       default_limit_with_subselect class method.

	   lock	[ TYPE | HASHREF ]
	       Select the objects using	some form of locking.  These lock
	       directives have database-specific behavior and not all
	       directives are supported	by all databases.  Consult your
	       database's documentation	to find	out more.  Use the debug
	       parameter to see	the generated SQL.

	       The value should	be a reference to a hash or a TYPE string,
	       which is	equivalent to setting the value	of the "type" key in
	       the hash	reference form.	 For example, these are	both
	       equivalent:

		   lock	=> 'for	update'
		   lock	=> { type => 'for update' }

	       Valid hash keys are:

	       columns ARRAYREF
		   A reference to an array of column names to lock.  The
		   columns may be prefixed with	their table name or their "tN"
		   alias (e.g.,	"mytable.mycol"	or "t2.mycol") or left
		   unadorned if	they are not ambiguous.	 References to scalars
		   will	be de-referenced and used as-is, included literally in
		   the SQL locking clause.

	       nowait BOOL
		   If true, do not wait	to acquire the lock.  If supported,
		   this	is usually by adding a "NOWAIT"	directive to the SQL.

	       on ARRAYREF
		   A reference to an array of items to lock.  Depending	on the
		   database, these may be column or tables.  Both column and
		   table names should be specified using dot-separated
		   relationship	paths.

		   For example,	"vendor.region.name" would lock	the "name"
		   column in the table arrived at by traversing	the "vendor"
		   and then the	"region" relationships,	starting from the
		   primary table ("t1").  Lone column names may	also be	used,
		   provided they're not	ambiguous.

		   For locking whole tables, "vendor.region" would lock	the
		   table arrived at by traversing the "vendor" and then	the
		   "region" relationships.  (See the require_objects parameter
		   for more information	on relationship	traversal.)

		   Finally, references to scalars will be de-referenced	and
		   used	as-is, included	literally in the SQL locking clause.

	       skip_locked BOOL
		   If true, skip any locked rows.  If supported, this is
		   usually by adding a "SKIP LOCKED" clause to the SQL.

	       tables ARRAYREF
		   A reference to an array of tables to	lock.  Table named or
		   "tN"	aliases	may be used.  References to scalars will be
		   de-referenced and used as-is, included literally in the SQL
		   locking clause.

	       type TYPE
		   The type of lock to acquire.	 Valid values for TYPE are
		   "for	update"	and "shared".  This hash key is	required
		   unless the for_update parameter was passed with a true
		   value.

	       wait TIME
		   Wait	for the	specified TIME (generally seconds) before
		   giving up acquiring the lock. If supported, this is usually
		   by adding a "WAIT ..." clause to the	SQL.

	       You may pass only one of	the parameters that specifies "what to
	       lock" (i.e., "columns", "on", or	"tables").

	   nested_joins	BOOL
	       This parameter controls whether or not this method will
	       consider	using nested JOIN syntax when fetching related
	       objects.	 Not all databases support this	syntax,	and not	all
	       queries will use	it even	in supported databases.	 If this
	       parameter is true, the feature will be used when	possible.

	       The default value is determined by the default_nested_joins
	       class method.

	   multi_many_ok BOOL
	       If true,	do not print a warning when attempting to do multiple
	       LEFT OUTER JOINs	against	tables related by "... to many"
	       relationships.  See the documentation for the "with_objects"
	       parameter for more information.

	   nonlazy [ BOOL | ARRAYREF ]
	       By default, get_objects will honor all load-on-demand columns
	       when fetching objects.  Use this	parameter to override that
	       behavior	and select all columns instead.

	       If the value is a true boolean value (typically "1"), then all
	       columns will be fetched for all participating classes (i.e.,
	       the main	object class as	well as	any sub-object classes).

	       The value can also be a reference to an array of	relationship
	       names.  The sub-objects corresponding to	each relationship name
	       will have all their columns selected.  To refer to the main
	       class (the "t1" table), use the special name "self".

	   object_args HASHREF
	       A reference to a	hash of	name/value pairs to be passed to the
	       constructor of each "object_class" object fetched, in addition
	       to the values from the database.

	   object_class	CLASS
	       The name	of the Rose::DB::Object-derived	objects	to be fetched.
	       This parameter is required; a fatal error will occur if it is
	       omitted.	 Defaults to the value returned	by the object_class
	       class method.

	   offset NUM
	       Skip the	first NUM rows.	 If the	database supports some sort of
	       "limit with offset" syntax (e.g., "LIMIT	10 OFFSET 20") then it
	       will be used.  Otherwise, the first NUM rows will be fetched
	       and then	discarded.

	       This parameter can only be used along with the "limit"
	       parameter, otherwise a fatal error will occur.

	   page	NUM
	       Show page number	NUM of objects.	 Pages are numbered starting
	       from 1.	A page number less than	or equal to zero causes	the
	       page number to default to 1.

	       The number of objects per page can be set by the	"per_page"
	       parameter.  If the "per_page" parameter is supplied and this
	       parameter is omitted, it	defaults to 1 (the first page).

	       If this parameter is included along with	either of the "limit"
	       or <offset> parameters, a fatal error will occur.

	   per_page NUM
	       The number of objects per "page".   Defaults to the value
	       returned	by the default_objects_per_page	class method (20, by
	       default).

	       If this parameter is included along with	either of the "limit"
	       or <offset> parameters, a fatal error will occur.

	   prepare_cached BOOL
	       If true,	then DBI's prepare_cached method will be used (instead
	       of the prepare method) when preparing the SQL statement that
	       will fetch the objects.	If omitted, the	default	value is
	       determined by the dbi_prepare_cached class method.

	   query ARRAYREF
	       The query parameters, passed as a reference to an array of
	       name/value pairs.  These	pairs are used to formulate the
	       "where" clause of the SQL query that, in	turn, is used to fetch
	       the objects from	the database.  Arbitrarily nested boolean
	       logic is	supported.

	       For the complete	list of	valid parameter	names and values, see
	       the documentation for the "query" parameter of the build_select
	       function	in the Rose::DB::Object::QueryBuilder module.

	       This class also supports	an extension to	the query syntax
	       supported by Rose::DB::Object::QueryBuilder.  In	addition to
	       table names and aliases,	column (or column method) names	may be
	       prefixed	with foreign key or relationship names.	 These names
	       may be chained, with dots (".") separating the components.

	       For example, imagine three tables, "products", "vendors", and
	       "regions", fronted by three Rose::DB::Object-derived classes,
	       "Product", "Vendor", and	"Region", respectively.	 Each
	       "Product" has a "Vendor", and each "Vendor" has a "Region".

	       To select only products whose vendors are in the	United States,
	       use a query argument like this:

		   query => [ 'vendor.region.name' => 'US' ],

	       This assumes that the "Product" class has a relationship	or
	       foreign key named "vendor" that points to the product's
	       "Vendor", and that the "Vendor" class has a foreign key or
	       relationship named "region" that	points to the vendor's
	       "Region", and that 'vendor.region' (or any foreign key or
	       relationship name chain that begins with	'vendor.region.') is
	       an argument to the "with_objects" or "require_objects"
	       parameters.

	       Please note that	the "tN" table aliases are not allowed in
	       front of	these kinds of chained relationship parameters.	 (The
	       chain of	relationship names specifies the target	table, so any
	       "tN" alias would	be redundant at	best, or present a conflict at
	       worst.)

	   require_objects ARRAYREF
	       Only fetch rows from the	primary	table that have	all of the
	       associated sub-objects listed in	ARRAYREF, a reference to an
	       array of	foreign	key or relationship names defined for
	       "object_class".	The supported relationship types are "one to
	       one," "one to many," and	 "many to many".

	       For each	foreign	key or relationship name listed	in ARRAYREF,
	       another table will be added to the query	via an implicit	inner
	       join.  The join conditions will be constructed automatically
	       based on	the foreign key	or relationship	definitions.  Note
	       that each related table must have a Rose::DB::Object-derived
	       class fronting it.

	       Foreign key and relationship names may be chained, with dots
	       (".") separating	each name.  For	example, imagine three tables,
	       "products", "vendors", and "regions", fronted by	three
	       Rose::DB::Object-derived	classes, "Product", "Vendor", and
	       "Region", respectively.	Each "Product" has a "Vendor", and
	       each "Vendor" has a "Region".

	       To fetch	"Product"s along with their "Vendor"s, and their
	       vendors'	"Region"s, provide a "with_objects" argument like
	       this:

		   require_objects => [	'vendor.region'	],

	       This assumes that the "Product" class has a relationship	or
	       foreign key named "vendor" that points to the product's
	       "Vendor", and that the "Vendor" class has a foreign key or
	       relationship named "region" that	points to the vendor's
	       "Region".

	       This chaining syntax can	be used	to traverse relationships of
	       any kind, including "one	to many" and "many to many"
	       relationships, to an arbitrary depth.

	       The following optional suffixes may be added after any name in
	       the chain in order to override the join type used:

		   Suffix    Join Type
		   ------    ----------
		   !	     Inner join
		   ?	     Left outer	join

	       Each link in a "require_objects"	chain uses an inner join by
	       default.	 In other words, the following "require_objects"
	       parameters are all equivalent:

		   # These all mean the	same thing
		   require_objects => [	'vendor.region'	  ]
		   require_objects => [	'vendor!.region!' ]
		   require_objects => [	'vendor.region!'  ]
		   require_objects => [	'vendor!.region'  ]

	       Thus, it	is only	really useful to use the "?" suffix in
	       "require_objects" parameters (though the	"!" suffixes don't do
	       any harm).  Here's a useful example of a	call with hybrid join
	       chain:

		   $products =
		     Product::Manager->get_products(
		       require_objects => [ 'vendor.region?' ]);

	       All product objects returned would have associated vendor
	       objects,	but those vendor objects may or	may not	have
	       associated region objects.

	       Note that inner joins may be implicit and nested_joins may or
	       may not be used.	 When in doubt,	use the	debug parameter	to see
	       the generated SQL.

	       Warning:	there may be a geometric explosion of redundant	data
	       returned	by the database	if you include more than one "... to
	       many" relationship in ARRAYREF.	Sometimes this may still be
	       more efficient than making additional queries to	fetch these
	       sub-objects, but	that all depends on the	actual data.  A
	       warning will be emitted (via Carp::cluck) if you	include	more
	       than one	"... to	many" relationship in ARRAYREF.	 If you're
	       sure you	know what you're doing,	you can	silence	this warning
	       by passing the "multi_many_ok" parameter	with a true value.

	       Note: the "require_objects" list	currently cannot be used to
	       simultaneously fetch two	objects	that both front	the same
	       database	table, but are of different classes.  One workaround
	       is to make one class use	a synonym or alias for one of the
	       tables.	Another	option is to make one table a trivial view of
	       the other.  The objective is to get the table names to be
	       different for each different class (even	if it's	just a matter
	       of letter case, if your database	is not case-sensitive when it
	       comes to	table names).

	   select [ CLAUSE | ARRAYREF ]
	       Select only the columns specified in either a comma-separated
	       string of column	names or a reference to	an array of column
	       names.  Strings are naively split between each comma.  If you
	       need more complex parsing, please use the array-reference
	       argument	format instead.

	       Column names should be prefixed by the appropriate "tN" table
	       alias, the table	name, or the foreign key or relationship name.
	       The prefix should be joined to the column name with a dot
	       (".").  Examples: "t2.name", "vendors.age".

	       Unprefixed columns are assumed to belong	to the primary table
	       ("t1") and are explicitly prefixed as such when selecting from
	       more than one table.  If	a column name matches "/ AS \w+$/"
	       then no prefix is applied.

	       If the column name is "*" (e.g.,	"t1.*")	then all columns from
	       that table are selected.

	       If an item in the referenced array is itself a reference	to a
	       scalar, then that item will be dereferenced and passed through
	       unmodified.

	       If selecting sub-objects	via the	"with_objects" or
	       "require_objects" parameters, you must select the primary key
	       columns from each sub-object table.  Failure to do so will
	       cause those sub-objects not to be created.

	       Be warned that you should provide some way to determine which
	       column or method	and which class	an item	belongs	to: a tN
	       prefix, a column	name, or at the	very least an "... AS ..."
	       alias clause.

	       If any "with_objects" or	"require_objects" arguments are
	       included	in this	call, the "select" list	must include at	least
	       the primary key column(s) from each table that contributes to
	       the named relationships.

	       This parameter conflicts	with the "fetch_only" parameter.  A
	       fatal error will	occur if both are used in the same call.

	       If this parameter is omitted, then all columns from all
	       participating tables are	selected (optionally modified by the
	       "nonlazy" parameter).

	   share_db BOOL
	       If true,	"db" will be passed to each Rose::DB::Object-derived
	       object when it is constructed.  Defaults	to true.

	   sort_by [ CLAUSE | ARRAYREF ]
	       A fully formed SQL "ORDER BY ..." clause, sans the words	"ORDER
	       BY", or a reference to an array of strings or scalar references
	       to be de-referenced as needed, joined with a comma, and
	       appended	to the "ORDER BY" clause.

	       If an argument is a reference to	a scalar, then it is passed
	       through to the ORDER BY clause unmodified.

	       Otherwise, within each string, any instance of "NAME." will be
	       replaced	with the appropriate "tN." table alias,	where NAME is
	       a table,	foreign	key, or	relationship name.  All	unprefixed
	       simple column names are assumed to belong to the	primary	table
	       ("t1").

	       If selecting sub-objects	(via "require_objects" or
	       "with_objects") that are	related	through	"one to	many" or "many
	       to many"	relationships, the first condition in the sort order
	       clause must be a	column in the primary table (t1).  If this
	       condition is not	met, the list of primary key columns will be
	       added to	the beginning of the sort order	clause automatically.

	   table_aliases BOOL
	       When only a single table	is used	in q auery, this parameter
	       controls	whether	or not the "tN"	aliases	are used.  If the
	       parameter is not	passed,	then tables are	aliased.  If it	is
	       passed with a false value, then tables are not aliased.	When
	       more than one table participates	in a query, the	"tN" table
	       aliases are always used and this	option is ignored.

	   unique_aliases BOOL
	       If true,	and if there is	no explicit value for the "select"
	       parameter and more than one table is participating in the
	       query, then each	selected column	will be	given a	unique alias
	       by prefixing it with its	table alias and	an underscore.	The
	       default value is	false.	Example:

		   SELECT
		     t1.id    AS t1_id,
		     t1.name  AS t1_name,
		     t2.id    AS t2_id,
		     t2.name  AS t2_name
		   FROM
		     foo AS t1,
		     bar AS t2
		   WHERE
		     ...

	       These unique aliases provide a technique	of last	resort for
	       unambiguously addressing	a column in a query clause.

	   where ARRAYREF
	       This is an alias	for the	"query"	parameter (see above).

	   with_map_records [ BOOL | METHOD | HASHREF ]
	       When fetching related objects through a "many to	many"
	       relationship, objects of	the map	class are not retrieved	by
	       default.	 Use this parameter to override	the default behavior.

	       If the value is "1", then each object fetched through a mapping
	       table will have its associated map record available through a
	       "map_record()" attribute.

	       If a method name	is provided instead, then each object fetched
	       through a mapping table will have its associated	map record
	       available through a method of that name.

	       If the value is a reference to a	hash, then the keys of the
	       hash should be "many to many" relationship names, and the
	       values should be	the method names through which the maps
	       records will be available for each relationship.

	   with_objects	ARRAYREF
	       Also fetch sub-objects (if any) associated with rows in the
	       primary table based on a	reference to an	array of foreign key
	       or relationship names defined for "object_class".  The
	       supported relationship types are	"one to	one," "one to many,"
	       and  "many to many".

	       For each	foreign	key or relationship name listed	in ARRAYREF,
	       another table will be added to the query	via an explicit	LEFT
	       OUTER JOIN.  (Foreign keys whose	columns	are all	NOT NULL are
	       the exception, however.	They are always	fetched	via inner
	       joins.)	 The join conditions will be constructed automatically
	       based on	the foreign key	or relationship	definitions.  Note
	       that each related table must have a Rose::DB::Object-derived
	       class fronting it.  See the synopsis for	an example.

	       "Many to	many" relationships are	a special case.	 They will add
	       two tables to the query (the "map" table	plus the table with
	       the actual data), which will offset the "tN" table numbering by
	       one extra table.

	       Foreign key and relationship names may be chained, with dots
	       (".") separating	each name.  For	example, imagine three tables,
	       "products", "vendors", and "regions", fronted by	three
	       Rose::DB::Object-derived	classes, "Product", "Vendor", and
	       "Region", respectively.	Each "Product" has a "Vendor", and
	       each "Vendor" has a "Region".

	       To fetch	"Product"s along with their "Vendor"s, and their
	       vendors'	"Region"s, provide a "with_objects" argument like
	       this:

		   with_objects	=> [ 'vendor.region' ],

	       This assumes that the "Product" class has a relationship	or
	       foreign key named "vendor" that points to the product's
	       "Vendor", and that the "Vendor" class has a foreign key or
	       relationship named "region" that	points to the vendor's
	       "Region".

	       This chaining syntax can	be used	to traverse relationships of
	       any kind, including "one	to many" and "many to many"
	       relationships, to an arbitrary depth.

	       The following optional suffixes may be added after any name in
	       the chain in order to override the join type used:

		   Suffix    Join Type
		   ------    ----------
		   !	     Inner join
		   ?	     Left outer	join

	       Each link in a "with_objects" chain uses	a left outer join by
	       default.	 In other words, the following "with_objects"
	       parameters are all equivalent:

		   # These all mean the	same thing
		   with_objects	=> [ 'vendor.region'   ]
		   with_objects	=> [ 'vendor?.region?' ]
		   with_objects	=> [ 'vendor.region?'  ]
		   with_objects	=> [ 'vendor?.region'  ]

	       Thus, it	is only	really useful to use the "!" suffix in
	       "with_objects" parameters (though the "?" suffixes don't	do any
	       harm).  Here's a	useful example of a call with hybrid join
	       chain:

		   $products =
		     Product::Manager->get_products(
		       with_objects => [ 'vendor!.region' ]);

	       All product objects returned would have associated vendor
	       objects,	but those vendor object	may or may not have associated
	       region objects.

	       Note that inner joins may be implicit and nested_joins may or
	       may not be used.	 When in doubt,	use the	debug parameter	to see
	       the generated SQL.

	       Warning:	there may be a geometric explosion of redundant	data
	       returned	by the database	if you include more than one "... to
	       many" relationship in ARRAYREF.	Sometimes this may still be
	       more efficient than making additional queries to	fetch these
	       sub-objects, but	that all depends on the	actual data.  A
	       warning will be emitted (via Carp::cluck) if you	include	more
	       than one	"... to	many" relationship in ARRAYREF.	 If you're
	       sure you	know what you're doing,	you can	silence	this warning
	       by passing the "multi_many_ok" parameter	with a true value.

	       Note: the "with_objects"	list currently cannot be used to
	       simultaneously fetch two	objects	that both front	the same
	       database	table, but are of different classes.  One workaround
	       is to make one class use	a synonym or alias for one of the
	       tables.	Another	option is to make one table a trivial view of
	       the other.  The objective is to get the table names to be
	       different for each different class (even	if it's	just a matter
	       of letter case, if your database	is not case-sensitive when it
	       comes to	table names).

       get_objects_count [PARAMS]
	   Accepts the same arguments as get_objects, but just returns the
	   number of objects that would	have been fetched, or undef if there
	   was an error.

       get_objects_from_sql [ SQL | PARAMS ]
	   Fetch objects using a custom	SQL query.  Pass either	a single SQL
	   query string	or name/value parameters as arguments.	Valid
	   parameters are:

	   args	ARRAYREF
	       A reference to an array of arguments to be passed to DBI's
	       execute method when the query is	run.  The number of items in
	       this array must exactly match the number	of placeholders	in the
	       SQL query.

	   db DB
	       A Rose::DB-derived object used to access	the database.  If
	       omitted,	one will be created by calling the init_db method of
	       the "object_class".

	   object_class	CLASS
	       The class name of the Rose::DB::Object-derived objects to be
	       fetched.	 Defaults to the value returned	by the object_class
	       class method.

	   prepare_cached BOOL
	       If true,	then DBI's prepare_cached method will be used (instead
	       of the prepare method) when preparing the SQL statement that
	       will fetch the objects.	If omitted, the	default	value is
	       determined by the dbi_prepare_cached class method.

	   prepare_options HASHREF
	       A reference to a	hash of	attributes to be passed	to DBI's
	       prepare or prepare_cached method	when preparing the SQL
	       statement.

	   share_db BOOL
	       If true,	"db" will be passed to each Rose::DB::Object-derived
	       object when it is constructed.  Defaults	to true.

	   sql SQL
	       The SQL query string.  This parameter is	required.

	   Each	column returned	by the SQL query must be either	a column or
	   method name in "object_class".  Column names	take precedence	in the
	   case	of a conflict.

	   Returns a reference to an array of "object_class" objects.

	   Examples:

	       package Product::Manager;
	       use Product;
	       use base	'Rose::DB::Object::Manager';
	       sub object_class	{ 'Product' }
	       ...

	       $products = Product::Manager->get_objects_from_sql(<<"EOF");
	       SELECT *	FROM products WHERE sku	% 2 != 0 ORDER BY status, type
	       EOF

	       $products =
		 Product::Manager->get_objects_from_sql(
		   args	=> [ '2005-01-01' ],
		   sql	=> 'SELECT * FROM products WHERE release_date >	?');

       get_objects_iterator [PARAMS]
	   Accepts any valid get_objects arguments, but	return a
	   Rose::DB::Object::Iterator object, or undef if there	was an error.

       get_objects_iterator_from_sql [PARAMS]
	   Accepts any valid get_objects_from_sql arguments, but return	a
	   Rose::DB::Object::Iterator object, or undef if there	was an error.

       get_objects_sql [PARAMS]
	   Accepts the same arguments as get_objects, but return the SQL query
	   string that would have been used to fetch the objects (in scalar
	   context), or	the SQL	query string and a reference to	an array of
	   bind	values (in list	context).

       make_manager_methods PARAMS
	   Create convenience wrappers for Rose::DB::Object::Manager's
	   get_objects,	get_objects_iterator, and get_objects_count class
	   methods in the target class.	 These wrapper methods will not
	   overwrite any existing methods in the target	class.	If there is an
	   existing method with	the same name, a fatal error will occur.

	   PARAMS can take several forms, depending on the calling context.
	   For a call to make_manager_methods to succeed, the following
	   information must be determined:

	   o   object class

	       The class of the	Rose::DB::Object-derived objects to be fetched
	       or counted.

	   o   base name or method name

	       The base	name is	a string used as the basis of the method
	       names.  For example, the	base name "products" might be used to
	       create methods named "get_products", "get_products_count",
	       "get_products_iterator",	"delete_products", and
	       "update_products".

	       In the absence of a base	name, an explicit method name may be
	       provided	instead.  The method name will be used as is.

	   o   method types

	       The types of methods that should	be generated.  Each method
	       type is a wrapper for a Rose::DB::Object::Manager class method.
	       The mapping of method type names	to actual
	       Rose::DB::Object::Manager class methods defaults	to the
	       following:

		   Type	       Method
		   --------    ----------------------
		   objects     get_objects()
		   iterator    get_objects_iterator()
		   count       get_objects_count()
		   delete      delete_objects()
		   update      update_objects()

	       You may override	the auto_manager_method_name method in the
	       object_class's convention manager class to customize one	or
	       more of these names.

	   o   target class

	       The class that the methods should be installed in.

	   Here	are all	of the different ways that each	of those pieces	of
	   information can be provided,	either implicitly or explicitly	as
	   part	of PARAMS.

	   o   object class

	       If an "object_class" parameter is passed	in PARAMS, then	its
	       value is	used as	the object class.  Example:

		   $class->make_manager_methods(object_class =>	'Product', ...);

	       If the "object_class" parameter is not passed, and if the
	       target class inherits from Rose::DB::Object::Manager and	has
	       also defined an "object_class" method, then the return value of
	       that method is used as the object class.	 Example:

		 package Product::Manager;

		 use Rose::DB::Object::Manager;
		 our @ISA = qw(Rose::DB::Object::Manager);

		 sub object_class { 'Product' }

		 # Assume object_class parameter is not	part of	the ...	below
		 __PACKAGE__->make_manager_methods(...);

	       In this case, the object	class would be "Product".

	       Finally,	if none	of the above conditions	are met, one final
	       option is considered.  If the target class inherits from
	       Rose::DB::Object, then the object class is set to the target
	       class.

	       If the object class cannot be determined	in one of the ways
	       described above,	then a fatal error will	occur.

	   o   base name or method name

	       If a "base_name"	parameter is passed in PARAMS, then its	value
	       is used as the base name	for the	generated methods.  Example:

		   $class->make_manager_methods(base_name => 'products', ...);

	       If the "base_name" parameter is not passed, and if there	is
	       only one	argument passed	to the method, then the	lone argument
	       is used as the base name.  Example:

		   $class->make_manager_methods('products');

	       (Note that, since the object class must be derived somehow,
	       this will only work in one of the situations (described above)
	       where the object	class can be derived from the calling context
	       or class.)

	       If a "methods" parameter	is passed with a hash ref value, then
	       each key	of the hash is used as the base	name for the method
	       types listed in the corresponding value.	 (See method types
	       below for more information.)

	       If a key	of the "methods" hash ends in "()", then it is taken
	       as the method name and is used as is.  For example, the key
	       "foo" will be used as a base name, but the key "foo()" will be
	       used as a method	name.

	       If the base name	cannot be determined in	one of the ways
	       described above,	then the auto_manager_base_name	method in the
	       object_class's convention manager is called on to supply	a base
	       name.

	   o   method types

	       If an explicit list of method types is not passed to the
	       method, then all	of the default_manager_method_types are
	       created.	 Example:

		   # Base name is determined by	convention manager auto_manager_base_name()
		   # method, all default method	types created
		   $class->make_manager_methods();

		   # Base name is "products", all default method types created
		   $class->make_manager_methods('products');

		   # Base name is "products", all default method types created
		   $class->make_manager_methods(base_name => products',	...);

	       (Again, note that the object class must be derived somehow.)

	       If a "methods" parameter	is passed, then	its value must be a
	       reference to a hash whose keys are base names or	method names,
	       and whose values	are method types or references to arrays of
	       method types.

	       If a key	ends in	"()", then it is taken as a method name	and is
	       used as is.  Otherwise, it is used as a base name.  For
	       example,	the key	"foo" will be used as a	base name, but the key
	       "foo()" will be used as a method	name.

	       If a key	is a method name and its value specifies more than one
	       method type, then a fatal error will occur.  (It's impossible
	       to have more than one method with the same name.)

	       Example:

		   # Make the following	methods:
		   #
		   # * Base name: products; method types: objects, iterators
		   #
		   #	 get_products()
		   #	 get_products_iterator()
		   #
		   # * Method name: product_count; method type:	count
		   #
		   #	 product_count()
		   #
		   $class->make_manager_methods(...,
		     methods =>
		     {
		       'products'	 => [ qw(objects iterator) ],
		       'product_count()' => 'count'
		     });

	       If the value of the "methods" parameter is not a	reference to a
	       hash, or	if both	the "methods" and "base_name" parameters are
	       passed, then a fatal error will occur.

	   o   target class

	       If a "target_class" parameter is	passed in PARAMS, then its
	       value is	used as	the target class.  Example:

		   $class->make_manager_methods(target_class =>	'Product', ...);

	       If a "target_class" parameter is	not passed, and	if the calling
	       class is	not Rose::DB::Object::Manager, then the	calling	class
	       is used as the target class.  Otherwise,	the class from which
	       the method was called is	used as	the target class.  Examples:

		   # Target class is Product, regardless of the	calling
		   # context or	the value of $class
		   $class->make_manager_methods(target_class =>	'Product', ...);

		   package Foo;

		   # Target class is Foo: no target_class parameter is passed
		   # and the calling class is Rose::DB::Object::Manager, so
		   # the class from which the method was called	(Foo) is used.
		   Rose::DB::Object::Manager->make_manager_methods(
		     object_class => 'Bar',
		     base_name	  => 'Baz');

		   package Bar;

		   # Target class is Foo: no target_class parameter is passed
		   # and the calling class is not Rose::DB::Object::Manager,
		   # so	the calling class (Foo)	is used.
		   Foo->make_manager_methods(object_class => 'Bar',
					     base_name	  => 'Baz');

	   There's a lot of flexibility	in this	method's arguments (although
	   some	might use the word "confusion" instead), but the examples can
	   be pared down to a few common usage scenarios.

	   The first is	the recommended	technique, as seen in the synopsis.
	   Create a separate manager class that	inherits from
	   Rose::DB::Object::Manager, override the "object_class" method to
	   specify the class of	the objects being fetched, and then pass a
	   lone	base name argument to the call to make_manager_methods.

	     package Product::Manager;

	     use Rose::DB::Object::Manager;
	     our @ISA =	qw(Rose::DB::Object::Manager);

	     sub object_class {	'Product' }

	     __PACKAGE__->make_manager_methods('products');

	   The second example is used to install object	manager	methods
	   directly into a Rose::DB::Object-derived class.  I do not recommend
	   this	practice; I consider it	"semantically impure" for the class
	   that	represents a single object to also be the class	that's used to
	   fetch multiple objects.  Inevitably,	classes	grow, and I'd like the
	   "object manager" class to be	separate from the object class itself
	   so they can grow happily in isolation, with no potential clashes.

	   Also, keep in mind that Rose::DB::Object and
	   Rose::DB::Object::Manager have separate error_mode settings which
	   must	be synchronized	or otherwise dealt with.  Another advantage of
	   using a separate Rose::DB::Object::Manager subclass (as described
	   earlier) is that you	can override the error_mode in your
	   Rose::DB::Object::Manager subclass only, rather than	overriding the
	   base	class Rose::DB::Object::Manager	error_mode, which may affect
	   other classes.

	   If none of that dissuades you, here's how to	do it:

	     package Product;

	     use Rose::DB::Object:;
	     our @ISA =	qw(Rose::DB::Object);

	     __PACKAGE__->make_manager_methods('products');

	   Finally, sometimes you don't	want or	need to	use
	   make_manager_methods	at all.	 In fact, this method did not exist in
	   earlier versions of this module.  The formerly recommended way to
	   use this class is  still perfectly valid: subclass it and then call
	   through to the base class methods.

	     package Product::Manager;

	     use Rose::DB::Object::Manager;
	     our @ISA =	qw(Rose::DB::Object::Manager);

	     sub get_products
	     {
	       shift->get_objects(object_class => 'Product', @_);
	     }

	     sub get_products_iterator
	     {
	       shift->get_objects_iterator(object_class	=> 'Product', @_);
	     }

	     sub get_products_count
	     {
	       shift->get_objects_count(object_class =>	'Product', @_);
	     }

	     sub delete_products
	     {
	       shift->delete_objects(object_class => 'Product',	@_);
	     }

	     sub update_products
	     {
	       shift->update_objects(object_class => 'Product',	@_);
	     }

	   Of course, these methods will all look very similar in each
	   Rose::DB::Object::Manager-derived class.  Creating these
	   identically structured methods is exactly what make_manager_methods
	   automates for you.

	   But sometimes you want to customize these methods, in which case
	   the "longhand" technique above becomes essential.  For example,
	   imagine that	we want	to extend the code in the synopsis, adding
	   support for a "with_categories" parameter to	the "get_products()"
	   method.

	     Product::Manager->get_products(date_created    => '10/21/2001',
					    with_categories => 1);

	     ...

	     sub get_products
	     {
	       my($class, %args) @_;

	       if(delete $args{'with_categories'}) # boolean flag
	       {
		 push(@{$args{'with_objects'}},	'category');
	       }

	       Rose::DB::Object::Manager->get_objects(
		 %args,	object_class =>	'Product')
	     }

	   Here	we've coerced the caller-friendly "with_categories" boolean
	   flag	parameter into the "with_objects => [ 'category' ]" pair that
	   Rose::DB::Object::Manager's get_objects method can understand.

	   This	is the typical evolution of an object manager method.  It
	   starts out as being auto-generated by make_manager_methods, then
	   becomes customized as new arguments are added.

       make_manager_method_from_sql [ NAME => SQL | PARAMS ]
	   Create a class method in the	calling	class that will	fetch objects
	   using a custom SQL query.  The method created will return a
	   reference to	an array of objects or a Rose::DB::Object::Iterator
	   object, depending on	whether	the "iterator" parameter is set	(see
	   below).

	   Pass	either a method	name and an SQL	query string or	name/value
	   parameters as arguments.  Valid parameters are:

	   iterator BOOL
	       If true,	the method created will	return a
	       Rose::DB::Object::Iterator object.

	   object_class	CLASS
	       The class name of the Rose::DB::Object-derived objects to be
	       fetched.	 Defaults to the value returned	by the object_class
	       class method.

	   params ARRAYREF
	       To allow	the method that	will be	created	to accept named
	       parameters (name/value pairs) instead of	positional parameters,
	       provide a reference to an array of parameter names in the order
	       that they should	be passed to the call to DBI's execute method.

	   method NAME
	       The name	of the method to be created.  This parameter is
	       required.

	   prepare_cached BOOL
	       If true,	then DBI's prepare_cached method will be used (instead
	       of the prepare method) when preparing the SQL statement that
	       will fetch the objects.	If omitted, the	default	value is
	       determined by the dbi_prepare_cached class method.

	   share_db BOOL
	       If true,	"db" will be passed to each Rose::DB::Object-derived
	       object when it is constructed.  Defaults	to true.

	   sql SQL
	       The SQL query string.  This parameter is	required.

	   Each	column returned	by the SQL query must be either	a column or
	   method name in "object_class".  Column names	take precedence	in the
	   case	of a conflict.

	   Arguments passed to the created method will be passed to DBI's
	   execute method when the query is run.  The number of	arguments must
	   exactly match the number of placeholders in the SQL query.
	   Positional parameters are required unless the "params" parameter is
	   used.  (See description above.)

	   Returns a code reference to the method created.

	   Examples:

	       package Product::Manager;

	       use base	'Rose::DB::Object::Manager';
	       ...

	       # Make method that takes	no arguments
	       __PACKAGE__->make_manager_method_from_sql(get_odd_products =><<"EOF");
	       SELECT *	FROM products WHERE sku	% 2 != 0
	       EOF

	       # Make method that takes	one positional parameter
	       __PACKAGE__->make_manager_method_from_sql(get_new_products =><<"EOF");
	       SELECT *	FROM products WHERE release_date > ?
	       EOF

	       # Make method that takes	named parameters
	       __PACKAGE__->make_manager_method_from_sql(
		 method	=> 'get_named_products',
		 params	=> [ qw(type name) ],
		 sql	=> <<"EOF");
	       SELECT *	FROM products WHERE type = ? AND name LIKE ?
	       EOF

	       ...

	       $products = Product::Manager->get_odd_products();

	       $products = Product::Manager->get_new_products('2005-01-01');

	       $products =
		 Product::Manager->get_named_products(
		   name	=> 'Kite%',
		   type	=> 'toy');

	       # Make method that takes	named parameters and returns an	iterator
	       __PACKAGE__->make_manager_method_from_sql(
		 method	  => 'get_named_products_iterator',
		 iterator => 1,
		 params	  => [ qw(type name) ],
		 sql	  => <<"EOF");
	       SELECT *	FROM products WHERE type = ? AND name LIKE ?
	       EOF

	       $iterator =
		 Product::Manager->get_named_products_iterator(
		   name	=> 'Kite%',
		   type	=> 'toy');

	       while(my	$product = $iterator->next)
	       {
		 ... # do something with $product

		 $iterator->finish  if(...); # finish early?
	       }

       normalize_get_objects_args [ARGS]
	   This	method takes ARGS in the forms accepted	by get_objects (and
	   other similar methods) and normalizes them into name/value pairs.
	   Since get_objects can take arguments	in many	forms, this method is
	   useful when overriding get_objects in a custom
	   Rose::DB::Object::Manager subclass.	Example:

	       package Product::Manager;

	       use base	'Rose::DB::Object::Manager';

	       use Product;

	       sub object_class	{ 'Product' }
	       ...

	       sub get_products
	       {
		 my($class, %args) = shift->normalize_get_objects_args(@_);

		 # Detect, extract, and	handle custom argument
		 if(delete $args{'active_only'})
		 {
		   push(@{$args{'query'}}, status => 'active');
		 }

		 return	$class->get_objects(%args); # call through to normal method
	       }

	   Now all of the following calls will work:

	       $products =
		 Product::Manager->get_products([ type => 'boat' ], sort_by => 'name');

	       $products =
		 Product::Manager->get_products({ name => { like => '%Dog%' } });

	       $products =
		 Product::Manager->get_products([ id =>	{ gt =>	123 } ], active_only =>	1);

       object_class
	   Returns the class name of the Rose::DB::Object-derived objects to
	   be managed by this class.  Override this method in your subclass.
	   The default implementation returns undef.

       perl_class_definition
	   Attempts to create the Perl source code that	is equivalent to the
	   current class.  This	works best for classes created via
	   Rose::DB::Object::Metadata's	make_manager_class method, but it will
	   also	work most of the time for classes whose	methods	were created
	   using make_manager_methods.

	   The Perl code is returned as	a string.  Here's an example:

	     package My::Product::Manager;

	     use My::Product;

	     use Rose::DB::Object::Manager;
	     our @ISA =	qw(Rose::DB::Object::Manager);

	     sub object_class {	'My::Product' }

	     __PACKAGE__->make_manager_methods('products');

	     1;

       update_objects [PARAMS]
	   Update rows in a table fronted by a Rose::DB::Object-derived	class
	   based on PARAMS, where PARAMS are name/value	pairs.	Returns	the
	   number of rows updated, or undef if there was an error.

	   Valid parameters are:

	   all BOOL
	       If set to a true	value, this parameter indicates	an explicit
	       request to update all rows in the table.	 If both the "all" and
	       the "where" parameters are passed, a fatal error	will occur.

	   db DB
	       A Rose::DB-derived object used to access	the database.  If
	       omitted,	one will be created by calling the init_db method of
	       the "object_class".

	   object_class	CLASS
	       The class name of the Rose::DB::Object-derived class that
	       fronts the table	whose rows will	to be updated.	This parameter
	       is required; a fatal error will occur if	it is omitted.
	       Defaults	to the value returned by the object_class class
	       method.

	   set PARAMS
	       The names and values of the columns to be updated.  PARAMS
	       should be a reference to	a hash.	 Each key of the hash should
	       be a column name	or column get/set method name.	If a value is
	       a simple	scalar,	then it	is passed through the get/set method
	       that services the column	before being incorporated into the SQL
	       query.

	       If a value is a reference to a scalar, then it is dereferenced
	       and incorporated	into the SQL query as-is.

	       If a value is a reference to a hash, then it must contain a
	       single key named	"sql" and a corresponding value	that will be
	       incorporated into the SQL query as-is.

	       Example:

		 $num_rows_updated =
		   Product::Manager->update_products(
		     set =>
		     {
		       end_date	  => DateTime->now,
		       region_num => { sql => 'region_num * -1'	}
		       count	  => \q(count +	1),
		       status	  => 'defunct',
		     },
		     where =>
		     [
		       status  => [ 'stale', 'old' ],
		       name    => { like => 'Wax%' }
		       or =>
		       [
			 start_date => { gt => '2008-12-30' },
			 end_date   => { gt => 'now' },
		       ],
		     ]);

	       The call	above would execute an SQL statement something like
	       the one shown below (depending on the database vendor, and
	       assuming	the current date was September 20th, 2005):

		   UPDATE products SET
		     end_date	= '2005-09-20',
		     region_num	= region_num * -1,
		     count	= count	+ 1,
		     status	= 'defunct'
		   WHERE
		     status IN ('stale', 'old')	AND
		     name LIKE 'Wax%' AND
		     (
		       start_date > '2008-12-30' OR
		       end_date	  > '2005-09-20'
		     )

	   where PARAMS
	       The query parameters, passed as a reference to an array of
	       name/value pairs.  These	PARAMS are used	to formulate the
	       "where" clause of the SQL query that is used to update the rows
	       in the table.  Arbitrarily nested boolean logic is supported.

	       For the complete	list of	valid parameter	names and values, see
	       the documentation for the "query" parameter of the build_select
	       function	in the Rose::DB::Object::QueryBuilder module.

	       If this parameter is omitted, this method will refuse to	update
	       all rows	in the table and a fatal error will occur.  To update
	       all rows	in a table, you	must pass the "all" parameter with a
	       true value.  If both the	"all" and the "where" parameters are
	       passed, a fatal error will occur.

       strict_ops [BOOL]
	   Get or set a	boolean	value that indicates whether using a
	   comparison operator in the "query" that is not listed in the
	   Rose::DB::Object::QueryBuilder documentation	will cause a fatal
	   error.  The default value is	false.

SUPPORT
       For an informal overview	of Rose::DB::Object, including
       Rose::DB::Object::Manager, consult the Rose::DB::Object::Tutorial.

	   perldoc Rose::DB::Object::Tutorial

       Any Rose::DB::Object::Manager questions or problems can be posted to
       the Rose::DB::Object mailing list.  To subscribe	to the list or view
       the archives, go	here:

       <http://groups.google.com/group/rose-db-object>

       Although	the mailing list is the	preferred support mechanism, you can
       also email the author (see below) or file bugs using the	CPAN bug
       tracking	system:

       <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Rose-DB-Object>

       There's also a wiki and other resources linked from the Rose project
       home page:

       <http://rose.googlecode.com>

AUTHOR
       John C. Siracusa	(siracusa@gmail.com)

LICENSE
       Copyright (c) 2010 by John C. Siracusa.	All rights reserved.  This
       program is free software; you can redistribute it and/or	modify it
       under the same terms as Perl itself.

perl v5.32.1			  2015-03-17	  Rose::DB::Object::Manager(3)

NAME | SYNOPSIS | DESCRIPTION | CLASS METHODS | SUPPORT | AUTHOR | LICENSE

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Rose::DB::Object::Manager&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help