Skip to content

Instantly share code, notes, and snippets.

@jef-sure
Last active May 5, 2017 08:01
Show Gist options
  • Save jef-sure/0b4969900a9f0636785f01c108a0ad37 to your computer and use it in GitHub Desktop.
Save jef-sure/0b4969900a9f0636785f01c108a0ad37 to your computer and use it in GitHub Desktop.
findBy inspired from spring-data
use strict;
use warnings;
sub ccmap ($) {
my $name = $_[0];
$name =~ s/([[:upper:]])/_\l$1/g;
$name =~ s/^_//;
return $name;
}
#<<<
my @uneq = (
qr/LessThanEqual$/, '<=',
qr/LessThan$/, '<',
qr/GreaterThanEqual$/, '>=',
qr/GreaterThan$/, '>',
qr/IsNull$/, sub {"'$_[0]' => {'=', undef}"},
qr/IsNotNull$/, sub {"'$_[0]' => {'!=', undef}"},
qr/IsNot$/, '!=',
qr/NotNull$/, sub {"'$_[0]' => {'!=', undef}"},
qr/NotEquals$/, '!=',
qr/NotIn$/, '-not_in',
qr/NotLike$/, '-not_like',
qr/IsEqualTo$/, '=',
qr/IsTrue$/, sub {"-bool => '$_[0]'"},
qr/IsFalse$/, sub {"-not_bool => '$_[0]'"},
qr/Equals$/, '=',
qr/True$/, sub {"-bool => '$_[0]'"},
qr/False$/, sub {"-not_bool => '$_[0]'"},
qr/Like$/, '-like',
qr/Is$/, '=',
qr/Not$/, '!=',
qr/In$/, '-in',
);
#>>>
sub parse_find_by {
my ($table, $find) = @_;
$find =~ s/^find(?<what>.*?)By(?![[:lower:]])// || $find =~ s/^find(?<what>.*)// or die "bad pattern: $find";
my $what = $+{what} || 'All';
$what =~ s/(?<distinct>Distinct)(?![[:lower:]])//;
my $distinct = $+{distinct} // 0;
$what =~ s/((?<type>(All|One|First))(?<limit>\d+)?)(?![[:lower:]])//;
my $type = $+{type} // 'All';
my $limit = $+{limit};
$what =~ s/(?<column>\w+)//;
my $column = ccmap($+{column} // '');
$find =~ s/OrderBy(?<order>.*?)(?<asc>Asc|Desc)(?=[[:upper:]]|$)// || $find =~ s/OrderBy(?<order>.*?)$//;
my $order = $+{order};
my $asc = $+{asc} || 'Asc';
my $where = $find;
if ($type eq 'First' && !$limit) {
$limit = 1;
}
if ($limit && $limit == 1) {
$type = 'One';
}
my $pi = 0;
my $pp = sub {
my ($param) = @_;
my $found;
for (my $i = 0; $i < @uneq; $i += 2) {
if ($param =~ s/$uneq[$i]//) {
$found = $i + 1;
last;
}
}
$param = ccmap($param);
my $ret;
if ($found) {
if ('CODE' eq ref $uneq[$found]) {
$ret = $uneq[$found]->($param);
} else {
$ret = "'$param' => { '$uneq[$found]' => \$_[$pi]}";
++$pi;
}
} else {
$ret = "'$param' => \$_[$pi]";
++$pi;
}
$ret;
};
#<<<
my $conds = join(
", ",
map {
/And(?![[:lower:]])/
? '-and => [' . join(", ", map {$pp->($_)} split /And(?![[:lower:]])/x, $_) . ']'
: $pp->($_);
} split /Or(?![[:lower:]])/, $where
);
#>>>
my $obj = $type eq 'One' ? 'one_row' : 'all_rows';
my $flags = $column ? ", -column => '$column'" : '';
$flags = $distinct ? $flags ? ", -distinct => '$column'" : ", '-distinct'" : '';
$order
= $order
? $asc eq 'Asc'
? ", -order_by => '" . ccmap($order) . "'"
: ", -order_by => {-desc => '" . ccmap($order) . "'}"
: '';
$where = $conds ? ", -where => [$conds]" : '';
$limit = $limit && $limit > 1 && $type ne 'One' ? ", -limit => $limit" : '';
my $tspec = "'$table'" . $flags;
$tspec = "[$tspec]" if $column;
$tspec .= $where . $order . $limit;
my $func = "sub { $obj($tspec) }";
eval $func or die $!;
print "$_[1] -> $func\n";
}
# output:
#findAll -> sub { all_rows('table') }
#findOnePeopleDistinctByLastnameAndFirstname -> sub { one_row(['table', -distinct => 'people'], -where => [-and => ['lastname' => $_[0], 'firstname' => $_[1]]]) }
#findFirst1PeopleDistinctByLastnameAndFirstname -> sub { one_row(['table', -distinct => 'people'], -where => [-and => ['lastname' => $_[0], 'firstname' => $_[1]]]) }
#findPeopleDistinctByLastnameAndFirstname -> sub { all_rows(['table', -distinct => 'people'], -where => [-and => ['lastname' => $_[0], 'firstname' => $_[1]]]) }
#findDistinctnessDistinctByLastnameAndFirstname -> sub { all_rows(['table', -distinct => 'distinctness'], -where => [-and => ['lastname' => $_[0], 'firstname' => $_[1]]]) }
#findFirst10DistinctPeopleByLastnameAndFirstname -> sub { all_rows(['table', -distinct => 'people'], -where => [-and => ['lastname' => $_[0], 'firstname' => $_[1]]], -limit => 10) }
#findFirst10DistinctPeopleByAndyAndFirstname -> sub { all_rows(['table', -distinct => 'people'], -where => [-and => ['andy' => $_[0], 'firstname' => $_[1]]], -limit => 10) }
#findByLastnameAndFirstname -> sub { all_rows('table', -where => [-and => ['lastname' => $_[0], 'firstname' => $_[1]]]) }
#findByAddressZipCode -> sub { all_rows('table', -where => ['address_zip_code' => $_[0]]) }
#findByLastname -> sub { all_rows('table', -where => ['lastname' => $_[0]]) }
#findFirstByOrderByLastnameAsc -> sub { one_row('table', -order_by => 'lastname') }
#findFirstByOrderByLastnameDesc -> sub { one_row('table', -order_by => {-desc => 'lastname'}) }
#findFirst10ByOrderByLastnameAscFirstname -> sub { all_rows('table', -where => ['firstname' => $_[0]], -order_by => 'lastname', -limit => 10) }
#findFirst10ByFirstnameOrderByLastname -> sub { all_rows('table', -where => ['firstname' => $_[0]], -order_by => 'lastname', -limit => 10) }
#findFirst10ByLastname -> sub { all_rows('table', -where => ['lastname' => $_[0]], -limit => 10) }
#findFirst10ByOrderByFirstnameAscLastname -> sub { all_rows('table', -where => ['lastname' => $_[0]], -order_by => 'firstname', -limit => 10) }
#findAllByCustomQueryAndStream -> sub { all_rows('table', -where => [-and => ['custom_query' => $_[0], 'stream' => $_[1]]]) }
#findAllByStartDateLessThan -> sub { all_rows('table', -where => ['start_date' => { '<' => $_[0]}]) }
#findAllByStartDateGreaterThanAndEndDateLessThanAndReferralIsNull -> sub { all_rows('table', -where => [-and => ['start_date' => { '>' => $_[0]}, 'end_date' => { '<' => $_[1]}, 'referral' => {'=', undef}]]) }
parse_find_by("table", "findAll");
parse_find_by("table", "findOnePeopleDistinctByLastnameAndFirstname");
parse_find_by("table", "findFirst1PeopleDistinctByLastnameAndFirstname");
parse_find_by("table", "findPeopleDistinctByLastnameAndFirstname");
parse_find_by("table", "findDistinctnessDistinctByLastnameAndFirstname");
parse_find_by("table", "findFirst10DistinctPeopleByLastnameAndFirstname");
parse_find_by("table", "findFirst10DistinctPeopleByAndyAndFirstname");
parse_find_by("table", "findByLastnameAndFirstname");
parse_find_by("table", "findByAddressZipCode");
parse_find_by("table", "findByLastname");
parse_find_by("table", "findFirstByOrderByLastnameAsc");
parse_find_by("table", "findFirstByOrderByLastnameDesc");
parse_find_by("table", "findFirst10ByOrderByLastnameAscFirstname");
parse_find_by("table", "findFirst10ByFirstnameOrderByLastname");
parse_find_by("table", "findFirst10ByLastname");
parse_find_by("table", "findFirst10ByOrderByFirstnameAscLastname");
parse_find_by("table", "findAllByCustomQueryAndStream");
parse_find_by("table", "findAllByStartDateLessThan");
parse_find_by("table", "findAllByStartDateGreaterThanAndEndDateLessThanAndReferralIsNull");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment