ActiveRecord-Simple

 view release on metacpan or  search on metacpan

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

    return $self;
}

sub offset {
    my ($self, $offset) = @_;

    #return if not defined $self->{SQL};
    return $self if exists $self->{prep_offset};

    $self->{prep_offset} = $offset; ### TODO: move $offset to $self->{BIND}

    return $self;
}

sub fetch {
    my ($self, $param) = @_;

    my ($read_only, $limit);
    if (ref $param eq 'HASH') {
        $limit     = $param->{limit};
        $read_only = $param->{read_only};
    }
    else {
        $limit = $param;
    }

    return $self->_get_slice($limit) if $self->{_objects};

    $self->_finish_sql_stmt();
    $self->_quote_sql_stmt();

    my $class = $self->{class};
    my $sth = $self->dbh->prepare($self->{SQL}) or croak $self->dbh->errstr;

    $sth->execute(@{ $self->{BIND} }) or croak $self->dbh->errstr;
    if (wantarray) {
        my @objects;
        my $i = 0;
        while (my $object_data = $sth->fetchrow_hashref()) {
            $i++;
            my $obj = $class->new($object_data);
            $self->_finish_object_representation($obj, $object_data, $read_only);
            push @objects, $obj;

            last if $limit && $i == $limit;
        }
        delete $self->{has_joined_table};

        return @objects;
    }
    else {
        my $object_data = $sth->fetchrow_hashref() or return;
        my $obj = $class->new($object_data);
        $self->_finish_object_representation($obj, $object_data, $read_only);
        delete $self->{has_joined_table};

        return $obj;
    }
}

sub upload {
    my ($self, $param) = @_;

    my $o = $self->fetch($param);
    $_[0] = $o;

    return $_[0];
}

sub next {
    my ($self, $n) = @_;

    $n ||= 1;

    $self->{prep_limit} = $n;
    $self->{prep_offset} = 0 unless defined $self->{prep_offset};
    my @result = $self->fetch;

    $self->{prep_offset} += $n;

    return wantarray ? @result : $result[0];
}

sub with {
    my ($self, @rels) = @_;

    return $self if exists $self->{prep_left_joins};
    return $self unless @rels;

    $self->{class}->can('_get_relations')
        or die "Class doesn't have any relations";

    my $table_name = $self->{class}->_get_table_name;

    $self->{prep_left_joins} = [];
    $self->{with} = \@rels;

    RELATION:
    for my $rel_name (@rels) {
        my $relation = $self->{class}->_get_relations->{$rel_name}
            or next RELATION;

        next RELATION unless grep { $_ eq $relation->{type} } qw/one only/;
        my $rel_table_name = $relation->{class}->_get_table_name;
        my $rel_columns = $relation->{class}->_get_columns;

        REL_COLUMN:
        for (@$rel_columns) {
            next REL_COLUMN if ref $_;
            push @{ $self->{prep_select_fields} }, qq/"$rel_table_name"."$_" AS "JOINED_$rel_name\_$_"/;
        }

        if ($relation->{type} eq 'one') {
            my $join_sql = qq/LEFT JOIN "$rel_table_name" ON /;
            $join_sql .= qq/"$rel_table_name"."$relation->{params}{pk}"/;
            $join_sql .= qq/ = "$table_name"."$relation->{params}{fk}"/;

            push @{ $self->{prep_left_joins} }, $join_sql;
        }
    }

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


    # 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



( run in 0.762 second using v1.01-cache-2.11-cpan-b16cb0d3907 )