Rose::...eneric(3pm)
πΈ NAME πΈ
okay bestie, listen: Rose::DB::Object::MakeMethods::Generic is a method maker that creates generic object methods for your Rose::DB::Object-derived objects. that's the whole entire job. she's Rose::DB::Object::MakeMethods::Generic(3pm), filed under User Contributed Perl Documentation, and she's about to carry your whole model layer π
π SYNOPSIS π
like⦠just look at her go:
package MyDBObject;
our @ISA = qw(Rose::DB::Object);
use Rose::DB::Object::MakeMethods::Generic
(
scalar =>
[
'type' =>
{
with_init => 1,
check_in => [ qw(AA AAA C D) ],
},
'set_type' => { hash_key => 'type' },
],
character =>
[
code => { length => 6 }
],
varchar =>
[
name => { length => 10 }
],
boolean =>
[
'is_red',
'is_happy' => { default => 1 },
],
);
sub init_type { 'C' }
...
$obj = MyDBObject->new(...);
print $obj->type; # C
$obj->name('Bob'); # set
$obj->set_type('C'); # set
$obj->type('AA'); # set
$obj->set_type; # Fatal error: no argument passed to "set" method
$obj->name('C' x 40); # truncate on set
print $obj->name; # 'CCCCCCCCCC'
$obj->code('ABC'); # pad on set
print $obj->code; # 'ABC '
eval { $obj->type('foo') }; # fatal error: invalid value
print $obj->name, ' is ', $obj->type; # get
$obj->is_red; # returns undef
$obj->is_red('true'); # returns 1 (assuming "true" a
# valid boolean literal according to
# $obj->db->parse_boolean('true'))
$obj->is_red(''); # returns 0
$obj->is_red; # returns 0
$obj->is_happy; # returns 1
...
package Person;
our @ISA = qw(Rose::DB::Object);
...
use Rose::DB::Object::MakeMethods::Generic
(
scalar => 'name',
set =>
[
'nicknames',
'parts' => { default => [ qw(arms legs) ] },
],
# See the Rose::DB::Object::Metadata::Relationship::ManyToMany
# documentation for a more complete example
objects_by_map =>
[
friends =>
{
map_class => 'FriendMap',
manager_args => { sort_by => Friend->meta->table . '.name' },
},
],
);
...
@parts = $person->parts; # ('arms', 'legs')
$parts = $person->parts; # [ 'arms', 'legs' ]
$person->nicknames('Jack', 'Gimpy'); # set with list
$person->nicknames([ 'Slim', 'Gip' ]); # set with array ref
print join(', ', map { $_->name } $person->friends);
...
package Program;
our @ISA = qw(Rose::DB::Object);
...
use Rose::DB::Object::MakeMethods::Generic
(
objects_by_key =>
[
bugs =>
{
class => 'Bug',
key_columns =>
{
# Map Program column names to Bug column names
id => 'program_id',
version => 'version',
},
manager_args =>
{
sort_by => Bug->meta->table . '.date_submitted DESC',
},
query_args => [ state => { ne => 'closed' } ],
},
]
);
...
$prog = Program->new(id => 5, version => '3.0', ...);
$bugs = $prog->bugs;
# Calls (essentially):
#
# Rose::DB::Object::Manager->get_objects(
# db => $prog->db, # share_db defaults to true
# object_class => 'Bug',
# query =>
# {
# program_id => 5, # value of $prog->id
# version => '3.0', # value of $prog->version
# state => { ne => 'closed' },
# },
# sort_by => 'date_submitted DESC');
...
package Product;
our @ISA = qw(Rose::DB::Object);
...
use Rose::DB::Object::MakeMethods::Generic
(
object_by_key =>
[
category =>
{
class => 'Category',
key_columns =>
{
# Map Product column names to Category column names
category_id => 'id',
},
},
]
);
...
$product = Product->new(id => 5, category_id => 99);
$category = $product->category;
# $product->category call is roughly equivalent to:
#
# $cat = Category->new(id => $product->category_id,
# db => $prog->db);
#
# $ret = $cat->load;
# return $ret unless($ret);
# return $cat;
β¨ DESCRIPTION β¨
so Rose::DB::Object::MakeMethods::Generic is a method maker, and she inherits from Rose::Object::MakeMethods. if you want the tea on how the interface actually works, go read the Rose::Object::MakeMethods documentation β that's where all the "how do i even call this" lore lives π. the method types this module provides are all described right down below π
also, super important: every single method type defined by this module is designed to work with objects that are subclasses of (or that otherwise conform to the interface of) Rose::DB::Object. specifically, the object is expected to have a db method that returns a Rose::DB-derived object. want more details? the Rose::DB::Object documentation has you covered π«Ά
π οΈ METHODS TYPES π οΈ
π array π
creates get/set methods for array attributes. quick context bestie: an array column in a database table contains an ordered list of values. but heads up β not all databases support an array column type, so check the Rose::DB documentation for your database type before you get too excited π
π Options π
default VALUEβ determines the default value of the attribute. it should be a reference to an array.hash_key NAMEβ the key inside the hash-based object used to store this attribute. defaults to the name of the method.interface NAMEβ picks the interface. default isget_set.
π¦ Interfaces π¦
get_setβ creates a get/set method for anarrayobject attribute. (anarraycolumn in a database table contains an ordered list of values, we know, iconic β¨)- when setting the attribute, the value is passed through the
parse_arraymethod of the object'sdbattribute. - when saving to the database, if the attribute value is defined, the method passes the attribute value through the
format_arraymethod of the object'sdbattribute before returning it. - when not saving to the database, the method returns the array as a list in list context, or as a reference to the array in scalar context.
- when setting the attribute, the value is passed through the
getβ creates an accessor method for anarrayobject attribute. (again:arraycolumn, database table, ordered list of values, you know the drill π)- when saving to the database, if the attribute value is defined, the method passes the attribute value through the
format_arraymethod of the object'sdbattribute before returning it. - when not saving to the database, the method returns the array as a list in list context, or as a reference to the array in scalar context.
- when saving to the database, if the attribute value is defined, the method passes the attribute value through the
setβ creates a mutator method for anarrayobject attribute. (ordered list of values,arraycolumn, yes yes π )- when setting the attribute, the value is passed through the
parse_arraymethod of the object'sdbattribute. - when saving to the database, if the attribute value is defined, the method passes the attribute value through the
format_arraymethod of the object'sdbattribute before returning it. - when not saving to the database, the method returns the array as a list in list context, or as a reference to the array in scalar context.
- > if called with no arguments, a fatal error will occur. no cap, do not do this π
- when setting the attribute, the value is passed through the
πΈ Example πΈ
package Person;
our @ISA = qw(Rose::DB::Object);
...
use Rose::DB::Object::MakeMethods::Generic
(
array =>
[
'nicknames',
set_nicks => { interface => 'set', hash_key => 'nicknames' },
parts => { default => [ qw(arms legs) ] },
],
);
...
@parts = $person->parts; # ('arms', 'legs')
$parts = $person->parts; # [ 'arms', 'legs' ]
$person->nicknames('Jack', 'Gimpy'); # set with list
$person->nicknames([ 'Slim', 'Gip' ]); # set with array ref
$person->set_nicks('Jack', 'Gimpy'); # set with list
$person->set_nicks([ 'Slim', 'Gip' ]); # set with array ref
π¦ bitfield π¦
creates get/set methods for bitfield attributes. bit math era π₯
π Options π
default VALUEβ determines the default value of the attribute.hash_key NAMEβ the key inside the hash-based object used to store this attribute. defaults to the name of the method.interface NAMEβ picks the interface. default isget_set.intersects NAMEβ sets the name of the"intersects"method. (see"with_intersects"below.) defaults to the bitfield attribute method name with"_intersects"appended.bits INTβ the number of bits in the bitfield. defaults to32.with_intersects BOOLβ this option is only applicable with the"get_set"interface. if true, it creates an"intersects"helper method in addition to the"get_set"method. the intersection method name is the attribute method name with"_intersects"appended, or the value of the"intersects"option if it's passed. the"intersects"method returns true if there's any intersection between its arguments and the value of the bitfield attribute (i.e., if Bit::Vector'sIntersectionmethod returns a value greater than zero), and false (but still defined, bestie) otherwise. its argument is passed through theparse_bitfieldmethod of the object'sdbattribute before being tested for intersection. returnsundefif the bitfield is not defined.
π¦ Interfaces π¦
get_setβ creates a get/set method for a bitfield attribute. when setting the attribute, the value is passed through theparse_bitfieldmethod of the object'sdbattribute before being assigned.
When it's time to save to the database, the method runs the attribute value through the format_bitfield method of the object's db attribute before handing it back. Otherwise? The value just comes back as-is. No notes. π
getβ makes an accessor method for a bitfield attribute. When saving to the database, the method passes the attribute value through theformat_bitfieldmethod of the object'sdbattribute before returning it. Otherwise, the value is returned as-is.setβ makes a mutator method for a bitfield attribute. When you set the attribute, the value gets passed through theparse_bitfieldmethod of the object'sdbattribute before it's assigned.
When saving to the database, the method passes the attribute value through the format_bitfield method of the object's db attribute before returning it. Otherwise, the value is returned as-is.
And if you call it with no arguments, a fatal error will occur. Not a vibe, but it's the rules. π
Example:
package MyDBObject;
our @ISA = qw(Rose::DB::Object);
use Rose::DB::Object::MakeMethods::Generic
(
bitfield =>
[
'flags' => { size => 32, default => 2 },
'bits' => { size => 16, with_intersects => 1 },
],
);
...
print $o->flags->to_Bin; # 00000000000000000000000000000010
$o->bits('101');
$o->bits_intersects('100'); # true
$o->bits_intersects('010'); # false
π boolean
Bestie. Make get/set methods for boolean attributes. So simple. So clean. We love a yes/no king. π
Options
default VALUEβ sets the default value of the attribute.hash_key NAMEβ the key inside the hash-based object used to store this attribute. Defaults to the name of the method.interface NAMEβ picks the interface. Default is"get_set".
Interfaces
get_setβ makes a get/set method for a boolean attribute. When setting, if the value is"true"by Perl's rules, it gets compared against a lil list of "common" true and false values:1,0,1.0(with any number of zeros),0.0(with any number of zeros),t,true,f,false,yes,no. (All case-insensitive, obviously.) If the value matches, it's set to true (1) or false (0) accordingly.
If it doesn't match any of those, it gets passed through the parse_boolean method of the object's db attribute. If parse_boolean returns true (1) or false (0), the attribute is set accordingly. If parse_boolean returns undef, a fatal error will occur π. If the value is "false" by Perl's rules, the attribute is set to zero (0).
When saving to the database, the method passes the attribute value through the format_boolean method of the object's db attribute before returning it. Otherwise, the value is returned as-is.
getβ makes an accessor method for a boolean attribute. When saving to the database, the method passes the attribute value through theformat_booleanmethod of the object'sdbattribute before returning it. Otherwise, the value is returned as-is.setβ makes a mutator method for a boolean attribute. When setting, if the value is"true"by Perl's rules, it's compared against that same list of "common" true and false values:1,0,1.0(with any number of zeros),0.0(with any number of zeros),t,true,f,false,yes,no. (All case-insensitive.) If the value matches, it's set to true (1) or false (0) accordingly.
If it doesn't match any of those, it's passed through the parse_boolean method of the object's db attribute. If parse_boolean returns true (1) or false (0), the attribute is set accordingly. If parse_boolean returns undef, a fatal error will occur. If the value is "false" by Perl's rules, the attribute is set to zero (0).
And yep β called with no arguments, a fatal error will occur. π«
Example:
package MyDBObject;
our @ISA = qw(Rose::DB::Object);
use Rose::DB::Object::MakeMethods::Generic
(
boolean =>
[
'is_red',
'is_happy' => { default => 1 },
'set_happy' => { interface => 'set', hash_key => 'is_happy' },
],
);
$obj->is_red; # returns undef
$obj->is_red('true'); # returns 1 (assuming "true" a
# valid boolean literal according to
# $obj->db->parse_boolean('true'))
$obj->is_red(''); # returns 0
$obj->is_red; # returns 0
$obj->is_happy; # returns 1
$obj->set_happy(0); # returns 0
$obj->is_happy; # returns 0
πΈ character
Make get/set methods for fixed-length character string attributes. Length? Enforced. Padding? Automatic. Iconic behavior, honestly. β¨
Options
check_in ARRAYREFβ a reference to an array of valid values. When setting the attribute, if the new value isn't equal (string comparison) to one of the valid values, a fatal error will occur.default VALUEβ sets the default value of the attribute.hash_key NAMEβ the key inside the hash-based object used to store this attribute. Defaults to the name of the method.init_method NAMEβ the name of the method to call when initializing the value of an undefined attribute. Defaults to the method name with the prefixinit_added. This option implies"with_init".interface NAMEβ picks the interface. Default is"get_set".length INTβ the number of characters in the string. Any strings shorter than this get padded with spaces to meet the length requirement. Iflengthis omitted, the string is left unmodified.overflow BEHAVIORβ decides what happens when the value is greater than the number of characters specified by the"length"option. Valid values for BEHAVIOR are:fatalβ throw an exception. πtruncateβ truncate the value to the correct length. βοΈwarnβ print a warning message. π’
with_init BOOLβ switches up the behavior of the"get_set"and"get"interfaces. If the attribute is undefined, the method specified by the"init_method"option gets called and the attribute is set to the return value of that method.
Interfaces
get_setβ makes a get/set method for a fixed-length character string attribute. When setting, any strings longer than"length"get truncated, and any strings shorter get padded with spaces to meet the length requirement. If"length"is omitted, the string is left unmodified.getβ makes an accessor method for a fixed-length character string attribute.setβ makes a mutator method for a fixed-length character string attribute. Any strings longer than"length"get truncated, and any strings shorter get padded with spaces to meet the length requirement. If"length"is omitted, the string is left unmodified.
Example:
package MyDBObject;
our @ISA = qw(Rose::DB::Object);
use Rose::DB::Object::MakeMethods::Generic
(
character =>
[
'name' => { length => 3 },
],
);
...
$o->name('John'); # truncates on set
print $o->name; # 'Joh'
$o->name('A'); # pads on set
print $o->name; # 'A '
π¦ enum
Make get/set methods for enum attributes. The "pick one from the list or perish" of attributes. π
Options
default VALUEβ sets the default value of the attribute.values ARRAYREFβ a reference to an array of the enum values. This attribute is required β like, non-negotiable. When setting the attribute, if the new value isn't equal (string comparison) to one of the enum values, a fatal error will occur.hash_key NAMEβ the key inside the hash-based object used to store this attribute. Defaults to the name of the method.init_method NAMEβ the name of the method to call when initializing the value of an undefined attribute. Defaults to the method name with the prefixinit_added. This option implies"with_init".interface NAMEβ picks the interface. The"get_set"interface is the default.with_init BOOLβ switches up the behavior of the"get_set"and"get"interfaces. If the attribute is undefined, the method specified by the"init_method"option gets called and the attribute is set to the return value of that method.
Interfaces
get_setβ makes a get/set method for an enum attribute. When called with an argument, the value of the attribute gets set. If the value is invalid, a fatal error will occur. The current value of the attribute is returned.getβ makes an accessor method for an object attribute that returns the current value of the attribute.setβ makes a mutator method for an object attribute. When called with an argument, the value of the attribute gets set. If the value is invalid, a fatal error will occur. And if you call it with no arguments? Fatal error. Again. π
Example:
package MyDBObject;
our @ISA = qw(Rose::DB::Object);
use Rose::DB::Object::MakeMethods::Generic
(
enum =>
[
type => { values => [ qw(main aux extra) ], default => 'aux' },
stage => { values => [ qw(new std old) ], with_init => 1 },
],
);
sub init_stage { 'new' }
...
$o = MyDBObject->new(...);
print $o->type; # aux
print $o->stage; # new
$o->type('aux'); # set
$o->stage('old'); # set
eval { $o->type('foo') }; # fatal error: invalid value
print $o->type, ' is at stage ', $o->stage; # get
See how stage pulls its starting value out of init_stage β¨ and type just defaults to 'aux' like a good little attribute? And then 'foo' gets absolutely rejected β fatal error, no cap π. That's the enum vibe check working exactly as intended.
integer π’
Makes get/set methods for integer attributes. Numbers only, bestie β this is the whole personality.
Options
default VALUEβ sets what the attribute defaults to when nothing's been assigned yet.hash_key NAMEβ which key inside the hash-based object actually stores this attribute. Defaults to the name of the method, iykyk.init_method NAMEβ the name of the method to call when initializing an undefined attribute. Defaults to the method name with the prefixinit_stuck on the front. Heads up: this option implieswith_initπ«Ά (so you don't have to say it twice).interface NAMEβ picks the interface.get_setis the default.with_init BOOLβ changes up how theget_setandgetinterfaces behave. If the attribute is undefined, the method named byinit_methodgets called, and the attribute gets set to whatever that method hands back. Cute, right? π
Interfaces
get_setβ creates a get/set method for an integer object attribute. Call it with an argument β the attribute gets set. Either way, you get the current value back.getβ creates an accessor for an integer object attribute that returns the current value. That's it. It just tells you things πsetβ creates a mutator for an integer object attribute. Call it with an argument β the attribute gets set. Call it with no arguments β fatal error. Not a vibe, but them's the rules π
Example
package MyDBObject;
our @ISA = qw(Rose::DB::Object);
use Rose::DB::Object::MakeMethods::Generic
(
integer =>
[
code => { default => 99 },
type => { with_init => 1 }
],
);
sub init_type { 123 }
...
$o = MyDBObject->new(...);
print $o->code; # 99
print $o->type; # 123
$o->code(8675309); # set
$o->type(42); # set
So code just defaults to 99 like a chill little default, while type lowkey calls init_type and comes back with 123 π₯. And yes, 8675309 is a legal integer value, don't @ me.
objects_by_key π
Okay bestie, this one's the β¨iconicβ¨ one. It makes get/set methods for an array of Rose::DB::Object-derived objects, fetched based on a key built out of the current object's own attributes. Like, "go find me all the things that match me," basically π¦
Options
class CLASSβ the name of the Rose::DB::Object-derived class of the objects being fetched. Required. No class, no deal πhash_key NAMEβ which key inside the hash-based object stores the fetched objects. Defaults to the name of the method.key_columns HASHREFβ a reference to a hash mapping column names in the current object to the ones in the objects to be fetched. Required. This is literally the whole key situation πmanager_args HASHREFβ a reference to a hash of args passed tomanager_classwhen fetching objects. Ifmanager_classdefaults to Rose::DB::Object::Manager, this argument gets added to themanager_argshash:object_class => CLASS, where CLASS is the value of theclassoption (see above π). And ifmanager_argsincludes asort_byargument, be sure to prefix each column name with the appropriate table name. (Check the synopsis for examples, fr fr.)manager_class CLASSβ the name of the Rose::DB::Object::Manager-derived class used to fetch the objects. Themanager_methodclass method gets called on it. Defaults to Rose::DB::Object::Manager.manager_method NAMEβ the name of the class method to call onmanager_classto fetch the objects. Defaults toget_objects.manager_count_method NAMEβ the name of the class method to call onmanager_classto count the objects. Defaults toget_objects_count.interface NAMEβ picks the interface.get_setis the default.relationship OBJECTβ the Rose::DB::Object::Metadata::Relationship object describing the "key" through which theobjects_by_keyget fetched. Required when you're using theadd_now,add_on_save, andget_set_on_saveinterfaces. Don't skip it π«Άshare_db BOOLβ if true, thedbattribute of the current object is shared with all the fetched objects. Defaults to true.query_args ARRAYREFβ a reference to an array of arguments added to the value of thequeryparameter passed to the call tomanager_class'smanager_methodclass method.
Interfaces
countβ creates a method that attempts to count Rose::DB::Object-derived objects based on a key formed from the current object's attributes, plus any extra parameters you pass to the method call. Note that this counts the objects in the database at the time of the call π β that can absolutely be different from the number of objects attached to the current object or otherwise hanging out in memory. Not the same thing, bestie, don't get it twisted.
Since the objects counted are partially decided by the arguments you pass in, the count is not retained. It's just returned. Every single call counts the specified objects all over again, even if the arguments are identical to last time. No caching, no shortcuts π
If the first argument is a reference to a hash or array, it gets converted to a reference to an array (if necessary) and taken as the value of the query parameter. All arguments get passed on to manager_class's manager_count_method method, augmented by the key formed from the current object's attributes. Query parameters get added to the existing contents of the query parameter. Other parameters replace existing parameters if the existing values are simple scalars, or augment existing parameters if the existing values are references to hashes or arrays.
The count can fail for several reasons π. It won't even be attempted if any of the key attributes in the current object are undefined β instead you get undef (in scalar context) or an empty list (in list context). And if the call to manager_class's manager_count_method returns undef, the behavior is decided by the metadata object's error_mode. If the mode is return, that false value (scalar context) or an empty list (list context) comes back to you.
If the count succeeds, the number is returned. (Zero objects found? The count is 0 β and that's still considered success β¨ slay.)
findβ creates a method that attempts to fetch Rose::DB::Object-derived objects based on a key formed from the current object's attributes, plus any extra parameters passed to the method call. Since the fetched objects are partially determined by the arguments, the list of objects is not retained β it's simply returned. Each call fetches the requested objects all over again, even if the arguments match the previous call π
If the first argument is a reference to a hash or array, it's converted to a reference to an array (if necessary) and taken as the value of the query parameter. All arguments get passed on to manager_class's manager_method method, augmented by the key formed from the current object's attributes. Query parameters get added to the existing contents of the query parameter. Other parameters replace existing parameters when the existing values are simple scalars, or augment existing parameters when the existing values are references to hashes or arrays.
The fetch can fail for several reasons π. It won't even be attempted if any of the key attributes in the current object are undefined β instead, undef (scalar context) or an empty list (list context) comes back. If the call to manager_class's manager_method returns false, the behavior is decided by the metadata object's error_mode. If the mode is return, that false value (scalar context) or an empty list (list context) is returned.
If the fetch succeeds, you get a list (list context) or a reference to the array of objects (scalar context). (Zero objects found? That list or arrayref is just empty. Still a success, bestie π«Ά.)
iteratorβ behaves just likefind, but hands you back an iterator instead of an array or arrayref. Same energy, different delivery π§get_setβ creates a method that attempts to fetch Rose::DB::Object-derived objects based on a key formed from the current object's attributes.
If you pass a single argument of undef, the hash_key used to store the objects gets set to undef. Otherwise, the argument(s) must be a list or a reference to an array containing items in one or more of the following formats:
- An object of type
class. - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
Okay so those last two formats? π
They're how you construct an object of type "class". A single primary key value is only a valid argument format if the "class" in question has a single-column primary key. A hash reference argument must contain sufficient information for the object to be uniquely identified.
The list of objects gets assigned to "hash_key". Quick vibe check: these objects are not added to the database. π¨ Use the get_set_now or get_set_on_save interface to do that.
If called with no arguments and the hash key used to store the list of objects is defined, you get the list (in list context) or a reference to that array (in scalar context) of objects. Otherwise, the objects are fetched.
The fetch may fail for several reasons. The fetch will not even be attempted if any of the key attributes in the current object are undefined. Instead, undef (in scalar context) or an empty list (in list context) will be returned. If the call to manager_class's manager_method method returns false, the behavior is determined by the metadata object's error_mode. If the mode is "return", that false value (in scalar context) or an empty list (in list context) is returned.
If the fetch succeeds, a list (in list context) or a reference to the array of objects (in scalar context) is returned. (If the fetch finds zero objects, the list or array reference will simply be empty. This is still considered success.) β¨
get_set_now
This one creates a method that will attempt to fetch Rose::DB::Object-derived objects based on a key formed from attributes of the current object. It will also save the objects to the database when called with arguments. The objects do not have to already exist in the database; they will be inserted if needed. π₯
If passed a single argument of undef, the list of objects is set to undef, causing it to be reloaded the next time the method is called with no arguments. (Pass a reference to an empty array to cause all of the existing objects to be deleted from the database.) Any pending set_on_save or add_on_save actions are discarded.
Otherwise, the argument(s) must be a list or reference to an array containing items in one or more of the following formats:
- An object of type
"class". - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats will be used to construct an object of type "class". A single primary key value is only a valid argument format if the "class" in question has a single-column primary key. A hash reference argument must contain sufficient information for the object to be uniquely identified.
The list of objects is assigned to "hash_key", the old objects are deleted from the database, and the new ones are added to the database. Any pending set_on_save or add_on_save actions are discarded.
When adding each object, if the object does not already exist in the database, it will be inserted. If the object was previously loaded from or saved to the database, it will be updated. Otherwise, it will be loaded.
The parent object must have been loaded or saved prior to setting the list of objects. If this method is called with arguments before the object has been loaded or saved, a fatal error will occur. π
If called with no arguments and the hash key used to store the list of objects is defined, the list (in list context) or a reference to that array (in scalar context) of objects is returned. Otherwise, the objects are fetched.
The fetch may fail for several reasons. The fetch will not even be attempted if any of the key attributes in the current object are undefined. Instead, undef (in scalar context) or an empty list (in list context) will be returned. If the call to manager_class's manager_method method returns false, the behavior is determined by the metadata object's error_mode. If the mode is "return", that false value (in scalar context) or an empty list (in list context) is returned.
If the fetch succeeds, a list (in list context) or a reference to the array of objects (in scalar context) is returned. (If the fetch finds zero objects, the list or array reference will simply be empty. This is still considered success.) π¦
get_set_on_save
Creates a method that will attempt to fetch Rose::DB::Object-derived objects based on a key formed from attributes of the current object, and will also save the objects to the database when the "parent" object is saved. The objects do not have to already exist in the database; they will be inserted if needed. πΈ
If passed a single argument of undef, the list of objects is set to undef, causing it to be reloaded the next time the method is called with no arguments. (Pass a reference to an empty array to cause all of the existing objects to be deleted from the database when the parent is saved.)
Otherwise, the argument(s) must be a list or reference to an array containing items in one or more of the following formats:
- An object of type
"class". - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats will be used to construct an object of type "class". A single primary key value is only a valid argument format if the "class" in question has a single-column primary key. A hash reference argument must contain sufficient information for the object to be uniquely identified.
The list of objects is assigned to "hash_key". The old objects are scheduled to be deleted from the database and the new ones are scheduled to be added to the database when the parent is saved. Any pending set_on_save or add_on_save actions are discarded.
When adding each object when the parent is saved, if the object does not already exist in the database, it will be inserted. If the object was previously loaded from or saved to the database, it will be updated. Otherwise, it will be loaded.
If called with no arguments and the hash key used to store the list of objects is defined, the list (in list context) or a reference to that array (in scalar context) of objects is returned. Otherwise, the objects are fetched.
The fetch may fail for several reasons. The fetch will not even be attempted if any of the key attributes in the current object are undefined. Instead, undef (in scalar context) or an empty list (in list context) will be returned. If the call to manager_class's manager_method method returns false, the behavior is determined by the metadata object's error_mode. If the mode is "return", that false value (in scalar context) or an empty list (in list context) is returned.
If the fetch succeeds, a list (in list context) or a reference to the array of objects (in scalar context) is returned. (If the fetch finds zero objects, the list or array reference will simply be empty. This is still considered success.) π
add_now
Creates a method that will add to a list of Rose::DB::Object-derived objects that are related to the current object by a key formed from attributes of the current object. The objects do not have to already exist in the database; they will be inserted if needed. β¨
This method returns the list of objects added when called in list context, and the number of objects added when called in scalar context. If one or more objects could not be added, undef (in scalar context) or an empty list (in list context) is returned and the parent object's error attribute is set.
If passed an empty list, the method does nothing and the parent object's error attribute is set.
If passed any arguments, the parent object must have been loaded or saved prior to adding to the list of objects. If this method is called with a non-empty list as an argument before the parent object has been loaded or saved, a fatal error will occur. π«Ά
The argument(s) must be a list or reference to an array containing items in one or more of the following formats:
- An object of type
"class". - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats will be used to construct an object of type "class". A single primary key value is only a valid argument format if the "class" in question has a single-column primary key. A hash reference argument must contain sufficient information for the object to be uniquely identified.
These objects are linked to the parent object (by setting the appropriate key attributes) and then added to the database.
When adding each object, if the object does not already exist in the database, it will be inserted. If the object was previously loaded from or saved to the database, it will be updated. Otherwise, it will be loaded. π
The parent object's list of related objects is then set to undef, which means the related objects get reloaded from the database the next time they're actually needed. Lazy loading, but make it fashion β¨
π add_on_save
Okay bestie, this one creates a method that will add to a list of Rose::DB::Object-derived objects that are related to the current object by a key formed from attributes of the current object. Say that five times fast, I dare you π The objects get added to the database when the parent object is saved. And here's the cute part: the objects do not have to already exist in the database β they'll be inserted if needed. So chill, they'll show up. π
This method returns the list of objects to be added when called in list context, and the number of items to be added when called in scalar context. Context matters, always has, always will π«Ά
If passed an empty list, the method does nothing and the parent object's error attribute is set. So like, rude but fair β it's telling you something's off.
Otherwise, the argument(s) must be a list or reference to an array containing items in one or more of the following formats:
- An object of type
class. π - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats will be used to construct an object of type class. A single primary key value is only a valid argument format if the class in question has a single-column primary key β no exceptions, no cap. A hash reference argument must contain sufficient information for the object to be uniquely identified. Give it what it needs, bestie π₯Ί
These objects are linked to the parent object (by setting the appropriate key attributes, whether or not they're defined in the parent object) and are scheduled to be added to the database when the parent object is saved. They're also added to the parent object's current list of related objects, if the list is defined at the time of the call. Conditional queen π
When adding each object when the parent is saved, if the object does not already exist in the database, it will be inserted. If the object was previously loaded from or saved to the database, it will be updated. Otherwise, it will be loaded. It's giving β¨adaptiveβ¨
Example setup:
# CLASS DB TABLE
# ------- --------
# Program programs
# Bug bugs
package Program;
our @ISA = qw(Rose::DB::Object);
...
# You will almost never call the method-maker directly
# like this. See the Rose::DB::Object::Metadata docs
# for examples of more common usage.
use Rose::DB::Object::MakeMethods::Generic
(
objects_by_key =>
[
find_bugs =>
{
interface => 'find',
class => 'Bug',
key_columns =>
{
# Map Program column names to Bug column names
id => 'program_id',
version => 'version',
},
manager_args => { sort_by => 'date_submitted DESC' },
},
bugs =>
{
interface => '...', # get_set, get_set_now, get_set_on_save
class => 'Bug',
key_columns =>
{
# Map Program column names to Bug column names
id => 'program_id',
version => 'version',
},
manager_args => { sort_by => 'date_submitted DESC' },
query_args => { state => { ne => 'closed' } },
},
add_bugs =>
{
interface => '...', # add_now or add_on_save
class => 'Bug',
key_columns =>
{
# Map Program column names to Bug column names
id => 'program_id',
version => 'version',
},
manager_args => { sort_by => 'date_submitted DESC' },
query_args => { state => { ne => 'closed' } },
},
]
);
...
Example β find interface:
# Read from the programs table
$prog = Program->new(id => 5)->load;
# Read from the bugs table
$bugs = $prog->find_bugs;
# Calls (essentially):
#
# Rose::DB::Object::Manager->get_objects(
# db => $prog->db, # share_db defaults to true
# object_class => 'Bug',
# query =>
# [
# program_id => 5, # value of $prog->id
# version => '3.0', # value of $prog->version
# ],
# sort_by => 'date_submitted DESC');
# Augment query
$bugs = $prog->find_bugs({ state => 'open' });
# Calls (essentially):
#
# Rose::DB::Object::Manager->get_objects(
# db => $prog->db, # share_db defaults to true
# object_class => 'Bug',
# query =>
# [
# program_id => 5, # value of $prog->id
# version => '3.0', # value of $prog->version
# state => 'open',
# ],
# sort_by => 'date_submitted DESC');
...
# Augment query and replace sort_by value
$bugs = $prog->find_bugs(query => [ state => 'defunct' ],
sort_by => 'name');
# Calls (essentially):
#
# Rose::DB::Object::Manager->get_objects(
# db => $prog->db, # share_db defaults to true
# object_class => 'Bug',
# query =>
# [
# program_id => 5, # value of $prog->id
# version => '3.0', # value of $prog->version
# state => 'defunct',
# ],
# sort_by => 'name');
...
Example β get_set interface:
# Read from the programs table
$prog = Program->new(id => 5)->load;
# Read from the bugs table
$bugs = $prog->bugs;
# Calls (essentially):
#
# Rose::DB::Object::Manager->get_objects(
# db => $prog->db, # share_db defaults to true
# object_class => 'Bug',
# query =>
# [
# program_id => 5, # value of $prog->id
# version => '3.0', # value of $prog->version
# state => { ne => 'closed' },
# ],
# sort_by => 'date_submitted DESC');
...
$prog->version($new_version); # Does not hit the db
$prog->bugs(@new_bugs); # Does not hit the db
# @new_bugs can contain any mix of these types:
#
# @new_bugs =
# (
# 123, # primary key value
# { id => 456 }, # method name/value pairs
# Bug->new(id => 789), # object
# );
# Write to the programs table only. The bugs table is not
# updated. See the get_set_now and get_set_on_save method
# types for ways to write to the bugs table.
$prog->save;
Example β get_set_now interface:
# Read from the programs table
$prog = Program->new(id => 5)->load;
# Read from the bugs table
$bugs = $prog->bugs;
$prog->name($new_name); # Does not hit the db
# Writes to the bugs table, deleting existing bugs and
# replacing them with @new_bugs (which must be an array
# of Bug objects, either existing or new)
$prog->bugs(@new_bugs);
# @new_bugs can contain any mix of these types:
#
# @new_bugs =
# (
# 123, # primary key value
# { id => 456 }, # method name/value pairs
# Bug->new(id => 789), # object
# );
# Write to the programs table
$prog->save;
Example β get_set_on_save interface:
# Read from the programs table
$prog = Program->new(id => 5)->load;
# Read from the bugs table
$bugs = $prog->bugs;
$prog->name($new_name); # Does not hit the db
$prog->bugs(@new_bugs); # Does not hit the db
# @new_bugs can contain any mix of these types:
#
# @new_bugs =
# (
# 123, # primary key value
# { id => 456 }, # method name/value pairs
# Bug->new(id => 789), # object
# );
# Write to the programs table and the bugs table, deleting any
# existing bugs and replacing them with @new_bugs (which must be
# an array of Bug objects, either existing or new)
$prog->save;
Example β add_now interface:
# Read from the programs table
$prog = Program->new(id => 5)->load;
# Read from the bugs table
$bugs = $prog->bugs;
$prog->name($new_name); # Does not hit the db
# Writes to the bugs table, adding @new_bugs to the current
# list of bugs for this program
$prog->add_bugs(@new_bugs);
# @new_bugs can contain any mix of these types:
#
# @new_bugs =
# (
# 123, # primary key value
# { id => 456 }, # method name/value pairs
# Bug->new(id => 789), # object
# );
# Read from the bugs table, getting the full list of bugs,
# including the ones that were added above.
$bugs = $prog->bugs;
# Write to the programs table only
$prog->save;
Example β add_on_save interface:
# Read from the programs table
$prog = Program->new(id => 5)->load;
# Read from the bugs table
$bugs = $prog->bugs;
$prog->name($new_name); # Does not hit the db
$prog->add_bugs(@new_bugs); # Does not hit the db
$prog->add_bugs(@more_bugs); # Does not hit the db
# @new_bugs and @more_bugs can contain any mix of these types:
#
# @new_bugs =
# (
# 123, # primary key value
# { id => 456 }, # method name/value pairs
# Bug->new(id => 789), # object
# );
# Write to the programs table and the bugs table, adding
# @new_bugs to the current list of bugs for this program
$prog->save;
okay so that comment block up there is literally showing you that @new_bugs and @more_bugs can be any mix of those three things β a plain primary key value, a hashref of method name/value pairs, or a whole object. Mix 'em, match 'em, whatever, it's fine π
And then $prog->save writes to the programs table and the bugs table, adding @new_bugs onto the current list of bugs for this program. iconic.
objects_by_map πΊοΈβ¨
This one builds you methods that fetch Rose::DB::Object-derived objects through an intermediate Rose::DB::Object-derived class β like, a class that maps between two other Rose::DB::Object-derived classes. Bestie, it's giving matchmaker energy fr fr.
For a more complete example of this type of method in action, go peek at the Rose::DB::Object::Metadata::Relationship::ManyToMany documentation. π«Ά
Options π
hash_keyNAME β the key inside the hash-based object that's used to store the fetched objects. Defaults to the name of the method. β¨interfaceNAME β picks the interface. Theget_setinterface is the default, no cap.manager_argsHASHREF β a reference to a hash of arguments that get passed to themanager_classwhen fetching objects. β οΈ Heads up: ifmanager_argsincludes asort_byargument, be sure to prefix each column name with the appropriate table name. (The synopsis has examples, go look.)manager_classCLASS β the name of the Rose::DB::Object::Manager-derived class that themap_classwill use to fetch records. Defaults toRose::DB::Object::Manager.manager_methodNAME β the name of the class method to call onmanager_classto fetch the objects. Defaults toget_objects.manager_count_methodNAME β the name of the class method to call onmanager_classto count the objects. Defaults toget_objects_count.map_classCLASS β the name of the Rose::DB::Object-derived class that maps between the other two Rose::DB::Object-derived classes. This class must have a foreign key and/or "many to one" relationship for each of the two tables that it maps between. π¦map_fromNAME β the name of the "many to one" relationship or foreign key inmap_classthat points to the object of the class that this relationship exists in. You only need to set this ifmap_classhas more than one foreign key or "many to one" relationship pointing to one of the classes that it maps between.map_toNAME β the name of the "many to one" relationship or foreign key inmap_classthat points to the "foreign" object to be fetched. Again, you only need to set this ifmap_classhas more than one foreign key or "many to one" relationship pointing to one of the classes that it maps between.relationshipOBJECT β theRose::DB::Object::Metadata::Relationshipobject that describes the "key" through which theobjects_by_keyare fetched. This option is required. π¨share_dbBOOL β if it's true, the db attribute of the current object gets shared with all of the objects that get fetched. Defaults to true.query_argsARRAYREF β a reference to an array of arguments that get added to the value of thequeryparameter passed to the call tomanager_class'smanager_methodclass method. π
Interfaces π
count π’
Creates a method that'll attempt to count Rose::DB::Object-derived objects related to the current object through the map_class, plus any extra parameters you pass into the method call. Lowkey important: this method counts the objects in the database at the time of the call, which may be a totally different number than the objects attached to the current object or otherwise chillin' in memory. π
And since the objects counted are partly determined by the arguments you pass in, the count is not retained β it's just returned straight up. Every single call counts the specified objects again, even if your arguments are identical to the previous call. no caching, no shortcuts, periodt.
If the first argument is a reference to a hash or an array, it gets converted to a reference to an array (if necessary) and taken as the value of the query parameter. All arguments get passed on to the manager_class's manager_count_method method, augmented by the mapping to the current object. Query parameters are added to whatever's already in the query parameter. Other parameters replace existing parameters if the existing values are simple scalars, or augment existing parameters if the existing values are references to hashes or arrays. π§
The count can fail for a bunch of reasons. The count won't even be attempted if any of the key attributes in the current object are undefined β instead you get undef (in scalar context) or an empty list (in list context). If the call to manager_class's manager_count_method method returns undef, the behavior is decided by the metadata object's error_mode. If the mode is return, that false value (in scalar context) or an empty list (in list context) is what you get back. π
If the count succeeds, the number is returned. (If the count finds zero objects, the count will be 0. That still counts as success, bestie β zero is a valid answer. β¨)
find π
Creates a method that'll attempt to fetch Rose::DB::Object-derived objects related to the current object through the map_class, plus any extra parameters passed to the method call. Since the objects fetched are partly determined by the arguments, the list of objects is not retained β it's simply returned. Each call fetches the requested objects again, even if the arguments are the same as last time. π
If the first argument is a reference to a hash or array, it gets converted to a reference to an array (if necessary) and taken as the value of the query parameter. All arguments get passed on to the manager_class's manager_method method, augmented by the mapping to the current object. Query parameters are added to the existing contents of the query parameter. Other parameters replace existing parameters if those existing values are simple scalars, or augment existing parameters if the existing values are references to hashes or arrays. πΈ
The fetch can fail for several reasons. It won't even be attempted if any of the key attributes in the current object are undefined β instead you get undef (in scalar context) or an empty list (in list context). If the call to manager_class's manager_method method returns false, the behavior is determined by the metadata object's error_mode. If the mode is return, that false value (in scalar context) or an empty list (in list context) is returned.
If the fetch succeeds, you get a list (in list context) or a reference to the array of objects (in scalar context). (And if the fetch finds zero objects, the list or array reference will simply be empty β still considered success. π)
iterator π
Behaves just like find but returns an iterator rather than an array or arrayref. That's it, that's the whole vibe. iykyk.
get_set π
Creates a method that'll attempt to fetch Rose::DB::Object-derived objects related to the current object through the map_class.
If you pass it a single argument of undef, the hash_key used to store the objects gets set to undef. Otherwise, the argument(s) must be a list or reference to an array containing items in one or more of these formats:
- An object of type
class. - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats get used to construct an object of type class. A single primary key value is only a valid argument format if the class in question has a single-column primary key β no cap. A hash reference argument has to contain sufficient information for the object to be uniquely identified. π₯
The list of objects is assigned to hash_key. β οΈ But note: these objects are not added to the database. Use the get_set_now or get_set_on_save interface if you actually want that.
If called with no arguments and the hash key used to store the list of objects is defined, you get the list (in list context) or a reference to that array of objects (in scalar context) back. Otherwise, the objects get fetched. π¦
When fetching objects from the database, if the call to manager_class's manager_method method returns false, you get that false value (in scalar context) or an empty list (in list context).
If the fetch succeeds, you get a list (in list context) or a reference to the array of objects (in scalar context). (If the fetch finds zero objects, the list or array reference will simply be empty β yes, this is still considered success, we've been over this π .)
π
get_set_now
Okay so this one creates a method that tries to fetch Rose::DB::Object-derived objects related to the current object through the map_class β and it'll also save objects to the database and map them to the parent object whenever you call it with arguments. And listen: those objects don't have to already exist in the database. If they're needed, they get inserted. no cap π«Ά
If you pass a single argument of undef, the list of objects is set to undef, which means it gets reloaded the next time the method is called with no arguments. (Oh and β pass a reference to an empty array if you want all the existing objects to be "unmapped", meaning their entries in the mapping table get deleted from the database. π) Any pending set_on_save or add_on_save actions are discarded.
Otherwise the argument(s) must be a list or a reference to an array containing items in one or more of these formats:
- An object of type
class. - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats get used to construct an object of type class. Heads up tho: a single primary key value is only a valid argument format if the class in question has a single-column primary key. And a hash reference argument must contain sufficient information for the object to be uniquely identified. iykyk β¨
The list of object is assigned to hash_key, the old entries are deleted from the mapping table in the database, and the new objects are added to the database, along with their corresponding mapping entries. Any pending set_on_save or add_on_save actions are discarded.
When adding each object, if the object doesn't already exist in the database, it will be inserted. If the object was previously loaded from or saved to the database, it will be updated. Otherwise, it will be loaded.
π¨ Real talk: the parent object must have been loaded or saved prior to setting the list of objects. If this method is called with arguments before the object has been loaded or saved, a fatal error will occur. Like, actual death. π
If called with no arguments and the hash key used to store the list of objects is defined, the list (in list context) or a reference to that array (in scalar context) of objects is returned. Otherwise, the objects are fetched.
When fetching, if the call to manager_class's manager_method method returns false, that false value (in scalar context) or an empty list (in list context) is returned.
If the fetch succeeds, a list (in list context) or a reference to the array of objects (in scalar context) is returned. (And if the fetch finds zero objects, the list or array reference will simply be empty β that's still considered success, bestie. πΈ)
π
get_set_on_save
Same vibe, slight plot twist: this creates a method that tries to fetch Rose::DB::Object-derived objects related to the current object through the map_class, and will also save objects to the database and map them to the parent object when the "parent" object is saved. The objects don't have to already exist in the database β they'll be inserted if needed. π¦
If passed a single argument of undef, the list of objects is set to undef, causing it to be reloaded the next time the method is called with no arguments. (Pass a reference to an empty array to cause all of the existing objects to be "unmapped" β that is, to have their entries in the mapping table deleted from the database.) Any pending set_on_save or add_on_save actions are discarded.
Otherwise, the argument(s) must be a list or reference to an array containing items in one or more of the following formats:
- An object of type
class. - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats will be used to construct an object of type class. A single primary key value is only a valid argument format if the class in question has a single-column primary key. A hash reference argument must contain sufficient information for the object to be uniquely identified.
The list of object is assigned to hash_key. The mapping table records that mapped the old objects to the parent object are scheduled to be deleted from the database and new ones are scheduled to be added to the database when the parent is saved. Any previously pending set_on_save or add_on_save actions are discarded.
When adding each object when the parent is saved, if the object doesn't already exist in the database, it will be inserted. If the object was previously loaded from or saved to the database, it will be updated. Otherwise, it will be loaded. π₯
If called with no arguments and the hash key used to store the list of objects is defined, the list (in list context) or a reference to that array (in scalar context) of objects is returned. Otherwise, the objects are fetched.
When fetching, if the call to manager_class's manager_method method returns false, that false value (in scalar context) or an empty list (in list context) is returned.
If the fetch succeeds, a list (in list context) or a reference to the array of objects (in scalar context) is returned. (If the fetch finds zero objects, the list or array reference will simply be empty. This is still considered success. π)
β¨ add_now
Creates a method that adds to a list of Rose::DB::Object-derived objects that are related to the current object through the map_class, and will also save objects to the database and map them to the parent object. The objects don't have to already exist in the database; they'll be inserted if needed. π
This method returns the list of objects added when called in list context, and the number of objects added when called in scalar context. If one or more objects could not be added, undef (in scalar context) or an empty list (in list context) is returned and the parent object's error attribute is set. π
If passed an empty list, the method does nothing and the parent object's error attribute is set. Like, it just sits there. π
π¨ If passed any arguments, the parent object must have been loaded or saved prior to adding to the list of objects. If this method is called with a non-empty list as an argument before the parent object has been loaded or saved, a fatal error will occur.
The argument(s) must be a list or reference to an array containing items in one or more of the following formats:
- An object of type
class. - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats will be used to construct an object of type class. A single primary key value is only a valid argument format if the class in question has a single-column primary key. A hash reference argument must contain sufficient information for the object to be uniquely identified. π
The parent object's list of related objects is then set to undef, causing the related objects to be reloaded from the database the next time they're needed.
β¨ add_on_save
Creates a method that adds to a list of Rose::DB::Object-derived objects that are related to the current object through the map_class, and will also save objects to the database and map them to the parent object when the "parent" object is saved. The objects and map records will be added to the database when the parent object is saved. The objects don't have to already exist in the database; they'll be inserted if needed. π
This method returns the list of objects to be added when called in list context, and the number of items to be added when called in scalar context.
If passed an empty list, the method does nothing and the parent object's error attribute is set.
Otherwise, the argument(s) must be a list or reference to an array containing items in one or more of the following formats:
- An object of type
class. - A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter two formats will be used to construct an object of type class. A single primary key value is only a valid argument format if the class in question has a single-column primary key. A hash reference argument must contain sufficient information for the object to be uniquely identified. β
These objects are scheduled to be added to the database and mapped to the parent object when the parent object is saved. They're also added to the parent object's current list of related objects β but only if that list is defined at the time of the call. π§
For a complete example of this method type in action, see the Rose::DB::Object::Metadata::Relationship::ManyToMany documentation. fr fr, go read it, it slays. π
π
object_by_key π
Okay so this one gives you get/set methods for a single Rose::DB::Object-derived object, and it gets loaded by a primary key built out of the current object's own attributes. Cute, right? Let's get into it.
Options π
class CLASSβ the name of the Rose::DB::Object-derived class of the object you want loaded. This one is required, no skipping it bestie.foreign_key OBJECTβ theRose::DB::Object::Metadata::ForeignKeyobject that describes the "key" yourobject_by_keygets fetched through. This (or therelationshipparam) is required when you're using thedelete_now,delete_on_save, andget_set_on_saveinterfaces.hash_key NAMEβ which key inside the hash-based object holds the object. Defaults to the name of the method. β¨if_not_found CONSEQUENCEβ this decides what goes down whenkey_columnshave defined values, but the foreign object they point to justβ¦ doesn't exist. ValidCONSEQUENCEvalues:fatal, which throws an exception when the foreign object isn't found, andok, which just makes the relevant method(s) return undef. Default isfatal. πkey_columns HASHREFβ a reference to a hash mapping column names in the current object to the ones in the primary key of the object being loaded. Required, periodt.interface NAMEβ pick your interface. Default isget_set.relationship OBJECTβ theRose::DB::Object::Metadata::Relationship-derived object describing the relationship the object gets fetched through. This (or theforeign_keyparam) is required when you're using thedelete_now,delete_on_save, andget_set_on_saveinterfaces.referential_integrity BOOLβ if true, then calling a method in one of theget*interfaces with no related object found = fatal error. Default comes from thereferential_integrityattribute of theforeign_keyobject, or true if you didn't pass aforeign_keyparam at all. π«Ά
Heads up: this param conflicts with the required param. Pass one of the two, not both. Fr fr.
required BOOLβ if true, then calling a method in one of theget*interfaces and finding no related object = fatal error. Default comes from therequiredattribute of therelationshipobject, or true if you didn't pass arelationshipparam at all.
And yes, this one conflicts with referential_integrity. Only one of the two, bestie. π
share_db BOOLβ if true, thedbattribute of the current object gets shared with the loaded object. Defaults to true. π
Interfaces π¦
delete_nowβ deletes a Rose::DB::Object-derived object from the database, keyed off a primary key formed from the current object's attributes. Ifreferential_integrityorrequiredis true, then the "parent" object has every attribute that refers to the "foreign" object set to null (except any columns that are also part of the primary key), and it gets saved into the database. This has to happen first, because a database that enforces referential integrity will not let a row be deleted while it's still referenced by a foreign key in another table. π₯
Any previously pending get_set_on_save action is discarded.
The whole process runs inside a transaction if the database supports it. If you're not already in a transaction, a new one gets started, then committed on success and rolled back on failure.
Returns true if the foreign object was deleted successfully or didn't exist in the database, false if any of the keys referring to the foreign object were undef, and triggers the normal Rose::DB::Object error handling for any other kind of failure. π
delete_on_saveβ deletes a Rose::DB::Object-derived object from the database when the "parent" object is saved, keyed off a primary key formed from the current object's attributes. Ifreferential_integrityorrequiredis true, then the "parent" object has all its attributes that refer to the "foreign" object set to null immediately (except any columns that are also part of the primary key) β but the actual delete doesn't happen until the parent is saved. β
Any previously pending get_set_on_save action is discarded.
Same transaction situation as above: the whole thing runs in a transaction if the database supports it. If you're not currently in a transaction, a new one is started, then committed on success and rolled back on failure.
Returns true if the foreign object was deleted successfully or didn't exist in the database, false if any of the keys referring to the foreign object were undef, and triggers the normal Rose::DB::Object error handling for any other kind of failure. π
get_setβ creates a method that tries to create and load a Rose::DB::Object-derived object based on a primary key formed from attributes of the current object.
If you pass it a single argument of undef, the hash_key used to store the object is set to undef. If referential_integrity or required is true, then the columns that participate in the key are set to undef too. (If any key column is part of the primary key, though, it is not set to undef.) Otherwise, the argument has to be one of these:
- An object of type
class - A list of method name/value pairs
- A reference to a hash containing method name/value pairs
- A single scalar primary key value
The latter three argument types get used to construct an object of type class. A single primary key value is only valid if the class in question has a single-column primary key. And a hash reference argument has to contain enough info for the object to be uniquely identified, iykyk. β¨
The object gets assigned to hash_key after having its key_columns set to their corresponding values in the current object.
If you call it with no arguments and the hash_key used to store the object is defined, the object gets returned. Otherwise, it's created and loaded. π
The load can fail for several reasons. The load won't even be attempted if any of the key attributes in the current object are undefined β instead, you just get undef back.
If the call to the newly created object's load method returns false, then the normal Rose::DB::Object error handling is triggered. The false value returned by that load call gets returned (assuming no exception was raised).
If the load succeeds, the object is returned. Slay. π
get_set_nowβ creates a method that tries to create and load a Rose::DB::Object-derived object based on a primary key formed from attributes of the current object, and also saves the object to the database when called with an appropriate object as an argument. πΈ
If you pass it a single argument of undef, the hash_key used to store the object is set to undef. If referential_integrity or required is true, then the columns that participate in the key are set to undef too. (If any key column is part of the primary key, though, it is not set to undef.) Otherwise, the argument has to be one of these:
- An object of type
class - A list of method name/value pairs
- A reference to a hash containing method name/value pairs
- A single scalar primary key value
The latter three argument types get used to construct an object of type class. A single primary key value is only a valid argument format if the class in question has a single-column primary key. A hash reference argument has to contain enough info for the object to be uniquely identified.
The object gets assigned to hash_key after having its key_columns set to their corresponding values in the current object. Then it's immediately saved to the database. β‘
If the object doesn't already exist in the database, it gets inserted. If it was previously loaded from or saved to the database, it gets updated. Otherwise, it gets loaded.
Important: the parent object must have been loaded or saved before you set the list of objects. If this method is called with arguments before the object has been loaded or saved, you get a fatal error. π
If you call it with no arguments and the hash_key used to store the object is defined, the object is returned. Otherwise, it's created and loaded.
The load can fail for several reasons. The load won't even be attempted if any of the key attributes in the current object are undefined β instead, undef is returned.
If the call to the newly created object's load method returns false, then the normal Rose::DB::Object error handling is triggered. The false value returned by the load call is returned (assuming no exception was raised).
If the load succeeds, the object is returned. π
π
get_set_on_save
Okay bestie, so get_set_on_save is the delayed-gratification version of object-by-key π
It creates a method that tries to create and load a Rose::DB::Object-derived object based on a primary key formed from attributes of the current object, and then saves that object when the "parent" object is saved.
If you pass it a single argument of undef, the hash_key used to store the object is set to undef. If referential_integrity or required is true, then the columns that participate in the key are set to undef. (If any key column is part of the primary key, though, it is not set to undef.) Otherwise, the argument has to be one of these:
- An object of type
class - A list of method name/value pairs.
- A reference to a hash containing method name/value pairs.
- A single scalar primary key value.
The latter three argument types will be used to construct an object of type class. A single primary key value is only a valid argument format if the class in question has a single-column primary key. A hash reference argument must contain sufficient information for the object to be uniquely identified. iykyk β¨
The object is assigned to hash_key after having its key_columns set to their corresponding values in the current object. The object will be saved into the database when the "parent" object is saved. Any previously pending get_set_on_save action is discarded.
If the object doesn't already exist in the database, it will be inserted. If the object was previously loaded from or saved to the database, it will be updated. Otherwise, it will be loaded.
If called with no arguments and the hash_key used to store the object is defined, the object is returned. Otherwise, the object is created and loaded from the database.
The load may fail for several reasons. The load will not even be attempted if any of the key attributes in the current object are undefined. Instead, undef will be returned.
If the call to the newly created object's load method returns false, then the normal Rose::DB::Object error handling is triggered. The false value returned by the call to the load method is returned (assuming no exception was raised).
If the load succeeds, the object is returned. slay π
Example setup:
# CLASS DB TABLE
# ------- --------
# Product products
# Category categories
package Product;
our @ISA = qw(Rose::DB::Object);
...
# You will almost never call the method-maker directly
# like this. See the Rose::DB::Object::Metadata docs
# for examples of more common usage.
use Rose::DB::Object::MakeMethods::Generic
(
object_by_key =>
[
category =>
{
interface => 'get_set',
class => 'Category',
key_columns =>
{
# Map Product column names to Category column names
category_id => 'id',
},
},
]
);
...
Example - get_set interface:
$product = Product->new(id => 5, category_id => 99);
# Read from the categories table
$category = $product->category;
# $product->category call is roughly equivalent to:
#
# $cat = Category->new(id => $product->category_id
# db => $prog->db);
#
# $ret = $cat->load;
# return $ret unless($ret);
# return $cat;
# Does not write to the db
$product->category(Category->new(...));
$product->save; # writes to products table only
Example - get_set_now interface:
# Read from the products table
$product = Product->new(id => 5)->load;
# Read from the categories table
$category = $product->category;
# Write to the categories table:
# (all possible argument formats show)
# Object argument
$product->category(Category->new(...));
# Primary key value
$product->category(123);
# Method name/value pairs in a hashref
$product->category(id => 123);
# Method name/value pairs in a hashref
$product->category({ id => 123 });
# Write to the products table
$product->save;
Example - get_set_on_save interface:
# Read from the products table
$product = Product->new(id => 5)->load;
# Read from the categories table
$category = $product->category;
# These do not write to the db:
# Object argument
$product->category(Category->new(...));
# Primary key value
$product->category(123);
# Method name/value pairs in a hashref
$product->category(id => 123);
# Method name/value pairs in a hashref
$product->category({ id => 123 });
# Write to both the products and categories tables
$product->save;
Example - delete_now interface:
# Read from the products table
$product = Product->new(id => 5)->load;
# Write to both the categories and products tables
$product->delete_category();
Example - delete_on_save interface:
# Read from the products table
$product = Product->new(id => 5)->load;
# Does not write to the db
$product->delete_category();
# Write to both the products and categories tables
$product->save;
β¨ scalar
scalar creates get/set methods for scalar attributes. Main character energy, honestly π
Options
default VALUEβ Determines the default value of the attribute.check_in ARRAYREFβ A reference to an array of valid values. When setting the attribute, if the new value is not equal (string comparison) to one of the valid values, a fatal error will occur.hash_key NAMEβ The key inside the hash-based object to use for the storage of this attribute. Defaults to the name of the method.init_method NAMEβ The name of the method to call when initializing the value of an undefined attribute. Defaults to the method name with the prefixinit_added. This option implieswith_init.interface NAMEβ Choose the interface. Theget_setinterface is the default.length INTβ The maximum number of characters in the string.overflow BEHAVIORβ Determines the behavior when the value is greater than the number of characters specified by thelengthoption. Valid values for BEHAVIOR are:fatalβ Throw an exception.truncateβ Truncate the value to the correct length.warnβ Print a warning message.
with_init BOOLβ Modifies the behavior of theget_setandgetinterfaces. If the attribute is undefined, the method specified by theinit_methodoption is called and the attribute is set to the return value of that method.
Interfaces
get_setβ Creates a get/set method for an object attribute. When called with an argument, the value of the attribute is set. The current value of the attribute is returned.getβ Creates an accessor method for an object attribute that returns the current value of the attribute.setβ Creates a mutator method for an object attribute. When called with an argument, the value of the attribute is set. If called with no arguments, a fatal error will occur.
Example:
package MyDBObject;
our @ISA = qw(Rose::DB::Object);
use Rose::DB::Object::MakeMethods::Generic
(
scalar =>
[
name => { default => 'Joe' },
type =>
{
with_init => 1,
check_in => [ qw(AA AAA C D) ],
}
set_type =>
{
check_in => [ qw(AA AAA C D) ],
}
],
);
sub init_type { 'C' }
...
$o = MyDBObject->new(...);
print $o->name; # Joe
print $o->type; # C
$o->name('Bob'); # set
$o->type('AA'); # set
eval { $o->type('foo') }; # fatal error: invalid value
print $o->name, ' is ', $o->type; # get
πΈ set
set creates get/set methods for "set" attributes. A "set" column in a database table contains an unordered group of values. Not all databases support a "set" column type. Check the Rose::DB documentation for your database type. fr fr π«Ά
Options
default ARRAYREFβ Determines the default value of the attribute. The value should be a reference to an array.hash_key NAMEβ The key inside the hash-based object to use for the storage of this attribute. Defaults to the name of the method.interface NAMEβ Choose the interface. The default isget_set.values ARRAYREFβ A reference to an array of valid values for the set. If present, attempting to use an invalid value will cause a fatal error.
Interfaces
get_setβ Creates a get/set method for a"set"object attribute. A"set"column in a database table contains an unordered group of values. On the Perl side of the fence, an ordered list (an array) is used to store the values, but keep in mind that the order is not significant, nor is it guaranteed to be preserved.
When setting the attribute, the value is passed through the parse_set method of the object's db attribute.
When you're saving to the database and the attribute value is defined, the method runs that value through the format_set method of the object's db attribute before returning it. π
When you're not saving to the database, the method hands you the set as a list in list context, or as a reference to the array in scalar context. Simple, iconic.
get
get creates an accessor method for a set object attribute. A set column in a database table is an unordered group of values. On the Perl side of the fence, an ordered list (an array) is used to store the values, but keep in mind that the order is not significant, nor is it guaranteed to be preserved. π«Ά
When saving to the database, if the attribute value is defined, the method passes the attribute value through the format_set method of the object's db attribute before returning it.
When not saving to the database, the method returns the set as a list in list context, or as a reference to the array in scalar context.
set
set creates a mutator method for a set object attribute. A set column in a database table contains an unordered group of values. On the Perl side of the fence, an ordered list (an array) is used to store the values, but keep in mind that the order is not significant, nor is it guaranteed to be preserved. β¨
When setting the attribute, the value is passed through the parse_set method of the object's db attribute.
When saving to the database, if the attribute value is defined, the method passes the attribute value through the format_set method of the object's db attribute before returning it.
When not saving to the database, the method returns the set as a list in list context, or as a reference to the array in scalar context.
Example:
package Person;
our @ISA = qw(Rose::DB::Object);
...
use Rose::DB::Object::MakeMethods::Generic
(
set =>
[
'nicknames',
'set_nicks' => { interface => 'set', hash_key => 'nicknames' },
'parts' => { default => [ qw(arms legs) ] },
],
);
...
@parts = $person->parts; # ('arms', 'legs')
$parts = $person->parts; # [ 'arms', 'legs' ]
$person->nicknames('Jack', 'Gimpy'); # set with list
$person->nicknames([ 'Slim', 'Gip' ]); # set with array ref
$person->set_nicks('Jack', 'Gimpy'); # set with list
$person->set_nicks([ 'Slim', 'Gip' ]); # set with array ref
varchar
Creates get/set methods for variable-length character string attributes. π
Options
defaultVALUE β determines the default value of the attribute.hash_keyNAME β the key inside the hash-based object to use for the storage of this attribute. Defaults to the name of the method.init_methodNAME β the name of the method to call when initializing the value of an undefined attribute. Defaults to the method name with the prefixinit_added. This option implieswith_init.interfaceNAME β choose the interface. Theget_setinterface is the default.lengthINT β the maximum number of characters in the string.overflowBEHAVIOR β determines the behavior when the value is greater than the number of characters specified by thelengthoption. Valid values for BEHAVIOR are:fatalβ throw an exception.truncateβ truncate the value to the correct length.warnβ print a warning message.
with_initBOOL β modifies the behavior of theget_setandgetinterfaces. If the attribute is undefined, the method specified by theinit_methodoption is called and the attribute is set to the return value of that method.
Interfaces
get_setβ creates a get/set accessor method for a fixed-length character string attribute. When setting, any strings longer thanlengthwill be truncated. Iflengthis omitted, the string will be left unmodified.
Example:
package MyDBObject;
our @ISA = qw(Rose::DB::Object);
use Rose::DB::Object::MakeMethods::Generic
(
varchar =>
[
'name' => { length => 3 },
],
);
...
$o->name('John'); # truncates on set
print $o->name; # 'Joh'
π 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.
Okay bestie, that's the whole page! This little icon came from Perl v5.40.1, dated 2025-08-21, and it's the Rose::...eneric(3pm) footer energy. Mwah πβ¨
π¦ where this page comes from
- ubuntu resolute: librose-db-object-perl 1:0.822-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: librose-db-object-perl 1:0.822-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms