Ambrosia
view release on metacpan or search on metacpan
lib/Ambrosia/EntityDataModel.pm view on Meta::CPAN
#NEW ÐовÑй обÑекÑ. ÐнÑоÑмаÑÐ¸Ñ Ð² storage не оÑпÑавлÑлаÑÑ.
#LOADED ÐбÑÐµÐºÑ Ð¿ÑоÑиÑан из storage.
#UPDATED ÐбÑÐµÐºÑ Ð²Ð·ÑÑ Ð¸Ð· Ñ
ÑанилиÑа и изменен.
#SAVED ÐнÑоÑмаÑÐ¸Ñ Ð¾Ð± обÑекÑе ÑоÑ
Ñанена в storage.
use Ambrosia::Meta;
class abstract
{
private => [qw/_state/],
};
our $VERSION = 0.010;
################################################################################
sub _map() { return shift->__AMBROSIA_ALIAS_FIELDS__ || {} }
sub _init
{
my $self = shift;
$self->SUPER::_init(@_);
if ( $self->key_value() )
{
$self->SET_LOADED;
}
else
{
$self->SET_NEW;
}
}
################################################################################
# statics
################################################################################
sub handler
{
storage()->driver($_[0]->driver_type(), $_[0]->source_name())->handler()
}
sub driver_type
{
return 'DBI';
}
sub source_name
{
}
sub table
{
}
sub source_path
{
my $driver = storage()->driver($_[0]->driver_type(), $_[0]->source_name());
return $driver->catalog, $driver->schema, $_[0]->table();
}
#РедакÑиÑÑемÑе Ð¿Ð¾Ð»Ñ (ÑоÑ
ÑанÑемÑе в ÐÐ). Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð²Ñе public Ð¿Ð¾Ð»Ñ ÐºÐ»Ð°ÑÑа
#Edited fields (storage in Data Source). Default all publick fields of class.
sub edit_fields
{
return $_[0]->fields();
}
sub fields_mapping()
{
my $proto = shift;
return map { $proto->_map->{$_} || $_ } $proto->edit_fields();
}
#ÐозвÑаÑÐ°ÐµÑ Ð¸Ð¼Ñ ÐºÐ»ÑÑа клаÑÑа.
#СооÑвеÑÑÑвÑÐµÑ Ð°Ð²ÑоинкÑеменÑÐ½Ð¾Ð¼Ñ Ð¿Ð¾Ð»Ñ Ð² ÐÐ.
#ÐÑли поле не авÑоинкÑеменÑное иÑполÑзÑем key
sub primary_key
{
}
#СоÑÑÑавной клÑÑ
#Ðоведение по-ÑмолÑаниÑ. ÐÐ¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÐµÑеопÑеделено в доÑеÑнем клаÑÑе.
sub key
{
$_[0]->primary_key;
}
################################################################################
sub id_value
{
my $self = shift;
my $key_name = $self->key();
if ( ref $key_name )
{
return [ map { $self->$_ } @$key_name ];
}
else
{
return $self->$key_name
}
}
sub key_value
{
goto &id_value;
}
sub primary_key_value
{
my $self = shift;
my $pk_name = $self->primary_key();
return $self->$pk_name;
}
################################################################################
sub need_insert
{
return $_[0]->IS_NEW;
}
sub need_update
{
return $_[0]->IS_LOADED || $_[0]->IS_UPDATED
}
sub id_value_from_hash
{
my $proto = shift;
my $h = shift;
my $key_name = $proto->key();
lib/Ambrosia/EntityDataModel.pm view on Meta::CPAN
{
my $self = shift;
my $driver = storage->driver($self->driver_type, $self->source_name);
assert {$driver} 'Unknown source for insert data: ' . ($self->source_name || 'undefined source');
return new Ambrosia::core::Nil unless $driver;
$driver->reset()
->source( $self->source_path() )
->insert()
->what( $self->fields_mapping() )
->execute( $self->value($self->fields) );
if ( (my $pk = $self->primary_key()) && $self->IS_NEW )
{
$self->$pk = $driver->last_insert_id($self->source_path(), $pk);
$driver->cache->set($self->get_cache_code(), $self);
}
}
sub delete
{
my $self = shift;
my $driver = storage->driver($self->driver_type, $self->source_name);
assert {$driver} 'Unknown source for delete data: ' . ($self->source_name || 'undefined source');
return new Ambrosia::core::Nil unless $driver;
my %cond = @_;
my $q = $driver->reset()
->source( $self->source_path() )
->delete();
foreach ( keys %cond )
{
$q->predicate($_, '=', $cond{$_});
}
$q->execute(0);
if ( ref $self )
{
$driver->cache->delete($self->get_cache_code());
}
}
sub update
{
my $self = shift;
my $driver = storage->driver($self->driver_type, $self->source_name);
assert {$driver} 'Unknown source for update data: ' . ($self->source_name || 'undefined source');
return new Ambrosia::core::Nil unless $driver;
my $q = $driver->reset()
->source( $self->source_path() )
->update()
->what( $self->fields_mapping() );
foreach ( pare_list($self->key, $self->key_value) )
{
$q->predicate($_->[0], '=', $_->[1]);
}
$q->execute($self->value($self->edit_fields));
}
sub find
{
my $proto = shift;
my $class = ref($proto) || $proto;
my $var = shift || my $entity;
my $driver = storage->driver($class->driver_type, $class->source_name);
assert {$driver} 'Unknown source for find data: ' . ($class->source_name || 'undefined source');
return new Ambrosia::core::Nil unless $driver;
my $source_path = join '_', grep defined $_, $class->source_path();
return Ambrosia::EntityDataModel::_find->new(
edm => $class,
var => \$var,
query => Ambrosia::QL
->from([$class->source_path()], \$var)
->in($driver)
->what($class->fields_mapping)
->select(sub {
my %h = map { my $v = $var->{$_}; s/^${source_path}_//; $_ => $v } keys %$var;
%$var = %h;
if ( my $old = $driver->cache->get($class->get_cache_code($class->id_value_from_hash(\%h))) )
{
return $old;
}
my $e = $class->new(%h);
$driver->cache->set($e->get_cache_code, $e);
$e->after_load;
return $e;
})
);
}
sub link_one2one
{
no strict 'refs';
my $proto = shift;
my %params = @_;
my $type = $params{type};
my $pk = $params{from};
my $yeld = $params{optional}
? sub {new Ambrosia::core::Nil}
: sub {throw Ambrosia::error::Exception shift};
if ( $type->primary_key && $type->primary_key eq $params{to} )
{
*{$proto . '::' . $params{name}} = sub() {
my $self = shift;
return ($self->$pk ? $type->load($self->$pk) : undef)
|| $yeld->('Wrong relationship for ' . $type . ': ' . $pk . '=' . $self->$pk);
};
}
else
( run in 0.816 second using v1.01-cache-2.11-cpan-13bb782fe5a )