) SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth USING (id);
$$ LANGUAGE SQL ROWS 1;
+CREATE OR REPLACE FUNCTION actor.org_unit_descendants( INT, INT, INT ) RETURNS SETOF actor.org_unit AS $$
+ WITH RECURSIVE descendant_depth AS (
+ SELECT ou.id,
+ ou.parent_ou,
+ out.depth
+ FROM actor.org_unit ou
+ JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+ JOIN anscestor_depth ad ON (ad.id = ou.id)
+ WHERE ad.depth = $2
+ UNION ALL
+ SELECT ou.id,
+ ou.parent_ou,
+ out.depth
+ 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)
+ ), anscestor_depth AS (
+ SELECT ou.id,
+ ou.parent_ou,
+ out.depth
+ FROM actor.org_unit ou
+ JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+ WHERE ou.id = $1
+ UNION ALL
+ SELECT ou.id,
+ ou.parent_ou,
+ out.depth
+ FROM actor.org_unit ou
+ JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+ JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
+ ) SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth USING (id) WHERE depth <= $3;
+$$ LANGUAGE SQL ROWS 1;
+
CREATE OR REPLACE FUNCTION actor.org_unit_descendants( INT ) RETURNS SETOF actor.org_unit AS $$
WITH RECURSIVE descendant_depth AS (
SELECT ou.id,
SELECT * FROM actor.org_unit_full_path((actor.org_unit_ancestor_at_depth($1, $2)).id)
$$ LANGUAGE SQL STABLE ROWS 1;
+CREATE OR REPLACE FUNCTION actor.org_unit_full_path ( INT, INT, INT ) RETURNS SETOF actor.org_unit AS $$
+ SELECT *
+ FROM actor.org_unit_ancestor_fenced_path($1, $2)
+ UNION
+ SELECT *
+ FROM actor.org_unit_descendants($1, (SELECT depth FROM actor.org_unit AS aou INNER JOIN
+ actor.org_unit_type AS aout ON aou.ou_type = aout.id
+ WHERE aou.id = $1), $3);
+$$ LANGUAGE SQL STABLE ROWS 1;
+
CREATE OR REPLACE FUNCTION actor.org_unit_combined_ancestors ( INT, INT ) RETURNS SETOF actor.org_unit AS $$
SELECT *
FROM actor.org_unit_ancestors($1)
FROM actor.org_unit_ancestors($2);
$$ LANGUAGE SQL STABLE ROWS 1;
+CREATE OR REPLACE FUNCTION actor.org_unit_ancestor_fenced_path( INT, INT ) RETURNS SETOF actor.org_unit AS $$
+ WITH RECURSIVE org_unit_ancestors_distance(id, distance) AS (
+ SELECT $1, 0
+ UNION
+ SELECT ou.parent_ou, ouad.distance+1
+ FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad ON (ou.id = ouad.id)
+ WHERE ou.parent_ou IS NOT NULL
+ )
+ SELECT ou.* FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad USING (id) ORDER BY ouad.distance DESC OFFSET $2;
+$$ LANGUAGE SQL ROWS 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
excluded_count INT := 0;
luri_as_copy BOOL;
+ search_anc_rec_vis_depth INT;
+ search_des_rec_vis_depth INT;
+ pref_anc_rec_vis_depth INT;
+ pref_des_rec_vis_depth INT;
+
BEGIN
check_limit := COALESCE( param_check, 1000 );
SELECT COALESCE( enabled, FALSE ) INTO luri_as_copy FROM config.global_flag WHERE name = 'opac.located_uri.act_as_copy';
+ SELECT COALESCE( substring(value, '\d+'), '0' ) INTO search_anc_rec_vis_depth
+ FROM actor.org_unit_ancestor_setting('opac.luri_ancestor_record_visibility_depth', param_search_ou);
+
+ SELECT COALESCE( substring(value, '\d+'), '100' ) INTO search_des_rec_vis_depth
+ FROM actor.org_unit_ancestor_setting('opac.luri_descendants_record_visibility_depth', param_search_ou);
+
+ SELECT COALESCE( substring(value, '\d+'), '0') INTO pref_anc_rec_vis_depth
+ FROM actor.org_unit_ancestor_setting('opac.luri_pref_ancestor_record_visibility_depth', param_pref_ou);
+
+ SELECT COALESCE( substring(value, '\d+'), '100' ) INTO pref_des_rec_vis_depth
+ FROM actor.org_unit_ancestor_setting('opac.luri_pref_descendants_record_visibility_depth', param_pref_ou);
+
-- core_skip_chk := COALESCE( param_skip_chk, 1 );
IF param_search_ou > 0 THEN
END IF;
IF luri_as_copy THEN
- SELECT ARRAY_AGG(distinct id) INTO luri_org_list FROM actor.org_unit_full_path( param_search_ou );
+ SELECT ARRAY_AGG(distinct id) INTO luri_org_list FROM actor.org_unit_full_path( param_search_ou,
+ search_anc_rec_vis_depth, search_des_rec_vis_depth );
ELSE
- SELECT ARRAY_AGG(distinct id) INTO luri_org_list FROM actor.org_unit_ancestors( param_search_ou );
+ SELECT ARRAY_AGG(distinct id) INTO luri_org_list FROM actor.org_unit_ancestor_fenced_path( param_search_ou,
+ search_anc_rec_vis_depth );
END IF;
ELSIF param_search_ou < 0 THEN
FOR tmp_int IN SELECT * FROM UNNEST(search_org_list) LOOP
IF luri_as_copy THEN
- SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_full_path( tmp_int );
+ SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_full_path( tmp_int,
+ search_anc_rec_vis_depth, search_des_rec_vis_depth );
ELSE
- SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestors( tmp_int );
+ SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestor_fenced_path( tmp_int,
+ search_anc_rec_vis_depth );
END IF;
luri_org_list := luri_org_list || tmp_int_list;
IF param_pref_ou IS NOT NULL THEN
IF luri_as_copy THEN
- SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_full_path( param_pref_ou );
+ SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_full_path( param_pref_ou,
+ pref_anc_rec_vis_depth, pref_des_rec_vis_depth );
ELSE
- SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestors( param_pref_ou );
+ SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestor_fenced_path( param_pref_ou,
+ pref_anc_rec_vis_depth );
END IF;
luri_org_list := luri_org_list || tmp_int_list;
END;
$func$ LANGUAGE PLPGSQL;
-
COMMIT;
)
);
+-- LURI scoping setting types
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp)
+VALUES (
+ 'opac.luri_anc_vis_depth',
+ oils_i18n_gettext(
+ 'opac.luri_anc_vis_depth',
+ 'Limit the depth of ancestor URI retrieval ',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_anc_vis_depth',
+ 'When retrieving URIs for a record, limit the depth of ancestors checked for URI ownership',
+ 'coust',
+ 'description'
+ ),
+ 'opac'
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp)
+VALUES (
+ 'opac.luri_ancestor_record_visibility_depth',
+ oils_i18n_gettext(
+ 'opac.luri_ancestor_record_visibility_depth',
+ 'Limit the depth of luri ancestor records returned',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_ancestor_record_visibility_depth',
+ 'Limit the records returned for ancestors when searching for records with URIs according to the depth specified',
+ 'coust',
+ 'description'
+ ),
+ 'opac'
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp)
+VALUES (
+ 'opac.luri_des_vis_depth',
+ oils_i18n_gettext(
+ 'opac.luri_des_vis_depth',
+ 'Limit the depth of descendant URI retrieval',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_des_vis_depth',
+ 'When retrieving URIs for a record, limit the depth of descendants checked for URI ownership',
+ 'coust',
+ 'description'
+ ),
+ 'opac'
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp)
+VALUES (
+ 'opac.luri_descendants_record_visibility_depth',
+ oils_i18n_gettext(
+ 'opac.luri_descendants_record_visibility_depth',
+ 'Limit the depth of luri descendant records returned',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_descendants_record_visibility_depth',
+ 'Limit the records returned for descendants when searching for records with URIs according to the depth specified',
+ 'coust',
+ 'description'
+ ),
+ 'opac'
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp)
+VALUES (
+ 'opac.luri_pref_ancestor_record_visibility_depth',
+ oils_i18n_gettext(
+ 'opac.luri_pref_ancestor_record_visibility_depth',
+ 'Limit the depth of luri ancestor records returned for the pref lib',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_pref_ancestor_record_visibility_depth',
+ 'Limit the records returned for ancestors when searching for records with URIs, via the pref lib, according to the depth specified',
+ 'coust',
+ 'description'
+ ),
+ 'opac'
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp)
+VALUES (
+ 'opac.luri_pref_descendants_record_visibility_depth',
+ oils_i18n_gettext(
+ 'opac.luri_pref_descendants_record_visibility_depth',
+ 'Limit the depth of luri descendant records returned for the pref lib',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_pref_descendants_record_visibility_depth',
+ 'Limit the records returned for descendatns when searching for records with URIs, via the pref lib, according to the depth specified',
+ 'coust',
+ 'description'
+ ),
+ 'opac'
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp)
+VALUES (
+ 'opac.luri_results_uri_limit',
+ oils_i18n_gettext(
+ 'opac.luri_results_uri_limit',
+ 'Limit the number of URIs on the results page',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_results_uri_limit',
+ 'When retrieving results if a record will display more URIs than the number set here, then limit the number of URIs displayed to this setting''s value',
+ 'coust',
+ 'description'
+ ),
+ 'opac'
+);
+
INSERT INTO config.floating_group(name) VALUES ('Everywhere');
INSERT INTO config.floating_group_member(floating_group, org_unit) VALUES (1, 1);
RETURNS TABLE (id BIGINT, name TEXT, label_sortkey TEXT, rank BIGINT)
AS $$ SELECT * FROM evergreen.ranked_volumes(ARRAY[$1],$2,$3,$4,$5,$6,$7) $$ LANGUAGE SQL STABLE;
-
CREATE OR REPLACE FUNCTION evergreen.located_uris (
bibid BIGINT[],
ouid INT,
WHERE acn.record = ANY ($1)
AND acn.deleted IS FALSE
AND auri.active IS TRUE
- AND ((NOT all_orgs.flag AND aou.id IS NOT NULL) OR (all_orgs.flag AND COALESCE(aou.id,aoud.id) IS NOT NULL))
+ AND ((NOT all_orgs.flag AND aou.id IS NOT NULL AND aou.id IN
+ (SELECT id FROM actor.org_unit_ancestor_fenced_path($2, (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = $2))) OR aou.id IN
+ (SELECT id FROM actor.org_unit_ancestor_fenced_path(COALESCE($3, $2), (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = COALESCE($3, $2)))))
+ OR (all_orgs.flag AND COALESCE(aou.id,aoud.id) IS NOT NULL AND (
+ COALESCE(aou.id, aoud.id) IN
+ (SELECT id FROM actor.org_unit_full_path($2, (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = $2),
+ (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_des_vis_depth' AND org_unit = $2))) OR
+ COALESCE(aou.id, aoud.id) IN
+ (SELECT id FROM actor.org_unit_full_path(COALESCE($3, $2), (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = COALESCE($3, $2)),
+ (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_des_vis_depth' AND org_unit = COALESCE($3, $2)))))))
UNION
SELECT acn.id, COALESCE(aou.name,aoud.name) AS name, acn.label_sortkey, evergreen.rank_ou(aou.id, $2, $3) AS pref_ou
FROM asset.call_number acn
WHERE acn.record = ANY ($1)
AND acn.deleted IS FALSE
AND auri.active IS TRUE
- AND ((NOT all_orgs.flag AND aou.id IS NOT NULL) OR (all_orgs.flag AND COALESCE(aou.id,aoud.id) IS NOT NULL)))x
+ AND ((NOT all_orgs.flag AND aou.id IS NOT NULL and aou.id IN
+ (SELECT id FROM actor.org_unit_ancestor_fenced_path($2, (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = $2))) OR aou.id IN
+ (SELECT id FROM actor.org_unit_ancestor_fenced_path(COALESCE($3, $2), (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = COALESCE($3, $2)))))
+ OR (all_orgs.flag AND COALESCE(aou.id,aoud.id) IS NOT NULL AND (
+ COALESCE(aou.id, aoud.id) IN
+ (SELECT id FROM actor.org_unit_full_path($2, (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = $2),
+ (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_des_vis_depth' AND org_unit = $2))) OR
+ COALESCE(aou.id, aoud.id) IN
+ (SELECT id FROM actor.org_unit_full_path(COALESCE($3, $2), (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = COALESCE($3, $2)),
+ (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_des_vis_depth' AND org_unit = COALESCE($3, $2))))))))x
ORDER BY id, pref_ou DESC;
$$
LANGUAGE SQL STABLE;
--- /dev/null
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp, update_perm, view_perm)
+VALUES (
+ 'opac.luri_anc_vis_depth',
+ oils_i18n_gettext(
+ 'opac.luri_anc_vis_depth',
+ 'Limit the depth of ancestor URI retrieval ',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_anc_vis_depth',
+ 'When retrieving URIs for a record, limit the depth of ancestors checked for URI ownership',
+ 'coust',
+ 'description'
+ ),
+ 'opac',
+ 93,
+ 192
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp, update_perm, view_perm)
+VALUES (
+ 'opac.luri_ancestor_record_visibility_depth',
+ oils_i18n_gettext(
+ 'opac.luri_ancestor_record_visibility_depth',
+ 'Limit the depth of luri ancestor records returned',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_ancestor_record_visibility_depth',
+ 'Limit the records returned for ancestors when searching for records with URIs according to the depth specified',
+ 'coust',
+ 'description'
+ ),
+ 'opac',
+ 93,
+ 192
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp, update_perm, view_perm)
+VALUES (
+ 'opac.luri_des_vis_depth',
+ oils_i18n_gettext(
+ 'opac.luri_des_vis_depth',
+ 'Limit the depth of descendant URI retrieval',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_des_vis_depth',
+ 'When retrieving URIs for a record, limit the depth of descendants checked for URI ownership',
+ 'coust',
+ 'description'
+ ),
+ 'opac',
+ 93,
+ 192
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp, update_perm, view_perm)
+VALUES (
+ 'opac.luri_descendants_record_visibility_depth',
+ oils_i18n_gettext(
+ 'opac.luri_descendants_record_visibility_depth',
+ 'Limit the depth of luri descendant records returned',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_descendants_record_visibility_depth',
+ 'Limit the records returned for descendants when searching for records with URIs according to the depth specified',
+ 'coust',
+ 'description'
+ ),
+ 'opac',
+ 93,
+ 192
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp, update_perm, view_perm)
+VALUES (
+ 'opac.luri_pref_ancestor_record_visibility_depth',
+ oils_i18n_gettext(
+ 'opac.luri_pref_ancestor_record_visibility_depth',
+ 'Limit the depth of luri ancestor records returned for the pref lib',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_pref_ancestor_record_visibility_depth',
+ 'Limit the records returned for ancestors when searching for records with URIs, via the pref lib, according to the depth specified',
+ 'coust',
+ 'description'
+ ),
+ 'opac',
+ 93,
+ 192
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp, update_perm, view_perm)
+VALUES (
+ 'opac.luri_pref_descendants_record_visibility_depth',
+ oils_i18n_gettext(
+ 'opac.luri_pref_descendants_record_visibility_depth',
+ 'Limit the depth of luri descendant records returned for the pref lib',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_pref_descendants_record_visibility_depth',
+ 'Limit the records returned for descendatns when searching for records with URIs, via the pref lib, according to the depth specified',
+ 'coust',
+ 'description'
+ ),
+ 'opac',
+ 93,
+ 192
+);
+
+INSERT INTO config.org_unit_setting_type
+ (name, label, datatype, description, grp, update_perm, view_perm)
+VALUES (
+ 'opac.luri_results_uri_limit',
+ oils_i18n_gettext(
+ 'opac.luri_results_uri_limit',
+ 'Limit the number of URIs on the results page',
+ 'coust',
+ 'label'
+ ),
+ 'integer',
+ oils_i18n_gettext(
+ 'opac.luri_results_uri_limit',
+ 'When retrieving results if a record will display more URIs than the number set here, then limit the number of URIs displayed to this setting''s value',
+ 'coust',
+ 'description'
+ ),
+ 'opac',
+ 93,
+ 192
+);
--- /dev/null
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+CREATE OR REPLACE FUNCTION actor.org_unit_descendants( INT, INT, INT ) RETURNS SETOF actor.org_unit AS $$
+ WITH RECURSIVE descendant_depth AS (
+ SELECT ou.id,
+ ou.parent_ou,
+ out.depth
+ FROM actor.org_unit ou
+ JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+ JOIN anscestor_depth ad ON (ad.id = ou.id)
+ WHERE ad.depth = $2
+ UNION ALL
+ SELECT ou.id,
+ ou.parent_ou,
+ out.depth
+ 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)
+ ), anscestor_depth AS (
+ SELECT ou.id,
+ ou.parent_ou,
+ out.depth
+ FROM actor.org_unit ou
+ JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+ WHERE ou.id = $1
+ UNION ALL
+ SELECT ou.id,
+ ou.parent_ou,
+ out.depth
+ FROM actor.org_unit ou
+ JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+ JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
+ ) SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth USING (id) WHERE depth <= $3;
+$$ LANGUAGE SQL ROWS 1;
+
+COMMIT;
--- /dev/null
+BEGIN;
+
+CREATE OR REPLACE FUNCTION actor.org_unit_full_path ( INT, INT, INT ) RETURNS SETOF actor.org_unit AS $$
+ SELECT *
+ FROM actor.org_unit_ancestor_fenced_path($1, $2)
+ UNION
+ SELECT *
+ FROM actor.org_unit_descendants($1, (SELECT depth FROM actor.org_unit AS aou INNER JOIN
+ actor.org_unit_type AS aout ON aou.ou_type = aout.id
+ WHERE aou.id = $1), $3);
+$$ LANGUAGE SQL STABLE ROWS 1;
+
+COMMIT;
--- /dev/null
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+CREATE OR REPLACE FUNCTION actor.org_unit_ancestor_fenced_path( INT, INT ) RETURNS SETOF actor.org_unit AS $$
+ WITH RECURSIVE org_unit_ancestors_distance(id, distance) AS (
+ SELECT $1, 0
+ UNION
+ SELECT ou.parent_ou, ouad.distance+1
+ FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad ON (ou.id = ouad.id)
+ WHERE ou.parent_ou IS NOT NULL
+ )
+ SELECT ou.* FROM actor.org_unit ou JOIN org_unit_ancestors_distance ouad USING (id) ORDER BY ouad.distance DESC OFFSET $2;
+$$ LANGUAGE SQL ROWS 1;
+
+COMMIT;
--- /dev/null
+BEGIN;
+
+CREATE OR REPLACE FUNCTION search.query_parser_fts (
+
+ param_search_ou INT,
+ param_depth INT,
+ param_query TEXT,
+ param_statuses INT[],
+ param_locations INT[],
+ param_offset INT,
+ param_check INT,
+ param_limit INT,
+ metarecord BOOL,
+ staff BOOL,
+ deleted_search BOOL,
+ param_pref_ou INT DEFAULT NULL
+) RETURNS SETOF search.search_result AS $func$
+DECLARE
+
+ current_res search.search_result%ROWTYPE;
+ search_org_list INT[];
+ luri_org_list INT[];
+ tmp_int_list INT[];
+
+ check_limit INT;
+ core_limit INT;
+ core_offset INT;
+ tmp_int INT;
+
+ core_result RECORD;
+ core_cursor REFCURSOR;
+ core_rel_query TEXT;
+
+ total_count INT := 0;
+ check_count INT := 0;
+ deleted_count INT := 0;
+ visible_count INT := 0;
+ excluded_count INT := 0;
+
+ luri_as_copy BOOL;
+ search_anc_rec_vis_depth INT;
+ search_des_rec_vis_depth INT;
+ pref_anc_rec_vis_depth INT;
+ pref_des_rec_vis_depth INT;
+
+BEGIN
+
+ check_limit := COALESCE( param_check, 1000 );
+ core_limit := COALESCE( param_limit, 25000 );
+ core_offset := COALESCE( param_offset, 0 );
+
+ SELECT COALESCE( enabled, FALSE ) INTO luri_as_copy FROM config.global_flag WHERE name = 'opac.located_uri.act_as_copy';
+
+ SELECT COALESCE( substring(value, '\d+'), '0' ) INTO search_anc_rec_vis_depth
+ FROM actor.org_unit_ancestor_setting('opac.luri_ancestor_record_visibility_depth', param_search_ou);
+
+ SELECT COALESCE( substring(value, '\d+'), '100' ) INTO search_des_rec_vis_depth
+ FROM actor.org_unit_ancestor_setting('opac.luri_descendants_record_visibility_depth', param_search_ou);
+
+ SELECT COALESCE( substring(value, '\d+'), '0') INTO pref_anc_rec_vis_depth
+ FROM actor.org_unit_ancestor_setting('opac.luri_pref_ancestor_record_visibility_depth', param_pref_ou);
+
+ SELECT COALESCE( substring(value, '\d+'), '100' ) INTO pref_des_rec_vis_depth
+ FROM actor.org_unit_ancestor_setting('opac.luri_pref_descendants_record_visibility_depth', param_pref_ou);
+
+ -- core_skip_chk := COALESCE( param_skip_chk, 1 );
+
+ IF param_search_ou > 0 THEN
+ IF param_depth IS NOT NULL THEN
+ SELECT ARRAY_AGG(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou, param_depth );
+ ELSE
+ SELECT ARRAY_AGG(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou );
+ END IF;
+
+ IF luri_as_copy THEN
+ SELECT ARRAY_AGG(distinct id) INTO luri_org_list FROM actor.org_unit_full_path( param_search_ou,
+ search_anc_rec_vis_depth, search_des_rec_vis_depth );
+ ELSE
+ SELECT ARRAY_AGG(distinct id) INTO luri_org_list FROM actor.org_unit_ancestor_fenced_path( param_search_ou,
+ search_anc_rec_vis_depth );
+ END IF;
+
+ ELSIF param_search_ou < 0 THEN
+ SELECT ARRAY_AGG(distinct org_unit) INTO search_org_list FROM actor.org_lasso_map WHERE lasso = -param_search_ou;
+
+ FOR tmp_int IN SELECT * FROM UNNEST(search_org_list) LOOP
+
+ IF luri_as_copy THEN
+ SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_full_path( tmp_int,
+ search_anc_rec_vis_depth, search_des_rec_vis_depth );
+ ELSE
+ SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestor_fenced_path( tmp_int,
+ search_anc_rec_vis_depth );
+ END IF;
+
+ luri_org_list := luri_org_list || tmp_int_list;
+ END LOOP;
+
+ SELECT ARRAY_AGG(DISTINCT x.id) INTO luri_org_list FROM UNNEST(luri_org_list) x(id);
+
+ ELSIF param_search_ou = 0 THEN
+ -- reserved for user lassos (ou_buckets/type='lasso') with ID passed in depth ... hack? sure.
+ END IF;
+
+ IF param_pref_ou IS NOT NULL THEN
+ IF luri_as_copy THEN
+ SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_full_path( param_pref_ou,
+ pref_anc_rec_vis_depth, pref_des_rec_vis_depth );
+ ELSE
+ SELECT ARRAY_AGG(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestor_fenced_path( param_pref_ou,
+ pref_anc_rec_vis_depth );
+ END IF;
+
+ luri_org_list := luri_org_list || tmp_int_list;
+ END IF;
+
+ OPEN core_cursor FOR EXECUTE param_query;
+
+ LOOP
+
+ FETCH core_cursor INTO core_result;
+ EXIT WHEN NOT FOUND;
+ EXIT WHEN total_count >= core_limit;
+
+ total_count := total_count + 1;
+
+ CONTINUE WHEN total_count NOT BETWEEN core_offset + 1 AND check_limit + core_offset;
+
+ check_count := check_count + 1;
+
+ IF NOT deleted_search THEN
+
+ PERFORM 1 FROM biblio.record_entry b WHERE NOT b.deleted AND b.id IN ( SELECT * FROM unnest( core_result.records ) );
+ IF NOT FOUND THEN
+ -- RAISE NOTICE ' % were all deleted ... ', core_result.records;
+ deleted_count := deleted_count + 1;
+ CONTINUE;
+ END IF;
+
+ PERFORM 1
+ FROM biblio.record_entry b
+ JOIN config.bib_source s ON (b.source = s.id)
+ WHERE s.transcendant
+ AND b.id IN ( SELECT * FROM unnest( core_result.records ) );
+
+ IF FOUND THEN
+ -- RAISE NOTICE ' % were all transcendant ... ', core_result.records;
+ visible_count := visible_count + 1;
+
+ current_res.id = core_result.id;
+ current_res.rel = core_result.rel;
+
+ tmp_int := 1;
+ IF metarecord THEN
+ SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
+ END IF;
+
+ IF tmp_int = 1 THEN
+ current_res.record = core_result.records[1];
+ ELSE
+ current_res.record = NULL;
+ END IF;
+
+ RETURN NEXT current_res;
+
+ CONTINUE;
+ END IF;
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
+ JOIN asset.uri uri ON (map.uri = uri.id)
+ WHERE NOT cn.deleted
+ AND cn.label = '##URI##'
+ AND uri.active
+ AND ( param_locations IS NULL OR array_upper(param_locations, 1) IS NULL )
+ AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
+ AND cn.owning_lib IN ( SELECT * FROM unnest( luri_org_list ) )
+ LIMIT 1;
+
+ IF FOUND THEN
+ -- RAISE NOTICE ' % have at least one URI ... ', core_result.records;
+ visible_count := visible_count + 1;
+
+ current_res.id = core_result.id;
+ current_res.rel = core_result.rel;
+
+ tmp_int := 1;
+ IF metarecord THEN
+ SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
+ END IF;
+
+ IF tmp_int = 1 THEN
+ current_res.record = core_result.records[1];
+ ELSE
+ current_res.record = NULL;
+ END IF;
+
+ RETURN NEXT current_res;
+
+ CONTINUE;
+ END IF;
+
+ IF param_statuses IS NOT NULL AND array_upper(param_statuses, 1) > 0 THEN
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.copy cp ON (cp.call_number = cn.id)
+ WHERE NOT cn.deleted
+ AND NOT cp.deleted
+ AND cp.status IN ( SELECT * FROM unnest( param_statuses ) )
+ AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.status IN ( SELECT * FROM unnest( param_statuses ) )
+ AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ -- RAISE NOTICE ' % and multi-home linked records were all status-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ END IF;
+
+ END IF;
+
+ IF param_locations IS NOT NULL AND array_upper(param_locations, 1) > 0 THEN
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.copy cp ON (cp.call_number = cn.id)
+ WHERE NOT cn.deleted
+ AND NOT cp.deleted
+ AND cp.location IN ( SELECT * FROM unnest( param_locations ) )
+ AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.location IN ( SELECT * FROM unnest( param_locations ) )
+ AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ -- RAISE NOTICE ' % and multi-home linked records were all copy_location-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ END IF;
+
+ END IF;
+
+ IF staff IS NULL OR NOT staff THEN
+
+ PERFORM 1
+ FROM asset.opac_visible_copies
+ WHERE circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
+ AND record IN ( SELECT * FROM unnest( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.opac_visible_copies cp ON (cp.copy_id = pr.target_copy)
+ WHERE cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
+ AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+
+ -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ END IF;
+
+ ELSE
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.copy cp ON (cp.call_number = cn.id)
+ WHERE NOT cn.deleted
+ AND NOT cp.deleted
+ AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
+ AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.circ_lib IN ( SELECT * FROM unnest( search_org_list ) )
+ AND pr.peer_record IN ( SELECT * FROM unnest( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.copy cp ON (cp.call_number = cn.id)
+ WHERE cn.record IN ( SELECT * FROM unnest( core_result.records ) )
+ AND NOT cp.deleted
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ -- Recheck Located URI visibility in the case of no "foreign" copies
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
+ JOIN asset.uri uri ON (map.uri = uri.id)
+ WHERE NOT cn.deleted
+ AND cn.label = '##URI##'
+ AND uri.active
+ AND cn.record IN ( SELECT * FROM unnest( core_result.records ) )
+ AND cn.owning_lib NOT IN ( SELECT * FROM unnest( luri_org_list ) )
+ LIMIT 1;
+
+ IF FOUND THEN
+ -- RAISE NOTICE ' % were excluded for foreign located URIs... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ ELSE
+ -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ END IF;
+
+ END IF;
+
+ END IF;
+
+ END IF;
+
+ visible_count := visible_count + 1;
+
+ current_res.id = core_result.id;
+ current_res.rel = core_result.rel;
+
+ tmp_int := 1;
+ IF metarecord THEN
+ SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
+ END IF;
+
+ IF tmp_int = 1 THEN
+ current_res.record = core_result.records[1];
+ ELSE
+ current_res.record = NULL;
+ END IF;
+
+ RETURN NEXT current_res;
+
+ IF visible_count % 1000 = 0 THEN
+ -- RAISE NOTICE ' % visible so far ... ', visible_count;
+ END IF;
+
+ END LOOP;
+
+ current_res.id = NULL;
+ current_res.rel = NULL;
+ current_res.record = NULL;
+ current_res.total = total_count;
+ current_res.checked = check_count;
+ current_res.deleted = deleted_count;
+ current_res.visible = visible_count;
+ current_res.excluded = excluded_count;
+
+ CLOSE core_cursor;
+
+ RETURN NEXT current_res;
+
+END;
+$func$ LANGUAGE PLPGSQL;
+
+COMMIT;
--- /dev/null
+BEGIN;
+
+CREATE OR REPLACE FUNCTION evergreen.located_uris (
+ bibid BIGINT[],
+ ouid INT,
+ pref_lib INT DEFAULT NULL
+) RETURNS TABLE (id BIGINT, name TEXT, label_sortkey TEXT, rank INT) AS $$
+ WITH all_orgs AS (SELECT COALESCE( enabled, FALSE ) AS flag FROM config.global_flag WHERE name = 'opac.located_uri.act_as_copy')
+ SELECT DISTINCT ON (id) * FROM (
+ SELECT acn.id, COALESCE(aou.name,aoud.name), acn.label_sortkey, evergreen.rank_ou(aou.id, $2, $3) AS pref_ou
+ FROM asset.call_number acn
+ INNER JOIN asset.uri_call_number_map auricnm ON acn.id = auricnm.call_number
+ INNER JOIN asset.uri auri ON auri.id = auricnm.uri
+ LEFT JOIN actor.org_unit_ancestors( COALESCE($3, $2) ) aou ON (acn.owning_lib = aou.id)
+ LEFT JOIN actor.org_unit_descendants( COALESCE($3, $2) ) aoud ON (acn.owning_lib = aoud.id),
+ all_orgs
+ WHERE acn.record = ANY ($1)
+ AND acn.deleted IS FALSE
+ AND auri.active IS TRUE
+ AND ((NOT all_orgs.flag AND aou.id IS NOT NULL AND aou.id IN
+ (SELECT id FROM actor.org_unit_ancestor_fenced_path($2, (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = $2))) OR aou.id IN
+ (SELECT id FROM actor.org_unit_ancestor_fenced_path(COALESCE($3, $2), (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = COALESCE($3, $2)))))
+ OR (all_orgs.flag AND COALESCE(aou.id,aoud.id) IS NOT NULL AND (
+ COALESCE(aou.id, aoud.id) IN
+ (SELECT id FROM actor.org_unit_full_path($2, (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = $2),
+ (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_des_vis_depth' AND org_unit = $2))) OR
+ COALESCE(aou.id, aoud.id) IN
+ (SELECT id FROM actor.org_unit_full_path(COALESCE($3, $2), (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = COALESCE($3, $2)),
+ (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_des_vis_depth' AND org_unit = COALESCE($3, $2)))))))
+ UNION
+ SELECT acn.id, COALESCE(aou.name,aoud.name) AS name, acn.label_sortkey, evergreen.rank_ou(aou.id, $2, $3) AS pref_ou
+ FROM asset.call_number acn
+ INNER JOIN asset.uri_call_number_map auricnm ON acn.id = auricnm.call_number
+ INNER JOIN asset.uri auri ON auri.id = auricnm.uri
+ LEFT JOIN actor.org_unit_ancestors( $2 ) aou ON (acn.owning_lib = aou.id)
+ LEFT JOIN actor.org_unit_descendants( $2 ) aoud ON (acn.owning_lib = aoud.id),
+ all_orgs
+ WHERE acn.record = ANY ($1)
+ AND acn.deleted IS FALSE
+ AND auri.active IS TRUE
+ AND ((NOT all_orgs.flag AND aou.id IS NOT NULL and aou.id IN
+ (SELECT id FROM actor.org_unit_ancestor_fenced_path($2, (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = $2))) OR aou.id IN
+ (SELECT id FROM actor.org_unit_ancestor_fenced_path(COALESCE($3, $2), (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = COALESCE($3, $2)))))
+ OR (all_orgs.flag AND COALESCE(aou.id,aoud.id) IS NOT NULL AND (
+ COALESCE(aou.id, aoud.id) IN
+ (SELECT id FROM actor.org_unit_full_path($2, (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = $2),
+ (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_des_vis_depth' AND org_unit = $2))) OR
+ COALESCE(aou.id, aoud.id) IN
+ (SELECT id FROM actor.org_unit_full_path(COALESCE($3, $2), (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_anc_vis_depth' AND org_unit = COALESCE($3, $2)),
+ (SELECT substring(value, '\d+')::INT
+ FROM actor.org_unit_setting
+ WHERE name = 'opac.luri_des_vis_depth' AND org_unit = COALESCE($3, $2))))))))x
+ ORDER BY id, pref_ou DESC;
+$$
+LANGUAGE SQL STABLE;
+
+COMMIT;
</td>
</tr>
[% END %]
+ [%
+ IF ctx.search_ou;
+ limit_uris_displayed = ctx.get_org_setting(ctx.search_ou, 'opac.luri_results_uri_limit');
+ END;
+ %]
[% FOR uri IN args.uris %]
<tr name='bib_uri_list' class='result_table_title_cell'>
<td valign='top'>
</td>
<td><a href="[% uri.href %]">[% uri.link | html %]</a>[% ' - ' _ uri.note | html IF uri.note %]</td>
</tr>
+ [%
+ IF loop.count >= limit_uris_displayed;
+ %]
+ <tr>
+ <td>
+ <a class='record_title search_link' name='record_[% rec.id %]'
+ href="[% record_url %]"
+ [% html_text_attr('title', l('Display record details for "[_1]"', attrs.title)) %]>
+ More...
+ </a>
+ </td>
+ </tr>
+ [%
+ LAST;
+ END;
+ %]
[% END %]
[% END %]
[%- IF args.holdings.size > 0;