DBIx-NoSQL-Store-Manager
view release on metacpan or search on metacpan
lib/DBIx/NoSQL/Store/Manager/StoreModel.pm view on Meta::CPAN
1213141516171819202122232425262728293031323334353637383940414243444546474849has
store_model
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
required
=> 1,
predicate
=>
'has_store_model'
,
);
has
cascade_model
=> (
is
=>
'ro'
,
isa
=>
'Bool'
,
default
=>
sub
{ 0 },
);
has
cascade_save
=> (
is
=>
'ro'
,
isa
=>
'Bool'
,
lazy
=> 1,
default
=>
sub
{
$_
[0]->cascade_model },
);
has
cascade_delete
=> (
is
=>
'ro'
,
isa
=>
'Bool'
,
lazy
=> 1,
default
=>
sub
{
$_
[0]->cascade_model },
);
before
_process_options
=>
sub
(
$meta
,
$name
,
$options
) {
my
$type
= InstanceOf[
$options
->{store_model } ] | Str | HashRef;
if
(
grep
{
$_
eq
'Moose::Meta::Attribute::Native::Trait::Array'
} @{
$options
->{traits} || [] } ) {
$type
=
'ArrayRef'
;
}
$options
->{isa} ||=
$type
;
lib/DBIx/NoSQL/Store/Manager/StoreModel.pm view on Meta::CPAN
717273747576777879808182838485868788899091my
$array_context
=
grep
{
$_
eq
'Moose::Meta::Attribute::Native::Trait::Array'
} @{
$attr
->applied_traits };
my
$reader
=
$attr
->get_read_method;
# class that has the attribute
my
$main_class
=
$attr
->associated_class;
$main_class
->add_before_method_modifier(
delete
=>
sub
(
$self
, @) {
my
$obj
=
$self
->
$reader
or
return
;
$_
->
delete
for
$array_context
?
@$obj
:
$obj
;
})
if
$attr
->cascade_delete;
$main_class
->add_before_method_modifier(
$attr
->
get_read_method
=>
sub
(
$self
,
@rest
) {
return
if
@rest
;
my
$value
=
$attr
->get_value(
$self
);
return
unless
grep
{
defined
$_
and not blessed
$_
}
$array_context
?
@$value
:
$value
;
if
(
$array_context
) {
$attr
->set_raw_value(
$self
, [
map
{
$attr
->_expand_to_object(
$_
,
$self
) }
@$value
] );
lib/DBIx/NoSQL/Store/Manager/StoreModel.pm view on Meta::CPAN
100101102103104105106107108109110111112113114115116117118119120121122123124125
my
$packed
=
$orig
->(
$self
);
my
$val
=
$self
->
$reader
;
if
(
$val
) {
$packed
->{
$attr
->name } =
$array_context
? [
map
{
$_
->store_key }
@$val
] :
$val
->store_key;
}
return
$packed
;
} );
if
(
$attr
->cascade_save ) {
$main_class
->add_before_method_modifier(
'save'
=>
sub
(
$self
,
$store
=
undef
) {
# TODO bug if we remove the value altogether
my
$value
=
$self
->
$reader
or
return
;
if
(
$attr
->cascade_delete ) {
my
$priors
=
eval
{
$self
->store_db->get(
$self
->store_model,
$self
->store_key )->
$reader
};
if
(
$array_context
) {
my
%priors
=
map
{
$_
->
store_key
=>
$_
}
@$priors
;
for
(
@$value
) {
delete
$priors
{
$_
->store_key };
}
$_
->
delete
for
values
%priors
;
}
else
{
lib/DBIx/NoSQL/Store/Manager/StoreModel.pm view on Meta::CPAN
154155156157158159160161162163164165166167168169170171172173174175version 1.0.0
=head1 SYNOPSIS
package Blog::Model::Entry;
has author => (
traits => [ 'StoreModel' ],
store_model => 'Blog::Model::Author',
cascade_save => 1,
cascade_delete => 0,
is => 'rw',
);
=head1 DESCRIPTION
I<DBIx::NoSQL::Store::Manager::StoreModel> (also aliased to I<StoreModel>)
This trait ties the value of the attribute to a model of the store.
The value of the attribute can be set via either a model object, a hashref, or
lib/DBIx/NoSQL/Store/Manager/StoreModel.pm view on Meta::CPAN
196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234a collection of objects. The same logic applies as above, only wrapped in an arrayref.
=head1 ATTRIBUTES
=head2 store_model => $model_class
Required. Takes in the model associated with the target attribute.
Will automatically populate the C<isa> attribute to
C<$model_class|Str_HashRef>.
=head2 cascade_model => $boolean
Sets the default of C<cascade_save> and C<cascade_delete>.
Defaults to C<false>.
=head2 cascade_save => $boolean
If C<true> the object associated with the attribute is automatically saved
to the store when the main object is C<save()>d.
=head2 cascade_delete => $boolean
If C<true>, deletes the attribute object (if there is any)
from the store when the main object is C<delete()>d.
If both C<cascade_delete> and C<cascade_save> are C<true>,
then when saving the main object, if the attribute object has been
modified, its previous value will be deleted from the store.
# assuming the author attribute has `cascade_model => 1`...
my $blog_entry = $store->create( 'Entry',
author => Blog::Model::Author->new(
name => 'yanick',
bio => 'necrohacker',
),
);
# store now has yanick as an author
t/lib/Blog/Model/Entry2.pm view on Meta::CPAN
89101112131415161718192021222324252627282930313233with
'https://metacpan.org/pod/DBIx::NoSQL::Store::Manager::Model">DBIx::NoSQL::Store::Manager::Model'
;
has
url
=> (
traits
=> [
'StoreKey'
],
is
=>
'ro'
,
required
=> 1,
);
has
author
=> (
traits
=> [
'StoreModel'
],
cascade_model
=> 1,
store_model
=>
'Blog::Model::Author'
,
is
=>
'rw'
,
);
has
tags
=> (
traits
=> [
'Array'
,
'StoreModel'
],
cascade_save
=> 1,
store_model
=>
'Blog::Model::Tag'
,
is
=>
'ro'
,
default
=>
sub
{ [] },
);
__PACKAGE__->meta->make_immutable;
1;
t/model-attribute.t view on Meta::CPAN
18192021222324252627282930313233343536373839404142434445464748495051525354555657cmp_deeply
$entry
->
pack
=> superhashof({
__CLASS__
=>
'Blog::Model::Entry'
,
url
=>
'/first'
,
author
=>
'yanick'
,
});
is
$store
->create(
'Entry'
,
url
=>
'/first'
,
author
=>
'yanick'
)->author->
bio
=>
'necrohacker'
,
'expansion happens'
;
subtest
'cascade_save'
=>
sub
{
$store
->create(
Entry
=> (
url
=>
'/second'
,
author
=> Blog::Model::Author->new(
name
=>
'bob'
,
),
));
ok !
$store
->get(
'Author'
=>
'bob'
),
"author is not auto-saved"
;
$store
->create(
Entry2
=> (
url
=>
'/second'
,
author
=> Blog::Model::Author->new(
name
=>
'bob'
,
),
));
ok
$store
->get(
'Author'
=>
'bob'
),
"author is auto-saved"
;
};
subtest
'cascade_delete'
=>
sub
{
my
$author
=
$store
->create(
Author
=> (
name
=>
'charles'
,
bio
=>
'foo'
) );
my
$entry
=
$store
->create(
Entry
=> (
url
=>
'/third'
,
author
=>
$author
) );
ok
$store
->get(
'Entry'
=>
'/third'
),
"entry is there"
;
$entry
->
delete
;
( run in 0.392 second using v1.01-cache-2.11-cpan-26ccb49234f )