Last active
May 5, 2017 08:01
-
-
Save jef-sure/0b4969900a9f0636785f01c108a0ad37 to your computer and use it in GitHub Desktop.
findBy inspired from spring-data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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