Aniki

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

    $db->insert(module => {
        name      => 'Riji',
        author_id => $author_id,
    });

    my $module = $db->select(module => {
        name => 'Riji',
    }, {
        limit => 1,
    })->first;
    say '$module->name:         ', $module->name;         ## Riji
    say '$module->author->name: ', $module->author->name; ## SONGMU

    my $author = $db->select(author => {
        name => 'songmu',
    }, {
        limit    => 1,
        prefetch => [qw/modules/],
    })->first;

    say '$author->name:   ', $author->name;                 ## SONGMU
    say 'modules[]->name: ', $_->name for $author->modules; ## DBIx::Schema::DSL, Riji
};

1;
```

# DESCRIPTION

Aniki is ORM.
Lite, but powerful.

README.md  view on Meta::CPAN

        varchar 'name', unique;
    };
};
```

A `author` has many `modules`.
So you can access `author` row object to `modules`.

```perl
my $author = $db->select(author => { name => 'songmu' })->first;
say 'modules[]->name: ', $_->name for $author->modules; ## DBIx::Schema::DSL, Riji
```

Also `module` has a `author`.
So you can access `module` row object to `author` also.

```perl
my $module = $db->select(module => { name => 'Riji' })->first;
say "Riji's author is ", $module->author->name; ## SONGMU
```

And you can pre-fetch related rows.

```perl
my @modules = $db->select(module => {}, { prefetch => [qw/author/] });
say $_->name, "'s author is ", $_->author->name for @modules;
```

# SETUP

Install Aniki from CPAN:

```
cpanm Aniki
```

author/benchmark.pl  view on Meta::CPAN

use Benchmark qw/cmpthese timethese/;

my $aniki = SampleAniki::DB->new(connect_info => ["dbi:SQLite:dbname=:memory:", "", "", { ShowErrorStatement => 1 }]);
my $dbic = SampleDbic::Schema->connect('dbi:SQLite:dbname=:memory:');
my $teng = SampleTeng::DB->new({ connect_info => ["dbi:SQLite:dbname=:memory:", "", ""], sql_builder_args => { strict => 1 } });

$aniki->dbh->do($_) for split /;/, SampleAniki::DB::Schema->output;
$teng->dbh->do($_) for split /;/, SampleAniki::DB::Schema->output;
$dbic->storage->dbh->do($_) for split /;/, SampleAniki::DB::Schema->output;

say '=============== SCHEMA ===============';
print SampleAniki::DB::Schema->output;

say '=============== INSERT (no fetch) ===============';
my ($dbic_id, $teng_id, $aniki_id) = (0, 0, 0);
timethese 100000 => {
    aniki => sub {
        $aniki->insert('author' => {
            name => "name:".$aniki_id++,
        });
    },
};

$aniki->dbh->do('DELETE FROM author');
$aniki->dbh->do('DELETE FROM sqlite_sequence WHERE name = ?', undef, 'author');

say '=============== INSERT (fetch auto increment id only) ===============';
($dbic_id, $teng_id, $aniki_id) = (0, 0, 0);
cmpthese timethese 100000 => {
    teng => sub {
        my $id = $teng->fast_insert('author' => {
            name => "name:".$teng_id++,
        });
    },
    aniki => sub {
        my $id = $aniki->insert_and_fetch_id('author' => {
            name => "name:".$aniki_id++,
        });
    },
};

$aniki->dbh->do('DELETE FROM author');
$aniki->dbh->do('DELETE FROM sqlite_sequence WHERE name = ?', undef, 'author');
$teng->dbh->do('DELETE FROM author');
$teng->dbh->do('DELETE FROM sqlite_sequence WHERE name = ?', undef, 'author');

