sub flattened_search {
my ($self, $conn, $auth, $hint, $map, $where, $slo) = @_;
+ # All but the last argument really are necessary.
+ $slo ||= {};
+
# Process the map to normalize it, and to get all our joins and fleshing
# structure into the jffolo.
- my ($map, $jffolo) =
+ my ($map, $jffolo) =
OpenILS::Application::Flattener::process_map($hint, $map);
# Process the suppied where clause, using our map, to make the
# filter.
my $filter = OpenILS::Application::Flattener::prepare_filter($map, $where);
- return [$filter, $jffolo];
-# # Process the supplied sort/limit/offset clause and use it to finish the
-# # jffolo.
-# $jffolo = OpenILS::Application::Flattener::finish_jffolo(
-# $map, $jffolo, $slo
-# );
+ # Process the supplied sort/limit/offset clause and use it to finish the
+ # jffolo.
+ $jffolo = OpenILS::Application::Flattener::finish_jffolo(
+ $hint, $map, $jffolo, $slo
+ );
# Reach out and touch pcrud (could be cstore, if we wanted to offer
# this as a private service).
-# my $pcrud = create OpenSRF::AppSession("open-ils.pcrud");
-# my $req = $pcrud->request(
-# "open-ils.pcrud.search.$hint", $auth, $filter, $jffolo
-# );
-#
-# # Stream back flattened results.
-# while (my $resp = $req->recv(timeout => 60)) {
-# $conn->respond(
-# OpenILS::Application::Flattener::process_result($map, $resp)
-# );
-# }
-#
-# # Clean up.
-# $pcrud->kill_me;
+ my $pcrud = create OpenSRF::AppSession("open-ils.pcrud");
+ my $req = $pcrud->request(
+ "open-ils.pcrud.search.$hint", $auth, $filter, $jffolo
+ );
+
+ # Stream back flattened results.
+ while (my $resp = $req->recv(timeout => 60)) {
+ $conn->respond(
+ OpenILS::Application::Flattener::process_result($map, $resp)
+ );
+ }
+
+ # Clean up.
+ $pcrud->kill_me;
return;
}
$alias = "__${column_name}_${hint}";
my $new_join;
- if ($reltype eq 'has_a') {
+ if ($reltype eq "has_a") {
$new_join = {
class => $hint,
fkey => $piece,
field => $field
};
- } elsif ($reltype eq 'has_many' or $reltype eq 'might_have') {
+ } elsif ($reltype eq "has_many" or $reltype eq "might_have") {
$new_join = {
class => $hint,
fkey => $last_ident,
# and make it use Set::Scalar so it's more semantic, which would
# mean a new Evergreen dependency.
#
- # The nonobvious point of the block is to merge the arrays at
- # $old->{flesh_fields}{$key} and $new->{flesh_fields}{$key},
- # treating the arrays as sets.
+ # The nonobvious point of the following code is to merge the
+ # arrays at $old->{flesh_fields}{$key} and
+ # $new->{flesh_fields}{$key}, treating the arrays as sets.
my %hash = map { $_ => 1 } (
@{ $old->{flesh_fields}{$key} },
my $column = $map->{$key}{path}[-1];
if ($table) {
+ $table = "+" . $table;
$o->{$table} ||= {};
$o->{$table}{$column} = $o->{$key};
$state ||= {};
- if (ref $o eq 'HASH') {
+ if (ref $o eq "HASH") {
foreach my $key (keys %$o) {
+ # XXX this business about "in_expr" may prove inadequate, but it's
+ # intended to avoid trying to map things like "between" in
+ # constructs like:
+ # {"somecolumn": {"between": [1,10]}}
+ # and to that extend, it succeeds.
+
if (not $state->{in_expr} and $key =~ /^[a-z]/) {
$state->{in_expr} = 1;
);
}
}
- } elsif (ref $o eq 'ARRAY') {
+ } elsif (ref $o eq "ARRAY") {
_flattened_search_recursively_apply_map_to_filter(
$_, $map, $state
) foreach @$o;
return $filter;
}
+# Return a jffolo with sort/limit/offset from the simplified sort hash (slo)
+# mixed in. limit and offset are copied as-is. sort is translated into
+# an order_by that calls simplified column named by their real names by checking
+# the map.
+sub finish_jffolo {
+ my ($core_hint, $map, $jffolo, $slo) = @_;
+
+ $jffolo = { %$jffolo }; # clone
+ $slo = { %$slo }; # clone
+
+ $jffolo->{limit} = $slo->{limit} if exists $slo->{limit};
+ $jffolo->{offset} = $slo->{offset} if exists $slo->{offset};
+
+ return $jffolo unless $slo->{sort};
+
+ # The slo has a special format for 'sort' that gives callers what they
+ # need, but isn't as flexible as json_query's order_by.
+ #
+ # "sort": [{"column1": "asc"}, {"column2": "desc"}]
+ # or optionally,
+ # "sort": {"onlycolumn": "asc"}
+
+ $jffolo->{order_by} = [];
+
+ # coerce from optional simpler format (see comment blob above)
+ $slo->{sort} = [ $slo->{sort} ] if ref $slo->{sort} eq "HASH";
+
+ foreach my $exp (@{ $slo->{sort} }) {
+ # XXX By assuming that each sort expression is a single key/value pair,
+ # we preclude the ability to use transforms and the like for now.
+
+ my ($key) = keys(%$exp);
+
+ if ($map->{$key}) {
+ my $class = $map->{$key}{last_join_alias} || $core_hint;
+ push @{ $jffolo->{order_by} }, {
+ class => $class,
+ field => $map->{$key}{path}[-1],
+ direction => $exp->{$key}
+ };
+ }
+
+ # If the key wasn't defined in the map, we'll leave it out of our
+ # order_by clause.
+ }
+
+ return $jffolo;
+}
+
+sub process_result {
+ my ($map, $resp) = @_;
+
+ # XXX TODO
+ return $resp;
+}
+
1;