# For this we would only need sasum, sdist and ssub, but
# because we also need to be able to page (and therefore must sort) the
- # results we get, we need a reasonable column on which to do the sorting,
- # so for that we join sitem (via sstr) so we can sort on the maximum
+ # results we get, we need reasonable columns on which to do the sorting.
+ # So for that we join sitem (via sstr) so we can sort on the maximum
# date_expected (which is basically the issue pub date) for items that
- # have been received.
+ # have been received. That maximum date_expected is actually the second
+ # sort key, however. The first is the holding lib's position in a
+ # depth-first representation of the org tree (if you think about it,
+ # paging through holdings held at diverse points in the tree only makes
+ # sense if you do it this way).
my $rows = $e->json_query({
select => {
limit => int($limit),
offset => int($offset),
order_by => [
- # XXX so first order by an array-ized path from root to org,
- # THEN order by this date_expected business
+ {
+ class => "sdist",
+ field => "holding_lib",
+ transform => "actor.org_unit_simple_path",
+ params => [$org_tree->id]
+ },
{
class => "sitem",
field => "date_expected",
generated_coverage, textual_holdings, show_generated
FROM serial.supplement_summary ;
--- XXX wait, this is cool, but will I actually need this? The problem I really
--- set out to solve was how to order a set of rows that have OU ids in them by
--- those OU's positions in a depth-first tree. can i just sort by something
--- like the path here? i think so
-CREATE OR REPLACE FUNCTION actor.org_unit_descendants_depth_first( INT ) RETURNS SETOF actor.org_unit AS $$
- WITH RECURSIVE descendant_depth(id, parent_ou, depth, path) AS (
- SELECT ou.id,
- ou.parent_ou,
- out.depth,
- ARRAY[ou.id]
- FROM actor.org_unit ou
- JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
- WHERE ou.id = $1
+
+-- Given the IDs of two rows in actor.org_unit, *the second being an ancestor
+-- of the first*, return in array form the path from the ancestor to the
+-- descendant, with each point in the path being an org_unit ID. This is
+-- useful for sorting org_units by their position in a depth-first (display
+-- order) representation of the tree.
+--
+-- This breaks with the precedent set by actor.org_unit_full_path() and others,
+-- and gets the parameters "backwards," but otherwise this function would
+-- not be very usable within json_query.
+CREATE OR REPLACE FUNCTION actor.org_unit_simple_path(INT, INT)
+RETURNS INT[] AS $$
+ WITH RECURSIVE descendant_depth(id, path) AS (
+ SELECT aou.id,
+ ARRAY[aou.id]
+ FROM actor.org_unit aou
+ JOIN actor.org_unit_type aout ON (aout.id = aou.ou_type)
+ WHERE aou.id = $2
UNION ALL
- SELECT ou.id,
- ou.parent_ou,
- out.depth,
- ot.path || ARRAY[ou.id]
- FROM actor.org_unit ou
- JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
- JOIN descendant_depth ot ON (ot.id = ou.parent_ou)
- ) SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth dd USING (id) ORDER BY dd.path;
-$$ LANGUAGE SQL ROWS 1;
+ SELECT aou.id,
+ dd.path || ARRAY[aou.id]
+ FROM actor.org_unit aou
+ JOIN actor.org_unit_type aout ON (aout.id = aou.ou_type)
+ JOIN descendant_depth dd ON (dd.id = aou.parent_ou)
+ ) SELECT dd.path
+ FROM actor.org_unit aou
+ JOIN descendant_depth dd USING (id)
+ WHERE aou.id = $1 ORDER BY dd.path;
+$$ LANGUAGE SQL;
COMMIT;