say '=============== INSERT ===============';
($dbic_id, $teng_id, $aniki_id) = (0, 0, 0);
cmpthese {
    %{
        timethese 20000 => {
            dbic => sub {
                my $row = $dbic->resultset('Author')->create({
                    name => "name:".$dbic_id++,
                });
            },
            teng => sub {

author/benchmark.pl  view on Meta::CPAN

            'aniki(fetch)' => sub {
                my $row = $aniki->insert_and_fetch_row('author' => {
                    name => "name:".$aniki_id++,
                });
            },
        }
    },
};


say '=============== SELECT ===============';
cmpthese timethese 20000 => {
    dbic => sub {
        my @rows = $dbic->resultset('Author')->search({}, { rows => 10, order_by => { -asc => 'id' } })->all;
    },
    teng => sub {
        my @rows = $teng->search('author' => {}, { limit => 10, order_by => { id => 'ASC' } })->all;
    },
    aniki => sub {
        my @rows = $aniki->select('author' => {}, { limit => 10, order_by => { id => 'ASC' } })->all;
    },
};

say '=============== UPDATE ===============';
cmpthese timethese 20000 => {
    dbic => sub {
        my $row = $dbic->resultset('Author')->single({ id => 1 });
        $row->update({ message => 'good morning' });
    },
    'teng(row)' => sub {
        my $row = $teng->single('author' => { id => 1 });
        $row->update({ message => 'good morning' });
    },
    teng => sub {

author/benchmark.pl  view on Meta::CPAN

    },
    'aniki(row)' => sub {
        my $row = $aniki->select('author' => { id => 1 }, { limit => 1 })->first;
        $aniki->update($row => { message => 'good morning' });
    },
    aniki => sub {
        $aniki->update('author' => { message => 'good morning' }, { id => 1 });
    },
};

say '=============== DELETE ===============';
my ($dbic_delete_id, $teng_delete_id, $aniki_delete_id) = (0, 0, 0);
cmpthese {
    %{
        timethese 20000 => {
            dbic => sub {
                my $row = $dbic->resultset('Author')->single({ id => ++$dbic_delete_id });
                $row->delete;
            },
            'teng(row)' => sub {
                my $row = $teng->single('author' => { id => ++$teng_delete_id });

eg/synopsis.pl  view on Meta::CPAN

$db->insert(module => {
    name      => 'Riji',
    author_id => $author_id,
});

my $module = $db->select(module => {
    name => 'Riji',
}, {
    limit => 1,
})->first;
say '$module->name:         ', $module->name;         ## Riji
say '$module->author->name: ', $module->author->name; ## SONGMU

my $author = $db->select(author => {
    name => 'songmu',
}, {
    limit    => 1,
    prefetch => [qw/modules/],
})->first;

say '$author->name:   ', $author->name;                 ## SONGMU
say 'modules[]->name: ', $_->name for $author->modules; ## DBIx::Schema::DSL, Riji

lib/Aniki.pm  view on Meta::CPAN

        $db->insert(module => {
            name      => 'Riji',
            author_id => $author_id,
        });

        my $module = $db->select(module => {
            name => 'Riji',
        }, {
            limit => 1,
        })->first;
        say '$module->name:         ', $module->name;         ## Riji
        say '$module->author->name: ', $module->author->name; ## SONGMU

        my $author = $db->select(author => {
            name => 'songmu',
        }, {
            limit    => 1,
            prefetch => [qw/modules/],
        })->first;

        say '$author->name:   ', $author->name;                 ## SONGMU
        say 'modules[]->name: ', $_->name for $author->modules; ## DBIx::Schema::DSL, Riji
    };

    1;

=head1 DESCRIPTION

Aniki is ORM.
Lite, but powerful.

=head2 FEATURES

lib/Aniki.pm  view on Meta::CPAN

        create_table 'author' => columns {
            integer 'id', primary_key, auto_increment;
            varchar 'name', unique;
        };
    };

A C<author> has many C<modules>.
So you can access C<author> row object to C<modules>.

    my $author = $db->select(author => { name => 'songmu' })->first;
    say 'modules[]->name: ', $_->name for $author->modules; ## DBIx::Schema::DSL, Riji

Also C<module> has a C<author>.
So you can access C<module> row object to C<author> also.

    my $module = $db->select(module => { name => 'Riji' })->first;
    say "Riji's author is ", $module->author->name; ## SONGMU

And you can pre-fetch related rows.

    my @modules = $db->select(module => {}, { prefetch => [qw/author/] });
    say $_->name, "'s author is ", $_->author->name for @modules;

=head1 SETUP

Install Aniki from CPAN:

    cpanm Aniki

And run C<install-aniki> command.

    install-aniki --lib=./lib MyApp::DB



( run in 1.530 second using v1.01-cache-2.11-cpan-a1f116cd669 )