ActiveRecord-Simple

 view release on metacpan or  search on metacpan

lib/ActiveRecord/Simple/Find.pm  view on Meta::CPAN

    # asc/desc is called before: ->asc->desc
    return if defined $self->{prep_asc_desc};

    # $direction should be ASC/DESC
    return unless $direction =~ /^(ASC|DESC)$/i;

    # Add $direction to the latest field
    @{$self->{prep_order_by}}[-1] .= " $direction";
    $self->{prep_asc_desc} = 1;

    return $self;
}

sub DESTROY { }

sub AUTOLOAD {
    my $call = $AUTOLOAD;
    my $self = shift;
    my $class = ref $self;

    $call =~ s/.*:://;
    my $error = "Can't call method `$call` on class $class.\nPerhaps you have forgotten to fetch your object?";

    croak $error;
}

1;

__END__;


=head1 NAME

ActiveRecord::Simple::Find

=head1 DESCRIPTION

ActiveRecord::Simple is a simple lightweight implementation of ActiveRecord
pattern. It's fast, very simple and very light.

ActiveRecord::Simple::Find is a class to search, ordering, organize and fetch data from database.
It generates SQL-code and iteracts with DBI to execute it.

=head1 SYNOPSIS

my @customers = Customer->find({ name => 'Bill' })->fetch;
my @customers = Customer->find({ zip => [1001, 1002, 1003] })->fetch;
my @customers = Customer->find('age > ?', 21)->fetch;
my @customers = Customer->find([1, 2, 3, 4, 5])->order_by('id')->desc->fetch;


=head1 METHODS

L<ActiveRecord::Simple::Find> implements the following methods.

=head2 new

Object constructor, creates basic search pattern. Available from method "find"
of the base class:

    # SELECT * FROM log WHERE site_id = 1 AND level = 'error';
    my $f = Log->find({ id => 1, level => 'error' });

    # SELECT * FROM log WHERE site_id = 1 AND level IN ('error', 'warning');
    my $f = Log->find({ id => 1, level => ['error', 'warning'] });

    # SELECT * FROM customer WHERE age > 21;
    Customer->find('age > ?', 21);

    # SELECT * FROM customer WHERE id = 100;
    Customer->find(100);

    # SELECT * FROM customer WHERE id IN (100, 101, 191);
    Customer->find([100, 101, 191]);

=head2 last

Fetch last row from database:

    # get very last log:
    my $last_log = Log->find->last; 

    # get last error log of site number 1:
    my $last_log = Log->find({ level => 'error', site_id => 1 })->last;

=head2 first

Fetch first row:

    # get very first log:
    my $first_log = Log->find->first; 

    # get first error log of site number 1:
    my $first_log = Log->find({ level => 'error', site_id => 1 })->first;

=head2 count

Fetch number of records in the database:

    my $cnt = Log->find->count();
    my $cnt_warnings = Log->find({ level => 'warnings' })->count;

=head2 exists 

Check the record is exist:

    if (Log->find({ level => 'fatal' })->exists) {
        die "got fatal error log!";
    }

=head2 fetch

Fetch data from the database as objects:

    my @errors = Log->find({ level => 'error' })->fetch;
    my $errors = Log->find({ level => 'error' })->fetch; # the same, but returns ARRAY ref
    my $error = Log->find(1)->fetch; # only one record
    my @only_five_errors = Log->find({ level => 'error' })->fetch(5);

=head2 next

Fetch next n rows from the database:

    my $finder = Log->find({ level => 'info' });
    
    # get logs by lists of 10 elements:
    while (my @logs = $finder->next(10)) {
        print $_->id, "\n" for @logs;
    }

=head2 only 

Specify field names to get from database:

    # SELECT id, message FROM log;
    my @logs = Log->find->only('id', 'message');

=head2 fields

The same as "only":

    # SELECT id, message FROM log;
    my @logs = Log->find->fields('id', 'message');

=head2 order_by

Set "ORDER BY" command to the query:

    # SELECT * FROM log ORDER BY inserted_time;
    my @logs = Log->find->order_by('inserted_time');

    # SELECT * FROM log ORDER BY level, id;
    my @logs = Log->find->order_by('level', 'id');

=head2 asc

Set "ASC" to the query:

    # SELECT * FROM log ORDER BY id ASC;
    my @logs = Log->find->order_by('id')->asc;

=head2 desc

Set "DESC" to the query:

    # SELECT * FROM log ORDER BY id DESC;
    my @logs = Log->find->order_by('id')->desc;

=head2 limit

SET "LIMIT" to the query:

    # SELECT * FROM log LIMIT 100;
    my @logs = Log->find->limit(100);

=head2 offset

SET "OFFSET" to the query:

    # SELECT * FROM log LIMIT 100 OFFSET 99;
    my @logs = Log->find->limit(100)->offset(99);

=head2 group_by

Set "GROUP BY":

    my @logs = Log->find->group_by('level');

=head2 with 

Set "LEFT JOIN" command to the query:

    # SELECT l.*, s.* FROM logs l LEFT JOIN sites s ON s.id = l.site_id
    my @logs_and_sites = Log->find->with('sites');
    print $_->site->name, ": ", $_->mesage for @logs_and_sites;

=head2 left_join

The same as "with" method

=head2 uplod

Fetch object from database and load into ActiveRecord::Simple::Find object:

    my $logs = Log->find({ level => ['error', 'fatal'] });
    $logs->order_by('level')->desc;
    $logs->limit(100);
    $logs->upload;

    print $_->message for @$logs;

=head2 to_sql

Show SQL-query that genereted by ActiveRecord::Simple::Find class:

    my $finder = Log->frind->only('message')->order_by('level')->desc->limit(100);
    print $finder->to_sql; # prints: SELECT message FROM log ORDER BY level DESC LIMIT 100;


=head1 EXAMPLES

    # SELECT * FROM pizza WHERE name = 'pepperoni';
    Pizza->find({ name => 'pepperoni' });

    # SELECT first_name, last_name FORM customer WHERE age > 21 ORDER BY id DESC LIMIT 100;
    Customer->find('age > ?', 21)->only('first_name', 'last_name')->order_by('id')->desc->limit(100);

    # SELECT p.filename, p.id, pp.* FROM photo p LEFT JOIN person pp ON p.person_id = pp.id WHERE p.size = '1020x768';
    Photo->find({ size => '1020x768' })->with('person')->only('filename', 'id');

    # SELECT t.* FROM topping_pizza tp LEFT JOIN topping t ON t.id = tp.topping_id  WHERE tp.pizza_id = <$val>;
    Pizza->get(<$val>)->toppings();

=head1 AUTHOR

shootnix, C<< <shootnix at cpan.org> >>

=head1 BUGS

Please report any bugs or feature requests to C<shootnix@cpan.org>, or through
the github: https://github.com/shootnix/activerecord-simple/issues

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc ActiveRecord::Simple


You can also look for information at:

=over 1

=item * Github wiki:

L<https://github.com/shootnix/activerecord-simple/wiki>

=back

=head1 ACKNOWLEDGEMENTS


=head1 LICENSE AND COPYRIGHT

Copyright 2013-2018 shootnix.

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

=cut



( run in 0.708 second using v1.01-cache-2.11-cpan-39bf76dae61 )