Aniki

 view release on metacpan or  search on metacpan

lib/Aniki.pm  view on Meta::CPAN

            my %table_result_class;
            $guess_result_class = sub {
                my $table_name = $_[1];
                return $table_result_class{$table_name} //= try {
                    my $table_result_class = sprintf '%s::%s', $root_result_class, camelize($table_name);
                    Module::Load::load($table_result_class);
                    return $table_result_class;
                } catch {
                    die $_ unless /\A\QCan't locate/imo;
                    return $root_result_class;
                };
            };
        }

        $class->meta->add_method(root_result_class => sub { $root_result_class });
        $class->meta->add_method(guess_result_class => $guess_result_class);
    }
}

sub preload_all_row_classes {
    my $class = shift;
    for my $table ($class->schema->get_tables) {
        $class->guess_row_class($table->name);
    }
}

sub preload_all_result_classes {
    my $class = shift;
    for my $table ($class->schema->get_tables) {
        $class->guess_result_class($table->name);
    }
}

sub dbh {
    my $self = shift;
    # (for mysql)
    # XXX: `DBIx::Handler#dbh` send a ping to mysql.
    #      But, It removes `$dbh->{mysql_insertid}`.
    return $self->{_context} if exists $self->{_context};
    return $self->handler->dbh;
}

sub insert {
    my ($self, $table_name, $row, $opt) = @_;
    $row = $self->filter_on_insert($table_name, $row) unless $opt->{no_filter};

    my $table = $self->schema->get_table($table_name);
    $row = $self->_bind_sql_type_to_args($table, $row) if $table;

    my ($sql, @bind) = $self->query_builder->insert($table_name, $row, $opt);
    $self->execute($sql, @bind);
    return;
}

sub filter_on_insert {
    my ($self, $table_name, $row) = @_;
    $row = $self->filter->apply_trigger(insert => $table_name, $row);
    return $self->filter->deflate_row($table_name, $row);
}

sub update {
    my ($self, $table_name, $set, $where, $opt) = @_;

    # migrate for ($self, $row, $set, $opt)
    if (blessed $_[1] && $_[1]->isa('Aniki::Row')) {
        my $row = $_[1];
        $table_name = $row->table_name;
        $set = $_[2];
        $where = $self->_where_row_cond($row->table, $row->row_data);
        $opt = $_[3];
    }

    croak '(Aniki#update) `set` is required for update ("SET" parameter)' unless $set && %$set;
    croak '(Aniki#update) `where` condition must be a reference' unless ref $where;

    $set = $self->filter_on_update($table_name, $set) unless $opt->{no_filter};

    my $table = $self->schema->get_table($table_name);
    if ($table) {
        $set   = $self->_bind_sql_type_to_args($table, $set);
        $where = $self->_bind_sql_type_to_args($table, $where);
    }

    my ($sql, @bind) = $self->query_builder->update($table_name, $set, $where);
    return $self->execute($sql, @bind)->rows;
}

sub update_and_fetch_row {
    my ($self, $row, $set) = @_;
    croak '(Aniki#update_and_fetch_row) condition must be a Aniki::Row object.'
        unless blessed $row && $row->isa('Aniki::Row');

    my $emulated_row_data = $self->_update_and_emulate_row_data($row, $set);

    my $where = $self->_where_row_cond($row->table, $emulated_row_data);
    return $self->select($row->table_name, $where, { limit => 1, suppress_result_objects => 1 })->[0];
}

sub update_and_emulate_row {
    my ($self, $row, $set) = @_;
    croak '(Aniki#update_and_emulate_row) condition must be a Aniki::Row object.' unless blessed $row && $row->isa('Aniki::Row');

    my $emulated_row_data = $self->_update_and_emulate_row_data($row, $set);
    return $emulated_row_data if $self->suppress_row_objects;

    return $self->guess_row_class($row->table_name)->new(
        table_name => $row->table_name,
        handler    => $self,
        row_data   => $emulated_row_data,
    );
}

sub _update_and_emulate_row_data {
    my ($self, $row, $set) = @_;
    $set = $self->filter_on_update($row->table_name, $set);
    $self->update($row, $set, { no_filter => 1 });
    return {
        %{ $row->row_data },
        %$set,
    };
}

sub delete :method {
    my $self = shift;
    if (blessed $_[0] && $_[0]->isa('Aniki::Row')) {
        return $self->delete($_[0]->table_name, $self->_where_row_cond($_[0]->table, $_[0]->row_data), @_);
    }
    else {
        my ($table_name, $where, $opt) = @_;
        croak '(Aniki#delete) `where` condition must be a reference' unless ref $where;

        my $table = $self->schema->get_table($table_name);
        if ($table) {
            $where = $self->_bind_sql_type_to_args($table, $where);
        }

        my ($sql, @bind) = $self->query_builder->delete($table_name, $where, $opt);
        return $self->execute($sql, @bind)->rows;
    }
}

sub filter_on_update {
    my ($self, $table_name, $row) = @_;
    $row = $self->filter->apply_trigger(update => $table_name, $row);
    return $self->filter->deflate_row($table_name, $row);
}

sub insert_and_fetch_id {
    my $self = shift;

    local $self->{_context} = $self->dbh;
    $self->insert(@_);
    return unless defined wantarray;

    my $table_name = shift;
    return $self->last_insert_id($table_name);
}

sub insert_and_fetch_row {

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.603 second using v1.00-cache-2.02-grep-82fe00e-cpan-1310916c57ae )