Dumped on 2012-10-10
- acq
- acq_lineitem_history
- acq_lineitem_lifecycle
- acq_purchase_order_history
- acq_purchase_order_lifecycle
- all_fund_allocation_total
- all_fund_combined_balance
- all_fund_encumbrance_total
- all_fund_spent_balance
- all_fund_spent_total
- cancel_reason
- claim
- claim_event
- claim_event_type
- claim_policy
- claim_policy_action
- claim_type
- currency_type
- debit_attribution
- distribution_formula
- distribution_formula_application
- distribution_formula_entry
- edi_account
- edi_message
- exchange_rate
- fiscal_calendar
- fiscal_year
- fund
- fund_allocation
- fund_allocation_percent
- fund_allocation_total
- fund_combined_balance
- fund_debit
- fund_debit_total
- fund_encumbrance_total
- fund_spent_balance
- fund_spent_total
- fund_tag
- fund_tag_map
- fund_transfer
- funding_source
- funding_source_allocation_total
- funding_source_balance
- funding_source_credit
- funding_source_credit_total
- invoice
- invoice_entry
- invoice_item
- invoice_item_type
- invoice_method
- invoice_payment_method
- lineitem
- lineitem_alert_text
- lineitem_attr
- lineitem_attr_definition
- lineitem_detail
- lineitem_generated_attr_definition
- lineitem_local_attr_definition
- lineitem_marc_attr_definition
- lineitem_note
- lineitem_provider_attr_definition
- lineitem_usr_attr_definition
- ordered_funding_source_credit
- picklist
- po_item
- po_note
- provider
- provider_address
- provider_contact
- provider_contact_address
- provider_holding_subfield_map
- provider_note
- purchase_order
- serial_claim
- serial_claim_event
- user_request
- user_request_type
- attribute_debits()
- audit_acq_lineitem_func()
- audit_acq_purchase_order_func()
- create_acq_auditor(tbl text, sch text)
- create_acq_func(tbl text, sch text)
- create_acq_history(tbl text, sch text)
- create_acq_lifecycle(tbl text, sch text)
- create_acq_seq(tbl text, sch text)
- create_acq_update_trigger(tbl text, sch text)
- exchange_ratio(text, text, numeric)
- exchange_ratio(to_ex text, from_ex text)
- extract_holding_attr_table(tag integer, lineitem text)
- extract_provider_holding_data(lineitem_i integer)
- fap_limit_100()
- find_bad_fy()
- fund_alloc_percent_val()
- po_org_name_date_unique()
- propagate_funds_by_org_tree(org_unit_id integer, user_id integer, old_year integer)
- propagate_funds_by_org_unit(org_unit_id integer, user_id integer, old_year integer)
- purchase_order_name_default()
- rollover_funds_by_org_tree(org_unit_id integer, user_id integer, old_year integer)
- rollover_funds_by_org_unit(org_unit_id integer, user_id integer, old_year integer)
- transfer_fund(xfer_note integer, user_id numeric, new_amount integer, new_fund numeric, old_amount integer, old_fund text)
- action
- aged_circulation
- all_circulation
- archive_actor_stat_cat
- archive_asset_stat_cat
- billable_circulations
- circulation
- circulation_limit_group_map
- fieldset
- fieldset_col_val
- hold_copy_map
- hold_notification
- hold_request
- hold_request_cancel_cause
- hold_request_note
- hold_transit_copy
- in_house_use
- non_cat_in_house_use
- non_cataloged_circulation
- open_circulation
- reservation_transit_copy
- survey
- survey_answer
- survey_question
- survey_response
- transit_copy
- unfulfilled_hold_innermost_loop
- unfulfilled_hold_list
- unfulfilled_hold_loops
- unfulfilled_hold_max_loop
- unfulfilled_hold_min_loop
- age_circ_on_delete()
- age_parent_circ_on_delete()
- apply_fieldset(query integer, pkey_name text, table_name text, fieldset_id text)
- archive_stat_cats()
- circ_chain(ctx_circ_id integer)
- circulation_claims_returned()
- copy_related_hold_stats(copy_id integer)
- fill_circ_copy_location()
- find_circ_matrix_matchpoint(renewal integer, match_user bigint, match_item integer, context_ou boolean)
- find_circ_matrix_matchpoint(renewal integer, user_object asset.copy, item_object actor.usr, context_ou boolean)
- find_hold_matrix_matchpoint(match_requestor integer, match_user integer, match_item bigint, request_ou integer, pickup_ou integer)
- hold_request_permit_test(match_requestor integer, match_user integer, match_item bigint, request_ou integer, pickup_ou integer)
- hold_request_permit_test(retargetting integer, match_requestor integer, match_user bigint, match_item integer, request_ou integer, pickup_ou boolean)
- hold_retarget_permit_test(match_requestor integer, match_user integer, match_item bigint, request_ou integer, pickup_ou integer)
- item_user_circ_test(integer, bigint, integer)
- item_user_circ_test(renewal integer, match_user bigint, match_item integer, circ_ou boolean)
- item_user_renew_test(integer, bigint, integer)
- link_circ_limit_groups(bigint, integer[])
- purge_circulations()
- push_circ_due_time()
- summarize_circ_chain(ctx_circ_id integer)
- survey_response_answer_date_fixup()
- usr_visible_circ_copies(integer)
- usr_visible_circs(usr_id integer)
- usr_visible_holds(usr_id integer)
- action_trigger
- actor
- address_alert
- card
- hours_of_operation
- org_address
- org_lasso
- org_lasso_map
- org_unit
- org_unit_closed
- org_unit_custom_tree
- org_unit_custom_tree_node
- org_unit_proximity
- org_unit_setting
- org_unit_type
- stat_cat
- stat_cat_entry
- stat_cat_entry_default
- stat_cat_entry_usr_map
- stat_cat_sip_fields
- toolbar
- usr
- usr_activity
- usr_address
- usr_note
- usr_org_unit_opt_in
- usr_password_reset
- usr_saved_search
- usr_setting
- usr_standing_penalty
- workstation
- address_alert_matches(billing_address integer, mailing_address text, post_code text, country text, state text, county text, city text, street2 text, street1 boolean, org_unit boolean)
- approve_pending_address(pending_id integer)
- au_updated()
- calculate_system_penalties(context_org integer, match_user integer)
- crypt_pw_insert()
- crypt_pw_update()
- insert_usr_activity(ehow integer, ewhat text, ewho text, usr text)
- org_unit_ancestor_at_depth(integer, integer)
- org_unit_ancestor_setting(org_id text, setting_name integer)
- org_unit_ancestors(integer)
- org_unit_ancestors_distance(distance integer)
- org_unit_combined_ancestors(integer, integer)
- org_unit_common_ancestors(integer, integer)
- org_unit_descendants(integer)
- org_unit_descendants(integer, integer)
- org_unit_descendants_distance(distance integer)
- org_unit_full_path(integer)
- org_unit_full_path(integer, integer)
- org_unit_parent_protect()
- org_unit_prox_update()
- org_unit_proximity(integer, integer)
- org_unit_simple_path(integer, integer)
- stat_cat_check()
- usr_activity_get_type(ehow text, ewhat text, ewho text)
- usr_activity_transient_trg()
- usr_delete(dest_usr integer, src_usr integer)
- usr_merge(deactivate_cards integer, del_cards integer, del_addrs boolean, dest_usr boolean, src_usr boolean)
- usr_merge_rows(dest_usr text, src_usr text, col_name integer, table_name integer)
- usr_purge_data(specified_dest_usr integer, src_usr integer)
- asset
- call_number
- call_number_class
- call_number_note
- call_number_prefix
- call_number_suffix
- copy
- copy_location
- copy_location_group
- copy_location_group_map
- copy_location_order
- copy_note
- copy_part_map
- copy_template
- opac_visible_copies
- stat_cat
- stat_cat_entry
- stat_cat_entry_copy_map
- stat_cat_entry_transparency_map
- stat_cat_sip_fields
- uri
- uri_call_number_map
- acp_created()
- acp_status_changed()
- autogenerate_placeholder_barcode()
- cache_copy_visibility()
- label_normalizer()
- label_normalizer_dewey(text)
- label_normalizer_generic(text)
- label_normalizer_lc(text)
- merge_record_assets(source_record bigint, target_record bigint)
- metarecord_copy_count(transcendant integer, unshadow bigint, available boolean)
- normalize_affix_sortkey()
- opac_lasso_metarecord_copy_count(transcendant integer, unshadow bigint)
- opac_lasso_record_copy_count(transcendant integer, unshadow bigint)
- opac_ou_metarecord_copy_count(transcendant integer, unshadow bigint)
- opac_ou_record_copy_count(transcendant integer, unshadow bigint)
- record_copy_count(transcendant integer, unshadow bigint, available boolean)
- refresh_opac_visible_copies_mat_view()
- staff_lasso_metarecord_copy_count(transcendant integer, unshadow bigint)
- staff_lasso_record_copy_count(transcendant integer, unshadow bigint)
- staff_ou_metarecord_copy_count(transcendant integer, unshadow bigint)
- staff_ou_record_copy_count(transcendant integer, unshadow bigint)
- stat_cat_check()
- auditor
- authority
- bib_linking
- browse_axis
- browse_axis_authority_field_map
- control_set
- control_set_authority_field
- control_set_bib_field
- full_rec
- rec_descriptor
- record_entry
- record_note
- simple_heading
- thesaurus
- tracing_links
- atag_authority_tags(atag text)
- atag_authority_tags_refs(atag text)
- atag_browse_center(pagesize text, page text, q integer, a integer)
- atag_browse_center_refs(pagesize text, page text, q integer, a integer)
- atag_browse_top(pagesize text, page text, q integer, a integer)
- atag_browse_top_refs(pagesize text, page text, q integer, a integer)
- atag_search_heading(pagesize text, page text, q integer, a integer)
- atag_search_heading_refs(pagesize text, page text, q integer, a integer)
- atag_search_rank(pagesize text, page text, q integer, a integer)
- atag_search_rank_refs(pagesize text, page text, q integer, a integer)
- axis_authority_tags(a text)
- axis_authority_tags_refs(a text)
- axis_browse_center(pagesize text, page text, q integer, a integer)
- axis_browse_center_refs(pagesize text, page text, q integer, a integer)
- axis_browse_top(pagesize text, page text, q integer, a integer)
- axis_browse_top_refs(pagesize text, page text, q integer, a integer)
- axis_search_heading(pagesize text, page text, q integer, a integer)
- axis_search_heading_refs(pagesize text, page text, q integer, a integer)
- axis_search_rank(pagesize text, page text, q integer, a integer)
- axis_search_rank_refs(pagesize text, page text, q integer, a integer)
- btag_authority_tags(btag text)
- btag_authority_tags_refs(btag text)
- btag_browse_center(pagesize text, page text, q integer, a integer)
- btag_browse_center_refs(pagesize text, page text, q integer, a integer)
- btag_browse_top(pagesize text, page text, q integer, a integer)
- btag_browse_top_refs(pagesize text, page text, q integer, a integer)
- btag_search_heading(pagesize text, page text, q integer, a integer)
- btag_search_heading_refs(pagesize text, page text, q integer, a integer)
- btag_search_rank(pagesize text, page text, q integer, a integer)
- btag_search_rank_refs(pagesize text, page text, q integer, a integer)
- flatten_marc(rid bigint)
- generate_overlay_template(bigint)
- generate_overlay_template(source_xml text)
- indexing_ingest_or_delete()
- map_thesaurus_to_control_set()
- merge_records(source_record bigint, target_record bigint)
- normalize_heading(marcxml text)
- normalize_heading(no_thesaurus text, marcxml boolean)
- propagate_changes(aid bigint)
- propagate_changes(bid bigint, aid bigint)
- reingest_authority_full_rec(auth_id bigint)
- reingest_authority_rec_descriptor(auth_id bigint)
- simple_heading_browse_center(pagesize integer[], page text, q integer, atag_list integer)
- simple_heading_browse_top(pagesize integer[], page text, q integer, atag_list integer)
- simple_heading_find_pivot(q integer[], a text)
- simple_heading_search_heading(pagesize integer[], page text, q integer, atag_list integer)
- simple_heading_search_rank(pagesize integer[], page text, q integer, atag_list integer)
- simple_heading_set(marcxml text)
- simple_normalize_heading(marcxml text)
- biblio
- booking
- config
- container
- evergreen
- array_accum(anyelement)
- array_overlap_check()
- array_remove_item_by_value(el anyarray, inp anyelement)
- change_db_setting(settings text, setting_name text[])
- coded_value_map_normalizer(ctype text, input text)
- extract_marc_field(text, bigint, text)
- extract_marc_field(text, bigint, text, text)
- facet_force_nfc()
- fake_fkey_tgr()
- force_unicode_normal_form(form text, string text)
- generic_map_normalizer(text, text)
- get_barcodes(in_barcode integer, type text, select_ou text)
- get_locale_name(description text)
- is_json(text)
- limit_oustl()
- located_uris(rank bigint, label_sortkey integer, name integer)
- lowercase(text)
- lpad_number_substrings(text, text, integer)
- maintain_901()
- maintain_control_numbers()
- oils_i18n_code_tracking()
- oils_i18n_gettext(integer, text, text, text)
- oils_i18n_gettext(text, text, text, text)
- oils_i18n_id_tracking()
- oils_i18n_update_apply(hint text, new_ident text, old_ident text)
- oils_i18n_xlate(raw_locale text, keyvalue text, identcol text, keycol text, keyclass text, keytable text)
- oils_json_to_text(text)
- oils_text_as_bytea(text)
- oils_tsearch2()
- oils_xpath(text, text)
- oils_xpath(text, text, anyarray)
- oils_xpath_string(text, text)
- oils_xpath_string(text, text, anyarray)
- oils_xpath_string(text, text, text)
- oils_xpath_string(text, text, text, anyarray)
- oils_xpath_table(criteria text, xpaths text, relation_name text, document_field text, key text)
- oils_xslt_process(text, text)
- org_top()
- ous_change_log()
- ous_delete_log()
- rank_cp_status(status integer)
- rank_ou(pref_lib integer, search_lib integer, lib integer)
- ranked_volumes(rank bigint, label_sortkey integer, name integer, id public.hstore, pref_lib public.hstore, soffset integer)
- regexp_split_to_array(text, text)
- tableoid2name(oid)
- upgrade_deps_block_check(my_applied_to text, my_db_patch text)
- upgrade_list_applied_deprecated(my_db_patch text)
- upgrade_list_applied_deprecates(my_db_patch text)
- upgrade_list_applied_superseded(my_db_patch text)
- upgrade_list_applied_supersedes(my_db_patch text)
- upgrade_verify_no_dep_conflicts(my_db_patch text)
- xml_escape(str text)
- extend_reporter
- metabib
- author_field_entry
- browse_entry
- browse_entry_def_map
- facet_entry
- full_rec
- identifier_field_entry
- keyword_field_entry
- metarecord
- metarecord_source_map
- real_full_rec
- rec_descriptor
- record_attr
- series_field_entry
- subject_field_entry
- title_field_entry
- autosuggest_prepare_tsquery(orig text)
- browse_normalize(mapped_field text, facet_text integer)
- facet_normalize_trigger()
- reingest_metabib_field_entries(skip_search bigint, skip_browse boolean, skip_facet boolean, bib_id boolean)
- reingest_metabib_full_rec(bib_id bigint)
- remap_metarecord_for_bib(fp bigint, bib_id text)
- search_class_to_registered_components(search_class text)
- suggest_browse_entries(match text, buoyant text, rank text, field_weight integer, field_match integer, buoyant_and_class_match integer)
- money
- offline
- permission
- grp_penalty_threshold
- grp_perm_map
- grp_tree
- perm_list
- usr_grp_map
- usr_object_perm_map
- usr_perm_map
- usr_work_ou_map
- grp_ancestors(integer)
- grp_ancestors_distance(distance integer)
- grp_descendants_distance(distance integer)
- usr_can_grant_perm(target_ou integer, tperm text, iuser integer)
- usr_has_home_perm(target_ou integer, tperm text, iuser integer)
- usr_has_object_perm(integer, text, text, text)
- usr_has_object_perm(target_ou integer, obj_id text, obj_type text, tperm text, iuser integer)
- usr_has_perm(integer, text, integer)
- usr_has_perm_at(perm_code integer, user_id text)
- usr_has_perm_at_all(perm_code integer, user_id text)
- usr_has_perm_at_all_nd(perm_code integer, user_id text)
- usr_has_perm_at_nd(perm_code integer, user_id text)
- usr_has_work_perm(target_ou integer, tperm text, iuser integer)
- usr_perms(integer)
- public
- _get_parser_from_curcfg()
- agg_text(text)
- akeys(public.hstore)
- approximate_date(text, text)
- approximate_high_date(text)
- approximate_low_date(text)
- avals(public.hstore)
- call_number_dewey(text)
- call_number_dewey(text, integer)
- cleanup_acq_marc()
- concat(tsvector, tsvector)
- connectby(text, text, text, text, integer)
- connectby(text, text, text, text, integer, text)
- connectby(text, text, text, text, text, integer)
- connectby(text, text, text, text, text, integer, text)
- content_or_null(text)
- crosstab(text)
- crosstab(text, integer)
- crosstab(text, text)
- crosstab2(text)
- crosstab3(text)
- crosstab4(text)
- defined(public.hstore, text)
- delete(public.hstore, public.hstore)
- delete(public.hstore, text)
- delete(public.hstore, text[])
- dex_init(internal)
- dex_lexize(internal, internal, integer)
- each(value public.hstore)
- entityize(text)
- exist(public.hstore, text)
- exists_all(public.hstore, text[])
- exists_any(public.hstore, text[])
- extract_acq_marc_field(bigint, text, text)
- fetchval(public.hstore, text)
- first(anyelement)
- first5(text)
- first_agg(anyelement, anyelement)
- first_word(text)
- force_to_isbn13(text)
- get_covers(tsvector, tsquery)
- ghstore_compress(internal)
- ghstore_consistent(internal, internal, integer, oid, internal)
- ghstore_decompress(internal)
- ghstore_in(cstring)
- ghstore_out(public.ghstore)
- ghstore_penalty(internal, internal, internal)
- ghstore_picksplit(internal, internal)
- ghstore_same(internal, internal, internal)
- ghstore_union(internal, internal)
- gin_consistent_hstore(internal, smallint, internal, integer, internal, internal)
- gin_extract_hstore(internal, internal)
- gin_extract_hstore_query(internal, internal, smallint, internal, internal)
- headline(oid, text, tsquery)
- headline(oid, text, tsquery, text)
- headline(text, text, tsquery)
- headline(text, text, tsquery, text)
- headline(text, tsquery)
- headline(text, tsquery, text)
- hs_concat(public.hstore, public.hstore)
- hs_contained(public.hstore, public.hstore)
- hs_contains(public.hstore, public.hstore)
- hstore(record)
- hstore(text, text)
- hstore(text[])
- hstore(text[], text[])
- hstore_cmp(public.hstore, public.hstore)
- hstore_eq(public.hstore, public.hstore)
- hstore_ge(public.hstore, public.hstore)
- hstore_gt(public.hstore, public.hstore)
- hstore_hash(public.hstore)
- hstore_in(cstring)
- hstore_le(public.hstore, public.hstore)
- hstore_lt(public.hstore, public.hstore)
- hstore_ne(public.hstore, public.hstore)
- hstore_out(public.hstore)
- hstore_recv(internal)
- hstore_send(public.hstore)
- hstore_to_array(public.hstore)
- hstore_to_matrix(public.hstore)
- hstore_version_diag(public.hstore)
- ingest_acq_marc()
- integer_or_null(text)
- isdefined(public.hstore, text)
- isexists(public.hstore, text)
- last(anyelement)
- last_agg(anyelement, anyelement)
- left_trunc(text, integer)
- length(tsvector)
- lexize(oid, text)
- lexize(text)
- lexize(text, text)
- lowercase(text)
- naco_normalize(text)
- naco_normalize(text, text)
- naco_normalize_keep_comma(text)
- non_filing_normalize(text, "char")
- normal_rand(integer, double precision, double precision)
- normalize_space(text)
- numnode(tsquery)
- oils_tsearch2()
- parse(oid, text)
- parse(text)
- parse(text, text)
- plainto_tsquery(oid, text)
- plainto_tsquery(text)
- plainto_tsquery(text, text)
- populate_record(anyelement, public.hstore)
- prsd_end(internal)
- prsd_getlexeme(internal, internal, internal)
- prsd_headline(internal, internal, internal)
- prsd_lextype(internal)
- prsd_start(internal, integer)
- querytree(tsquery)
- rank(real[], tsvector, tsquery)
- rank(real[], tsvector, tsquery, integer)
- rank(tsvector, tsquery)
- rank(tsvector, tsquery, integer)
- rank_cd(real[], tsvector, tsquery)
- rank_cd(real[], tsvector, tsquery, integer)
- rank_cd(tsvector, tsquery)
- rank_cd(tsvector, tsquery, integer)
- remove_commas(text)
- remove_diacritics(text)
- remove_paren_substring(text)
- remove_whitespace(text)
- reset_tsearch()
- rewrite(tsquery, text)
- rewrite(tsquery, tsquery, tsquery)
- rewrite(tsquery[])
- rewrite_accum(tsquery, tsquery[])
- rewrite_finish(tsquery)
- right_trunc(text, integer)
- search_normalize(text)
- search_normalize(text, text)
- search_normalize_keep_comma(text)
- set_curcfg(integer)
- set_curcfg(text)
- set_curdict(integer)
- set_curdict(text)
- set_curprs(integer)
- set_curprs(text)
- setweight(tsvector, "char")
- show_curcfg()
- skeys(public.hstore)
- slice(public.hstore, text[])
- slice_array(public.hstore, text[])
- snb_en_init(internal)
- snb_lexize(internal, internal, integer)
- snb_ru_init(internal)
- snb_ru_init_koi8(internal)
- snb_ru_init_utf8(internal)
- spell_init(internal)
- spell_lexize(internal, internal, integer)
- split_date_range(text)
- stat(text)
- stat(text, text)
- strip(tsvector)
- svals(public.hstore)
- syn_init(internal)
- syn_lexize(internal, internal, integer)
- tconvert(text, text)
- text_concat(text, text)
- thesaurus_init(internal)
- thesaurus_lexize(internal, internal, integer, internal)
- to_tsquery(oid, text)
- to_tsquery(text)
- to_tsquery(text, text)
- to_tsvector(oid, text)
- to_tsvector(text)
- to_tsvector(text, text)
- token_type()
- token_type(integer)
- token_type(text)
- translate_isbn1013(text)
- ts_debug(text)
- tsearch2()
- tsq_mcontained(tsquery, tsquery)
- tsq_mcontains(tsquery, tsquery)
- tsquery_and(tsquery, tsquery)
- tsquery_not(tsquery)
- tsquery_or(tsquery, tsquery)
- uppercase(text)
- xml_encode_special_chars(text)
- xml_valid(text)
- xpath_bool(text, text)
- xpath_list(text, text)
- xpath_list(text, text, text)
- xpath_nodeset(text, text)
- xpath_nodeset(text, text, text)
- xpath_nodeset(text, text, text, text)
- xpath_number(text, text)
- xpath_string(text, text)
- xpath_table(text, text, text, text, text)
- xslt_process(text, text)
- xslt_process(text, text, text)
- query
- reporter
- search
- relevance_adjustment
- query_parser_fts(param_pref_ou integer, staff integer, metarecord text, param_limit integer[], param_check integer[], param_offset integer, param_locations integer, param_statuses integer, param_query boolean, param_depth boolean, param_search_ou integer)
- serial
- staging
- stats
- unapi
- bre_output_layout
- acl(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- acn(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- acnp(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- acns(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- acp(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- acpn(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- aou(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- ascecm(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- auri(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- biblio_record_entry_feed(header_xml bigint[], unapi_url text, update_ts text[], creator text, description integer, title public.hstore, include_xmlns public.hstore, soffset boolean, slimit text, depth text, org text, includes text, format text, id_list xml)
- bmp(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- bre(pref_lib bigint, include_xmlns text, soffset text, slimit text[], depth text, org integer, includes public.hstore, ename public.hstore, format boolean, obj_id integer)
- ccs(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- circ(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- holdings_xml(pref_lib bigint, include_xmlns integer, soffset text, slimit integer, includes text[], depth public.hstore, org public.hstore, ouid boolean, bid integer)
- memoize(include_xmlns text, soffset bigint, slimit text, depth text, org text[], includes text, ename integer, format public.hstore, obj_id public.hstore, classname boolean)
- mra(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- sbsum(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- sdist(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- siss(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- sisum(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- sitem(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- sssum(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- sstr(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- ssub(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- sunit(include_xmlns bigint, soffset text, slimit text, depth text[], org text, includes integer, ename public.hstore, format public.hstore, obj_id boolean)
- vandelay
- authority_attr_definition
- authority_match
- authority_queue
- bib_attr_definition
- bib_match
- bib_queue
- import_bib_trash_fields
- import_error
- import_item
- import_item_attr_definition
- match_set
- match_set_point
- match_set_quality
- merge_profile
- queue
- queued_authority_record
- queued_authority_record_attr
- queued_bib_record
- queued_bib_record_attr
- queued_record
- _get_expr_push_jrow(node vandelay.match_set_point)
- _get_expr_push_qrow(node vandelay.match_set_point)
- _get_expr_render_one(node vandelay.match_set_point)
- add_field(field text, source_xml text, target_xml text)
- add_field(force_add text, field text, source_xml text, target_xml integer)
- auto_overlay_authority_queue(merge_profile_id bigint, queue_id integer)
- auto_overlay_authority_queue(queue_id bigint)
- auto_overlay_authority_record(merge_profile_id bigint, import_id integer)
- auto_overlay_bib_queue(merge_profile_id bigint, queue_id integer)
- auto_overlay_bib_queue(queue_id bigint)
- auto_overlay_bib_queue_with_best(lwm_ratio_value bigint, merge_profile_id integer, queue_id numeric)
- auto_overlay_bib_queue_with_best(merge_profile_id bigint, import_id integer)
- auto_overlay_bib_record(merge_profile_id bigint, import_id integer)
- auto_overlay_bib_record_with_best(lwm_ratio_value_p bigint, merge_profile_id integer, import_id numeric)
- auto_overlay_bib_record_with_best(merge_profile_id bigint, import_id integer)
- cleanup_authority_marc()
- cleanup_bib_marc()
- compile_profile(incoming_xml text)
- extract_rec_attrs(attr_defs text, xml text[])
- extract_rec_attrs(xml text)
- find_bib_tcn_data(xml text)
- flatten_marc(marc text)
- flatten_marc_hstore(record_xml text)
- flay_marc(text)
- get_expr_from_match_set(match_set_id integer)
- get_expr_from_match_set_point(node vandelay.match_set_point)
- ingest_authority_marc()
- ingest_bib_items()
- ingest_bib_marc()
- ingest_items(attr_def_id bigint, import_id bigint)
- marc21_extract_all_fixed_fields(marc text)
- marc21_extract_fixed_field(ff text, marc text)
- marc21_physical_characteristics(marc text)
- marc21_record_type(marc text)
- match_bib_record()
- match_set_test_marcxml(record_xml integer, match_set_id text)
- measure_record_quality(match_set_id text, xml integer)
- merge_record_xml(strip_rule text, replace_preserve_rule text, add_rule text, source_xml text, target_xml text)
- merge_record_xml(template_marc text, target_marc text)
- overlay_authority_record(merge_profile_id bigint, eg_id bigint, import_id integer)
- overlay_bib_record(merge_profile_id bigint, eg_id bigint, import_id integer)
- replace_field(field text, source_xml text, target_xml text)
- strip_field(field text, xml text)
- template_overlay_bib_record(eg_id text, v_marc bigint)
- template_overlay_bib_record(merge_profile_id text, eg_id bigint, v_marc integer)
Schema acq
acq.acq_lineitem_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
id |
bigint |
NOT NULL
|
|
creator |
integer |
NOT NULL
|
|
editor |
integer |
NOT NULL
|
|
selector |
integer |
NOT NULL
|
|
provider |
integer |
|
|
purchase_order |
integer |
|
|
picklist |
integer |
|
|
expected_recv_time |
timestamp with time zone |
|
|
create_time |
timestamp with time zone |
NOT NULL
|
|
edit_time |
timestamp with time zone |
NOT NULL
|
|
marc |
text |
NOT NULL
|
|
eg_bib_id |
bigint |
|
|
source_label |
text |
|
|
state |
text |
NOT NULL
|
|
cancel_reason |
integer |
|
|
estimated_unit_price |
numeric |
|
|
claim_policy |
integer |
|
|
queued_record |
bigint |
|
acq_lineitem_hist_id_idx id
Index -
Schema acq
acq.acq_lineitem_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
?column? |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
id |
bigint |
|
|
creator |
integer |
|
|
editor |
integer |
|
|
selector |
integer |
|
|
provider |
integer |
|
|
purchase_order |
integer |
|
|
picklist |
integer |
|
|
expected_recv_time |
timestamp with time zone |
|
|
create_time |
timestamp with time zone |
|
|
edit_time |
timestamp with time zone |
|
|
marc |
text |
|
|
eg_bib_id |
bigint |
|
|
source_label |
text |
|
|
state |
text |
|
|
cancel_reason |
integer |
|
|
estimated_unit_price |
numeric |
|
|
claim_policy |
integer |
|
|
queued_record |
bigint |
|
SELECT (-1)
, now
() AS audit_time
,'-'::text AS audit_action
, lineitem.id
, lineitem.creator
, lineitem.editor
, lineitem.selector
, lineitem.provider
, lineitem.purchase_order
, lineitem.picklist
, lineitem.expected_recv_time
, lineitem.create_time
, lineitem.edit_time
, lineitem.marc
, lineitem.eg_bib_id
, lineitem.source_label
, lineitem.state
, lineitem.cancel_reason
, lineitem.estimated_unit_price
, lineitem.claim_policy
, lineitem.queued_record
FROM acq.lineitem
UNION ALLSELECT acq_lineitem_history.audit_id AS "?column?"
, acq_lineitem_history.audit_time
, acq_lineitem_history.audit_action
, acq_lineitem_history.id
, acq_lineitem_history.creator
, acq_lineitem_history.editor
, acq_lineitem_history.selector
, acq_lineitem_history.provider
, acq_lineitem_history.purchase_order
, acq_lineitem_history.picklist
, acq_lineitem_history.expected_recv_time
, acq_lineitem_history.create_time
, acq_lineitem_history.edit_time
, acq_lineitem_history.marc
, acq_lineitem_history.eg_bib_id
, acq_lineitem_history.source_label
, acq_lineitem_history.state
, acq_lineitem_history.cancel_reason
, acq_lineitem_history.estimated_unit_price
, acq_lineitem_history.claim_policy
, acq_lineitem_history.queued_record
FROM acq.acq_lineitem_history;
Index -
Schema acq
acq.acq_purchase_order_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
id |
integer |
NOT NULL
|
|
owner |
integer |
NOT NULL
|
|
creator |
integer |
NOT NULL
|
|
editor |
integer |
NOT NULL
|
|
ordering_agency |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
|
|
edit_time |
timestamp with time zone |
NOT NULL
|
|
provider |
integer |
NOT NULL
|
|
state |
text |
NOT NULL
|
|
order_date |
timestamp with time zone |
|
|
name |
text |
NOT NULL
|
|
cancel_reason |
integer |
|
|
prepayment_required |
boolean |
NOT NULL
|
acq_po_hist_id_idx id
Index -
Schema acq
acq.acq_purchase_order_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
?column? |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
id |
integer |
|
|
owner |
integer |
|
|
creator |
integer |
|
|
editor |
integer |
|
|
ordering_agency |
integer |
|
|
create_time |
timestamp with time zone |
|
|
edit_time |
timestamp with time zone |
|
|
provider |
integer |
|
|
state |
text |
|
|
order_date |
timestamp with time zone |
|
|
name |
text |
|
|
cancel_reason |
integer |
|
|
prepayment_required |
boolean |
|
SELECT (-1)
, now
() AS audit_time
,'-'::text AS audit_action
, purchase_order.id
, purchase_order.owner
, purchase_order.creator
, purchase_order.editor
, purchase_order.ordering_agency
, purchase_order.create_time
, purchase_order.edit_time
, purchase_order.provider
, purchase_order.state
, purchase_order.order_date
, purchase_order.name
, purchase_order.cancel_reason
, purchase_order.prepayment_required
FROM acq.purchase_order
UNION ALLSELECT acq_purchase_order_history.audit_id AS "?column?"
, acq_purchase_order_history.audit_time
, acq_purchase_order_history.audit_action
, acq_purchase_order_history.id
, acq_purchase_order_history.owner
, acq_purchase_order_history.creator
, acq_purchase_order_history.editor
, acq_purchase_order_history.ordering_agency
, acq_purchase_order_history.create_time
, acq_purchase_order_history.edit_time
, acq_purchase_order_history.provider
, acq_purchase_order_history.state
, acq_purchase_order_history.order_date
, acq_purchase_order_history.name
, acq_purchase_order_history.cancel_reason
, acq_purchase_order_history.prepayment_required
FROM acq.acq_purchase_order_history;
Index -
Schema acq
acq.all_fund_allocation_total Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT f.id AS fund
, COALESCE
(
(sum
(
(a.amount * acq.exchange_ratio
(s.currency_type
, f.currency_type
)
)
)
)::numeric
(100
,2
)
, (0)::numeric
) AS amount
FROM (
(acq.fund f
LEFT JOIN acq.fund_allocation a
ON (
(a.fund = f.id)
)
)
LEFT JOIN acq.funding_source s
ON (
(a.funding_source = s.id)
)
)
GROUP BY f.id;
Index -
Schema acq
acq.all_fund_combined_balance Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT a.fund
, (a.amount - COALESCE
(c.amount
, (0)::numeric
)
) AS amount
FROM (acq.all_fund_allocation_total a
LEFT JOIN (
SELECT fund_debit.fund
, sum
(fund_debit.amount) AS amount
FROM acq.fund_debit
GROUP BY fund_debit.fund
) c
USING (fund)
);
Index -
Schema acq
acq.all_fund_encumbrance_total Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT f.id AS fund
, COALESCE
(encumb.amount
, (0)::numeric
) AS amount
FROM (acq.fund f
LEFT JOIN (
SELECT fund_debit.fund
, sum
(fund_debit.amount) AS amount
FROM acq.fund_debit
WHERE fund_debit.encumbrance
GROUP BY fund_debit.fund
) encumb
ON (
(f.id = encumb.fund)
)
);
Index -
Schema acq
acq.all_fund_spent_balance Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT c.fund
, (c.amount - d.amount) AS amount
FROM (acq.all_fund_allocation_total c
LEFT JOIN acq.all_fund_spent_total d
USING (fund)
);
Index -
Schema acq
acq.all_fund_spent_total Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT f.id AS fund
, COALESCE
(spent.amount
, (0)::numeric
) AS amount
FROM (acq.fund f
LEFT JOIN (
SELECT fund_debit.fund
, sum
(fund_debit.amount) AS amount
FROM acq.fund_debit
WHERE (NOT fund_debit.encumbrance)
GROUP BY fund_debit.fund
) spent
ON (
(f.id = spent.fund)
)
);
Index -
Schema acq
acq.cancel_reason Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
org_unit |
integer |
UNIQUE#1
NOT NULL
|
|
label |
text |
UNIQUE#1
NOT NULL
|
|
description |
text |
NOT NULL
|
|
keep_debits |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
Tables referencing this one via Foreign Key Constraints:
claim_lid_idx lineitem_detail
Index -
Schema acq
acq.claim_event Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
acq.claim_event_type.id
|
type |
integer |
NOT NULL
|
acq.claim.id
|
claim |
serial |
NOT NULL
|
|
event_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
|
note |
text |
|
claim_event_claim_date_idx claim, event_date
Index -
Schema acq
acq.claim_event_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
org_unit |
integer |
UNIQUE#1
NOT NULL
|
|
code |
text |
UNIQUE#1
NOT NULL
|
|
description |
text |
NOT NULL
|
|
library_initiated |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.claim_policy Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
org_unit |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
description |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.claim_policy_action Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.claim_policy.id
|
claim_policy |
integer |
UNIQUE#1
NOT NULL
|
|
action_interval |
interval |
UNIQUE#1
NOT NULL
|
acq.claim_event_type.id
|
action |
integer |
NOT NULL
|
Index -
Schema acq
acq.claim_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
org_unit |
integer |
UNIQUE#1
NOT NULL
|
|
code |
text |
UNIQUE#1
NOT NULL
|
|
description |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.currency_type Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
label |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.debit_attribution Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
PRIMARY KEY
|
acq.fund_debit.id
|
fund_debit |
integer |
NOT NULL
|
|
debit_amount |
numeric |
NOT NULL
|
acq.funding_source_credit.id
|
funding_source_credit |
integer |
|
|
credit_amount |
numeric |
|
acq_attribution_credit_idx funding_source_credit
acq_attribution_debit_idx fund_debit
Index -
Schema acq
acq.distribution_formula Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
skip_count |
integer |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.distribution_formula_application Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
acq.distribution_formula.id
|
formula |
integer |
NOT NULL
|
acq.lineitem.id
|
lineitem |
integer |
NOT NULL
|
acqdfa_creator_idx creator
acqdfa_df_idx formula
acqdfa_li_idx lineitem
Index -
Schema acq
acq.distribution_formula_entry Constraints
Name |
Constraint |
acqdfe_must_be_somewhere |
CHECK (((owning_lib IS NOT NULL) OR (location IS NOT NULL))) |
Index -
Schema acq
acq.edi_account Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
PRIMARY KEY
DEFAULT nextval('config.remote_account_id_seq'::regclass)
|
|
label |
text |
NOT NULL
|
|
host |
text |
NOT NULL
|
|
username |
text |
|
|
password |
text |
|
|
account |
text |
|
|
path |
text |
|
|
owner |
integer |
NOT NULL
|
|
last_activity |
timestamp with time zone |
|
acq.provider.id
|
provider |
integer |
NOT NULL
|
|
in_dir |
text |
|
|
vendcode |
text |
|
|
vendacct |
text |
|
Table acq.edi_account Inherits
remote_account,
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.edi_message Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.edi_account.id
|
account |
integer |
|
|
remote_file |
text |
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
translate_time |
timestamp with time zone |
|
|
process_time |
timestamp with time zone |
|
|
error_time |
timestamp with time zone |
|
|
status |
text |
NOT NULL
DEFAULT 'new'::text
|
|
edi |
text |
|
|
jedi |
text |
|
|
error |
text |
|
acq.purchase_order.id
|
purchase_order |
integer |
|
|
message_type |
text |
NOT NULL
|
acq.edi_message Constraints
Name |
Constraint |
status_value |
CHECK ((status = ANY (ARRAY['new'::text, 'translated'::text, 'trans_error'::text, 'processed'::text, 'proc_error'::text, 'delete_error'::text, 'retry'::text, 'complete'::text]))) |
valid_message_type |
CHECK ((message_type = ANY (ARRAY['ORDERS'::text, 'ORDRSP'::text, 'INVOIC'::text, 'OSTENQ'::text, 'OSTRPT'::text]))) |
Index -
Schema acq
Index -
Schema acq
acq.fiscal_calendar Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.fiscal_year Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.fiscal_calendar.id
|
calendar |
integer |
UNIQUE#1
UNIQUE#2
NOT NULL
|
|
year |
integer |
UNIQUE#1
NOT NULL
|
|
year_begin |
timestamp with time zone |
UNIQUE#2
NOT NULL
|
|
year_end |
timestamp with time zone |
NOT NULL
|
Index -
Schema acq
acq.fund Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
org |
integer |
UNIQUE#2
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
year |
integer |
UNIQUE#2
UNIQUE#1
NOT NULL
DEFAULT date_part('year'::text, now())
|
acq.currency_type.code
|
currency_type |
text |
NOT NULL
|
|
code |
text |
UNIQUE#2
|
|
rollover |
boolean |
NOT NULL
DEFAULT false
|
|
propagate |
boolean |
NOT NULL
DEFAULT true
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
|
balance_warning_percent |
integer |
|
|
balance_stop_percent |
integer |
|
acq.fund Constraints
Name |
Constraint |
acq_fund_rollover_implies_propagate |
CHECK ((propagate OR (NOT rollover))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.fund_allocation Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.funding_source.id
|
funding_source |
integer |
NOT NULL
|
acq.fund.id
|
fund |
integer |
NOT NULL
|
|
amount |
numeric |
NOT NULL
|
actor.usr.id
|
allocator |
integer |
NOT NULL
|
|
note |
text |
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
fund_alloc_allocator_idx allocator
Index -
Schema acq
acq.fund_allocation_percent Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.funding_source.id
|
funding_source |
integer |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
org |
integer |
UNIQUE#1
NOT NULL
|
|
fund_code |
text |
UNIQUE#1
|
|
percent |
numeric |
NOT NULL
|
actor.usr.id
|
allocator |
integer |
NOT NULL
|
|
note |
text |
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
acq.fund_allocation_percent Constraints
Name |
Constraint |
percentage_range |
CHECK (((percent >= (0)::numeric) AND (percent <= (100)::numeric))) |
Index -
Schema acq
acq.fund_allocation_total Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric(100,2) |
|
SELECT a.fund
, (sum
(
(a.amount * acq.exchange_ratio
(s.currency_type
, f.currency_type
)
)
)
)::numeric
(100
,2
) AS amount
FROM (
(acq.fund_allocation a
JOIN acq.fund f
ON (
(a.fund = f.id)
)
)
JOIN acq.funding_source s
ON (
(a.funding_source = s.id)
)
)
GROUP BY a.fund;
Index -
Schema acq
acq.fund_combined_balance Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT c.fund
, (c.amount - COALESCE
(d.amount
, 0.0
)
) AS amount
FROM (acq.fund_allocation_total c
LEFT JOIN acq.fund_debit_total d
USING (fund)
);
Index -
Schema acq
acq.fund_debit Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.fund.id
|
fund |
integer |
NOT NULL
|
|
origin_amount |
numeric |
NOT NULL
|
acq.currency_type.code
|
origin_currency_type |
text |
NOT NULL
|
|
amount |
numeric |
NOT NULL
|
|
encumbrance |
boolean |
NOT NULL
DEFAULT true
|
|
debit_type |
text |
NOT NULL
|
acq.fund.id
|
xfer_destination |
integer |
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.fund_debit_total Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT fund.id AS fund
, sum
(COALESCE
(fund_debit.amount
, (0)::numeric
)
) AS amount
FROM (acq.fund fund
LEFT JOIN acq.fund_debit fund_debit
ON (
(fund.id = fund_debit.fund)
)
)
GROUP BY fund.id;
Index -
Schema acq
acq.fund_encumbrance_total Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT fund.id AS fund
, sum
(COALESCE
(fund_debit.amount
, (0)::numeric
)
) AS amount
FROM (acq.fund fund
LEFT JOIN acq.fund_debit fund_debit
ON (
(fund.id = fund_debit.fund)
)
)
WHERE fund_debit.encumbrance
GROUP BY fund.id;
Index -
Schema acq
acq.fund_spent_balance Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT c.fund
, (c.amount - COALESCE
(d.amount
, 0.0
)
) AS amount
FROM (acq.fund_allocation_total c
LEFT JOIN acq.fund_spent_total d
USING (fund)
);
Index -
Schema acq
acq.fund_spent_total Structure
F-Key |
Name |
Type |
Description |
|
fund |
integer |
|
|
amount |
numeric |
|
SELECT fund.id AS fund
, sum
(COALESCE
(fund_debit.amount
, (0)::numeric
)
) AS amount
FROM (acq.fund fund
LEFT JOIN acq.fund_debit fund_debit
ON (
(fund.id = fund_debit.fund)
)
)
WHERE (NOT fund_debit.encumbrance)
GROUP BY fund.id;
Index -
Schema acq
acq.fund_tag Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.fund_tag_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.fund.id
|
fund |
integer |
UNIQUE#1
NOT NULL
|
acq.fund_tag.id
|
tag |
integer |
UNIQUE#1
|
Index -
Schema acq
Fund Transfer
Each row represents the transfer of money from a source fund
to a destination fund. There should be corresponding entries
in acq.fund_allocation. The purpose of acq.fund_transfer is
to record how much money moved from which fund to which other
fund.
The presence of two amount fields, rather than one, reflects
the possibility that the two funds are denominated in different
currencies. If they use the same currency type, the two
amounts should be the same.
acq.fund_transfer Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.fund.id
|
src_fund |
integer |
NOT NULL
|
|
src_amount |
numeric |
NOT NULL
|
acq.fund.id
|
dest_fund |
integer |
|
|
dest_amount |
numeric |
|
|
transfer_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
actor.usr.id
|
transfer_user |
integer |
NOT NULL
|
|
note |
text |
|
acq.funding_source_credit.id
|
funding_source_credit |
integer |
NOT NULL
|
acqftr_usr_idx transfer_user
Index -
Schema acq
acq.funding_source Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
acq.currency_type.code
|
currency_type |
text |
NOT NULL
|
|
code |
text |
UNIQUE
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.funding_source_allocation_total Structure
F-Key |
Name |
Type |
Description |
|
funding_source |
integer |
|
|
amount |
numeric(100,2) |
|
SELECT a.funding_source
, (sum
(a.amount)
)::numeric
(100
,2
) AS amount
FROM acq.fund_allocation a
GROUP BY a.funding_source;
Index -
Schema acq
acq.funding_source_balance Structure
F-Key |
Name |
Type |
Description |
|
funding_source |
integer |
|
|
amount |
numeric(100,2) |
|
SELECT COALESCE
(c.funding_source
, a.funding_source
) AS funding_source
, (sum
(
(COALESCE
(c.amount
, 0.0
) - COALESCE
(a.amount
, 0.0
)
)
)
)::numeric
(100
,2
) AS amount
FROM (acq.funding_source_credit_total c FULL
JOIN acq.funding_source_allocation_total a
USING (funding_source)
)
GROUP BY COALESCE
(c.funding_source
, a.funding_source
);
Index -
Schema acq
acq.funding_source_credit Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.funding_source.id
|
funding_source |
integer |
NOT NULL
|
|
amount |
numeric |
NOT NULL
|
|
note |
text |
|
|
deadline_date |
timestamp with time zone |
|
|
effective_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.funding_source_credit_total Structure
F-Key |
Name |
Type |
Description |
|
funding_source |
integer |
|
|
amount |
numeric |
|
SELECT funding_source_credit.funding_source
, sum
(funding_source_credit.amount) AS amount
FROM acq.funding_source_credit
GROUP BY funding_source_credit.funding_source;
Index -
Schema acq
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.invoice_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.invoice.id
|
invoice |
integer |
NOT NULL
|
acq.purchase_order.id
|
purchase_order |
integer |
|
acq.lineitem.id
|
lineitem |
integer |
|
|
inv_item_count |
integer |
NOT NULL
|
|
phys_item_count |
integer |
|
|
note |
text |
|
|
billed_per_item |
boolean |
|
|
cost_billed |
numeric(8,2) |
|
|
actual_cost |
numeric(8,2) |
|
|
amount_paid |
numeric(8,2) |
|
ie_inv_idx invoice
ie_li_idx lineitem
ie_po_idx purchase_order
Index -
Schema acq
ii_inv_idx invoice
ii_po_idx purchase_order
ii_poi_idx po_item
Index -
Schema acq
acq.invoice_item_type Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
|
prorate |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.invoice_method Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.invoice_payment_method Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.lineitem Constraints
Name |
Constraint |
picklist_or_po |
CHECK (((picklist IS NOT NULL) OR (purchase_order IS NOT NULL))) |
Tables referencing this one via Foreign Key Constraints:
li_creator_idx creator
li_editor_idx editor
li_pl_idx picklist
li_po_idx purchase_order
li_selector_idx selector
Index -
Schema acq
acq.lineitem_alert_text Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
code |
text |
UNIQUE#1
NOT NULL
|
|
description |
text |
|
actor.org_unit.id
|
owning_lib |
integer |
UNIQUE#1
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.lineitem_attr Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
definition |
bigint |
NOT NULL
|
acq.lineitem.id
|
lineitem |
bigint |
NOT NULL
|
|
attr_type |
text |
NOT NULL
|
|
attr_name |
text |
NOT NULL
|
|
attr_value |
text |
NOT NULL
|
li_attr_definition_idx definition
li_attr_li_idx lineitem
li_attr_value_idx attr_value
Index -
Schema acq
acq.lineitem_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
code |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
|
remove |
text |
NOT NULL
DEFAULT ''::text
|
|
ident |
boolean |
NOT NULL
DEFAULT false
|
Index -
Schema acq
Tables referencing this one via Foreign Key Constraints:
li_detail_li_idx lineitem
Index -
Schema acq
acq.lineitem_generated_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('acq.lineitem_attr_definition_id_seq'::regclass)
|
|
code |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
|
remove |
text |
NOT NULL
DEFAULT ''::text
|
|
ident |
boolean |
NOT NULL
DEFAULT false
|
|
xpath |
text |
NOT NULL
|
Table acq.lineitem_generated_attr_definition Inherits
lineitem_attr_definition,
Index -
Schema acq
acq.lineitem_local_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('acq.lineitem_attr_definition_id_seq'::regclass)
|
|
code |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
|
remove |
text |
NOT NULL
DEFAULT ''::text
|
|
ident |
boolean |
NOT NULL
DEFAULT false
|
Table acq.lineitem_local_attr_definition Inherits
lineitem_attr_definition,
Index -
Schema acq
acq.lineitem_marc_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('acq.lineitem_attr_definition_id_seq'::regclass)
|
|
code |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
|
remove |
text |
NOT NULL
DEFAULT ''::text
|
|
ident |
boolean |
NOT NULL
DEFAULT false
|
|
xpath |
text |
NOT NULL
|
Table acq.lineitem_marc_attr_definition Inherits
lineitem_attr_definition,
Index -
Schema acq
acq.lineitem_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.lineitem.id
|
lineitem |
integer |
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
actor.usr.id
|
editor |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
value |
text |
NOT NULL
|
acq.lineitem_alert_text.id
|
alert_text |
integer |
|
|
vendor_public |
boolean |
NOT NULL
DEFAULT false
|
li_note_creator_idx creator
li_note_editor_idx editor
li_note_li_idx lineitem
Index -
Schema acq
acq.lineitem_provider_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('acq.lineitem_attr_definition_id_seq'::regclass)
|
|
code |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
|
remove |
text |
NOT NULL
DEFAULT ''::text
|
|
ident |
boolean |
NOT NULL
DEFAULT false
|
|
xpath |
text |
NOT NULL
|
acq.provider.id
|
provider |
integer |
NOT NULL
|
Table acq.lineitem_provider_attr_definition Inherits
lineitem_attr_definition,
Index -
Schema acq
acq.lineitem_usr_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('acq.lineitem_attr_definition_id_seq'::regclass)
|
|
code |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
|
remove |
text |
NOT NULL
DEFAULT ''::text
|
|
ident |
boolean |
NOT NULL
DEFAULT false
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
Table acq.lineitem_usr_attr_definition Inherits
lineitem_attr_definition,
li_usr_attr_def_usr_idx usr
Index -
Schema acq
The acq.ordered_funding_source_credit view is a prioritized
ordering of funding source credits. When ordered by the first
three columns, this view defines the order in which the various
credits are to be tapped for spending, subject to the allocations
in the acq.fund_allocation table.
The first column reflects the principle that we should spend
money with deadlines before spending money without deadlines.
The second column reflects the principle that we should spend the
oldest money first. For money with deadlines, that means that we
spend first from the credit with the earliest deadline. For
money without deadlines, we spend first from the credit with the
earliest effective date.
The third column is a tie breaker to ensure a consistent
ordering.
acq.ordered_funding_source_credit Structure
F-Key |
Name |
Type |
Description |
|
sort_priority |
integer |
|
|
sort_date |
timestamp with time zone |
|
|
id |
integer |
|
|
funding_source |
integer |
|
|
amount |
numeric |
|
|
note |
text |
|
SELECT CASE WHEN
(funding_source_credit.deadline_date IS NULL) THEN 2 ELSE 1 END AS sort_priority
, CASE WHEN
(funding_source_credit.deadline_date IS NULL) THEN funding_source_credit.effective_date ELSE funding_source_credit.deadline_date END AS sort_date
, funding_source_credit.id
, funding_source_credit.funding_source
, funding_source_credit.amount
, funding_source_credit.note
FROM acq.funding_source_credit;
Index -
Schema acq
acq.picklist Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
actor.usr.id
|
editor |
integer |
NOT NULL
|
actor.org_unit.id
|
org_unit |
integer |
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
acq_picklist_creator_idx creator
acq_picklist_editor_idx editor
acq_picklist_owner_idx owner
Index -
Schema acq
Tables referencing this one via Foreign Key Constraints:
poi_po_idx purchase_order
Index -
Schema acq
acq.po_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.purchase_order.id
|
purchase_order |
integer |
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
actor.usr.id
|
editor |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
value |
text |
NOT NULL
|
|
vendor_public |
boolean |
NOT NULL
DEFAULT false
|
acq_po_note_creator_idx creator
acq_po_note_editor_idx editor
po_note_po_idx purchase_order
Index -
Schema acq
acq.provider Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#2
UNIQUE#1
NOT NULL
|
acq.currency_type.code
|
currency_type |
text |
NOT NULL
|
|
code |
text |
UNIQUE#2
NOT NULL
|
|
holding_tag |
text |
|
|
san |
text |
|
acq.edi_account.id
|
edi_default |
integer |
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
|
prepayment_required |
boolean |
NOT NULL
DEFAULT false
|
|
url |
text |
|
|
email |
text |
|
|
phone |
text |
|
|
fax_phone |
text |
|
acq.claim_policy.id
|
default_claim_policy |
integer |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.provider_address Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
valid |
boolean |
NOT NULL
DEFAULT true
|
|
address_type |
text |
|
acq.provider.id
|
provider |
integer |
NOT NULL
|
|
street1 |
text |
NOT NULL
|
|
street2 |
text |
|
|
city |
text |
NOT NULL
|
|
county |
text |
|
|
state |
text |
NOT NULL
|
|
country |
text |
NOT NULL
|
|
post_code |
text |
NOT NULL
|
|
fax_phone |
text |
|
Index -
Schema acq
acq.provider_contact Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.provider.id
|
provider |
integer |
NOT NULL
|
|
name |
text |
NOT NULL
|
|
role |
text |
|
|
email |
text |
|
|
phone |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
acq.provider_contact_address Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
valid |
boolean |
NOT NULL
DEFAULT true
|
|
address_type |
text |
|
acq.provider_contact.id
|
contact |
integer |
NOT NULL
|
|
street1 |
text |
NOT NULL
|
|
street2 |
text |
|
|
city |
text |
NOT NULL
|
|
county |
text |
|
|
state |
text |
NOT NULL
|
|
country |
text |
NOT NULL
|
|
post_code |
text |
NOT NULL
|
|
fax_phone |
text |
|
Index -
Schema acq
acq.provider_holding_subfield_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.provider.id
|
provider |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
subfield |
text |
NOT NULL
|
Index -
Schema acq
acq.provider_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
acq.provider.id
|
provider |
integer |
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
actor.usr.id
|
editor |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
value |
text |
NOT NULL
|
acq_pro_note_creator_idx creator
acq_pro_note_editor_idx editor
acq_pro_note_pro_idx provider
Index -
Schema acq
acq.purchase_order Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
actor.usr.id
|
editor |
integer |
NOT NULL
|
actor.org_unit.id
|
ordering_agency |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
acq.provider.id
|
provider |
integer |
NOT NULL
|
|
state |
text |
NOT NULL
DEFAULT 'new'::text
|
|
order_date |
timestamp with time zone |
|
|
name |
text |
NOT NULL
|
acq.cancel_reason.id
|
cancel_reason |
integer |
|
|
prepayment_required |
boolean |
NOT NULL
DEFAULT false
|
acq.purchase_order Constraints
Name |
Constraint |
valid_po_state |
CHECK ((state = ANY (ARRAY['new'::text, 'pending'::text, 'on-order'::text, 'received'::text, 'cancelled'::text]))) |
Tables referencing this one via Foreign Key Constraints:
acq_po_org_name_order_date_idx ordering_agency, name, order_date
po_creator_idx creator
po_editor_idx editor
po_owner_idx owner
po_provider_idx provider
po_state_idx state
Index -
Schema acq
Tables referencing this one via Foreign Key Constraints:
serial_claim_lid_idx item
Index -
Schema acq
acq.serial_claim_event Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
acq.claim_event_type.id
|
type |
integer |
NOT NULL
|
acq.serial_claim.id
|
claim |
serial |
NOT NULL
|
|
event_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
|
note |
text |
|
serial_claim_event_claim_date_idx claim, event_date
Index -
Schema acq
acq.user_request Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
|
hold |
boolean |
NOT NULL
DEFAULT true
|
actor.org_unit.id
|
pickup_lib |
integer |
NOT NULL
|
|
holdable_formats |
text |
|
|
phone_notify |
text |
|
|
email_notify |
boolean |
NOT NULL
DEFAULT true
|
acq.lineitem.id
|
lineitem |
integer |
|
biblio.record_entry.id
|
eg_bib |
bigint |
|
|
request_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
need_before |
timestamp with time zone |
|
|
max_fee |
text |
|
acq.user_request_type.id
|
request_type |
integer |
NOT NULL
|
|
isxn |
text |
|
|
title |
text |
|
|
volume |
text |
|
|
author |
text |
|
|
article_title |
text |
|
|
article_pages |
text |
|
|
publisher |
text |
|
|
location |
text |
|
|
pubdate |
text |
|
|
mentioned |
text |
|
|
other_info |
text |
|
acq.cancel_reason.id
|
cancel_reason |
integer |
|
Index -
Schema acq
acq.user_request_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
label |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema acq
Returns: void
Language: PLPGSQL
/*
Function to attribute expenditures and encumbrances to funding source credits,
and thereby to funding sources.
Read the debits in chonological order, attributing each one to one or
more funding source credits. Constraints:
1. Don't attribute more to a credit than the amount of the credit.
2. For a given fund, don't attribute more to a funding source than the
source has allocated to that fund.
3. Attribute debits to credits with deadlines before attributing them to
credits without deadlines. Otherwise attribute to the earliest credits
first, based on the deadline date when present, or on the effective date
when there is no deadline. Use funding_source_credit.id as a tie-breaker.
This ordering is defined by an ORDER BY clause on the view
acq.ordered_funding_source_credit.
Start by truncating the table acq.debit_attribution. Then insert a row
into that table for each attribution. If a debit cannot be fully
attributed, insert a row for the unattributable balance, with the
funding_source_credit and credit_amount columns NULL.
*/
DECLARE
curr_fund_source_bal RECORD;
seqno INT; -- sequence num for credits applicable to a fund
fund_credit RECORD; -- current row in temp t_fund_credit table
fc RECORD; -- used for loading t_fund_credit table
sc RECORD; -- used for loading t_fund_credit table
--
-- Used exclusively in the main loop:
--
deb RECORD; -- current row from acq.fund_debit table
curr_credit_bal RECORD; -- current row from temp t_credit table
debit_balance NUMERIC; -- amount left to attribute for current debit
conv_debit_balance NUMERIC; -- debit balance in currency of the fund
attr_amount NUMERIC; -- amount being attributed, in currency of debit
conv_attr_amount NUMERIC; -- amount being attributed, in currency of source
conv_cred_balance NUMERIC; -- credit_balance in the currency of the fund
conv_alloc_balance NUMERIC; -- allocated balance in the currency of the fund
attrib_count INT; -- populates id of acq.debit_attribution
BEGIN
--
-- Load a temporary table. For each combination of fund and funding source,
-- load an entry with the total amount allocated to that fund by that source.
-- This sum may reflect transfers as well as original allocations. We will
-- reduce this balance whenever we attribute debits to it.
--
CREATE TEMP TABLE t_fund_source_bal
ON COMMIT DROP AS
SELECT
fund AS fund,
funding_source AS source,
sum( amount ) AS balance
FROM
acq.fund_allocation
GROUP BY
fund,
funding_source
HAVING
sum( amount ) > 0;
--
CREATE INDEX t_fund_source_bal_idx
ON t_fund_source_bal( fund, source );
-------------------------------------------------------------------------------
--
-- Load another temporary table. For each fund, load zero or more
-- funding source credits from which that fund can get money.
--
CREATE TEMP TABLE t_fund_credit (
fund INT,
seq INT,
credit INT
) ON COMMIT DROP;
--
FOR fc IN
SELECT DISTINCT fund
FROM acq.fund_allocation
ORDER BY fund
LOOP -- Loop over the funds
seqno := 1;
FOR sc IN
SELECT
ofsc.id
FROM
acq.ordered_funding_source_credit AS ofsc
WHERE
ofsc.funding_source IN
(
SELECT funding_source
FROM acq.fund_allocation
WHERE fund = fc.fund
)
ORDER BY
ofsc.sort_priority,
ofsc.sort_date,
ofsc.id
LOOP -- Add each credit to the list
INSERT INTO t_fund_credit (
fund,
seq,
credit
) VALUES (
fc.fund,
seqno,
sc.id
);
--RAISE NOTICE 'Fund % credit %', fc.fund, sc.id;
seqno := seqno + 1;
END LOOP; -- Loop over credits for a given fund
END LOOP; -- Loop over funds
--
CREATE INDEX t_fund_credit_idx
ON t_fund_credit( fund, seq );
-------------------------------------------------------------------------------
--
-- Load yet another temporary table. This one is a list of funding source
-- credits, with their balances. We shall reduce those balances as we
-- attribute debits to them.
--
CREATE TEMP TABLE t_credit
ON COMMIT DROP AS
SELECT
fsc.id AS credit,
fsc.funding_source AS source,
fsc.amount AS balance,
fs.currency_type AS currency_type
FROM
acq.funding_source_credit AS fsc,
acq.funding_source fs
WHERE
fsc.funding_source = fs.id
AND fsc.amount > 0;
--
CREATE INDEX t_credit_idx
ON t_credit( credit );
--
-------------------------------------------------------------------------------
--
-- Now that we have loaded the lookup tables: loop through the debits,
-- attributing each one to one or more funding source credits.
--
truncate table acq.debit_attribution;
--
attrib_count := 0;
FOR deb in
SELECT
fd.id,
fd.fund,
fd.amount,
f.currency_type,
fd.encumbrance
FROM
acq.fund_debit fd,
acq.fund f
WHERE
fd.fund = f.id
ORDER BY
fd.id
LOOP
--RAISE NOTICE 'Debit %, fund %', deb.id, deb.fund;
--
debit_balance := deb.amount;
--
-- Loop over the funding source credits that are eligible
-- to pay for this debit
--
FOR fund_credit IN
SELECT
credit
FROM
t_fund_credit
WHERE
fund = deb.fund
ORDER BY
seq
LOOP
--RAISE NOTICE ' Examining credit %', fund_credit.credit;
--
-- Look up the balance for this credit. If it's zero, then
-- it's not useful, so treat it as if you didn't find it.
-- (Actually there shouldn't be any zero balances in the table,
-- but we check just to make sure.)
--
SELECT *
INTO curr_credit_bal
FROM t_credit
WHERE
credit = fund_credit.credit
AND balance > 0;
--
IF curr_credit_bal IS NULL THEN
--
-- This credit is exhausted; try the next one.
--
CONTINUE;
END IF;
--
--
-- At this point we have an applicable credit with some money left.
-- Now see if the relevant funding_source has any money left.
--
-- Look up the balance of the allocation for this combination of
-- fund and source. If you find such an entry, but it has a zero
-- balance, then it's not useful, so treat it as unfound.
-- (Actually there shouldn't be any zero balances in the table,
-- but we check just to make sure.)
--
SELECT *
INTO curr_fund_source_bal
FROM t_fund_source_bal
WHERE
fund = deb.fund
AND source = curr_credit_bal.source
AND balance > 0;
--
IF curr_fund_source_bal IS NULL THEN
--
-- This fund/source doesn't exist or is already exhausted,
-- so we can't use this credit. Go on to the next one.
--
CONTINUE;
END IF;
--
-- Convert the available balances to the currency of the fund
--
conv_alloc_balance := curr_fund_source_bal.balance * acq.exchange_ratio(
curr_credit_bal.currency_type, deb.currency_type );
conv_cred_balance := curr_credit_bal.balance * acq.exchange_ratio(
curr_credit_bal.currency_type, deb.currency_type );
--
-- Determine how much we can attribute to this credit: the minimum
-- of the debit amount, the fund/source balance, and the
-- credit balance
--
--RAISE NOTICE ' deb bal %', debit_balance;
--RAISE NOTICE ' source % balance %', curr_credit_bal.source, conv_alloc_balance;
--RAISE NOTICE ' credit % balance %', curr_credit_bal.credit, conv_cred_balance;
--
conv_attr_amount := NULL;
attr_amount := debit_balance;
--
IF attr_amount > conv_alloc_balance THEN
attr_amount := conv_alloc_balance;
conv_attr_amount := curr_fund_source_bal.balance;
END IF;
IF attr_amount > conv_cred_balance THEN
attr_amount := conv_cred_balance;
conv_attr_amount := curr_credit_bal.balance;
END IF;
--
-- If we're attributing all of one of the balances, then that's how
-- much we will deduct from the balances, and we already captured
-- that amount above. Otherwise we must convert the amount of the
-- attribution from the currency of the fund back to the currency of
-- the funding source.
--
IF conv_attr_amount IS NULL THEN
conv_attr_amount := attr_amount * acq.exchange_ratio(
deb.currency_type, curr_credit_bal.currency_type );
END IF;
--
-- Insert a row to record the attribution
--
attrib_count := attrib_count + 1;
INSERT INTO acq.debit_attribution (
id,
fund_debit,
debit_amount,
funding_source_credit,
credit_amount
) VALUES (
attrib_count,
deb.id,
attr_amount,
curr_credit_bal.credit,
conv_attr_amount
);
--
-- Subtract the attributed amount from the various balances
--
debit_balance := debit_balance - attr_amount;
curr_fund_source_bal.balance := curr_fund_source_bal.balance - conv_attr_amount;
--
IF curr_fund_source_bal.balance <= 0 THEN
--
-- This allocation is exhausted. Delete it so
-- that we don't waste time looking at it again.
--
DELETE FROM t_fund_source_bal
WHERE
fund = curr_fund_source_bal.fund
AND source = curr_fund_source_bal.source;
ELSE
UPDATE t_fund_source_bal
SET balance = balance - conv_attr_amount
WHERE
fund = curr_fund_source_bal.fund
AND source = curr_fund_source_bal.source;
END IF;
--
IF curr_credit_bal.balance <= 0 THEN
--
-- This funding source credit is exhausted. Delete it
-- so that we don't waste time looking at it again.
--
--DELETE FROM t_credit
--WHERE
-- credit = curr_credit_bal.credit;
--
DELETE FROM t_fund_credit
WHERE
credit = curr_credit_bal.credit;
ELSE
UPDATE t_credit
SET balance = curr_credit_bal.balance
WHERE
credit = curr_credit_bal.credit;
END IF;
--
-- Are we done with this debit yet?
--
IF debit_balance <= 0 THEN
EXIT; -- We've fully attributed this debit; stop looking at credits.
END IF;
END LOOP; -- End loop over credits
--
IF debit_balance <> 0 THEN
--
-- We weren't able to attribute this debit, or at least not
-- all of it. Insert a row for the unattributed balance.
--
attrib_count := attrib_count + 1;
INSERT INTO acq.debit_attribution (
id,
fund_debit,
debit_amount,
funding_source_credit,
credit_amount
) VALUES (
attrib_count,
deb.id,
debit_balance,
NULL,
NULL
);
END IF;
END LOOP; -- End of loop over debits
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO acq.acq_lineitem_history
SELECT nextval('acq.acq_lineitem_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
OLD.*;
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO acq.acq_purchase_order_history
SELECT nextval('acq.acq_purchase_order_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
OLD.*;
RETURN NULL;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
PERFORM acq.create_acq_seq(sch, tbl);
PERFORM acq.create_acq_history(sch, tbl);
PERFORM acq.create_acq_func(sch, tbl);
PERFORM acq.create_acq_update_trigger(sch, tbl);
PERFORM acq.create_acq_lifecycle(sch, tbl);
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
EXECUTE $$
CREATE OR REPLACE FUNCTION acq.audit_$$ || sch || $$_$$ || tbl || $$_func ()
RETURNS TRIGGER AS $func$
BEGIN
INSERT INTO acq.$$ || sch || $$_$$ || tbl || $$_history
SELECT nextval('acq.$$ || sch || $$_$$ || tbl || $$_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
OLD.*;
RETURN NULL;
END;
$func$ LANGUAGE 'plpgsql';
$$;
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
EXECUTE $$
CREATE TABLE acq.$$ || sch || $$_$$ || tbl || $$_history (
audit_id BIGINT PRIMARY KEY,
audit_time TIMESTAMP WITH TIME ZONE NOT NULL,
audit_action TEXT NOT NULL,
LIKE $$ || sch || $$.$$ || tbl || $$
);
$$;
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
EXECUTE $$
CREATE OR REPLACE VIEW acq.$$ || sch || $$_$$ || tbl || $$_lifecycle AS
SELECT -1, now() as audit_time, '-' as audit_action, *
FROM $$ || sch || $$.$$ || tbl || $$
UNION ALL
SELECT *
FROM acq.$$ || sch || $$_$$ || tbl || $$_history;
$$;
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
EXECUTE $$
CREATE SEQUENCE acq.$$ || sch || $$_$$ || tbl || $$_pkey_seq;
$$;
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
EXECUTE $$
CREATE TRIGGER audit_$$ || sch || $$_$$ || tbl || $$_update_trigger
AFTER UPDATE OR DELETE ON $$ || sch || $$.$$ || tbl || $$ FOR EACH ROW
EXECUTE PROCEDURE acq.audit_$$ || sch || $$_$$ || tbl || $$_func ();
$$;
RETURN TRUE;
END;
Returns: numeric
Language: SQL
SELECT $3 * acq.exchange_ratio($1, $2);
Returns: numeric
Language: PLPGSQL
DECLARE
rat NUMERIC;
BEGIN
IF from_ex = to_ex THEN
RETURN 1.0;
END IF;
SELECT ratio INTO rat FROM acq.exchange_rate WHERE from_currency = from_ex AND to_currency = to_ex;
IF FOUND THEN
RETURN rat;
ELSE
SELECT ratio INTO rat FROM acq.exchange_rate WHERE from_currency = to_ex AND to_currency = from_ex;
IF FOUND THEN
RETURN 1.0/rat;
END IF;
END IF;
RETURN NULL;
END;
Returns: SET OF flat_lineitem_holding_subfield
Language: PLPGSQL
DECLARE
counter INT;
lida acq.flat_lineitem_holding_subfield%ROWTYPE;
BEGIN
SELECT COUNT(*) INTO counter
FROM oils_xpath_table(
'id',
'marc',
'acq.lineitem',
'//*[@tag="' || tag || '"]',
'id=' || lineitem
) as t(i int,c text);
FOR i IN 1 .. counter LOOP
FOR lida IN
SELECT *
FROM ( SELECT id,i,t,v
FROM oils_xpath_table(
'id',
'marc',
'acq.lineitem',
'//*[@tag="' || tag || '"][position()=' || i || ']/*/@code|' ||
'//*[@tag="' || tag || '"][position()=' || i || ']/*[@code]',
'id=' || lineitem
) as t(id int,t text,v text)
)x
LOOP
RETURN NEXT lida;
END LOOP;
END LOOP;
RETURN;
END;
Returns: SET OF flat_lineitem_detail
Language: PLPGSQL
DECLARE
prov_i INT;
tag_t TEXT;
lida acq.flat_lineitem_detail%ROWTYPE;
BEGIN
SELECT provider INTO prov_i FROM acq.lineitem WHERE id = lineitem_i;
IF NOT FOUND THEN RETURN; END IF;
SELECT holding_tag INTO tag_t FROM acq.provider WHERE id = prov_i;
IF NOT FOUND OR tag_t IS NULL THEN RETURN; END IF;
FOR lida IN
SELECT lineitem_i,
h.holding,
a.name,
h.data
FROM acq.extract_holding_attr_table( lineitem_i, tag_t ) h
JOIN acq.provider_holding_subfield_map a USING (subfield)
WHERE a.provider = prov_i
LOOP
RETURN NEXT lida;
END LOOP;
RETURN;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
--
total_percent numeric;
--
BEGIN
SELECT
sum( percent )
INTO
total_percent
FROM
acq.fund_allocation_percent AS fap
WHERE
fap.funding_source = NEW.funding_source;
--
IF total_percent > 100 THEN
RAISE EXCEPTION 'Total percentages exceed 100 for funding_source %',
NEW.funding_source;
ELSE
RETURN NEW;
END IF;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
first_row BOOLEAN;
curr_year RECORD;
prev_year RECORD;
return_rec RECORD;
BEGIN
first_row := true;
FOR curr_year in
SELECT
id,
calendar,
year,
year_begin,
year_end
FROM
acq.fiscal_year
ORDER BY
calendar,
year_begin
LOOP
--
IF first_row THEN
first_row := FALSE;
ELSIF curr_year.calendar = prev_year.calendar THEN
IF curr_year.year_begin > prev_year.year_end THEN
-- This ugly kludge works around the fact that older
-- versions of PostgreSQL don't support RETURN QUERY SELECT
FOR return_rec IN SELECT
prev_year.id,
prev_year.year,
'Gap between fiscal years'::TEXT
LOOP
RETURN NEXT return_rec;
END LOOP;
ELSIF curr_year.year_begin < prev_year.year_end THEN
FOR return_rec IN SELECT
prev_year.id,
prev_year.year,
'Overlapping fiscal years'::TEXT
LOOP
RETURN NEXT return_rec;
END LOOP;
ELSIF curr_year.year < prev_year.year THEN
FOR return_rec IN SELECT
prev_year.id,
prev_year.year,
'Fiscal years out of order'::TEXT
LOOP
RETURN NEXT return_rec;
END LOOP;
END IF;
END IF;
--
prev_year := curr_year;
END LOOP;
--
RETURN;
END;
Returns: trigger
Language: PLPGSQL
--
DECLARE
--
dummy int := 0;
--
BEGIN
SELECT
1
INTO
dummy
FROM
acq.fund
WHERE
org = NEW.org
AND code = NEW.fund_code
LIMIT 1;
--
IF dummy = 1 then
RETURN NEW;
ELSE
RAISE EXCEPTION 'No fund exists for org % and code %', NEW.org, NEW.fund_code;
END IF;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
collision INT;
BEGIN
--
-- If order_date is not null, then make sure we don't have a collision
-- on order_date (truncated to day), org, and name
--
IF NEW.order_date IS NULL THEN
RETURN NEW;
END IF;
--
-- In the WHERE clause, we compare the order_dates without regard to time of day.
-- We use a pair of inequalities instead of comparing truncated dates so that the
-- query can do an indexed range scan.
--
SELECT 1 INTO collision
FROM acq.purchase_order
WHERE
ordering_agency = NEW.ordering_agency
AND name = NEW.name
AND order_date >= date_trunc( 'day', NEW.order_date )
AND order_date < date_trunc( 'day', NEW.order_date ) + '1 day'::INTERVAL
AND id <> NEW.id;
--
IF collision IS NULL THEN
-- okay, no collision
RETURN NEW;
ELSE
-- collision; nip it in the bud
RAISE EXCEPTION 'Colliding purchase orders: ordering_agency %, date %, name ''%''',
NEW.ordering_agency, NEW.order_date, NEW.name;
END IF;
END;
Returns: void
Language: PLPGSQL
DECLARE
--
new_id INT;
old_fund RECORD;
org_found BOOLEAN;
--
BEGIN
--
-- Sanity checks
--
IF old_year IS NULL THEN
RAISE EXCEPTION 'Input year argument is NULL';
ELSIF old_year NOT BETWEEN 2008 and 2200 THEN
RAISE EXCEPTION 'Input year is out of range';
END IF;
--
IF user_id IS NULL THEN
RAISE EXCEPTION 'Input user id argument is NULL';
END IF;
--
IF org_unit_id IS NULL THEN
RAISE EXCEPTION 'Org unit id argument is NULL';
ELSE
SELECT TRUE INTO org_found
FROM actor.org_unit
WHERE id = org_unit_id;
--
IF org_found IS NULL THEN
RAISE EXCEPTION 'Org unit id is invalid';
END IF;
END IF;
--
-- Loop over the applicable funds
--
FOR old_fund in SELECT * FROM acq.fund
WHERE
year = old_year
AND propagate
AND org in (
SELECT id FROM actor.org_unit_descendants( org_unit_id )
)
LOOP
BEGIN
INSERT INTO acq.fund (
org,
name,
year,
currency_type,
code,
rollover,
propagate,
balance_warning_percent,
balance_stop_percent
) VALUES (
old_fund.org,
old_fund.name,
old_year + 1,
old_fund.currency_type,
old_fund.code,
old_fund.rollover,
true,
old_fund.balance_warning_percent,
old_fund.balance_stop_percent
)
RETURNING id INTO new_id;
EXCEPTION
WHEN unique_violation THEN
--RAISE NOTICE 'Fund % already propagated', old_fund.id;
CONTINUE;
END;
--RAISE NOTICE 'Propagating fund % to fund %',
-- old_fund.code, new_id;
END LOOP;
END;
Returns: void
Language: PLPGSQL
DECLARE
--
new_id INT;
old_fund RECORD;
org_found BOOLEAN;
--
BEGIN
--
-- Sanity checks
--
IF old_year IS NULL THEN
RAISE EXCEPTION 'Input year argument is NULL';
ELSIF old_year NOT BETWEEN 2008 and 2200 THEN
RAISE EXCEPTION 'Input year is out of range';
END IF;
--
IF user_id IS NULL THEN
RAISE EXCEPTION 'Input user id argument is NULL';
END IF;
--
IF org_unit_id IS NULL THEN
RAISE EXCEPTION 'Org unit id argument is NULL';
ELSE
SELECT TRUE INTO org_found
FROM actor.org_unit
WHERE id = org_unit_id;
--
IF org_found IS NULL THEN
RAISE EXCEPTION 'Org unit id is invalid';
END IF;
END IF;
--
-- Loop over the applicable funds
--
FOR old_fund in SELECT * FROM acq.fund
WHERE
year = old_year
AND propagate
AND org = org_unit_id
LOOP
BEGIN
INSERT INTO acq.fund (
org,
name,
year,
currency_type,
code,
rollover,
propagate,
balance_warning_percent,
balance_stop_percent
) VALUES (
old_fund.org,
old_fund.name,
old_year + 1,
old_fund.currency_type,
old_fund.code,
old_fund.rollover,
true,
old_fund.balance_warning_percent,
old_fund.balance_stop_percent
)
RETURNING id INTO new_id;
EXCEPTION
WHEN unique_violation THEN
--RAISE NOTICE 'Fund % already propagated', old_fund.id;
CONTINUE;
END;
--RAISE NOTICE 'Propagating fund % to fund %',
-- old_fund.code, new_id;
END LOOP;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF NEW.name IS NULL THEN
NEW.name := NEW.id::TEXT;
END IF;
RETURN NEW;
END;
Returns: void
Language: PLPGSQL
DECLARE
--
new_fund INT;
new_year INT := old_year + 1;
org_found BOOL;
xfer_amount NUMERIC;
roll_fund RECORD;
deb RECORD;
detail RECORD;
--
BEGIN
--
-- Sanity checks
--
IF old_year IS NULL THEN
RAISE EXCEPTION 'Input year argument is NULL';
ELSIF old_year NOT BETWEEN 2008 and 2200 THEN
RAISE EXCEPTION 'Input year is out of range';
END IF;
--
IF user_id IS NULL THEN
RAISE EXCEPTION 'Input user id argument is NULL';
END IF;
--
IF org_unit_id IS NULL THEN
RAISE EXCEPTION 'Org unit id argument is NULL';
ELSE
--
-- Validate the org unit
--
SELECT TRUE
INTO org_found
FROM actor.org_unit
WHERE id = org_unit_id;
--
IF org_found IS NULL THEN
RAISE EXCEPTION 'Org unit id % is invalid', org_unit_id;
END IF;
END IF;
--
-- Loop over the propagable funds to identify the details
-- from the old fund plus the id of the new one, if it exists.
--
FOR roll_fund in
SELECT
oldf.id AS old_fund,
oldf.org,
oldf.name,
oldf.currency_type,
oldf.code,
oldf.rollover,
newf.id AS new_fund_id
FROM
acq.fund AS oldf
LEFT JOIN acq.fund AS newf
ON ( oldf.code = newf.code )
WHERE
oldf.year = old_year
AND oldf.propagate
AND newf.year = new_year
AND oldf.org in (
SELECT id FROM actor.org_unit_descendants( org_unit_id )
)
LOOP
--RAISE NOTICE 'Processing fund %', roll_fund.old_fund;
--
IF roll_fund.new_fund_id IS NULL THEN
--
-- The old fund hasn't been propagated yet. Propagate it now.
--
INSERT INTO acq.fund (
org,
name,
year,
currency_type,
code,
rollover,
propagate,
balance_warning_percent,
balance_stop_percent
) VALUES (
roll_fund.org,
roll_fund.name,
new_year,
roll_fund.currency_type,
roll_fund.code,
true,
true,
roll_fund.balance_warning_percent,
roll_fund.balance_stop_percent
)
RETURNING id INTO new_fund;
ELSE
new_fund = roll_fund.new_fund_id;
END IF;
--
-- Determine the amount to transfer
--
SELECT amount
INTO xfer_amount
FROM acq.fund_spent_balance
WHERE fund = roll_fund.old_fund;
--
IF xfer_amount <> 0 THEN
IF roll_fund.rollover THEN
--
-- Transfer balance from old fund to new
--
--RAISE NOTICE 'Transferring % from fund % to %', xfer_amount, roll_fund.old_fund, new_fund;
--
PERFORM acq.transfer_fund(
roll_fund.old_fund,
xfer_amount,
new_fund,
xfer_amount,
user_id,
'Rollover'
);
ELSE
--
-- Transfer balance from old fund to the void
--
-- RAISE NOTICE 'Transferring % from fund % to the void', xfer_amount, roll_fund.old_fund;
--
PERFORM acq.transfer_fund(
roll_fund.old_fund,
xfer_amount,
NULL,
NULL,
user_id,
'Rollover'
);
END IF;
END IF;
--
IF roll_fund.rollover THEN
--
-- Move any lineitems from the old fund to the new one
-- where the associated debit is an encumbrance.
--
-- Any other tables tying expenditure details to funds should
-- receive similar treatment. At this writing there are none.
--
UPDATE acq.lineitem_detail
SET fund = new_fund
WHERE
fund = roll_fund.old_fund -- this condition may be redundant
AND fund_debit in
(
SELECT id
FROM acq.fund_debit
WHERE
fund = roll_fund.old_fund
AND encumbrance
);
--
-- Move encumbrance debits from the old fund to the new fund
--
UPDATE acq.fund_debit
SET fund = new_fund
wHERE
fund = roll_fund.old_fund
AND encumbrance;
END IF;
--
-- Mark old fund as inactive, now that we've closed it
--
UPDATE acq.fund
SET active = FALSE
WHERE id = roll_fund.old_fund;
END LOOP;
END;
Returns: void
Language: PLPGSQL
DECLARE
--
new_fund INT;
new_year INT := old_year + 1;
org_found BOOL;
xfer_amount NUMERIC;
roll_fund RECORD;
deb RECORD;
detail RECORD;
--
BEGIN
--
-- Sanity checks
--
IF old_year IS NULL THEN
RAISE EXCEPTION 'Input year argument is NULL';
ELSIF old_year NOT BETWEEN 2008 and 2200 THEN
RAISE EXCEPTION 'Input year is out of range';
END IF;
--
IF user_id IS NULL THEN
RAISE EXCEPTION 'Input user id argument is NULL';
END IF;
--
IF org_unit_id IS NULL THEN
RAISE EXCEPTION 'Org unit id argument is NULL';
ELSE
--
-- Validate the org unit
--
SELECT TRUE
INTO org_found
FROM actor.org_unit
WHERE id = org_unit_id;
--
IF org_found IS NULL THEN
RAISE EXCEPTION 'Org unit id % is invalid', org_unit_id;
END IF;
END IF;
--
-- Loop over the propagable funds to identify the details
-- from the old fund plus the id of the new one, if it exists.
--
FOR roll_fund in
SELECT
oldf.id AS old_fund,
oldf.org,
oldf.name,
oldf.currency_type,
oldf.code,
oldf.rollover,
newf.id AS new_fund_id
FROM
acq.fund AS oldf
LEFT JOIN acq.fund AS newf
ON ( oldf.code = newf.code )
WHERE
oldf.org = org_unit_id
and oldf.year = old_year
and oldf.propagate
and newf.year = new_year
LOOP
--RAISE NOTICE 'Processing fund %', roll_fund.old_fund;
--
IF roll_fund.new_fund_id IS NULL THEN
--
-- The old fund hasn't been propagated yet. Propagate it now.
--
INSERT INTO acq.fund (
org,
name,
year,
currency_type,
code,
rollover,
propagate,
balance_warning_percent,
balance_stop_percent
) VALUES (
roll_fund.org,
roll_fund.name,
new_year,
roll_fund.currency_type,
roll_fund.code,
true,
true,
roll_fund.balance_warning_percent,
roll_fund.balance_stop_percent
)
RETURNING id INTO new_fund;
ELSE
new_fund = roll_fund.new_fund_id;
END IF;
--
-- Determine the amount to transfer
--
SELECT amount
INTO xfer_amount
FROM acq.fund_spent_balance
WHERE fund = roll_fund.old_fund;
--
IF xfer_amount <> 0 THEN
IF roll_fund.rollover THEN
--
-- Transfer balance from old fund to new
--
--RAISE NOTICE 'Transferring % from fund % to %', xfer_amount, roll_fund.old_fund, new_fund;
--
PERFORM acq.transfer_fund(
roll_fund.old_fund,
xfer_amount,
new_fund,
xfer_amount,
user_id,
'Rollover'
);
ELSE
--
-- Transfer balance from old fund to the void
--
-- RAISE NOTICE 'Transferring % from fund % to the void', xfer_amount, roll_fund.old_fund;
--
PERFORM acq.transfer_fund(
roll_fund.old_fund,
xfer_amount,
NULL,
NULL,
user_id,
'Rollover'
);
END IF;
END IF;
--
IF roll_fund.rollover THEN
--
-- Move any lineitems from the old fund to the new one
-- where the associated debit is an encumbrance.
--
-- Any other tables tying expenditure details to funds should
-- receive similar treatment. At this writing there are none.
--
UPDATE acq.lineitem_detail
SET fund = new_fund
WHERE
fund = roll_fund.old_fund -- this condition may be redundant
AND fund_debit in
(
SELECT id
FROM acq.fund_debit
WHERE
fund = roll_fund.old_fund
AND encumbrance
);
--
-- Move encumbrance debits from the old fund to the new fund
--
UPDATE acq.fund_debit
SET fund = new_fund
wHERE
fund = roll_fund.old_fund
AND encumbrance;
END IF;
--
-- Mark old fund as inactive, now that we've closed it
--
UPDATE acq.fund
SET active = FALSE
WHERE id = roll_fund.old_fund;
END LOOP;
END;
Returns: void
Language: PLPGSQL
/* -------------------------------------------------------------------------------
Function to transfer money from one fund to another.
A transfer is represented as a pair of entries in acq.fund_allocation, with a
negative amount for the old (losing) fund and a positive amount for the new
(gaining) fund. In some cases there may be more than one such pair of entries
in order to pull the money from different funding sources, or more specifically
from different funding source credits. For each such pair there is also an
entry in acq.fund_transfer.
Since funding_source is a non-nullable column in acq.fund_allocation, we must
choose a funding source for the transferred money to come from. This choice
must meet two constraints, so far as possible:
1. The amount transferred from a given funding source must not exceed the
amount allocated to the old fund by the funding source. To that end we
compare the amount being transferred to the amount allocated.
2. We shouldn't transfer money that has already been spent or encumbered, as
defined by the funding attribution process. We attribute expenses to the
oldest funding source credits first. In order to avoid transferring that
attributed money, we reverse the priority, transferring from the newest funding
source credits first. There can be no guarantee that this approach will
avoid overcommitting a fund, but no other approach can do any better.
In this context the age of a funding source credit is defined by the
deadline_date for credits with deadline_dates, and by the effective_date for
credits without deadline_dates, with the proviso that credits with deadline_dates
are all considered "older" than those without.
----------
In the signature for this function, there is one last parameter commented out,
named "funding_source_in". Correspondingly, the WHERE clause for the query
driving the main loop has an OR clause commented out, which references the
funding_source_in parameter.
If these lines are uncommented, this function will allow the user optionally to
restrict a fund transfer to a specified funding source. If the source
parameter is left NULL, then there will be no such restriction.
------------------------------------------------------------------------------- */
DECLARE
same_currency BOOLEAN;
currency_ratio NUMERIC;
old_fund_currency TEXT;
old_remaining NUMERIC; -- in currency of old fund
new_fund_currency TEXT;
new_fund_active BOOLEAN;
new_remaining NUMERIC; -- in currency of new fund
curr_old_amt NUMERIC; -- in currency of old fund
curr_new_amt NUMERIC; -- in currency of new fund
source_addition NUMERIC; -- in currency of funding source
source_deduction NUMERIC; -- in currency of funding source
orig_allocated_amt NUMERIC; -- in currency of funding source
allocated_amt NUMERIC; -- in currency of fund
source RECORD;
BEGIN
--
-- Sanity checks
--
IF old_fund IS NULL THEN
RAISE EXCEPTION 'acq.transfer_fund: old fund id is NULL';
END IF;
--
IF old_amount IS NULL THEN
RAISE EXCEPTION 'acq.transfer_fund: amount to transfer is NULL';
END IF;
--
-- The new fund and its amount must be both NULL or both not NULL.
--
IF new_fund IS NOT NULL AND new_amount IS NULL THEN
RAISE EXCEPTION 'acq.transfer_fund: amount to transfer to receiving fund is NULL';
END IF;
--
IF new_fund IS NULL AND new_amount IS NOT NULL THEN
RAISE EXCEPTION 'acq.transfer_fund: receiving fund is NULL, its amount is not NULL';
END IF;
--
IF user_id IS NULL THEN
RAISE EXCEPTION 'acq.transfer_fund: user id is NULL';
END IF;
--
-- Initialize the amounts to be transferred, each denominated
-- in the currency of its respective fund. They will be
-- reduced on each iteration of the loop.
--
old_remaining := old_amount;
new_remaining := new_amount;
--
-- RAISE NOTICE 'Transferring % in fund % to % in fund %',
-- old_amount, old_fund, new_amount, new_fund;
--
-- Get the currency types of the old and new funds.
--
SELECT
currency_type
INTO
old_fund_currency
FROM
acq.fund
WHERE
id = old_fund;
--
IF old_fund_currency IS NULL THEN
RAISE EXCEPTION 'acq.transfer_fund: old fund id % is not defined', old_fund;
END IF;
--
IF new_fund IS NOT NULL THEN
SELECT
currency_type,
active
INTO
new_fund_currency,
new_fund_active
FROM
acq.fund
WHERE
id = new_fund;
--
IF new_fund_currency IS NULL THEN
RAISE EXCEPTION 'acq.transfer_fund: new fund id % is not defined', new_fund;
ELSIF NOT new_fund_active THEN
--
-- No point in putting money into a fund from whence you can't spend it
--
RAISE EXCEPTION 'acq.transfer_fund: new fund id % is inactive', new_fund;
END IF;
--
IF new_amount = old_amount THEN
same_currency := true;
currency_ratio := 1;
ELSE
--
-- We'll have to translate currency between funds. We presume that
-- the calling code has already applied an appropriate exchange rate,
-- so we'll apply the same conversion to each sub-transfer.
--
same_currency := false;
currency_ratio := new_amount / old_amount;
END IF;
END IF;
--
-- Identify the funding source(s) from which we want to transfer the money.
-- The principle is that we want to transfer the newest money first, because
-- we spend the oldest money first. The priority for spending is defined
-- by a sort of the view acq.ordered_funding_source_credit.
--
FOR source in
SELECT
ofsc.id,
ofsc.funding_source,
ofsc.amount,
ofsc.amount * acq.exchange_ratio( fs.currency_type, old_fund_currency )
AS converted_amt,
fs.currency_type
FROM
acq.ordered_funding_source_credit AS ofsc,
acq.funding_source fs
WHERE
ofsc.funding_source = fs.id
and ofsc.funding_source IN
(
SELECT funding_source
FROM acq.fund_allocation
WHERE fund = old_fund
)
-- and
-- (
-- ofsc.funding_source = funding_source_in
-- OR funding_source_in IS NULL
-- )
ORDER BY
ofsc.sort_priority desc,
ofsc.sort_date desc,
ofsc.id desc
LOOP
--
-- Determine how much money the old fund got from this funding source,
-- denominated in the currency types of the source and of the fund.
-- This result may reflect transfers from previous iterations.
--
SELECT
COALESCE( sum( amount ), 0 ),
COALESCE( sum( amount )
* acq.exchange_ratio( source.currency_type, old_fund_currency ), 0 )
INTO
orig_allocated_amt, -- in currency of the source
allocated_amt -- in currency of the old fund
FROM
acq.fund_allocation
WHERE
fund = old_fund
and funding_source = source.funding_source;
--
-- Determine how much to transfer from this credit, in the currency
-- of the fund. Begin with the amount remaining to be attributed:
--
curr_old_amt := old_remaining;
--
-- Can't attribute more than was allocated from the fund:
--
IF curr_old_amt > allocated_amt THEN
curr_old_amt := allocated_amt;
END IF;
--
-- Can't attribute more than the amount of the current credit:
--
IF curr_old_amt > source.converted_amt THEN
curr_old_amt := source.converted_amt;
END IF;
--
curr_old_amt := trunc( curr_old_amt, 2 );
--
old_remaining := old_remaining - curr_old_amt;
--
-- Determine the amount to be deducted, if any,
-- from the old allocation.
--
IF old_remaining > 0 THEN
--
-- In this case we're using the whole allocation, so use that
-- amount directly instead of applying a currency translation
-- and thereby inviting round-off errors.
--
source_deduction := - orig_allocated_amt;
ELSE
source_deduction := trunc(
( - curr_old_amt ) *
acq.exchange_ratio( old_fund_currency, source.currency_type ),
2 );
END IF;
--
IF source_deduction <> 0 THEN
--
-- Insert negative allocation for old fund in fund_allocation,
-- converted into the currency of the funding source
--
INSERT INTO acq.fund_allocation (
funding_source,
fund,
amount,
allocator,
note
) VALUES (
source.funding_source,
old_fund,
source_deduction,
user_id,
'Transfer to fund ' || new_fund
);
END IF;
--
IF new_fund IS NOT NULL THEN
--
-- Determine how much to add to the new fund, in
-- its currency, and how much remains to be added:
--
IF same_currency THEN
curr_new_amt := curr_old_amt;
ELSE
IF old_remaining = 0 THEN
--
-- This is the last iteration, so nothing should be left
--
curr_new_amt := new_remaining;
new_remaining := 0;
ELSE
curr_new_amt := trunc( curr_old_amt * currency_ratio, 2 );
new_remaining := new_remaining - curr_new_amt;
END IF;
END IF;
--
-- Determine how much to add, if any,
-- to the new fund's allocation.
--
IF old_remaining > 0 THEN
--
-- In this case we're using the whole allocation, so use that amount
-- amount directly instead of applying a currency translation and
-- thereby inviting round-off errors.
--
source_addition := orig_allocated_amt;
ELSIF source.currency_type = old_fund_currency THEN
--
-- In this case we don't need a round trip currency translation,
-- thereby inviting round-off errors:
--
source_addition := curr_old_amt;
ELSE
source_addition := trunc(
curr_new_amt *
acq.exchange_ratio( new_fund_currency, source.currency_type ),
2 );
END IF;
--
IF source_addition <> 0 THEN
--
-- Insert positive allocation for new fund in fund_allocation,
-- converted to the currency of the founding source
--
INSERT INTO acq.fund_allocation (
funding_source,
fund,
amount,
allocator,
note
) VALUES (
source.funding_source,
new_fund,
source_addition,
user_id,
'Transfer from fund ' || old_fund
);
END IF;
END IF;
--
IF trunc( curr_old_amt, 2 ) <> 0
OR trunc( curr_new_amt, 2 ) <> 0 THEN
--
-- Insert row in fund_transfer, using amounts in the currency of the funds
--
INSERT INTO acq.fund_transfer (
src_fund,
src_amount,
dest_fund,
dest_amount,
transfer_user,
note,
funding_source_credit
) VALUES (
old_fund,
trunc( curr_old_amt, 2 ),
new_fund,
trunc( curr_new_amt, 2 ),
user_id,
xfer_note,
source.id
);
END IF;
--
if old_remaining <= 0 THEN
EXIT; -- Nothing more to be transferred
END IF;
END LOOP;
END;
Schema action
action.aged_circulation Structure
F-Key |
Name |
Type |
Description |
|
usr_post_code |
text |
|
|
usr_home_ou |
integer |
NOT NULL
|
|
usr_profile |
integer |
NOT NULL
|
|
usr_birth_year |
integer |
|
|
copy_call_number |
integer |
NOT NULL
|
|
copy_owning_lib |
integer |
NOT NULL
|
|
copy_circ_lib |
integer |
NOT NULL
|
|
copy_bib_record |
bigint |
NOT NULL
|
|
id |
bigint |
PRIMARY KEY
|
|
xact_start |
timestamp with time zone |
NOT NULL
|
|
xact_finish |
timestamp with time zone |
|
|
unrecovered |
boolean |
|
|
target_copy |
bigint |
NOT NULL
|
|
circ_lib |
integer |
NOT NULL
|
|
circ_staff |
integer |
NOT NULL
|
|
checkin_staff |
integer |
|
|
checkin_lib |
integer |
|
|
renewal_remaining |
integer |
NOT NULL
|
|
grace_period |
interval |
NOT NULL
|
|
due_date |
timestamp with time zone |
|
|
stop_fines_time |
timestamp with time zone |
|
|
checkin_time |
timestamp with time zone |
|
|
create_time |
timestamp with time zone |
NOT NULL
|
|
duration |
interval |
|
|
fine_interval |
interval |
NOT NULL
|
|
recurring_fine |
numeric(6,2) |
|
|
max_fine |
numeric(6,2) |
|
|
phone_renewal |
boolean |
NOT NULL
|
|
desk_renewal |
boolean |
NOT NULL
|
|
opac_renewal |
boolean |
NOT NULL
|
|
duration_rule |
text |
NOT NULL
|
|
recurring_fine_rule |
text |
NOT NULL
|
|
max_fine_rule |
text |
NOT NULL
|
|
stop_fines |
text |
|
|
workstation |
integer |
|
|
checkin_workstation |
integer |
|
|
copy_location |
integer |
NOT NULL
|
|
checkin_scan_time |
timestamp with time zone |
|
|
parent_circ |
bigint |
|
action_aged_circulation_target_copy_idx target_copy
aged_circ_circ_lib_idx circ_lib
aged_circ_copy_circ_lib_idx copy_circ_lib
aged_circ_copy_location_idx copy_location
aged_circ_copy_owning_lib_idx copy_owning_lib
aged_circ_start_idx xact_start
Index -
Schema action
action.all_circulation Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
usr_post_code |
text |
|
|
usr_home_ou |
integer |
|
|
usr_profile |
integer |
|
|
usr_birth_year |
integer |
|
|
copy_call_number |
bigint |
|
|
copy_location |
integer |
|
|
copy_owning_lib |
integer |
|
|
copy_circ_lib |
integer |
|
|
copy_bib_record |
bigint |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
target_copy |
bigint |
|
|
circ_lib |
integer |
|
|
circ_staff |
integer |
|
|
checkin_staff |
integer |
|
|
checkin_lib |
integer |
|
|
renewal_remaining |
integer |
|
|
grace_period |
interval |
|
|
due_date |
timestamp with time zone |
|
|
stop_fines_time |
timestamp with time zone |
|
|
checkin_time |
timestamp with time zone |
|
|
create_time |
timestamp with time zone |
|
|
duration |
interval |
|
|
fine_interval |
interval |
|
|
recurring_fine |
numeric(6,2) |
|
|
max_fine |
numeric(6,2) |
|
|
phone_renewal |
boolean |
|
|
desk_renewal |
boolean |
|
|
opac_renewal |
boolean |
|
|
duration_rule |
text |
|
|
recurring_fine_rule |
text |
|
|
max_fine_rule |
text |
|
|
stop_fines |
text |
|
|
workstation |
integer |
|
|
checkin_workstation |
integer |
|
|
checkin_scan_time |
timestamp with time zone |
|
|
parent_circ |
bigint |
|
SELECT aged_circulation.id
, aged_circulation.usr_post_code
, aged_circulation.usr_home_ou
, aged_circulation.usr_profile
, aged_circulation.usr_birth_year
, aged_circulation.copy_call_number
, aged_circulation.copy_location
, aged_circulation.copy_owning_lib
, aged_circulation.copy_circ_lib
, aged_circulation.copy_bib_record
, aged_circulation.xact_start
, aged_circulation.xact_finish
, aged_circulation.target_copy
, aged_circulation.circ_lib
, aged_circulation.circ_staff
, aged_circulation.checkin_staff
, aged_circulation.checkin_lib
, aged_circulation.renewal_remaining
, aged_circulation.grace_period
, aged_circulation.due_date
, aged_circulation.stop_fines_time
, aged_circulation.checkin_time
, aged_circulation.create_time
, aged_circulation.duration
, aged_circulation.fine_interval
, aged_circulation.recurring_fine
, aged_circulation.max_fine
, aged_circulation.phone_renewal
, aged_circulation.desk_renewal
, aged_circulation.opac_renewal
, aged_circulation.duration_rule
, aged_circulation.recurring_fine_rule
, aged_circulation.max_fine_rule
, aged_circulation.stop_fines
, aged_circulation.workstation
, aged_circulation.checkin_workstation
, aged_circulation.checkin_scan_time
, aged_circulation.parent_circ
FROM action.aged_circulation
UNION ALLSELECT DISTINCT circ.id
, COALESCE
(a.post_code
, b.post_code
) AS usr_post_code
, p.home_ou AS usr_home_ou
, p.profile AS usr_profile
, (date_part
('year'::text
, p.dob
)
)::integer AS usr_birth_year
, cp.call_number AS copy_call_number
, circ.copy_location
, cn.owning_lib AS copy_owning_lib
, cp.circ_lib AS copy_circ_lib
, cn.record AS copy_bib_record
, circ.xact_start
, circ.xact_finish
, circ.target_copy
, circ.circ_lib
, circ.circ_staff
, circ.checkin_staff
, circ.checkin_lib
, circ.renewal_remaining
, circ.grace_period
, circ.due_date
, circ.stop_fines_time
, circ.checkin_time
, circ.create_time
, circ.duration
, circ.fine_interval
, circ.recurring_fine
, circ.max_fine
, circ.phone_renewal
, circ.desk_renewal
, circ.opac_renewal
, circ.duration_rule
, circ.recurring_fine_rule
, circ.max_fine_rule
, circ.stop_fines
, circ.workstation
, circ.checkin_workstation
, circ.checkin_scan_time
, circ.parent_circ
FROM (
(
(
(
(action.circulation circ
JOIN asset.copy cp
ON (
(circ.target_copy = cp.id)
)
)
JOIN asset.call_number cn
ON (
(cp.call_number = cn.id)
)
)
JOIN actor.usr p
ON (
(circ.usr = p.id)
)
)
LEFT JOIN actor.usr_address a
ON (
(p.mailing_address = a.id)
)
)
LEFT JOIN actor.usr_address b
ON (
(p.billing_address = b.id)
)
);
Index -
Schema action
action.archive_actor_stat_cat Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
xact |
bigint |
NOT NULL
|
|
stat_cat |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
Index -
Schema action
action.archive_asset_stat_cat Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
xact |
bigint |
NOT NULL
|
|
stat_cat |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
Index -
Schema action
action.billable_circulations Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
usr |
integer |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
unrecovered |
boolean |
|
|
target_copy |
bigint |
|
|
circ_lib |
integer |
|
|
circ_staff |
integer |
|
|
checkin_staff |
integer |
|
|
checkin_lib |
integer |
|
|
renewal_remaining |
integer |
|
|
grace_period |
interval |
|
|
due_date |
timestamp with time zone |
|
|
stop_fines_time |
timestamp with time zone |
|
|
checkin_time |
timestamp with time zone |
|
|
create_time |
timestamp with time zone |
|
|
duration |
interval |
|
|
fine_interval |
interval |
|
|
recurring_fine |
numeric(6,2) |
|
|
max_fine |
numeric(6,2) |
|
|
phone_renewal |
boolean |
|
|
desk_renewal |
boolean |
|
|
opac_renewal |
boolean |
|
|
duration_rule |
text |
|
|
recurring_fine_rule |
text |
|
|
max_fine_rule |
text |
|
|
stop_fines |
text |
|
|
workstation |
integer |
|
|
checkin_workstation |
integer |
|
|
copy_location |
integer |
|
|
checkin_scan_time |
timestamp with time zone |
|
|
parent_circ |
bigint |
|
SELECT circulation.id
, circulation.usr
, circulation.xact_start
, circulation.xact_finish
, circulation.unrecovered
, circulation.target_copy
, circulation.circ_lib
, circulation.circ_staff
, circulation.checkin_staff
, circulation.checkin_lib
, circulation.renewal_remaining
, circulation.grace_period
, circulation.due_date
, circulation.stop_fines_time
, circulation.checkin_time
, circulation.create_time
, circulation.duration
, circulation.fine_interval
, circulation.recurring_fine
, circulation.max_fine
, circulation.phone_renewal
, circulation.desk_renewal
, circulation.opac_renewal
, circulation.duration_rule
, circulation.recurring_fine_rule
, circulation.max_fine_rule
, circulation.stop_fines
, circulation.workstation
, circulation.checkin_workstation
, circulation.copy_location
, circulation.checkin_scan_time
, circulation.parent_circ
FROM action.circulation
WHERE (circulation.xact_finish IS NULL);
Index -
Schema action
action.circulation Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.billable_xact_id_seq'::regclass)
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
|
xact_start |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
xact_finish |
timestamp with time zone |
|
|
unrecovered |
boolean |
|
|
target_copy |
bigint |
NOT NULL
|
actor.org_unit.id
|
circ_lib |
integer |
NOT NULL
|
|
circ_staff |
integer |
NOT NULL
|
|
checkin_staff |
integer |
|
|
checkin_lib |
integer |
|
|
renewal_remaining |
integer |
NOT NULL
|
|
grace_period |
interval |
NOT NULL
|
|
due_date |
timestamp with time zone |
|
|
stop_fines_time |
timestamp with time zone |
|
|
checkin_time |
timestamp with time zone |
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
duration |
interval |
|
|
fine_interval |
interval |
NOT NULL
DEFAULT '1 day'::interval
|
|
recurring_fine |
numeric(6,2) |
|
|
max_fine |
numeric(6,2) |
|
|
phone_renewal |
boolean |
NOT NULL
DEFAULT false
|
|
desk_renewal |
boolean |
NOT NULL
DEFAULT false
|
|
opac_renewal |
boolean |
NOT NULL
DEFAULT false
|
|
duration_rule |
text |
NOT NULL
|
|
recurring_fine_rule |
text |
NOT NULL
|
|
max_fine_rule |
text |
NOT NULL
|
|
stop_fines |
text |
|
actor.workstation.id
|
workstation |
integer |
|
actor.workstation.id
|
checkin_workstation |
integer |
|
asset.copy_location.id
|
copy_location |
integer |
NOT NULL
DEFAULT 1
|
|
checkin_scan_time |
timestamp with time zone |
|
action.circulation.id
|
parent_circ |
bigint |
|
Table action.circulation Inherits
billable_xact,
action.circulation Constraints
Name |
Constraint |
circulation_stop_fines_check |
CHECK ((stop_fines = ANY (ARRAY['CHECKIN'::text, 'CLAIMSRETURNED'::text, 'LOST'::text, 'MAXFINES'::text, 'RENEW'::text, 'LONGOVERDUE'::text, 'CLAIMSNEVERCHECKEDOUT'::text]))) |
Tables referencing this one via Foreign Key Constraints:
action_circulation_target_copy_idx target_copy
circ_all_usr_idx usr
circ_checkin_staff_idx checkin_staff
circ_checkin_time checkin_time) WHERE (checkin_time IS NOT NULL
circ_circ_lib_idx circ_lib
circ_circ_staff_idx circ_staff
circ_open_date_idx xact_start) WHERE (xact_finish IS NULL
circ_open_xacts_idx usr) WHERE (xact_finish IS NULL
circ_outstanding_idx usr) WHERE (checkin_time IS NULL
Index -
Schema action
Index -
Schema action
action.fieldset Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
NOT NULL
|
actor.org_unit.id
|
owning_lib |
integer |
UNIQUE#1
NOT NULL
|
|
status |
text |
NOT NULL
|
|
creation_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
scheduled_time |
timestamp with time zone |
|
|
applied_time |
timestamp with time zone |
|
|
classname |
text |
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
query.stored_query.id
|
stored_query |
integer |
|
|
pkey_value |
text |
|
action.fieldset Constraints
Name |
Constraint |
fieldset_one_or_the_other |
CHECK ((((stored_query IS NOT NULL) AND (pkey_value IS NULL)) OR ((pkey_value IS NOT NULL) AND (stored_query IS NULL)))) |
valid_status |
CHECK ((status = ANY (ARRAY['PENDING'::text, 'APPLIED'::text, 'ERROR'::text]))) |
Tables referencing this one via Foreign Key Constraints:
action_fieldset_sched_time_idx scheduled_time
action_owner_idx owner
Index -
Schema action
action.fieldset_col_val Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
action.fieldset.id
|
fieldset |
integer |
UNIQUE#1
NOT NULL
|
|
col |
text |
UNIQUE#1
NOT NULL
|
|
val |
text |
|
Index -
Schema action
action.hold_copy_map Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
action.hold_request.id
|
hold |
integer |
UNIQUE#1
NOT NULL
|
|
target_copy |
bigint |
UNIQUE#1
NOT NULL
|
acm_copy_idx target_copy
Index -
Schema action
action.hold_notification Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
action.hold_request.id
|
hold |
integer |
NOT NULL
|
actor.usr.id
|
notify_staff |
integer |
|
|
notify_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
method |
text |
NOT NULL
|
|
note |
text |
|
ahn_hold_idx hold
ahn_notify_staff_idx notify_staff
Index -
Schema action
action.hold_request Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
request_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
capture_time |
timestamp with time zone |
|
|
fulfillment_time |
timestamp with time zone |
|
|
checkin_time |
timestamp with time zone |
|
|
return_time |
timestamp with time zone |
|
|
prev_check_time |
timestamp with time zone |
|
|
expire_time |
timestamp with time zone |
|
|
cancel_time |
timestamp with time zone |
|
action.hold_request_cancel_cause.id
|
cancel_cause |
integer |
|
|
cancel_note |
text |
|
|
target |
bigint |
NOT NULL
|
|
current_copy |
bigint |
|
actor.usr.id
|
fulfillment_staff |
integer |
|
actor.org_unit.id
|
fulfillment_lib |
integer |
|
actor.org_unit.id
|
request_lib |
integer |
NOT NULL
|
actor.usr.id
|
requestor |
integer |
NOT NULL
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
|
selection_ou |
integer |
NOT NULL
|
|
selection_depth |
integer |
NOT NULL
|
actor.org_unit.id
|
pickup_lib |
integer |
NOT NULL
|
|
hold_type |
text |
NOT NULL
|
|
holdable_formats |
text |
|
|
phone_notify |
text |
|
|
email_notify |
boolean |
NOT NULL
DEFAULT true
|
|
sms_notify |
text |
|
config.sms_carrier.id
|
sms_carrier |
integer |
|
|
frozen |
boolean |
NOT NULL
DEFAULT false
|
|
thaw_date |
timestamp with time zone |
|
|
shelf_time |
timestamp with time zone |
|
|
cut_in_line |
boolean |
|
|
mint_condition |
boolean |
NOT NULL
DEFAULT true
|
|
shelf_expire_time |
timestamp with time zone |
|
actor.org_unit.id
|
current_shelf_lib |
integer |
|
action.hold_request Constraints
Name |
Constraint |
sms_check |
CHECK (((sms_notify IS NULL) OR (sms_carrier IS NOT NULL))) |
Tables referencing this one via Foreign Key Constraints:
hold_request_current_copy_idx current_copy
hold_request_fulfillment_staff_idx fulfillment_staff
hold_request_pickup_lib_idx pickup_lib
hold_request_prev_check_time_idx prev_check_time
hold_request_requestor_idx requestor
hold_request_target_idx target
hold_request_usr_idx usr
Index -
Schema action
action.hold_request_cancel_cause Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
label |
text |
UNIQUE
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action
action.hold_request_note Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
action.hold_request.id
|
hold |
bigint |
NOT NULL
|
|
title |
text |
NOT NULL
|
|
body |
text |
NOT NULL
|
|
slip |
boolean |
NOT NULL
DEFAULT false
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
staff |
boolean |
NOT NULL
DEFAULT false
|
ahrn_hold_idx hold
Index -
Schema action
action.hold_transit_copy Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
PRIMARY KEY
DEFAULT nextval('action.transit_copy_id_seq'::regclass)
|
|
source_send_time |
timestamp with time zone |
|
|
dest_recv_time |
timestamp with time zone |
|
|
target_copy |
bigint |
NOT NULL
|
|
source |
integer |
NOT NULL
|
|
dest |
integer |
NOT NULL
|
|
prev_hop |
integer |
|
|
copy_status |
integer |
NOT NULL
|
|
persistant_transfer |
boolean |
NOT NULL
DEFAULT false
|
|
prev_dest |
integer |
|
action.hold_request.id
|
hold |
integer |
|
Table action.hold_transit_copy Inherits
transit_copy,
active_hold_transit_cp_idx target_copy
active_hold_transit_dest_idx dest
active_hold_transit_source_idx source
Index -
Schema action
action.in_house_use Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
item |
bigint |
NOT NULL
|
actor.usr.id
|
staff |
integer |
NOT NULL
|
actor.org_unit.id
|
org_unit |
integer |
NOT NULL
|
|
use_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
action_in_house_use_staff_idx staff
Index -
Schema action
non_cat_in_house_use_staff_idx staff
Index -
Schema action
action_non_cat_circ_patron_idx patron
action_non_cat_circ_staff_idx staff
Index -
Schema action
action.open_circulation Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
usr |
integer |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
unrecovered |
boolean |
|
|
target_copy |
bigint |
|
|
circ_lib |
integer |
|
|
circ_staff |
integer |
|
|
checkin_staff |
integer |
|
|
checkin_lib |
integer |
|
|
renewal_remaining |
integer |
|
|
grace_period |
interval |
|
|
due_date |
timestamp with time zone |
|
|
stop_fines_time |
timestamp with time zone |
|
|
checkin_time |
timestamp with time zone |
|
|
create_time |
timestamp with time zone |
|
|
duration |
interval |
|
|
fine_interval |
interval |
|
|
recurring_fine |
numeric(6,2) |
|
|
max_fine |
numeric(6,2) |
|
|
phone_renewal |
boolean |
|
|
desk_renewal |
boolean |
|
|
opac_renewal |
boolean |
|
|
duration_rule |
text |
|
|
recurring_fine_rule |
text |
|
|
max_fine_rule |
text |
|
|
stop_fines |
text |
|
|
workstation |
integer |
|
|
checkin_workstation |
integer |
|
|
copy_location |
integer |
|
|
checkin_scan_time |
timestamp with time zone |
|
|
parent_circ |
bigint |
|
SELECT circulation.id
, circulation.usr
, circulation.xact_start
, circulation.xact_finish
, circulation.unrecovered
, circulation.target_copy
, circulation.circ_lib
, circulation.circ_staff
, circulation.checkin_staff
, circulation.checkin_lib
, circulation.renewal_remaining
, circulation.grace_period
, circulation.due_date
, circulation.stop_fines_time
, circulation.checkin_time
, circulation.create_time
, circulation.duration
, circulation.fine_interval
, circulation.recurring_fine
, circulation.max_fine
, circulation.phone_renewal
, circulation.desk_renewal
, circulation.opac_renewal
, circulation.duration_rule
, circulation.recurring_fine_rule
, circulation.max_fine_rule
, circulation.stop_fines
, circulation.workstation
, circulation.checkin_workstation
, circulation.copy_location
, circulation.checkin_scan_time
, circulation.parent_circ
FROM action.circulation
WHERE (circulation.checkin_time IS NULL)
ORDER BY circulation.due_date;
Index -
Schema action
action.reservation_transit_copy Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
PRIMARY KEY
DEFAULT nextval('action.transit_copy_id_seq'::regclass)
|
|
source_send_time |
timestamp with time zone |
|
|
dest_recv_time |
timestamp with time zone |
|
booking.resource.id
|
target_copy |
bigint |
NOT NULL
|
|
source |
integer |
NOT NULL
|
|
dest |
integer |
NOT NULL
|
|
prev_hop |
integer |
|
|
copy_status |
integer |
NOT NULL
|
|
persistant_transfer |
boolean |
NOT NULL
DEFAULT false
|
|
prev_dest |
integer |
|
booking.reservation.id
|
reservation |
integer |
|
Table action.reservation_transit_copy Inherits
transit_copy,
active_reservation_transit_cp_idx target_copy
active_reservation_transit_dest_idx dest
active_reservation_transit_source_idx source
Index -
Schema action
action.survey Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
NOT NULL
|
|
start_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
end_date |
timestamp with time zone |
NOT NULL
DEFAULT (now() + '10 years'::interval)
|
|
usr_summary |
boolean |
NOT NULL
DEFAULT false
|
|
opac |
boolean |
NOT NULL
DEFAULT false
|
|
poll |
boolean |
NOT NULL
DEFAULT false
|
|
required |
boolean |
NOT NULL
DEFAULT false
|
|
name |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action
action.survey_answer Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
action.survey_question.id
|
question |
integer |
NOT NULL
|
|
answer |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action
action.survey_question Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
action.survey.id
|
survey |
integer |
NOT NULL
|
|
question |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action
action.survey_response Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
response_group_id |
integer |
|
|
usr |
integer |
|
action.survey.id
|
survey |
integer |
NOT NULL
|
action.survey_question.id
|
question |
integer |
NOT NULL
|
action.survey_answer.id
|
answer |
integer |
NOT NULL
|
|
answer_date |
timestamp with time zone |
|
|
effective_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
action_survey_response_usr_idx usr
Index -
Schema action
Tables referencing this one via Foreign Key Constraints:
active_transit_cp_idx target_copy
active_transit_dest_idx dest
active_transit_source_idx source
Index -
Schema action
action.unfulfilled_hold_innermost_loop Structure
F-Key |
Name |
Type |
Description |
|
hold |
integer |
|
|
circ_lib |
integer |
|
|
count |
bigint |
|
SELECT DISTINCT l.hold
, l.circ_lib
, l.count
FROM (action.unfulfilled_hold_loops l
JOIN action.unfulfilled_hold_min_loop m
USING (hold)
)
WHERE (l.count = m.min);
Index -
Schema action
action.unfulfilled_hold_list Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
current_copy |
bigint |
NOT NULL
|
|
hold |
integer |
NOT NULL
|
|
circ_lib |
integer |
NOT NULL
|
|
fail_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
uhr_hold_idx hold
Index -
Schema action
action.unfulfilled_hold_loops Structure
F-Key |
Name |
Type |
Description |
|
hold |
integer |
|
|
circ_lib |
integer |
|
|
count |
bigint |
|
SELECT u.hold
, c.circ_lib
, count
(*) AS count
FROM (action.unfulfilled_hold_list u
JOIN asset.copy c
ON (
(c.id = u.current_copy)
)
)
GROUP BY u.hold
, c.circ_lib;
Index -
Schema action
action.unfulfilled_hold_max_loop Structure
F-Key |
Name |
Type |
Description |
|
hold |
integer |
|
|
max |
bigint |
|
SELECT unfulfilled_hold_loops.hold
, max
(unfulfilled_hold_loops.count) AS max
FROM action.unfulfilled_hold_loops
GROUP BY unfulfilled_hold_loops.hold;
Index -
Schema action
action.unfulfilled_hold_min_loop Structure
F-Key |
Name |
Type |
Description |
|
hold |
integer |
|
|
min |
bigint |
|
SELECT unfulfilled_hold_loops.hold
, min
(unfulfilled_hold_loops.count) AS min
FROM action.unfulfilled_hold_loops
GROUP BY unfulfilled_hold_loops.hold;
Index -
Schema action
Returns: trigger
Language: PLPGSQL
DECLARE
found char := 'N';
BEGIN
-- If there are any renewals for this circulation, don't archive or delete
-- it yet. We'll do so later, when we archive and delete the renewals.
SELECT 'Y' INTO found
FROM action.circulation
WHERE parent_circ = OLD.id
LIMIT 1;
IF found = 'Y' THEN
RETURN NULL; -- don't delete
END IF;
-- Archive a copy of the old row to action.aged_circulation
INSERT INTO action.aged_circulation
(id,usr_post_code, usr_home_ou, usr_profile, usr_birth_year, copy_call_number, copy_location,
copy_owning_lib, copy_circ_lib, copy_bib_record, xact_start, xact_finish, target_copy,
circ_lib, circ_staff, checkin_staff, checkin_lib, renewal_remaining, grace_period, due_date,
stop_fines_time, checkin_time, create_time, duration, fine_interval, recurring_fine,
max_fine, phone_renewal, desk_renewal, opac_renewal, duration_rule, recurring_fine_rule,
max_fine_rule, stop_fines, workstation, checkin_workstation, checkin_scan_time, parent_circ)
SELECT
id,usr_post_code, usr_home_ou, usr_profile, usr_birth_year, copy_call_number, copy_location,
copy_owning_lib, copy_circ_lib, copy_bib_record, xact_start, xact_finish, target_copy,
circ_lib, circ_staff, checkin_staff, checkin_lib, renewal_remaining, grace_period, due_date,
stop_fines_time, checkin_time, create_time, duration, fine_interval, recurring_fine,
max_fine, phone_renewal, desk_renewal, opac_renewal, duration_rule, recurring_fine_rule,
max_fine_rule, stop_fines, workstation, checkin_workstation, checkin_scan_time, parent_circ
FROM action.all_circulation WHERE id = OLD.id;
RETURN OLD;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
-- Having deleted a renewal, we can delete the original circulation (or a previous
-- renewal, if that's what parent_circ is pointing to). That deletion will trigger
-- deletion of any prior parents, etc. recursively.
IF OLD.parent_circ IS NOT NULL THEN
DELETE FROM action.circulation
WHERE id = OLD.parent_circ;
END IF;
RETURN OLD;
END;
Returns: text
Language: PLPGSQL
Applies a specified fieldset, using a supplied table name and primary
key name. The query parameter should be non-null only for
query-based fieldsets.
Returns NULL if successful, or an error message if not.
DECLARE
statement TEXT;
fs_status TEXT;
fs_pkey_value TEXT;
fs_query TEXT;
sep CHAR;
status_code TEXT;
msg TEXT;
update_count INT;
cv RECORD;
BEGIN
-- Sanity checks
IF fieldset_id IS NULL THEN
RETURN 'Fieldset ID parameter is NULL';
END IF;
IF table_name IS NULL THEN
RETURN 'Table name parameter is NULL';
END IF;
IF pkey_name IS NULL THEN
RETURN 'Primary key name parameter is NULL';
END IF;
--
statement := 'UPDATE ' || table_name || ' SET';
--
SELECT
status,
quote_literal( pkey_value )
INTO
fs_status,
fs_pkey_value
FROM
action.fieldset
WHERE
id = fieldset_id;
--
IF fs_status IS NULL THEN
RETURN 'No fieldset found for id = ' || fieldset_id;
ELSIF fs_status = 'APPLIED' THEN
RETURN 'Fieldset ' || fieldset_id || ' has already been applied';
END IF;
--
sep := '';
FOR cv IN
SELECT col,
val
FROM action.fieldset_col_val
WHERE fieldset = fieldset_id
LOOP
statement := statement || sep || ' ' || cv.col
|| ' = ' || coalesce( quote_literal( cv.val ), 'NULL' );
sep := ',';
END LOOP;
--
IF sep = '' THEN
RETURN 'Fieldset ' || fieldset_id || ' has no column values defined';
END IF;
--
-- Add the WHERE clause. This differs according to whether it's a
-- single-row fieldset or a query-based fieldset.
--
IF query IS NULL AND fs_pkey_value IS NULL THEN
RETURN 'Incomplete fieldset: neither a primary key nor a query available';
ELSIF query IS NOT NULL AND fs_pkey_value IS NULL THEN
fs_query := rtrim( query, ';' );
statement := statement || ' WHERE ' || pkey_name || ' IN ( '
|| fs_query || ' );';
ELSIF query IS NULL AND fs_pkey_value IS NOT NULL THEN
statement := statement || ' WHERE ' || pkey_name || ' = '
|| fs_pkey_value || ';';
ELSE -- both are not null
RETURN 'Ambiguous fieldset: both a primary key and a query provided';
END IF;
--
-- Execute the update
--
BEGIN
EXECUTE statement;
GET DIAGNOSTICS update_count = ROW_COUNT;
--
IF UPDATE_COUNT > 0 THEN
status_code := 'APPLIED';
msg := NULL;
ELSE
status_code := 'ERROR';
msg := 'No eligible rows found for fieldset ' || fieldset_id;
END IF;
EXCEPTION WHEN OTHERS THEN
status_code := 'ERROR';
msg := 'Unable to apply fieldset ' || fieldset_id
|| ': ' || sqlerrm;
END;
--
-- Update fieldset status
--
UPDATE action.fieldset
SET status = status_code,
applied_time = now()
WHERE id = fieldset_id;
--
RETURN msg;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO action.archive_actor_stat_cat(xact, stat_cat, value)
SELECT NEW.id, asceum.stat_cat, asceum.stat_cat_entry
FROM actor.stat_cat_entry_usr_map asceum
JOIN actor.stat_cat sc ON asceum.stat_cat = sc.id
WHERE NEW.usr = asceum.target_usr AND sc.checkout_archive;
INSERT INTO action.archive_asset_stat_cat(xact, stat_cat, value)
SELECT NEW.id, ascecm.stat_cat, asce.value
FROM asset.stat_cat_entry_copy_map ascecm
JOIN asset.stat_cat sc ON ascecm.stat_cat = sc.id
JOIN asset.stat_cat_entry asce ON ascecm.stat_cat_entry = asce.id
WHERE NEW.target_copy = ascecm.owning_copy AND sc.checkout_archive;
RETURN NULL;
END;
Returns: SET OF circulation
Language: PLPGSQL
DECLARE
tmp_circ action.circulation%ROWTYPE;
circ_0 action.circulation%ROWTYPE;
BEGIN
SELECT INTO tmp_circ * FROM action.circulation WHERE id = ctx_circ_id;
IF tmp_circ IS NULL THEN
RETURN NEXT tmp_circ;
END IF;
circ_0 := tmp_circ;
-- find the front of the chain
WHILE TRUE LOOP
SELECT INTO tmp_circ * FROM action.circulation WHERE id = tmp_circ.parent_circ;
IF tmp_circ IS NULL THEN
EXIT;
END IF;
circ_0 := tmp_circ;
END LOOP;
-- now send the circs to the caller, oldest to newest
tmp_circ := circ_0;
WHILE TRUE LOOP
IF tmp_circ IS NULL THEN
EXIT;
END IF;
RETURN NEXT tmp_circ;
SELECT INTO tmp_circ * FROM action.circulation WHERE parent_circ = tmp_circ.id;
END LOOP;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF OLD.stop_fines IS NULL OR OLD.stop_fines <> NEW.stop_fines THEN
IF NEW.stop_fines = 'CLAIMSRETURNED' THEN
UPDATE actor.usr SET claims_returned_count = claims_returned_count + 1 WHERE id = NEW.usr;
END IF;
IF NEW.stop_fines = 'CLAIMSNEVERCHECKEDOUT' THEN
UPDATE actor.usr SET claims_never_checked_out_count = claims_never_checked_out_count + 1 WHERE id = NEW.usr;
END IF;
IF NEW.stop_fines = 'LOST' THEN
UPDATE asset.copy SET status = 3 WHERE id = NEW.target_copy;
END IF;
END IF;
RETURN NEW;
END;
Returns: hold_stats
Language: PLPGSQL
DECLARE
output action.hold_stats%ROWTYPE;
hold_count INT := 0;
copy_count INT := 0;
available_count INT := 0;
hold_map_data RECORD;
BEGIN
output.hold_count := 0;
output.copy_count := 0;
output.available_count := 0;
SELECT COUNT( DISTINCT m.hold ) INTO hold_count
FROM action.hold_copy_map m
JOIN action.hold_request h ON (m.hold = h.id)
WHERE m.target_copy = copy_id
AND NOT h.frozen;
output.hold_count := hold_count;
IF output.hold_count > 0 THEN
FOR hold_map_data IN
SELECT DISTINCT m.target_copy,
acp.status
FROM action.hold_copy_map m
JOIN asset.copy acp ON (m.target_copy = acp.id)
JOIN action.hold_request h ON (m.hold = h.id)
WHERE m.hold IN ( SELECT DISTINCT hold FROM action.hold_copy_map WHERE target_copy = copy_id ) AND NOT h.frozen
LOOP
output.copy_count := output.copy_count + 1;
IF hold_map_data.status IN (0,7,12) THEN
output.available_count := output.available_count + 1;
END IF;
END LOOP;
output.total_copy_ratio = output.copy_count::FLOAT / output.hold_count::FLOAT;
output.available_copy_ratio = output.available_count::FLOAT / output.hold_count::FLOAT;
END IF;
RETURN output;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
SELECT INTO NEW.copy_location location FROM asset.copy WHERE id = NEW.target_copy;
RETURN NEW;
END;
Returns: SET OF found_circ_matrix_matchpoint
Language: PLPGSQL
DECLARE
item_object asset.copy%ROWTYPE;
user_object actor.usr%ROWTYPE;
BEGIN
SELECT INTO item_object * FROM asset.copy WHERE id = match_item;
SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
RETURN QUERY SELECT * FROM action.find_circ_matrix_matchpoint( context_ou, item_object, user_object, renewal );
END;
Returns: found_circ_matrix_matchpoint
Language: PLPGSQL
DECLARE
cn_object asset.call_number%ROWTYPE;
rec_descriptor metabib.rec_descriptor%ROWTYPE;
cur_matchpoint config.circ_matrix_matchpoint%ROWTYPE;
matchpoint config.circ_matrix_matchpoint%ROWTYPE;
weights config.circ_matrix_weights%ROWTYPE;
user_age INTERVAL;
my_item_age INTERVAL;
denominator NUMERIC(6,2);
row_list INT[];
result action.found_circ_matrix_matchpoint;
BEGIN
-- Assume failure
result.success = false;
-- Fetch useful data
SELECT INTO cn_object * FROM asset.call_number WHERE id = item_object.call_number;
SELECT INTO rec_descriptor * FROM metabib.rec_descriptor WHERE record = cn_object.record;
-- Pre-generate this so we only calc it once
IF user_object.dob IS NOT NULL THEN
SELECT INTO user_age age(user_object.dob);
END IF;
-- Ditto
SELECT INTO my_item_age age(coalesce(item_object.active_date, now()));
-- Grab the closest set circ weight setting.
SELECT INTO weights cw.*
FROM config.weight_assoc wa
JOIN config.circ_matrix_weights cw ON (cw.id = wa.circ_weights)
JOIN actor.org_unit_ancestors_distance( context_ou ) d ON (wa.org_unit = d.id)
WHERE active
ORDER BY d.distance
LIMIT 1;
-- No weights? Bad admin! Defaults to handle that anyway.
IF weights.id IS NULL THEN
weights.grp := 11.0;
weights.org_unit := 10.0;
weights.circ_modifier := 5.0;
weights.marc_type := 4.0;
weights.marc_form := 3.0;
weights.marc_bib_level := 2.0;
weights.marc_vr_format := 2.0;
weights.copy_circ_lib := 8.0;
weights.copy_owning_lib := 8.0;
weights.user_home_ou := 8.0;
weights.ref_flag := 1.0;
weights.juvenile_flag := 6.0;
weights.is_renewal := 7.0;
weights.usr_age_lower_bound := 0.0;
weights.usr_age_upper_bound := 0.0;
weights.item_age := 0.0;
END IF;
-- Determine the max (expected) depth (+1) of the org tree and max depth of the permisson tree
-- If you break your org tree with funky parenting this may be wrong
-- Note: This CTE is duplicated in the find_hold_matrix_matchpoint function, and it may be a good idea to split it off to a function
-- We use one denominator for all tree-based checks for when permission groups and org units have the same weighting
WITH all_distance(distance) AS (
SELECT depth AS distance FROM actor.org_unit_type
UNION
SELECT distance AS distance FROM permission.grp_ancestors_distance((SELECT id FROM permission.grp_tree WHERE parent IS NULL))
)
SELECT INTO denominator MAX(distance) + 1 FROM all_distance;
-- Loop over all the potential matchpoints
FOR cur_matchpoint IN
SELECT m.*
FROM config.circ_matrix_matchpoint m
/*LEFT*/ JOIN permission.grp_ancestors_distance( user_object.profile ) upgad ON m.grp = upgad.id
/*LEFT*/ JOIN actor.org_unit_ancestors_distance( context_ou ) ctoua ON m.org_unit = ctoua.id
LEFT JOIN actor.org_unit_ancestors_distance( cn_object.owning_lib ) cnoua ON m.copy_owning_lib = cnoua.id
LEFT JOIN actor.org_unit_ancestors_distance( item_object.circ_lib ) iooua ON m.copy_circ_lib = iooua.id
LEFT JOIN actor.org_unit_ancestors_distance( user_object.home_ou ) uhoua ON m.user_home_ou = uhoua.id
WHERE m.active
-- Permission Groups
-- AND (m.grp IS NULL OR upgad.id IS NOT NULL) -- Optional Permission Group?
-- Org Units
-- AND (m.org_unit IS NULL OR ctoua.id IS NOT NULL) -- Optional Org Unit?
AND (m.copy_owning_lib IS NULL OR cnoua.id IS NOT NULL)
AND (m.copy_circ_lib IS NULL OR iooua.id IS NOT NULL)
AND (m.user_home_ou IS NULL OR uhoua.id IS NOT NULL)
-- Circ Type
AND (m.is_renewal IS NULL OR m.is_renewal = renewal)
-- Static User Checks
AND (m.juvenile_flag IS NULL OR m.juvenile_flag = user_object.juvenile)
AND (m.usr_age_lower_bound IS NULL OR (user_age IS NOT NULL AND m.usr_age_lower_bound < user_age))
AND (m.usr_age_upper_bound IS NULL OR (user_age IS NOT NULL AND m.usr_age_upper_bound > user_age))
-- Static Item Checks
AND (m.circ_modifier IS NULL OR m.circ_modifier = item_object.circ_modifier)
AND (m.marc_type IS NULL OR m.marc_type = COALESCE(item_object.circ_as_type, rec_descriptor.item_type))
AND (m.marc_form IS NULL OR m.marc_form = rec_descriptor.item_form)
AND (m.marc_bib_level IS NULL OR m.marc_bib_level = rec_descriptor.bib_level)
AND (m.marc_vr_format IS NULL OR m.marc_vr_format = rec_descriptor.vr_format)
AND (m.ref_flag IS NULL OR m.ref_flag = item_object.ref)
AND (m.item_age IS NULL OR (my_item_age IS NOT NULL AND m.item_age > my_item_age))
ORDER BY
-- Permission Groups
CASE WHEN upgad.distance IS NOT NULL THEN 2^(2*weights.grp - (upgad.distance/denominator)) ELSE 0.0 END +
-- Org Units
CASE WHEN ctoua.distance IS NOT NULL THEN 2^(2*weights.org_unit - (ctoua.distance/denominator)) ELSE 0.0 END +
CASE WHEN cnoua.distance IS NOT NULL THEN 2^(2*weights.copy_owning_lib - (cnoua.distance/denominator)) ELSE 0.0 END +
CASE WHEN iooua.distance IS NOT NULL THEN 2^(2*weights.copy_circ_lib - (iooua.distance/denominator)) ELSE 0.0 END +
CASE WHEN uhoua.distance IS NOT NULL THEN 2^(2*weights.user_home_ou - (uhoua.distance/denominator)) ELSE 0.0 END +
-- Circ Type -- Note: 4^x is equiv to 2^(2*x)
CASE WHEN m.is_renewal IS NOT NULL THEN 4^weights.is_renewal ELSE 0.0 END +
-- Static User Checks
CASE WHEN m.juvenile_flag IS NOT NULL THEN 4^weights.juvenile_flag ELSE 0.0 END +
CASE WHEN m.usr_age_lower_bound IS NOT NULL THEN 4^weights.usr_age_lower_bound ELSE 0.0 END +
CASE WHEN m.usr_age_upper_bound IS NOT NULL THEN 4^weights.usr_age_upper_bound ELSE 0.0 END +
-- Static Item Checks
CASE WHEN m.circ_modifier IS NOT NULL THEN 4^weights.circ_modifier ELSE 0.0 END +
CASE WHEN m.marc_type IS NOT NULL THEN 4^weights.marc_type ELSE 0.0 END +
CASE WHEN m.marc_form IS NOT NULL THEN 4^weights.marc_form ELSE 0.0 END +
CASE WHEN m.marc_vr_format IS NOT NULL THEN 4^weights.marc_vr_format ELSE 0.0 END +
CASE WHEN m.ref_flag IS NOT NULL THEN 4^weights.ref_flag ELSE 0.0 END +
-- Item age has a slight adjustment to weight based on value.
-- This should ensure that a shorter age limit comes first when all else is equal.
-- NOTE: This assumes that intervals will normally be in days.
CASE WHEN m.item_age IS NOT NULL THEN 4^weights.item_age - 1 + 86400/EXTRACT(EPOCH FROM m.item_age) ELSE 0.0 END DESC,
-- Final sort on id, so that if two rules have the same sorting in the previous sort they have a defined order
-- This prevents "we changed the table order by updating a rule, and we started getting different results"
m.id LOOP
-- Record the full matching row list
row_list := row_list || cur_matchpoint.id;
-- No matchpoint yet?
IF matchpoint.id IS NULL THEN
-- Take the entire matchpoint as a starting point
matchpoint := cur_matchpoint;
CONTINUE; -- No need to look at this row any more.
END IF;
-- Incomplete matchpoint?
IF matchpoint.circulate IS NULL THEN
matchpoint.circulate := cur_matchpoint.circulate;
END IF;
IF matchpoint.duration_rule IS NULL THEN
matchpoint.duration_rule := cur_matchpoint.duration_rule;
END IF;
IF matchpoint.recurring_fine_rule IS NULL THEN
matchpoint.recurring_fine_rule := cur_matchpoint.recurring_fine_rule;
END IF;
IF matchpoint.max_fine_rule IS NULL THEN
matchpoint.max_fine_rule := cur_matchpoint.max_fine_rule;
END IF;
IF matchpoint.hard_due_date IS NULL THEN
matchpoint.hard_due_date := cur_matchpoint.hard_due_date;
END IF;
IF matchpoint.total_copy_hold_ratio IS NULL THEN
matchpoint.total_copy_hold_ratio := cur_matchpoint.total_copy_hold_ratio;
END IF;
IF matchpoint.available_copy_hold_ratio IS NULL THEN
matchpoint.available_copy_hold_ratio := cur_matchpoint.available_copy_hold_ratio;
END IF;
IF matchpoint.renewals IS NULL THEN
matchpoint.renewals := cur_matchpoint.renewals;
END IF;
IF matchpoint.grace_period IS NULL THEN
matchpoint.grace_period := cur_matchpoint.grace_period;
END IF;
END LOOP;
-- Check required fields
IF matchpoint.circulate IS NOT NULL AND
matchpoint.duration_rule IS NOT NULL AND
matchpoint.recurring_fine_rule IS NOT NULL AND
matchpoint.max_fine_rule IS NOT NULL THEN
-- All there? We have a completed match.
result.success := true;
END IF;
-- Include the assembled matchpoint, even if it isn't complete
result.matchpoint := matchpoint;
-- Include (for debugging) the full list of matching rows
result.buildrows := row_list;
-- Hand the result back to caller
RETURN result;
END;
Returns: integer
Language: PLPGSQL
DECLARE
requestor_object actor.usr%ROWTYPE;
user_object actor.usr%ROWTYPE;
item_object asset.copy%ROWTYPE;
item_cn_object asset.call_number%ROWTYPE;
my_item_age INTERVAL;
rec_descriptor metabib.rec_descriptor%ROWTYPE;
matchpoint config.hold_matrix_matchpoint%ROWTYPE;
weights config.hold_matrix_weights%ROWTYPE;
denominator NUMERIC(6,2);
BEGIN
SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
SELECT INTO requestor_object * FROM actor.usr WHERE id = match_requestor;
SELECT INTO item_object * FROM asset.copy WHERE id = match_item;
SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
SELECT INTO rec_descriptor * FROM metabib.rec_descriptor WHERE record = item_cn_object.record;
SELECT INTO my_item_age age(coalesce(item_object.active_date, now()));
-- The item's owner should probably be the one determining if the item is holdable
-- How to decide that is debatable. Decided to default to the circ library (where the item lives)
-- This flag will allow for setting it to the owning library (where the call number "lives")
PERFORM * FROM config.internal_flag WHERE name = 'circ.holds.weight_owner_not_circ' AND enabled;
-- Grab the closest set circ weight setting.
IF NOT FOUND THEN
-- Default to circ library
SELECT INTO weights hw.*
FROM config.weight_assoc wa
JOIN config.hold_matrix_weights hw ON (hw.id = wa.hold_weights)
JOIN actor.org_unit_ancestors_distance( item_object.circ_lib ) d ON (wa.org_unit = d.id)
WHERE active
ORDER BY d.distance
LIMIT 1;
ELSE
-- Flag is set, use owning library
SELECT INTO weights hw.*
FROM config.weight_assoc wa
JOIN config.hold_matrix_weights hw ON (hw.id = wa.hold_weights)
JOIN actor.org_unit_ancestors_distance( item_cn_object.owning_lib ) d ON (wa.org_unit = d.id)
WHERE active
ORDER BY d.distance
LIMIT 1;
END IF;
-- No weights? Bad admin! Defaults to handle that anyway.
IF weights.id IS NULL THEN
weights.user_home_ou := 5.0;
weights.request_ou := 5.0;
weights.pickup_ou := 5.0;
weights.item_owning_ou := 5.0;
weights.item_circ_ou := 5.0;
weights.usr_grp := 7.0;
weights.requestor_grp := 8.0;
weights.circ_modifier := 4.0;
weights.marc_type := 3.0;
weights.marc_form := 2.0;
weights.marc_bib_level := 1.0;
weights.marc_vr_format := 1.0;
weights.juvenile_flag := 4.0;
weights.ref_flag := 0.0;
weights.item_age := 0.0;
END IF;
-- Determine the max (expected) depth (+1) of the org tree and max depth of the permisson tree
-- If you break your org tree with funky parenting this may be wrong
-- Note: This CTE is duplicated in the find_circ_matrix_matchpoint function, and it may be a good idea to split it off to a function
-- We use one denominator for all tree-based checks for when permission groups and org units have the same weighting
WITH all_distance(distance) AS (
SELECT depth AS distance FROM actor.org_unit_type
UNION
SELECT distance AS distance FROM permission.grp_ancestors_distance((SELECT id FROM permission.grp_tree WHERE parent IS NULL))
)
SELECT INTO denominator MAX(distance) + 1 FROM all_distance;
-- To ATTEMPT to make this work like it used to, make it reverse the user/requestor profile ids.
-- This may be better implemented as part of the upgrade script?
-- Set usr_grp = requestor_grp, requestor_grp = 1 or something when this flag is already set
-- Then remove this flag, of course.
PERFORM * FROM config.internal_flag WHERE name = 'circ.holds.usr_not_requestor' AND enabled;
IF FOUND THEN
-- Note: This, to me, is REALLY hacky. I put it in anyway.
-- If you can't tell, this is a single call swap on two variables.
SELECT INTO user_object.profile, requestor_object.profile
requestor_object.profile, user_object.profile;
END IF;
-- Select the winning matchpoint into the matchpoint variable for returning
SELECT INTO matchpoint m.*
FROM config.hold_matrix_matchpoint m
/*LEFT*/ JOIN permission.grp_ancestors_distance( requestor_object.profile ) rpgad ON m.requestor_grp = rpgad.id
LEFT JOIN permission.grp_ancestors_distance( user_object.profile ) upgad ON m.usr_grp = upgad.id
LEFT JOIN actor.org_unit_ancestors_distance( pickup_ou ) puoua ON m.pickup_ou = puoua.id
LEFT JOIN actor.org_unit_ancestors_distance( request_ou ) rqoua ON m.request_ou = rqoua.id
LEFT JOIN actor.org_unit_ancestors_distance( item_cn_object.owning_lib ) cnoua ON m.item_owning_ou = cnoua.id
LEFT JOIN actor.org_unit_ancestors_distance( item_object.circ_lib ) iooua ON m.item_circ_ou = iooua.id
LEFT JOIN actor.org_unit_ancestors_distance( user_object.home_ou ) uhoua ON m.user_home_ou = uhoua.id
WHERE m.active
-- Permission Groups
-- AND (m.requestor_grp IS NULL OR upgad.id IS NOT NULL) -- Optional Requestor Group?
AND (m.usr_grp IS NULL OR upgad.id IS NOT NULL)
-- Org Units
AND (m.pickup_ou IS NULL OR (puoua.id IS NOT NULL AND (puoua.distance = 0 OR NOT m.strict_ou_match)))
AND (m.request_ou IS NULL OR (rqoua.id IS NOT NULL AND (rqoua.distance = 0 OR NOT m.strict_ou_match)))
AND (m.item_owning_ou IS NULL OR (cnoua.id IS NOT NULL AND (cnoua.distance = 0 OR NOT m.strict_ou_match)))
AND (m.item_circ_ou IS NULL OR (iooua.id IS NOT NULL AND (iooua.distance = 0 OR NOT m.strict_ou_match)))
AND (m.user_home_ou IS NULL OR (uhoua.id IS NOT NULL AND (uhoua.distance = 0 OR NOT m.strict_ou_match)))
-- Static User Checks
AND (m.juvenile_flag IS NULL OR m.juvenile_flag = user_object.juvenile)
-- Static Item Checks
AND (m.circ_modifier IS NULL OR m.circ_modifier = item_object.circ_modifier)
AND (m.marc_type IS NULL OR m.marc_type = COALESCE(item_object.circ_as_type, rec_descriptor.item_type))
AND (m.marc_form IS NULL OR m.marc_form = rec_descriptor.item_form)
AND (m.marc_bib_level IS NULL OR m.marc_bib_level = rec_descriptor.bib_level)
AND (m.marc_vr_format IS NULL OR m.marc_vr_format = rec_descriptor.vr_format)
AND (m.ref_flag IS NULL OR m.ref_flag = item_object.ref)
AND (m.item_age IS NULL OR (my_item_age IS NOT NULL AND m.item_age > my_item_age))
ORDER BY
-- Permission Groups
CASE WHEN rpgad.distance IS NOT NULL THEN 2^(2*weights.requestor_grp - (rpgad.distance/denominator)) ELSE 0.0 END +
CASE WHEN upgad.distance IS NOT NULL THEN 2^(2*weights.usr_grp - (upgad.distance/denominator)) ELSE 0.0 END +
-- Org Units
CASE WHEN puoua.distance IS NOT NULL THEN 2^(2*weights.pickup_ou - (puoua.distance/denominator)) ELSE 0.0 END +
CASE WHEN rqoua.distance IS NOT NULL THEN 2^(2*weights.request_ou - (rqoua.distance/denominator)) ELSE 0.0 END +
CASE WHEN cnoua.distance IS NOT NULL THEN 2^(2*weights.item_owning_ou - (cnoua.distance/denominator)) ELSE 0.0 END +
CASE WHEN iooua.distance IS NOT NULL THEN 2^(2*weights.item_circ_ou - (iooua.distance/denominator)) ELSE 0.0 END +
CASE WHEN uhoua.distance IS NOT NULL THEN 2^(2*weights.user_home_ou - (uhoua.distance/denominator)) ELSE 0.0 END +
-- Static User Checks -- Note: 4^x is equiv to 2^(2*x)
CASE WHEN m.juvenile_flag IS NOT NULL THEN 4^weights.juvenile_flag ELSE 0.0 END +
-- Static Item Checks
CASE WHEN m.circ_modifier IS NOT NULL THEN 4^weights.circ_modifier ELSE 0.0 END +
CASE WHEN m.marc_type IS NOT NULL THEN 4^weights.marc_type ELSE 0.0 END +
CASE WHEN m.marc_form IS NOT NULL THEN 4^weights.marc_form ELSE 0.0 END +
CASE WHEN m.marc_vr_format IS NOT NULL THEN 4^weights.marc_vr_format ELSE 0.0 END +
CASE WHEN m.ref_flag IS NOT NULL THEN 4^weights.ref_flag ELSE 0.0 END +
-- Item age has a slight adjustment to weight based on value.
-- This should ensure that a shorter age limit comes first when all else is equal.
-- NOTE: This assumes that intervals will normally be in days.
CASE WHEN m.item_age IS NOT NULL THEN 4^weights.item_age - 86400/EXTRACT(EPOCH FROM m.item_age) ELSE 0.0 END DESC,
-- Final sort on id, so that if two rules have the same sorting in the previous sort they have a defined order
-- This prevents "we changed the table order by updating a rule, and we started getting different results"
m.id;
-- Return just the ID for now
RETURN matchpoint.id;
END;
Returns: SET OF matrix_test_result
Language: SQL
SELECT * FROM action.hold_request_permit_test( $1, $2, $3, $4, $5, FALSE );
Returns: SET OF matrix_test_result
Language: PLPGSQL
DECLARE
matchpoint_id INT;
user_object actor.usr%ROWTYPE;
age_protect_object config.rule_age_hold_protect%ROWTYPE;
standing_penalty config.standing_penalty%ROWTYPE;
transit_range_ou_type actor.org_unit_type%ROWTYPE;
transit_source actor.org_unit%ROWTYPE;
item_object asset.copy%ROWTYPE;
item_cn_object asset.call_number%ROWTYPE;
item_status_object config.copy_status%ROWTYPE;
item_location_object asset.copy_location%ROWTYPE;
ou_skip actor.org_unit_setting%ROWTYPE;
result action.matrix_test_result;
hold_test config.hold_matrix_matchpoint%ROWTYPE;
use_active_date TEXT;
age_protect_date TIMESTAMP WITH TIME ZONE;
hold_count INT;
hold_transit_prox INT;
frozen_hold_count INT;
context_org_list INT[];
done BOOL := FALSE;
BEGIN
SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( pickup_ou );
result.success := TRUE;
-- Fail if we couldn't find a user
IF user_object.id IS NULL THEN
result.fail_part := 'no_user';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
RETURN;
END IF;
SELECT INTO item_object * FROM asset.copy WHERE id = match_item;
-- Fail if we couldn't find a copy
IF item_object.id IS NULL THEN
result.fail_part := 'no_item';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
RETURN;
END IF;
SELECT INTO matchpoint_id action.find_hold_matrix_matchpoint(pickup_ou, request_ou, match_item, match_user, match_requestor);
result.matchpoint := matchpoint_id;
SELECT INTO ou_skip * FROM actor.org_unit_setting WHERE name = 'circ.holds.target_skip_me' AND org_unit = item_object.circ_lib;
-- Fail if the circ_lib for the item has circ.holds.target_skip_me set to true
IF ou_skip.id IS NOT NULL AND ou_skip.value = 'true' THEN
result.fail_part := 'circ.holds.target_skip_me';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
RETURN;
END IF;
-- Fail if user is barred
IF user_object.barred IS TRUE THEN
result.fail_part := 'actor.usr.barred';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
RETURN;
END IF;
SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
SELECT INTO item_status_object * FROM config.copy_status WHERE id = item_object.status;
SELECT INTO item_location_object * FROM asset.copy_location WHERE id = item_object.location;
-- Fail if we couldn't find any matchpoint (requires a default)
IF matchpoint_id IS NULL THEN
result.fail_part := 'no_matchpoint';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
RETURN;
END IF;
SELECT INTO hold_test * FROM config.hold_matrix_matchpoint WHERE id = matchpoint_id;
IF hold_test.holdable IS FALSE THEN
result.fail_part := 'config.hold_matrix_test.holdable';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
IF item_object.holdable IS FALSE THEN
result.fail_part := 'item.holdable';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
IF item_status_object.holdable IS FALSE THEN
result.fail_part := 'status.holdable';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
IF item_location_object.holdable IS FALSE THEN
result.fail_part := 'location.holdable';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
IF hold_test.transit_range IS NOT NULL THEN
SELECT INTO transit_range_ou_type * FROM actor.org_unit_type WHERE id = hold_test.transit_range;
IF hold_test.distance_is_from_owner THEN
SELECT INTO transit_source ou.* FROM actor.org_unit ou JOIN asset.call_number cn ON (cn.owning_lib = ou.id) WHERE cn.id = item_object.call_number;
ELSE
SELECT INTO transit_source * FROM actor.org_unit WHERE id = item_object.circ_lib;
END IF;
PERFORM * FROM actor.org_unit_descendants( transit_source.id, transit_range_ou_type.depth ) WHERE id = pickup_ou;
IF NOT FOUND THEN
result.fail_part := 'transit_range';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
END IF;
FOR standing_penalty IN
SELECT DISTINCT csp.*
FROM actor.usr_standing_penalty usp
JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
WHERE usr = match_user
AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
AND (usp.stop_date IS NULL or usp.stop_date > NOW())
AND csp.block_list LIKE '%HOLD%' LOOP
result.fail_part := standing_penalty.name;
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END LOOP;
IF hold_test.stop_blocked_user IS TRUE THEN
FOR standing_penalty IN
SELECT DISTINCT csp.*
FROM actor.usr_standing_penalty usp
JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
WHERE usr = match_user
AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
AND (usp.stop_date IS NULL or usp.stop_date > NOW())
AND csp.block_list LIKE '%CIRC%' LOOP
result.fail_part := standing_penalty.name;
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END LOOP;
END IF;
IF hold_test.max_holds IS NOT NULL AND NOT retargetting THEN
SELECT INTO hold_count COUNT(*)
FROM action.hold_request
WHERE usr = match_user
AND fulfillment_time IS NULL
AND cancel_time IS NULL
AND CASE WHEN hold_test.include_frozen_holds THEN TRUE ELSE frozen IS FALSE END;
IF hold_count >= hold_test.max_holds THEN
result.fail_part := 'config.hold_matrix_test.max_holds';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
END IF;
IF item_object.age_protect IS NOT NULL THEN
SELECT INTO age_protect_object * FROM config.rule_age_hold_protect WHERE id = item_object.age_protect;
IF hold_test.distance_is_from_owner THEN
SELECT INTO use_active_date value FROM actor.org_unit_ancestor_setting('circ.holds.age_protect.active_date', item_cn_object.owning_lib);
ELSE
SELECT INTO use_active_date value FROM actor.org_unit_ancestor_setting('circ.holds.age_protect.active_date', item_object.circ_lib);
END IF;
IF use_active_date = 'true' THEN
age_protect_date := COALESCE(item_object.active_date, NOW());
ELSE
age_protect_date := item_object.create_date;
END IF;
IF age_protect_date + age_protect_object.age > NOW() THEN
IF hold_test.distance_is_from_owner THEN
SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
SELECT INTO hold_transit_prox prox FROM actor.org_unit_proximity WHERE from_org = item_cn_object.owning_lib AND to_org = pickup_ou;
ELSE
SELECT INTO hold_transit_prox prox FROM actor.org_unit_proximity WHERE from_org = item_object.circ_lib AND to_org = pickup_ou;
END IF;
IF hold_transit_prox > age_protect_object.prox THEN
result.fail_part := 'config.rule_age_hold_protect.prox';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
END IF;
END IF;
IF NOT done THEN
RETURN NEXT result;
END IF;
RETURN;
END;
Returns: SET OF matrix_test_result
Language: SQL
SELECT * FROM action.hold_request_permit_test( $1, $2, $3, $4, $5, TRUE );
Returns: SET OF circ_matrix_test_result
Language: SQL
SELECT * FROM action.item_user_circ_test( $1, $2, $3, FALSE );
Returns: SET OF circ_matrix_test_result
Language: PLPGSQL
DECLARE
user_object actor.usr%ROWTYPE;
standing_penalty config.standing_penalty%ROWTYPE;
item_object asset.copy%ROWTYPE;
item_status_object config.copy_status%ROWTYPE;
item_location_object asset.copy_location%ROWTYPE;
result action.circ_matrix_test_result;
circ_test action.found_circ_matrix_matchpoint;
circ_matchpoint config.circ_matrix_matchpoint%ROWTYPE;
circ_limit_set config.circ_limit_set%ROWTYPE;
hold_ratio action.hold_stats%ROWTYPE;
penalty_type TEXT;
items_out INT;
context_org_list INT[];
done BOOL := FALSE;
BEGIN
-- Assume success unless we hit a failure condition
result.success := TRUE;
-- Need user info to look up matchpoints
SELECT INTO user_object * FROM actor.usr WHERE id = match_user AND NOT deleted;
-- (Insta)Fail if we couldn't find the user
IF user_object.id IS NULL THEN
result.fail_part := 'no_user';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
RETURN;
END IF;
-- Need item info to look up matchpoints
SELECT INTO item_object * FROM asset.copy WHERE id = match_item AND NOT deleted;
-- (Insta)Fail if we couldn't find the item
IF item_object.id IS NULL THEN
result.fail_part := 'no_item';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
RETURN;
END IF;
SELECT INTO circ_test * FROM action.find_circ_matrix_matchpoint(circ_ou, item_object, user_object, renewal);
circ_matchpoint := circ_test.matchpoint;
result.matchpoint := circ_matchpoint.id;
result.circulate := circ_matchpoint.circulate;
result.duration_rule := circ_matchpoint.duration_rule;
result.recurring_fine_rule := circ_matchpoint.recurring_fine_rule;
result.max_fine_rule := circ_matchpoint.max_fine_rule;
result.hard_due_date := circ_matchpoint.hard_due_date;
result.renewals := circ_matchpoint.renewals;
result.grace_period := circ_matchpoint.grace_period;
result.buildrows := circ_test.buildrows;
-- (Insta)Fail if we couldn't find a matchpoint
IF circ_test.success = false THEN
result.fail_part := 'no_matchpoint';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
RETURN;
END IF;
-- All failures before this point are non-recoverable
-- Below this point are possibly overridable failures
-- Fail if the user is barred
IF user_object.barred IS TRUE THEN
result.fail_part := 'actor.usr.barred';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
-- Fail if the item can't circulate
IF item_object.circulate IS FALSE THEN
result.fail_part := 'asset.copy.circulate';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
-- Fail if the item isn't in a circulateable status on a non-renewal
IF NOT renewal AND item_object.status NOT IN ( 0, 7, 8 ) THEN
result.fail_part := 'asset.copy.status';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
-- Alternately, fail if the item isn't checked out on a renewal
ELSIF renewal AND item_object.status <> 1 THEN
result.fail_part := 'asset.copy.status';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
-- Fail if the item can't circulate because of the shelving location
SELECT INTO item_location_object * FROM asset.copy_location WHERE id = item_object.location;
IF item_location_object.circulate IS FALSE THEN
result.fail_part := 'asset.copy_location.circulate';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
-- Use Circ OU for penalties and such
SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( circ_ou );
IF renewal THEN
penalty_type = '%RENEW%';
ELSE
penalty_type = '%CIRC%';
END IF;
FOR standing_penalty IN
SELECT DISTINCT csp.*
FROM actor.usr_standing_penalty usp
JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
WHERE usr = match_user
AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
AND (usp.stop_date IS NULL or usp.stop_date > NOW())
AND csp.block_list LIKE penalty_type LOOP
result.fail_part := standing_penalty.name;
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END LOOP;
-- Fail if the test is set to hard non-circulating
IF circ_matchpoint.circulate IS FALSE THEN
result.fail_part := 'config.circ_matrix_test.circulate';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
-- Fail if the total copy-hold ratio is too low
IF circ_matchpoint.total_copy_hold_ratio IS NOT NULL THEN
SELECT INTO hold_ratio * FROM action.copy_related_hold_stats(match_item);
IF hold_ratio.total_copy_ratio IS NOT NULL AND hold_ratio.total_copy_ratio < circ_matchpoint.total_copy_hold_ratio THEN
result.fail_part := 'config.circ_matrix_test.total_copy_hold_ratio';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
END IF;
-- Fail if the available copy-hold ratio is too low
IF circ_matchpoint.available_copy_hold_ratio IS NOT NULL THEN
IF hold_ratio.hold_count IS NULL THEN
SELECT INTO hold_ratio * FROM action.copy_related_hold_stats(match_item);
END IF;
IF hold_ratio.available_copy_ratio IS NOT NULL AND hold_ratio.available_copy_ratio < circ_matchpoint.available_copy_hold_ratio THEN
result.fail_part := 'config.circ_matrix_test.available_copy_hold_ratio';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
END IF;
-- Fail if the user has too many items out by defined limit sets
FOR circ_limit_set IN SELECT ccls.* FROM config.circ_limit_set ccls
JOIN config.circ_matrix_limit_set_map ccmlsm ON ccmlsm.limit_set = ccls.id
WHERE ccmlsm.active AND ( ccmlsm.matchpoint = circ_matchpoint.id OR
( ccmlsm.matchpoint IN (SELECT * FROM unnest(result.buildrows)) AND ccmlsm.fallthrough )
) LOOP
IF circ_limit_set.items_out > 0 AND NOT renewal THEN
SELECT INTO context_org_list ARRAY_AGG(aou.id)
FROM actor.org_unit_full_path( circ_ou ) aou
JOIN actor.org_unit_type aout ON aou.ou_type = aout.id
WHERE aout.depth >= circ_limit_set.depth;
IF circ_limit_set.global THEN
WITH RECURSIVE descendant_depth AS (
SELECT ou.id,
ou.parent_ou
FROM actor.org_unit ou
WHERE ou.id IN (SELECT * FROM unnest(context_org_list))
UNION
SELECT ou.id,
ou.parent_ou
FROM actor.org_unit ou
JOIN descendant_depth ot ON (ot.id = ou.parent_ou)
) SELECT INTO context_org_list ARRAY_AGG(ou.id) FROM actor.org_unit ou JOIN descendant_depth USING (id);
END IF;
SELECT INTO items_out COUNT(DISTINCT circ.id)
FROM action.circulation circ
JOIN asset.copy copy ON (copy.id = circ.target_copy)
LEFT JOIN action.circulation_limit_group_map aclgm ON (circ.id = aclgm.circ)
WHERE circ.usr = match_user
AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
AND circ.checkin_time IS NULL
AND (circ.stop_fines IN ('MAXFINES','LONGOVERDUE') OR circ.stop_fines IS NULL)
AND (copy.circ_modifier IN (SELECT circ_mod FROM config.circ_limit_set_circ_mod_map WHERE limit_set = circ_limit_set.id)
OR aclgm.limit_group IN (SELECT limit_group FROM config.circ_limit_set_group_map WHERE limit_set = circ_limit_set.id)
);
IF items_out >= circ_limit_set.items_out THEN
result.fail_part := 'config.circ_matrix_circ_mod_test';
result.success := FALSE;
done := TRUE;
RETURN NEXT result;
END IF;
END IF;
SELECT INTO result.limit_groups result.limit_groups || ARRAY_AGG(limit_group) FROM config.circ_limit_set_group_map WHERE limit_set = circ_limit_set.id AND NOT check_only;
END LOOP;
-- If we passed everything, return the successful matchpoint
IF NOT done THEN
RETURN NEXT result;
END IF;
RETURN;
END;
Returns: SET OF circ_matrix_test_result
Language: SQL
SELECT * FROM action.item_user_circ_test( $1, $2, $3, TRUE );
Returns: void
Language: SQL
INSERT INTO action.circulation_limit_group_map(circ, limit_group) SELECT $1, id FROM config.circ_limit_group WHERE id IN (SELECT * FROM UNNEST($2));
Returns: integer
Language: PLPGSQL
DECLARE
usr_keep_age actor.usr_setting%ROWTYPE;
usr_keep_start actor.usr_setting%ROWTYPE;
org_keep_age INTERVAL;
org_keep_count INT;
keep_age INTERVAL;
target_acp RECORD;
circ_chain_head action.circulation%ROWTYPE;
circ_chain_tail action.circulation%ROWTYPE;
purge_position INT;
count_purged INT;
BEGIN
count_purged := 0;
SELECT value::INTERVAL INTO org_keep_age FROM config.global_flag WHERE name = 'history.circ.retention_age' AND enabled;
SELECT value::INT INTO org_keep_count FROM config.global_flag WHERE name = 'history.circ.retention_count' AND enabled;
IF org_keep_count IS NULL THEN
RETURN count_purged; -- Gimme a count to keep, or I keep them all, forever
END IF;
-- First, find copies with more than keep_count non-renewal circs
FOR target_acp IN
SELECT target_copy,
COUNT(*) AS total_real_circs
FROM action.circulation
WHERE parent_circ IS NULL
AND xact_finish IS NOT NULL
GROUP BY target_copy
HAVING COUNT(*) > org_keep_count
LOOP
purge_position := 0;
-- And, for those, select circs that are finished and older than keep_age
FOR circ_chain_head IN
SELECT *
FROM action.circulation
WHERE target_copy = target_acp.target_copy
AND parent_circ IS NULL
ORDER BY xact_start
LOOP
-- Stop once we've purged enough circs to hit org_keep_count
EXIT WHEN target_acp.total_real_circs - purge_position <= org_keep_count;
SELECT * INTO circ_chain_tail FROM action.circ_chain(circ_chain_head.id) ORDER BY xact_start DESC LIMIT 1;
EXIT WHEN circ_chain_tail.xact_finish IS NULL;
-- Now get the user settings, if any, to block purging if the user wants to keep more circs
usr_keep_age.value := NULL;
SELECT * INTO usr_keep_age FROM actor.usr_setting WHERE usr = circ_chain_head.usr AND name = 'history.circ.retention_age';
usr_keep_start.value := NULL;
SELECT * INTO usr_keep_start FROM actor.usr_setting WHERE usr = circ_chain_head.usr AND name = 'history.circ.retention_start';
IF usr_keep_age.value IS NOT NULL AND usr_keep_start.value IS NOT NULL THEN
IF oils_json_to_text(usr_keep_age.value)::INTERVAL > AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ) THEN
keep_age := AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ);
ELSE
keep_age := oils_json_to_text(usr_keep_age.value)::INTERVAL;
END IF;
ELSIF usr_keep_start.value IS NOT NULL THEN
keep_age := AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ);
ELSE
keep_age := COALESCE( org_keep_age::INTERVAL, '2000 years'::INTERVAL );
END IF;
EXIT WHEN AGE(NOW(), circ_chain_tail.xact_finish) < keep_age;
-- We've passed the purging tests, purge the circ chain starting at the end
DELETE FROM action.circulation WHERE id = circ_chain_tail.id;
WHILE circ_chain_tail.parent_circ IS NOT NULL LOOP
SELECT * INTO circ_chain_tail FROM action.circulation WHERE id = circ_chain_tail.parent_circ;
DELETE FROM action.circulation WHERE id = circ_chain_tail.id;
END LOOP;
count_purged := count_purged + 1;
purge_position := purge_position + 1;
END LOOP;
END LOOP;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF (EXTRACT(EPOCH FROM NEW.duration)::INT % EXTRACT(EPOCH FROM '1 day'::INTERVAL)::INT) = 0 THEN
NEW.due_date = (NEW.due_date::DATE + '1 day'::INTERVAL - '1 second'::INTERVAL)::TIMESTAMPTZ;
END IF;
RETURN NEW;
END;
Returns: circ_chain_summary
Language: PLPGSQL
DECLARE
-- first circ in the chain
circ_0 action.circulation%ROWTYPE;
-- last circ in the chain
circ_n action.circulation%ROWTYPE;
-- circ chain under construction
chain action.circ_chain_summary;
tmp_circ action.circulation%ROWTYPE;
BEGIN
chain.num_circs := 0;
FOR tmp_circ IN SELECT * FROM action.circ_chain(ctx_circ_id) LOOP
IF chain.num_circs = 0 THEN
circ_0 := tmp_circ;
END IF;
chain.num_circs := chain.num_circs + 1;
circ_n := tmp_circ;
END LOOP;
chain.start_time := circ_0.xact_start;
chain.last_stop_fines := circ_n.stop_fines;
chain.last_stop_fines_time := circ_n.stop_fines_time;
chain.last_checkin_time := circ_n.checkin_time;
chain.last_checkin_scan_time := circ_n.checkin_scan_time;
SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
IF chain.num_circs > 1 THEN
chain.last_renewal_time := circ_n.xact_start;
SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
END IF;
RETURN chain;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
NEW.answer_date := NOW();
RETURN NEW;
END;
Returns: SET OF bigint
Language: SQL
SELECT DISTINCT(target_copy) FROM action.usr_visible_circs($1)
Returns: SET OF circulation
Language: PLPGSQL
DECLARE
c action.circulation%ROWTYPE;
view_age INTERVAL;
usr_view_age actor.usr_setting%ROWTYPE;
usr_view_start actor.usr_setting%ROWTYPE;
BEGIN
SELECT * INTO usr_view_age FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.circ.retention_age';
SELECT * INTO usr_view_start FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.circ.retention_start';
IF usr_view_age.value IS NOT NULL AND usr_view_start.value IS NOT NULL THEN
-- User opted in and supplied a retention age
IF oils_json_to_text(usr_view_age.value)::INTERVAL > AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ) THEN
view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
ELSE
view_age := oils_json_to_text(usr_view_age.value)::INTERVAL;
END IF;
ELSIF usr_view_start.value IS NOT NULL THEN
-- User opted in
view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
ELSE
-- User did not opt in
RETURN;
END IF;
FOR c IN
SELECT *
FROM action.circulation
WHERE usr = usr_id
AND parent_circ IS NULL
AND xact_start > NOW() - view_age
ORDER BY xact_start DESC
LOOP
RETURN NEXT c;
END LOOP;
RETURN;
END;
Returns: SET OF hold_request
Language: PLPGSQL
DECLARE
h action.hold_request%ROWTYPE;
view_age INTERVAL;
view_count INT;
usr_view_count actor.usr_setting%ROWTYPE;
usr_view_age actor.usr_setting%ROWTYPE;
usr_view_start actor.usr_setting%ROWTYPE;
BEGIN
SELECT * INTO usr_view_count FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_count';
SELECT * INTO usr_view_age FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_age';
SELECT * INTO usr_view_start FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_start';
FOR h IN
SELECT *
FROM action.hold_request
WHERE usr = usr_id
AND fulfillment_time IS NULL
AND cancel_time IS NULL
ORDER BY request_time DESC
LOOP
RETURN NEXT h;
END LOOP;
IF usr_view_start.value IS NULL THEN
RETURN;
END IF;
IF usr_view_age.value IS NOT NULL THEN
-- User opted in and supplied a retention age
IF oils_json_to_text(usr_view_age.value)::INTERVAL > AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ) THEN
view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
ELSE
view_age := oils_json_to_text(usr_view_age.value)::INTERVAL;
END IF;
ELSE
-- User opted in
view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
END IF;
IF usr_view_count.value IS NOT NULL THEN
view_count := oils_json_to_text(usr_view_count.value)::INT;
ELSE
view_count := 1000;
END IF;
-- show some fulfilled/canceled holds
FOR h IN
SELECT *
FROM action.hold_request
WHERE usr = usr_id
AND ( fulfillment_time IS NOT NULL OR cancel_time IS NOT NULL )
AND request_time > NOW() - view_age
ORDER BY request_time DESC
LIMIT view_count
LOOP
RETURN NEXT h;
END LOOP;
RETURN;
END;
Schema action_trigger
action_trigger.cleanup Structure
F-Key |
Name |
Type |
Description |
|
module |
text |
PRIMARY KEY
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action_trigger
action_trigger.collector Structure
F-Key |
Name |
Type |
Description |
|
module |
text |
PRIMARY KEY
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action_trigger
action_trigger.environment Constraints
Name |
Constraint |
environment_label_check |
CHECK ((label <> ALL (ARRAY['result'::text, 'target'::text, 'event'::text]))) |
Index -
Schema action_trigger
action_trigger.event Constraints
Name |
Constraint |
event_state_check |
CHECK ((state = ANY (ARRAY['pending'::text, 'invalid'::text, 'found'::text, 'collecting'::text, 'collected'::text, 'validating'::text, 'valid'::text, 'reacting'::text, 'reacted'::text, 'cleaning'::text, 'complete'::text, 'error'::text]))) |
event_user_data_check |
CHECK (((user_data IS NULL) OR is_json(user_data))) |
atev_target_def_idx target, event_def
Index -
Schema action_trigger
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action_trigger
action_trigger.event_output Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
is_error |
boolean |
NOT NULL
DEFAULT false
|
|
data |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action_trigger
action_trigger.event_params Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
action_trigger.event_definition.id
|
event_def |
integer |
UNIQUE#1
NOT NULL
|
|
param |
text |
UNIQUE#1
NOT NULL
|
|
value |
text |
NOT NULL
|
Index -
Schema action_trigger
action_trigger.hook Structure
F-Key |
Name |
Type |
Description |
|
key |
text |
PRIMARY KEY
|
|
core_type |
text |
NOT NULL
|
|
description |
text |
|
|
passive |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action_trigger
action_trigger.reactor Structure
F-Key |
Name |
Type |
Description |
|
module |
text |
PRIMARY KEY
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action_trigger
action_trigger.validator Structure
F-Key |
Name |
Type |
Description |
|
module |
text |
PRIMARY KEY
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema action_trigger
Schema actor
Holds all tables pertaining to users and libraries (org units).
actor.address_alert Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
NOT NULL
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
|
match_all |
boolean |
NOT NULL
DEFAULT true
|
|
alert_message |
text |
NOT NULL
|
|
street1 |
text |
|
|
street2 |
text |
|
|
city |
text |
|
|
county |
text |
|
|
state |
text |
|
|
country |
text |
|
|
post_code |
text |
|
|
mailing_address |
boolean |
NOT NULL
DEFAULT false
|
|
billing_address |
boolean |
NOT NULL
DEFAULT false
|
Index -
Schema actor
Library Cards
Each User has one or more library cards. The current "main"
card is linked to here from the actor.usr table, and it is up
to the consortium policy whether more than one card can be
active for any one user at a given time.
actor.card Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
|
barcode |
text |
UNIQUE
NOT NULL
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
actor_card_barcode_evergreen_lowercase_idx lowercase(barcode)
actor_card_usr_idx usr
Index -
Schema actor
When does this org_unit usually open and close? (Variations
are expressed in the actor.org_unit_closed table.)
actor.hours_of_operation Structure
F-Key |
Name |
Type |
Description |
actor.org_unit.id
|
id |
integer |
PRIMARY KEY
|
|
dow_0_open |
time without time zone |
NOT NULL
DEFAULT '09:00:00'::time without time zone
When does this org_unit open on Monday?
|
|
dow_0_close |
time without time zone |
NOT NULL
DEFAULT '17:00:00'::time without time zone
When does this org_unit close on Monday?
|
|
dow_1_open |
time without time zone |
NOT NULL
DEFAULT '09:00:00'::time without time zone
When does this org_unit open on Tuesday?
|
|
dow_1_close |
time without time zone |
NOT NULL
DEFAULT '17:00:00'::time without time zone
When does this org_unit close on Tuesday?
|
|
dow_2_open |
time without time zone |
NOT NULL
DEFAULT '09:00:00'::time without time zone
When does this org_unit open on Wednesday?
|
|
dow_2_close |
time without time zone |
NOT NULL
DEFAULT '17:00:00'::time without time zone
When does this org_unit close on Wednesday?
|
|
dow_3_open |
time without time zone |
NOT NULL
DEFAULT '09:00:00'::time without time zone
When does this org_unit open on Thursday?
|
|
dow_3_close |
time without time zone |
NOT NULL
DEFAULT '17:00:00'::time without time zone
When does this org_unit close on Thursday?
|
|
dow_4_open |
time without time zone |
NOT NULL
DEFAULT '09:00:00'::time without time zone
When does this org_unit open on Friday?
|
|
dow_4_close |
time without time zone |
NOT NULL
DEFAULT '17:00:00'::time without time zone
When does this org_unit close on Friday?
|
|
dow_5_open |
time without time zone |
NOT NULL
DEFAULT '09:00:00'::time without time zone
When does this org_unit open on Saturday?
|
|
dow_5_close |
time without time zone |
NOT NULL
DEFAULT '17:00:00'::time without time zone
When does this org_unit close on Saturday?
|
|
dow_6_open |
time without time zone |
NOT NULL
DEFAULT '09:00:00'::time without time zone
When does this org_unit open on Sunday?
|
|
dow_6_close |
time without time zone |
NOT NULL
DEFAULT '17:00:00'::time without time zone
When does this org_unit close on Sunday?
|
Index -
Schema actor
actor.org_address Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
valid |
boolean |
NOT NULL
DEFAULT true
|
|
address_type |
text |
NOT NULL
DEFAULT 'MAILING'::text
|
actor.org_unit.id
|
org_unit |
integer |
NOT NULL
|
|
street1 |
text |
NOT NULL
|
|
street2 |
text |
|
|
city |
text |
NOT NULL
|
|
county |
text |
|
|
state |
text |
NOT NULL
|
|
country |
text |
NOT NULL
|
|
post_code |
text |
NOT NULL
|
|
san |
text |
|
Tables referencing this one via Foreign Key Constraints:
actor_org_address_org_unit_idx org_unit
Index -
Schema actor
actor.org_lasso Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema actor
ou_lasso_org_unit_idx org_unit
Index -
Schema actor
Tables referencing this one via Foreign Key Constraints:
actor_org_unit_billing_address_idx billing_address
actor_org_unit_holds_address_idx holds_address
actor_org_unit_ill_address_idx ill_address
actor_org_unit_mailing_address_idx mailing_address
actor_org_unit_ou_type_idx ou_type
actor_org_unit_parent_ou_idx parent_ou
Index -
Schema actor
actor.org_unit_closed Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
org_unit |
integer |
NOT NULL
|
|
close_start |
timestamp with time zone |
NOT NULL
|
|
close_end |
timestamp with time zone |
NOT NULL
|
|
reason |
text |
|
Index -
Schema actor
actor.org_unit_custom_tree Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
active |
boolean |
DEFAULT false
|
|
purpose |
actor.org_unit_custom_tree_purpose |
UNIQUE
NOT NULL
DEFAULT 'opac'::actor.org_unit_custom_tree_purpose
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema actor
Tables referencing this one via Foreign Key Constraints:
Index -
Schema actor
actor.org_unit_proximity Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
from_org |
integer |
|
|
to_org |
integer |
|
|
prox |
integer |
|
from_prox_idx from_org
Index -
Schema actor
Org Unit settings
This table contains any arbitrary settings that a client
program would like to save for an org unit.
actor.org_unit_setting Constraints
Name |
Constraint |
aous_must_be_json |
CHECK (is_json(value)) |
actor_org_unit_setting_usr_idx org_unit
Index -
Schema actor
actor.org_unit_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
|
opac_label |
text |
NOT NULL
|
|
depth |
integer |
NOT NULL
|
actor.org_unit_type.id
|
parent |
integer |
|
|
can_have_vols |
boolean |
NOT NULL
DEFAULT true
|
|
can_have_users |
boolean |
NOT NULL
DEFAULT true
|
Tables referencing this one via Foreign Key Constraints:
actor_org_unit_type_parent_idx parent
Index -
Schema actor
User Statistical Catagories
Local data collected about Users is placed into a Statistical
Catagory. Here's where those catagories are defined.
actor.stat_cat Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
opac_visible |
boolean |
NOT NULL
DEFAULT false
|
|
usr_summary |
boolean |
NOT NULL
DEFAULT false
|
actor.stat_cat_sip_fields.field
|
sip_field |
character(2) |
|
|
sip_format |
text |
|
|
checkout_archive |
boolean |
NOT NULL
DEFAULT false
|
|
required |
boolean |
NOT NULL
DEFAULT false
|
|
allow_freetext |
boolean |
NOT NULL
DEFAULT true
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema actor
User Statistical Catagory Entries
Local data collected about Users is placed into a Statistical
Catagory. Each library can create entries into any of its own
stat_cats, its ancestors' stat_cats, or its descendants' stat_cats.
actor.stat_cat_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.stat_cat.id
|
stat_cat |
integer |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
value |
text |
UNIQUE#1
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema actor
User Statistical Category Default Entry
A library may choose one of the stat_cat entries to be the
default entry.
Index -
Schema actor
Statistical Catagory Entry to User map
Records the stat_cat entries for each user.
actor.stat_cat_entry_usr_map Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
stat_cat_entry |
text |
NOT NULL
|
actor.stat_cat.id
|
stat_cat |
integer |
UNIQUE#1
NOT NULL
|
actor.usr.id
|
target_usr |
integer |
UNIQUE#1
NOT NULL
|
actor_stat_cat_entry_usr_idx target_usr
Index -
Schema actor
Actor Statistical Category SIP Fields
Contains the list of valid SIP Field identifiers for
Statistical Categories.
actor.stat_cat_sip_fields Structure
F-Key |
Name |
Type |
Description |
|
field |
character(2) |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
|
one_only |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema actor
actor.toolbar Constraints
Name |
Constraint |
layout_must_be_json |
CHECK (is_json(layout)) |
only_one_type |
CHECK (((((ws IS NOT NULL) AND (COALESCE(org, usr) IS NULL)) OR ((org IS NOT NULL) AND (COALESCE(ws, usr) IS NULL))) OR ((usr IS NOT NULL) AND (COALESCE(org, ws) IS NULL)))) |
Index -
Schema actor
User objects
This table contains the core User objects that describe both
staff members and patrons. The difference between the two
types of users is based on the user's permissions.
actor.usr Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
card |
integer |
UNIQUE
|
permission.grp_tree.id
|
profile |
integer |
NOT NULL
|
|
usrname |
text |
UNIQUE
NOT NULL
|
|
email |
text |
|
|
passwd |
text |
NOT NULL
|
config.standing.id
|
standing |
integer |
NOT NULL
DEFAULT 1
|
config.identification_type.id
|
ident_type |
integer |
NOT NULL
|
|
ident_value |
text |
|
config.identification_type.id
|
ident_type2 |
integer |
|
|
ident_value2 |
text |
|
config.net_access_level.id
|
net_access_level |
integer |
NOT NULL
DEFAULT 1
|
|
photo_url |
text |
|
|
prefix |
text |
|
|
first_given_name |
text |
NOT NULL
|
|
second_given_name |
text |
|
|
family_name |
text |
NOT NULL
|
|
suffix |
text |
|
|
alias |
text |
|
|
day_phone |
text |
|
|
evening_phone |
text |
|
|
other_phone |
text |
|
actor.usr_address.id
|
mailing_address |
integer |
|
actor.usr_address.id
|
billing_address |
integer |
|
actor.org_unit.id
|
home_ou |
integer |
NOT NULL
|
|
dob |
timestamp with time zone |
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
|
master_account |
boolean |
NOT NULL
DEFAULT false
|
|
super_user |
boolean |
NOT NULL
DEFAULT false
|
|
barred |
boolean |
NOT NULL
DEFAULT false
|
|
deleted |
boolean |
NOT NULL
DEFAULT false
|
|
juvenile |
boolean |
NOT NULL
DEFAULT false
|
|
usrgroup |
serial |
NOT NULL
|
|
claims_returned_count |
integer |
NOT NULL
|
|
credit_forward_balance |
numeric(6,2) |
NOT NULL
DEFAULT 0.00
|
|
last_xact_id |
text |
NOT NULL
DEFAULT 'none'::text
|
|
alert_message |
text |
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
expire_date |
timestamp with time zone |
NOT NULL
DEFAULT (now() + '3 years'::interval)
|
|
claims_never_checked_out_count |
integer |
NOT NULL
|
|
last_update_time |
timestamp with time zone |
|
Tables referencing this one via Foreign Key Constraints:
actor_usr_billing_address_idx billing_address
actor_usr_day_phone_idx lowercase(day_phone)
actor_usr_day_phone_idx_numeric lowercase(regexp_replace(day_phone, '[^0-9]'::text, ''::text, 'g'::text))
actor_usr_email_idx lowercase(email)
actor_usr_evening_phone_idx lowercase(evening_phone)
actor_usr_evening_phone_idx_numeric lowercase(regexp_replace(evening_phone, '[^0-9]'::text, ''::text, 'g'::text))
actor_usr_family_name_idx lowercase(family_name)
actor_usr_first_given_name_idx lowercase(first_given_name)
actor_usr_home_ou_idx home_ou
actor_usr_ident_value2_idx lowercase(ident_value2)
actor_usr_ident_value_idx lowercase(ident_value)
actor_usr_mailing_address_idx mailing_address
actor_usr_other_phone_idx lowercase(other_phone)
actor_usr_other_phone_idx_numeric lowercase(regexp_replace(other_phone, '[^0-9]'::text, ''::text, 'g'::text))
actor_usr_second_given_name_idx lowercase(second_given_name)
actor_usr_usrgroup_idx usrgroup
Index -
Schema actor
actor.usr_activity Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
|
config.usr_activity_type.id
|
etype |
integer |
NOT NULL
|
|
event_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Index -
Schema actor
actor.usr_address Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
valid |
boolean |
NOT NULL
DEFAULT true
|
|
within_city_limits |
boolean |
NOT NULL
DEFAULT true
|
|
address_type |
text |
NOT NULL
DEFAULT 'MAILING'::text
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
|
street1 |
text |
NOT NULL
|
|
street2 |
text |
|
|
city |
text |
NOT NULL
|
|
county |
text |
|
|
state |
text |
NOT NULL
|
|
country |
text |
NOT NULL
|
|
post_code |
text |
NOT NULL
|
|
pending |
boolean |
NOT NULL
DEFAULT false
|
actor.usr_address.id
|
replaces |
integer |
|
Tables referencing this one via Foreign Key Constraints:
actor_usr_addr_city_idx lowercase(city)
actor_usr_addr_post_code_idx lowercase(post_code)
actor_usr_addr_state_idx lowercase(state)
actor_usr_addr_street1_idx lowercase(street1)
actor_usr_addr_street2_idx lowercase(street2)
actor_usr_addr_usr_idx usr
Index -
Schema actor
actor.usr_note Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.usr.id
|
usr |
bigint |
NOT NULL
|
actor.usr.id
|
creator |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
title |
text |
NOT NULL
|
|
value |
text |
NOT NULL
|
actor_usr_note_creator_idx creator
actor_usr_note_usr_idx usr
Index -
Schema actor
actor.usr_org_unit_opt_in Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
org_unit |
integer |
UNIQUE#1
NOT NULL
|
actor.usr.id
|
usr |
integer |
UNIQUE#1
NOT NULL
|
actor.usr.id
|
staff |
integer |
NOT NULL
|
|
opt_in_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
actor.workstation.id
|
opt_in_ws |
integer |
NOT NULL
|
usr_org_unit_opt_in_staff_idx staff
Index -
Schema actor
Self-serve password reset requests
actor.usr_password_reset Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
uuid |
text |
NOT NULL
|
actor.usr.id
|
usr |
bigint |
NOT NULL
|
|
request_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
has_been_reset |
boolean |
NOT NULL
DEFAULT false
|
actor_usr_password_reset_has_been_reset_idx has_been_reset
actor_usr_password_reset_request_time_idx request_time
actor_usr_password_reset_usr_idx usr
Index -
Schema actor
actor.usr_saved_search Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
query_text |
text |
NOT NULL
|
|
query_type |
text |
NOT NULL
DEFAULT 'URL'::text
|
|
target |
text |
NOT NULL
|
actor.usr_saved_search Constraints
Name |
Constraint |
valid_query_text |
CHECK ((query_type = 'URL'::text)) |
valid_target |
CHECK ((target = ANY (ARRAY['record'::text, 'metarecord'::text, 'callnumber'::text]))) |
Index -
Schema actor
User settings
This table contains any arbitrary settings that a client
program would like to save for a user.
actor.usr_setting Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
UNIQUE#1
NOT NULL
|
config.usr_setting_type.name
|
name |
text |
UNIQUE#1
NOT NULL
|
|
value |
text |
NOT NULL
|
actor_usr_setting_usr_idx usr
Index -
Schema actor
User standing penalties
actor.usr_standing_penalty Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
org_unit |
integer |
NOT NULL
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
config.standing_penalty.id
|
standing_penalty |
integer |
NOT NULL
|
actor.usr.id
|
staff |
integer |
|
|
set_date |
timestamp with time zone |
DEFAULT now()
|
|
stop_date |
timestamp with time zone |
|
|
note |
text |
|
actor_usr_standing_penalty_staff_idx staff
actor_usr_standing_penalty_usr_idx usr
Index -
Schema actor
actor.workstation Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
actor.org_unit.id
|
owning_lib |
integer |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema actor
Returns: SET OF address_alert
Language: SQL
SELECT *
FROM actor.address_alert
WHERE
active
AND owner IN (SELECT id FROM actor.org_unit_ancestors($1))
AND (
(NOT mailing_address AND NOT billing_address)
OR (mailing_address AND $9)
OR (billing_address AND $10)
)
AND (
(
match_all
AND COALESCE($2, '') ~* COALESCE(street1, '.*')
AND COALESCE($3, '') ~* COALESCE(street2, '.*')
AND COALESCE($4, '') ~* COALESCE(city, '.*')
AND COALESCE($5, '') ~* COALESCE(county, '.*')
AND COALESCE($6, '') ~* COALESCE(state, '.*')
AND COALESCE($7, '') ~* COALESCE(country, '.*')
AND COALESCE($8, '') ~* COALESCE(post_code, '.*')
) OR (
NOT match_all
AND (
$2 ~* street1
OR $3 ~* street2
OR $4 ~* city
OR $5 ~* county
OR $6 ~* state
OR $7 ~* country
OR $8 ~* post_code
)
)
)
ORDER BY actor.org_unit_proximity(owner, $1)
Returns: bigint
Language: PLPGSQL
Replaces an address with a pending address. This is done by giving the pending
address the ID of the old address. The replaced address is retained with -id.
DECLARE
old_id INT;
BEGIN
SELECT INTO old_id replaces FROM actor.usr_address where id = pending_id;
IF old_id IS NULL THEN
UPDATE actor.usr_address SET pending = 'f' WHERE id = pending_id;
RETURN pending_id;
END IF;
-- address replaces an existing address
DELETE FROM actor.usr_address WHERE id = -old_id;
UPDATE actor.usr_address SET id = -id WHERE id = old_id;
UPDATE actor.usr_address SET replaces = NULL, id = old_id, pending = 'f' WHERE id = pending_id;
RETURN old_id;
END
Returns: trigger
Language: PLPGSQL
BEGIN
NEW.last_update_time := now();
RETURN NEW;
END;
Returns: SET OF usr_standing_penalty
Language: PLPGSQL
DECLARE
user_object actor.usr%ROWTYPE;
new_sp_row actor.usr_standing_penalty%ROWTYPE;
existing_sp_row actor.usr_standing_penalty%ROWTYPE;
collections_fines permission.grp_penalty_threshold%ROWTYPE;
max_fines permission.grp_penalty_threshold%ROWTYPE;
max_overdue permission.grp_penalty_threshold%ROWTYPE;
max_items_out permission.grp_penalty_threshold%ROWTYPE;
tmp_grp INT;
items_overdue INT;
items_out INT;
context_org_list INT[];
current_fines NUMERIC(8,2) := 0.0;
tmp_fines NUMERIC(8,2);
tmp_groc RECORD;
tmp_circ RECORD;
tmp_org actor.org_unit%ROWTYPE;
tmp_penalty config.standing_penalty%ROWTYPE;
tmp_depth INTEGER;
BEGIN
SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
-- Max fines
SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
-- Fail if the user has a high fine balance
LOOP
tmp_grp := user_object.profile;
LOOP
SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 1 AND org_unit = tmp_org.id;
IF max_fines.threshold IS NULL THEN
SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
ELSE
EXIT;
END IF;
IF tmp_grp IS NULL THEN
EXIT;
END IF;
END LOOP;
IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
EXIT;
END IF;
SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
END LOOP;
IF max_fines.threshold IS NOT NULL THEN
RETURN QUERY
SELECT *
FROM actor.usr_standing_penalty
WHERE usr = match_user
AND org_unit = max_fines.org_unit
AND (stop_date IS NULL or stop_date > NOW())
AND standing_penalty = 1;
SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
SELECT SUM(f.balance_owed) INTO current_fines
FROM money.materialized_billable_xact_summary f
JOIN (
SELECT r.id
FROM booking.reservation r
WHERE r.usr = match_user
AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
AND xact_finish IS NULL
UNION ALL
SELECT g.id
FROM money.grocery g
WHERE g.usr = match_user
AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
AND xact_finish IS NULL
UNION ALL
SELECT circ.id
FROM action.circulation circ
WHERE circ.usr = match_user
AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
AND xact_finish IS NULL ) l USING (id);
IF current_fines >= max_fines.threshold THEN
new_sp_row.usr := match_user;
new_sp_row.org_unit := max_fines.org_unit;
new_sp_row.standing_penalty := 1;
RETURN NEXT new_sp_row;
END IF;
END IF;
-- Start over for max overdue
SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
-- Fail if the user has too many overdue items
LOOP
tmp_grp := user_object.profile;
LOOP
SELECT * INTO max_overdue FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 2 AND org_unit = tmp_org.id;
IF max_overdue.threshold IS NULL THEN
SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
ELSE
EXIT;
END IF;
IF tmp_grp IS NULL THEN
EXIT;
END IF;
END LOOP;
IF max_overdue.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
EXIT;
END IF;
SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
END LOOP;
IF max_overdue.threshold IS NOT NULL THEN
RETURN QUERY
SELECT *
FROM actor.usr_standing_penalty
WHERE usr = match_user
AND org_unit = max_overdue.org_unit
AND (stop_date IS NULL or stop_date > NOW())
AND standing_penalty = 2;
SELECT INTO items_overdue COUNT(*)
FROM action.circulation circ
JOIN actor.org_unit_full_path( max_overdue.org_unit ) fp ON (circ.circ_lib = fp.id)
WHERE circ.usr = match_user
AND circ.checkin_time IS NULL
AND circ.due_date < NOW()
AND (circ.stop_fines = 'MAXFINES' OR circ.stop_fines IS NULL);
IF items_overdue >= max_overdue.threshold::INT THEN
new_sp_row.usr := match_user;
new_sp_row.org_unit := max_overdue.org_unit;
new_sp_row.standing_penalty := 2;
RETURN NEXT new_sp_row;
END IF;
END IF;
-- Start over for max out
SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
-- Fail if the user has too many checked out items
LOOP
tmp_grp := user_object.profile;
LOOP
SELECT * INTO max_items_out FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 3 AND org_unit = tmp_org.id;
IF max_items_out.threshold IS NULL THEN
SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
ELSE
EXIT;
END IF;
IF tmp_grp IS NULL THEN
EXIT;
END IF;
END LOOP;
IF max_items_out.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
EXIT;
END IF;
SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
END LOOP;
-- Fail if the user has too many items checked out
IF max_items_out.threshold IS NOT NULL THEN
RETURN QUERY
SELECT *
FROM actor.usr_standing_penalty
WHERE usr = match_user
AND org_unit = max_items_out.org_unit
AND (stop_date IS NULL or stop_date > NOW())
AND standing_penalty = 3;
SELECT INTO items_out COUNT(*)
FROM action.circulation circ
JOIN actor.org_unit_full_path( max_items_out.org_unit ) fp ON (circ.circ_lib = fp.id)
WHERE circ.usr = match_user
AND circ.checkin_time IS NULL
AND (circ.stop_fines IN ('MAXFINES','LONGOVERDUE') OR circ.stop_fines IS NULL);
IF items_out >= max_items_out.threshold::INT THEN
new_sp_row.usr := match_user;
new_sp_row.org_unit := max_items_out.org_unit;
new_sp_row.standing_penalty := 3;
RETURN NEXT new_sp_row;
END IF;
END IF;
-- Start over for collections warning
SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
-- Fail if the user has a collections-level fine balance
LOOP
tmp_grp := user_object.profile;
LOOP
SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 4 AND org_unit = tmp_org.id;
IF max_fines.threshold IS NULL THEN
SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
ELSE
EXIT;
END IF;
IF tmp_grp IS NULL THEN
EXIT;
END IF;
END LOOP;
IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
EXIT;
END IF;
SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
END LOOP;
IF max_fines.threshold IS NOT NULL THEN
RETURN QUERY
SELECT *
FROM actor.usr_standing_penalty
WHERE usr = match_user
AND org_unit = max_fines.org_unit
AND (stop_date IS NULL or stop_date > NOW())
AND standing_penalty = 4;
SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
SELECT SUM(f.balance_owed) INTO current_fines
FROM money.materialized_billable_xact_summary f
JOIN (
SELECT r.id
FROM booking.reservation r
WHERE r.usr = match_user
AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
AND r.xact_finish IS NULL
UNION ALL
SELECT g.id
FROM money.grocery g
WHERE g.usr = match_user
AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
AND g.xact_finish IS NULL
UNION ALL
SELECT circ.id
FROM action.circulation circ
WHERE circ.usr = match_user
AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
AND circ.xact_finish IS NULL ) l USING (id);
IF current_fines >= max_fines.threshold THEN
new_sp_row.usr := match_user;
new_sp_row.org_unit := max_fines.org_unit;
new_sp_row.standing_penalty := 4;
RETURN NEXT new_sp_row;
END IF;
END IF;
-- Start over for in collections
SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
-- Remove the in-collections penalty if the user has paid down enough
-- This penalty is different, because this code is not responsible for creating
-- new in-collections penalties, only for removing them
LOOP
tmp_grp := user_object.profile;
LOOP
SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 30 AND org_unit = tmp_org.id;
IF max_fines.threshold IS NULL THEN
SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
ELSE
EXIT;
END IF;
IF tmp_grp IS NULL THEN
EXIT;
END IF;
END LOOP;
IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
EXIT;
END IF;
SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
END LOOP;
IF max_fines.threshold IS NOT NULL THEN
SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
-- first, see if the user had paid down to the threshold
SELECT SUM(f.balance_owed) INTO current_fines
FROM money.materialized_billable_xact_summary f
JOIN (
SELECT r.id
FROM booking.reservation r
WHERE r.usr = match_user
AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
AND r.xact_finish IS NULL
UNION ALL
SELECT g.id
FROM money.grocery g
WHERE g.usr = match_user
AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
AND g.xact_finish IS NULL
UNION ALL
SELECT circ.id
FROM action.circulation circ
WHERE circ.usr = match_user
AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
AND circ.xact_finish IS NULL ) l USING (id);
IF current_fines IS NULL OR current_fines <= max_fines.threshold THEN
-- patron has paid down enough
SELECT INTO tmp_penalty * FROM config.standing_penalty WHERE id = 30;
IF tmp_penalty.org_depth IS NOT NULL THEN
-- since this code is not responsible for applying the penalty, it can't
-- guarantee the current context org will match the org at which the penalty
--- was applied. search up the org tree until we hit the configured penalty depth
SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
WHILE tmp_depth >= tmp_penalty.org_depth LOOP
RETURN QUERY
SELECT *
FROM actor.usr_standing_penalty
WHERE usr = match_user
AND org_unit = tmp_org.id
AND (stop_date IS NULL or stop_date > NOW())
AND standing_penalty = 30;
IF tmp_org.parent_ou IS NULL THEN
EXIT;
END IF;
SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
END LOOP;
ELSE
-- no penalty depth is defined, look for exact matches
RETURN QUERY
SELECT *
FROM actor.usr_standing_penalty
WHERE usr = match_user
AND org_unit = max_fines.org_unit
AND (stop_date IS NULL or stop_date > NOW())
AND standing_penalty = 30;
END IF;
END IF;
END IF;
RETURN;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
NEW.passwd = MD5( NEW.passwd );
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF NEW.passwd <> OLD.passwd THEN
NEW.passwd = MD5( NEW.passwd );
END IF;
RETURN NEW;
END;
Returns: SET OF usr_activity
Language: PLPGSQL
DECLARE
new_row actor.usr_activity%ROWTYPE;
BEGIN
SELECT id INTO new_row.etype FROM actor.usr_activity_get_type(ewho, ewhat, ehow);
IF FOUND THEN
new_row.usr := usr;
INSERT INTO actor.usr_activity (usr, etype)
VALUES (usr, new_row.etype)
RETURNING * INTO new_row;
RETURN NEXT new_row;
END IF;
END;
Returns: org_unit
Language: SQL
SELECT a.*
FROM actor.org_unit a
WHERE id = ( SELECT FIRST(x.id)
FROM actor.org_unit_ancestors($1) x
JOIN actor.org_unit_type y
ON x.ou_type = y.id AND y.depth = $2);
Returns: SET OF org_unit_setting
Language: PLPGSQL
Search "up" the org_unit tree until we find the first occurrence of an
org_unit_setting with the given name.
DECLARE
setting RECORD;
cur_org INT;
BEGIN
cur_org := org_id;
LOOP
SELECT INTO setting * FROM actor.org_unit_setting WHERE org_unit = cur_org AND name = setting_name;
IF FOUND THEN
RETURN NEXT setting;
EXIT;
END IF;
SELECT INTO cur_org parent_ou FROM actor.org_unit WHERE id = cur_org;
EXIT WHEN cur_org IS NULL;
END LOOP;
RETURN;
END;
Returns: SET OF org_unit
Language: SQL
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;
Returns: SET OF record
Language: SQL
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 * FROM org_unit_ancestors_distance;
Returns: SET OF org_unit
Language: SQL
SELECT *
FROM actor.org_unit_ancestors($1)
UNION
SELECT *
FROM actor.org_unit_ancestors($2);
Returns: SET OF org_unit
Language: SQL
SELECT *
FROM actor.org_unit_ancestors($1)
INTERSECT
SELECT *
FROM actor.org_unit_ancestors($2);
Returns: SET OF org_unit
Language: SQL
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)
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 descendant_depth ot ON (ot.id = ou.parent_ou)
) SELECT ou.* FROM actor.org_unit ou JOIN descendant_depth USING (id);
Returns: SET OF org_unit
Language: SQL
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);
Returns: SET OF record
Language: SQL
WITH RECURSIVE org_unit_descendants_distance(id, distance) AS (
SELECT $1, 0
UNION
SELECT ou.id, oudd.distance+1
FROM actor.org_unit ou JOIN org_unit_descendants_distance oudd ON (ou.parent_ou = oudd.id)
)
SELECT * FROM org_unit_descendants_distance;
Returns: SET OF org_unit
Language: SQL
SELECT *
FROM actor.org_unit_ancestors($1)
UNION
SELECT *
FROM actor.org_unit_descendants($1);
Returns: SET OF org_unit
Language: SQL
SELECT * FROM actor.org_unit_full_path((actor.org_unit_ancestor_at_depth($1, $2)).id)
Returns: trigger
Language: PLPGSQL
DECLARE
current_aou actor.org_unit%ROWTYPE;
seen_ous INT[];
depth_count INT;
BEGIN
current_aou := NEW;
depth_count := 0;
seen_ous := ARRAY[NEW.id];
IF (TG_OP = 'UPDATE') THEN
IF (NEW.parent_ou IS NOT DISTINCT FROM OLD.parent_ou) THEN
RETURN NEW; -- Doing an UPDATE with no change, just return it
END IF;
END IF;
LOOP
IF current_aou.parent_ou IS NULL THEN -- Top of the org tree?
RETURN NEW; -- No loop. Carry on.
END IF;
IF current_aou.parent_ou = ANY(seen_ous) THEN -- Parent is one we have seen?
RAISE 'OU LOOP: Saw % twice', current_aou.parent_ou; -- LOOP! ABORT!
END IF;
-- Get the next one!
SELECT INTO current_aou * FROM actor.org_unit WHERE id = current_aou.parent_ou;
seen_ous := seen_ous || current_aou.id;
depth_count := depth_count + 1;
IF depth_count = 100 THEN
RAISE 'OU CHECK TOO DEEP';
END IF;
END LOOP;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF TG_OP = 'DELETE' THEN
DELETE FROM actor.org_unit_proximity WHERE (from_org = OLD.id or to_org= OLD.id);
END IF;
IF TG_OP = 'UPDATE' THEN
IF NEW.parent_ou <> OLD.parent_ou THEN
DELETE FROM actor.org_unit_proximity WHERE (from_org = OLD.id or to_org= OLD.id);
INSERT INTO actor.org_unit_proximity (from_org, to_org, prox)
SELECT l.id, r.id, actor.org_unit_proximity(l.id,r.id)
FROM actor.org_unit l, actor.org_unit r
WHERE (l.id = NEW.id or r.id = NEW.id);
END IF;
END IF;
IF TG_OP = 'INSERT' THEN
INSERT INTO actor.org_unit_proximity (from_org, to_org, prox)
SELECT l.id, r.id, actor.org_unit_proximity(l.id,r.id)
FROM actor.org_unit l, actor.org_unit r
WHERE (l.id = NEW.id or r.id = NEW.id);
END IF;
RETURN null;
END;
Returns: integer
Language: SQL
SELECT COUNT(id)::INT FROM (
SELECT id FROM actor.org_unit_combined_ancestors($1, $2)
EXCEPT
SELECT id FROM actor.org_unit_common_ancestors($1, $2)
) z;
Returns: integer[]
Language: SQL
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 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;
Returns: trigger
Language: PLPGSQL
DECLARE
sipfield actor.stat_cat_sip_fields%ROWTYPE;
use_count INT;
BEGIN
IF NEW.sip_field IS NOT NULL THEN
SELECT INTO sipfield * FROM actor.stat_cat_sip_fields WHERE field = NEW.sip_field;
IF sipfield.one_only THEN
SELECT INTO use_count count(id) FROM actor.stat_cat WHERE sip_field = NEW.sip_field AND id != NEW.id;
IF use_count > 0 THEN
RAISE EXCEPTION 'Sip field cannot be used twice';
END IF;
END IF;
END IF;
RETURN NEW;
END;
Returns: SET OF usr_activity_type
Language: SQL
SELECT * FROM config.usr_activity_type
WHERE
enabled AND
(ewho IS NULL OR ewho = $1) AND
(ewhat IS NULL OR ewhat = $2) AND
(ehow IS NULL OR ehow = $3)
ORDER BY
-- BOOL comparisons sort false to true
COALESCE(ewho, '') != COALESCE($1, ''),
COALESCE(ewhat,'') != COALESCE($2, ''),
COALESCE(ehow, '') != COALESCE($3, '')
LIMIT 1;
Returns: trigger
Language: PLPGSQL
BEGIN
DELETE FROM actor.usr_activity act USING config.usr_activity_type atype
WHERE atype.transient AND
NEW.etype = atype.id AND
act.etype = atype.id AND
act.usr = NEW.usr;
RETURN NEW;
END;
Returns: void
Language: PLPGSQL
Logically deletes a user. Removes personally identifiable information,
and purges associated data in other tables.
DECLARE
old_profile actor.usr.profile%type;
old_home_ou actor.usr.home_ou%type;
new_profile actor.usr.profile%type;
new_home_ou actor.usr.home_ou%type;
new_name text;
new_dob actor.usr.dob%type;
BEGIN
SELECT
id || '-PURGED-' || now(),
profile,
home_ou,
dob
INTO
new_name,
old_profile,
old_home_ou,
new_dob
FROM
actor.usr
WHERE
id = src_usr;
--
-- Quit if no such user
--
IF old_profile IS NULL THEN
RETURN;
END IF;
--
perform actor.usr_purge_data( src_usr, dest_usr );
--
-- Find the root grp_tree and the root org_unit. This would be simpler if we
-- could assume that there is only one root. Theoretically, someday, maybe,
-- there could be multiple roots, so we take extra trouble to get the right ones.
--
SELECT
id
INTO
new_profile
FROM
permission.grp_ancestors( old_profile )
WHERE
parent is null;
--
SELECT
id
INTO
new_home_ou
FROM
actor.org_unit_ancestors( old_home_ou )
WHERE
parent_ou is null;
--
-- Truncate date of birth
--
IF new_dob IS NOT NULL THEN
new_dob := date_trunc( 'year', new_dob );
END IF;
--
UPDATE
actor.usr
SET
card = NULL,
profile = new_profile,
usrname = new_name,
email = NULL,
passwd = random()::text,
standing = DEFAULT,
ident_type =
(
SELECT MIN( id )
FROM config.identification_type
),
ident_value = NULL,
ident_type2 = NULL,
ident_value2 = NULL,
net_access_level = DEFAULT,
photo_url = NULL,
prefix = NULL,
first_given_name = new_name,
second_given_name = NULL,
family_name = new_name,
suffix = NULL,
alias = NULL,
day_phone = NULL,
evening_phone = NULL,
other_phone = NULL,
mailing_address = NULL,
billing_address = NULL,
home_ou = new_home_ou,
dob = new_dob,
active = FALSE,
master_account = DEFAULT,
super_user = DEFAULT,
barred = FALSE,
deleted = TRUE,
juvenile = DEFAULT,
usrgroup = 0,
claims_returned_count = DEFAULT,
credit_forward_balance = DEFAULT,
last_xact_id = DEFAULT,
alert_message = NULL,
create_date = now(),
expire_date = now()
WHERE
id = src_usr;
END;
Returns: void
Language: PLPGSQL
Merges all user date from src_usr to dest_usr. When collisions occur,
keep dest_usr's data and delete src_usr's data.
DECLARE
suffix TEXT;
bucket_row RECORD;
picklist_row RECORD;
queue_row RECORD;
folder_row RECORD;
BEGIN
-- do some initial cleanup
UPDATE actor.usr SET card = NULL WHERE id = src_usr;
UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;
-- actor.*
IF del_cards THEN
DELETE FROM actor.card where usr = src_usr;
ELSE
IF deactivate_cards THEN
UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
END IF;
UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
END IF;
IF del_addrs THEN
DELETE FROM actor.usr_address WHERE usr = src_usr;
ELSE
UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
END IF;
UPDATE actor.usr_note SET usr = dest_usr WHERE usr = src_usr;
-- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);
-- permission.*
PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);
-- container.*
-- For each *_bucket table: transfer every bucket belonging to src_usr
-- into the custody of dest_usr.
--
-- In order to avoid colliding with an existing bucket owned by
-- the destination user, append the source user's id (in parenthesese)
-- to the name. If you still get a collision, add successive
-- spaces to the name and keep trying until you succeed.
--
FOR bucket_row in
SELECT id, name
FROM container.biblio_record_entry_bucket
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE container.biblio_record_entry_bucket
SET owner = dest_usr, name = name || suffix
WHERE id = bucket_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
FOR bucket_row in
SELECT id, name
FROM container.call_number_bucket
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE container.call_number_bucket
SET owner = dest_usr, name = name || suffix
WHERE id = bucket_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
FOR bucket_row in
SELECT id, name
FROM container.copy_bucket
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE container.copy_bucket
SET owner = dest_usr, name = name || suffix
WHERE id = bucket_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
FOR bucket_row in
SELECT id, name
FROM container.user_bucket
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE container.user_bucket
SET owner = dest_usr, name = name || suffix
WHERE id = bucket_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;
-- vandelay.*
-- transfer queues the same way we transfer buckets (see above)
FOR queue_row in
SELECT id, name
FROM vandelay.queue
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE vandelay.queue
SET owner = dest_usr, name = name || suffix
WHERE id = queue_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
-- money.*
PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;
-- action.*
UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;
-- acq.*
UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
-- transfer picklists the same way we transfer buckets (see above)
FOR picklist_row in
SELECT id, name
FROM acq.picklist
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE acq.picklist
SET owner = dest_usr, name = name || suffix
WHERE id = picklist_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;
-- asset.*
UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
-- serial.*
UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;
-- reporter.*
-- It's not uncommon to define the reporter schema in a replica
-- DB only, so don't assume these tables exist in the write DB.
BEGIN
UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
BEGIN
UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
BEGIN
UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
BEGIN
-- transfer folders the same way we transfer buckets (see above)
FOR folder_row in
SELECT id, name
FROM reporter.template_folder
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE reporter.template_folder
SET owner = dest_usr, name = name || suffix
WHERE id = folder_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
BEGIN
-- transfer folders the same way we transfer buckets (see above)
FOR folder_row in
SELECT id, name
FROM reporter.report_folder
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE reporter.report_folder
SET owner = dest_usr, name = name || suffix
WHERE id = folder_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
BEGIN
-- transfer folders the same way we transfer buckets (see above)
FOR folder_row in
SELECT id, name
FROM reporter.output_folder
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE reporter.output_folder
SET owner = dest_usr, name = name || suffix
WHERE id = folder_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
-- Finally, delete the source user
DELETE FROM actor.usr WHERE id = src_usr;
END;
Returns: void
Language: PLPGSQL
Attempts to move each row of the specified table from src_user to dest_user.
Where conflicts exist, the conflicting "source" row is deleted.
DECLARE
sel TEXT;
upd TEXT;
del TEXT;
cur_row RECORD;
BEGIN
sel := 'SELECT id::BIGINT FROM ' || table_name || ' WHERE ' || quote_ident(col_name) || ' = ' || quote_literal(src_usr);
upd := 'UPDATE ' || table_name || ' SET ' || quote_ident(col_name) || ' = ' || quote_literal(dest_usr) || ' WHERE id = ';
del := 'DELETE FROM ' || table_name || ' WHERE id = ';
FOR cur_row IN EXECUTE sel LOOP
BEGIN
--RAISE NOTICE 'Attempting to merge % %', table_name, cur_row.id;
EXECUTE upd || cur_row.id;
EXCEPTION WHEN unique_violation THEN
--RAISE NOTICE 'Deleting conflicting % %', table_name, cur_row.id;
EXECUTE del || cur_row.id;
END;
END LOOP;
END;
Returns: void
Language: PLPGSQL
Finds rows dependent on a given row in actor.usr and either deletes them
or reassigns them to a different user.
DECLARE
suffix TEXT;
renamable_row RECORD;
dest_usr INTEGER;
BEGIN
IF specified_dest_usr IS NULL THEN
dest_usr := 1; -- Admin user on stock installs
ELSE
dest_usr := specified_dest_usr;
END IF;
UPDATE actor.usr SET
active = FALSE,
card = NULL,
mailing_address = NULL,
billing_address = NULL
WHERE id = src_usr;
-- acq.*
UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
UPDATE acq.lineitem SET creator = dest_usr WHERE creator = src_usr;
UPDATE acq.lineitem SET editor = dest_usr WHERE editor = src_usr;
UPDATE acq.lineitem SET selector = dest_usr WHERE selector = src_usr;
UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
DELETE FROM acq.lineitem_usr_attr_definition WHERE usr = src_usr;
-- Update with a rename to avoid collisions
FOR renamable_row in
SELECT id, name
FROM acq.picklist
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE acq.picklist
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
UPDATE acq.picklist SET creator = dest_usr WHERE creator = src_usr;
UPDATE acq.picklist SET editor = dest_usr WHERE editor = src_usr;
UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
UPDATE acq.purchase_order SET creator = dest_usr WHERE creator = src_usr;
UPDATE acq.purchase_order SET editor = dest_usr WHERE editor = src_usr;
UPDATE acq.claim_event SET creator = dest_usr WHERE creator = src_usr;
-- action.*
DELETE FROM action.circulation WHERE usr = src_usr;
UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
DELETE FROM action.hold_request WHERE usr = src_usr;
UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
DELETE FROM action.non_cataloged_circulation WHERE patron = src_usr;
UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
DELETE FROM action.survey_response WHERE usr = src_usr;
UPDATE action.fieldset SET owner = dest_usr WHERE owner = src_usr;
-- actor.*
DELETE FROM actor.card WHERE usr = src_usr;
DELETE FROM actor.stat_cat_entry_usr_map WHERE target_usr = src_usr;
-- The following update is intended to avoid transient violations of a foreign
-- key constraint, whereby actor.usr_address references itself. It may not be
-- necessary, but it does no harm.
UPDATE actor.usr_address SET replaces = NULL
WHERE usr = src_usr AND replaces IS NOT NULL;
DELETE FROM actor.usr_address WHERE usr = src_usr;
DELETE FROM actor.usr_note WHERE usr = src_usr;
UPDATE actor.usr_note SET creator = dest_usr WHERE creator = src_usr;
DELETE FROM actor.usr_org_unit_opt_in WHERE usr = src_usr;
UPDATE actor.usr_org_unit_opt_in SET staff = dest_usr WHERE staff = src_usr;
DELETE FROM actor.usr_setting WHERE usr = src_usr;
DELETE FROM actor.usr_standing_penalty WHERE usr = src_usr;
UPDATE actor.usr_standing_penalty SET staff = dest_usr WHERE staff = src_usr;
-- asset.*
UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
-- auditor.*
DELETE FROM auditor.actor_usr_address_history WHERE id = src_usr;
DELETE FROM auditor.actor_usr_history WHERE id = src_usr;
UPDATE auditor.asset_call_number_history SET creator = dest_usr WHERE creator = src_usr;
UPDATE auditor.asset_call_number_history SET editor = dest_usr WHERE editor = src_usr;
UPDATE auditor.asset_copy_history SET creator = dest_usr WHERE creator = src_usr;
UPDATE auditor.asset_copy_history SET editor = dest_usr WHERE editor = src_usr;
UPDATE auditor.biblio_record_entry_history SET creator = dest_usr WHERE creator = src_usr;
UPDATE auditor.biblio_record_entry_history SET editor = dest_usr WHERE editor = src_usr;
-- biblio.*
UPDATE biblio.record_entry SET creator = dest_usr WHERE creator = src_usr;
UPDATE biblio.record_entry SET editor = dest_usr WHERE editor = src_usr;
UPDATE biblio.record_note SET creator = dest_usr WHERE creator = src_usr;
UPDATE biblio.record_note SET editor = dest_usr WHERE editor = src_usr;
-- container.*
-- Update buckets with a rename to avoid collisions
FOR renamable_row in
SELECT id, name
FROM container.biblio_record_entry_bucket
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE container.biblio_record_entry_bucket
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
FOR renamable_row in
SELECT id, name
FROM container.call_number_bucket
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE container.call_number_bucket
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
FOR renamable_row in
SELECT id, name
FROM container.copy_bucket
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE container.copy_bucket
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
FOR renamable_row in
SELECT id, name
FROM container.user_bucket
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE container.user_bucket
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
DELETE FROM container.user_bucket_item WHERE target_user = src_usr;
-- money.*
DELETE FROM money.billable_xact WHERE usr = src_usr;
DELETE FROM money.collections_tracker WHERE usr = src_usr;
UPDATE money.collections_tracker SET collector = dest_usr WHERE collector = src_usr;
-- permission.*
DELETE FROM permission.usr_grp_map WHERE usr = src_usr;
DELETE FROM permission.usr_object_perm_map WHERE usr = src_usr;
DELETE FROM permission.usr_perm_map WHERE usr = src_usr;
DELETE FROM permission.usr_work_ou_map WHERE usr = src_usr;
-- reporter.*
-- Update with a rename to avoid collisions
BEGIN
FOR renamable_row in
SELECT id, name
FROM reporter.output_folder
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE reporter.output_folder
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
BEGIN
UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
-- Update with a rename to avoid collisions
BEGIN
FOR renamable_row in
SELECT id, name
FROM reporter.report_folder
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE reporter.report_folder
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
BEGIN
UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
BEGIN
UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
-- Update with a rename to avoid collisions
BEGIN
FOR renamable_row in
SELECT id, name
FROM reporter.template_folder
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE reporter.template_folder
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
EXCEPTION WHEN undefined_table THEN
-- do nothing
END;
-- vandelay.*
-- Update with a rename to avoid collisions
FOR renamable_row in
SELECT id, name
FROM vandelay.queue
WHERE owner = src_usr
LOOP
suffix := ' (' || src_usr || ')';
LOOP
BEGIN
UPDATE vandelay.queue
SET owner = dest_usr, name = name || suffix
WHERE id = renamable_row.id;
EXCEPTION WHEN unique_violation THEN
suffix := suffix || ' ';
CONTINUE;
END;
EXIT;
END LOOP;
END LOOP;
END;
Schema asset
Tables referencing this one via Foreign Key Constraints:
asset_call_number_creator_idx creator
asset_call_number_dewey_idx call_number_dewey(label)
asset_call_number_editor_idx editor
asset_call_number_label_sortkey oils_text_as_bytea(label_sortkey)
asset_call_number_label_sortkey_browse oils_text_as_bytea(label_sortkey), oils_text_as_bytea(label), id, owning_lib) WHERE ((deleted IS FALSE) OR (deleted = false)
asset_call_number_record_idx record
asset_call_number_upper_label_id_owning_lib_idx oils_text_as_bytea(label), id, owning_lib
Index -
Schema asset
Defines the call number normalization database functions in the "normalizer"
column and the tag/subfield combinations to use to lookup the call number in
the "field" column for a given classification scheme. Tag/subfield combinations
are delimited by commas.
asset.call_number_class Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
|
normalizer |
text |
NOT NULL
DEFAULT 'asset.normalize_generic'::text
|
|
field |
text |
NOT NULL
DEFAULT '050ab,055ab,060ab,070ab,080ab,082ab,086ab,088ab,090,092,096,098,099'::text
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema asset
asset.call_number_note Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
asset.call_number.id
|
call_number |
bigint |
NOT NULL
|
actor.usr.id
|
creator |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
title |
text |
NOT NULL
|
|
value |
text |
NOT NULL
|
asset_call_number_note_creator_idx creator
Index -
Schema asset
asset.call_number_prefix Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owning_lib |
integer |
NOT NULL
|
|
label |
text |
NOT NULL
|
|
label_sortkey |
text |
|
Tables referencing this one via Foreign Key Constraints:
asset_call_number_prefix_sortkey_idx label_sortkey
Index -
Schema asset
asset.call_number_suffix Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owning_lib |
integer |
NOT NULL
|
|
label |
text |
NOT NULL
|
|
label_sortkey |
text |
|
Tables referencing this one via Foreign Key Constraints:
asset_call_number_suffix_sortkey_idx label_sortkey
Index -
Schema asset
asset.copy Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.org_unit.id
|
circ_lib |
integer |
NOT NULL
|
actor.usr.id
|
creator |
bigint |
NOT NULL
|
asset.call_number.id
|
call_number |
bigint |
NOT NULL
|
actor.usr.id
|
editor |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
DEFAULT now()
|
|
copy_number |
integer |
|
config.copy_status.id
|
status |
integer |
NOT NULL
|
asset.copy_location.id
|
location |
integer |
NOT NULL
DEFAULT 1
|
|
loan_duration |
integer |
NOT NULL
|
|
fine_level |
integer |
NOT NULL
|
|
age_protect |
integer |
|
|
circulate |
boolean |
NOT NULL
DEFAULT true
|
|
deposit |
boolean |
NOT NULL
DEFAULT false
|
|
ref |
boolean |
NOT NULL
DEFAULT false
|
|
holdable |
boolean |
NOT NULL
DEFAULT true
|
|
deposit_amount |
numeric(6,2) |
NOT NULL
DEFAULT 0.00
|
|
price |
numeric(8,2) |
|
|
barcode |
text |
NOT NULL
|
config.circ_modifier.code
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
dummy_title |
text |
|
|
dummy_author |
text |
|
|
alert_message |
text |
|
|
opac_visible |
boolean |
NOT NULL
DEFAULT true
|
|
deleted |
boolean |
NOT NULL
DEFAULT false
|
|
floating |
boolean |
NOT NULL
DEFAULT false
|
|
dummy_isbn |
text |
|
|
status_changed_time |
timestamp with time zone |
|
|
active_date |
timestamp with time zone |
|
|
mint_condition |
boolean |
NOT NULL
DEFAULT true
|
|
cost |
numeric(8,2) |
|
asset.copy Constraints
Name |
Constraint |
copy_fine_level_check |
CHECK ((fine_level = ANY (ARRAY[1, 2, 3]))) |
copy_loan_duration_check |
CHECK ((loan_duration = ANY (ARRAY[1, 2, 3]))) |
Tables referencing this one via Foreign Key Constraints:
cp_avail_cn_idx call_number
cp_cn_idx call_number
cp_create_date create_date
cp_creator_idx creator
cp_editor_idx editor
Index -
Schema asset
asset.copy_location Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
owning_lib |
integer |
UNIQUE#1
NOT NULL
|
|
holdable |
boolean |
NOT NULL
DEFAULT true
|
|
hold_verify |
boolean |
NOT NULL
DEFAULT false
|
|
opac_visible |
boolean |
NOT NULL
DEFAULT true
|
|
circulate |
boolean |
NOT NULL
DEFAULT true
|
|
label_prefix |
text |
|
|
label_suffix |
text |
|
|
checkin_alert |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema asset
asset.copy_location_group Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
pos |
integer |
NOT NULL
|
|
top |
boolean |
NOT NULL
DEFAULT false
|
|
opac_visible |
boolean |
NOT NULL
DEFAULT true
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema asset
Index -
Schema asset
asset.copy_location_order Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
asset.copy_location.id
|
location |
integer |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
org |
integer |
UNIQUE#1
NOT NULL
|
|
position |
integer |
NOT NULL
|
Index -
Schema asset
asset.copy_note Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
asset.copy.id
|
owning_copy |
bigint |
NOT NULL
|
actor.usr.id
|
creator |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
title |
text |
NOT NULL
|
|
value |
text |
NOT NULL
|
asset_copy_note_creator_idx creator
asset_copy_note_owning_copy_idx owning_copy
Index -
Schema asset
asset.copy_part_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
target_copy |
bigint |
NOT NULL
|
biblio.monograph_part.id
|
part |
integer |
NOT NULL
|
Index -
Schema asset
asset.copy_template Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owning_lib |
integer |
NOT NULL
|
actor.usr.id
|
creator |
bigint |
NOT NULL
|
actor.usr.id
|
editor |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
DEFAULT now()
|
|
name |
text |
NOT NULL
|
actor.org_unit.id
|
circ_lib |
integer |
|
config.copy_status.id
|
status |
integer |
|
asset.copy_location.id
|
location |
integer |
|
|
loan_duration |
integer |
|
|
fine_level |
integer |
|
|
age_protect |
integer |
|
|
circulate |
boolean |
|
|
deposit |
boolean |
|
|
ref |
boolean |
|
|
holdable |
boolean |
|
|
deposit_amount |
numeric(6,2) |
|
|
price |
numeric(8,2) |
|
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
alert_message |
text |
|
|
opac_visible |
boolean |
|
|
floating |
boolean |
|
|
mint_condition |
boolean |
|
asset.copy_template Constraints
Name |
Constraint |
valid_fine_level |
CHECK (((fine_level IS NULL) OR (loan_duration = ANY (ARRAY[1, 2, 3])))) |
valid_loan_duration |
CHECK (((loan_duration IS NULL) OR (loan_duration = ANY (ARRAY[1, 2, 3])))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema asset
Materialized view of copies that are visible in the OPAC, used by
search.query_parser_fts() to speed up OPAC visibility checks on large
databases. Contents are maintained by a set of triggers.
asset.opac_visible_copies Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
copy_id |
bigint |
|
|
record |
bigint |
|
|
circ_lib |
integer |
|
opac_visible_copies_copy_id_idx copy_id
opac_visible_copies_idx1 record, circ_lib
Index -
Schema asset
asset.stat_cat Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
opac_visible |
boolean |
NOT NULL
DEFAULT false
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
required |
boolean |
NOT NULL
DEFAULT false
|
asset.stat_cat_sip_fields.field
|
sip_field |
character(2) |
|
|
sip_format |
text |
|
|
checkout_archive |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema asset
asset.stat_cat_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
asset.stat_cat.id
|
stat_cat |
integer |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
value |
text |
UNIQUE#1
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema asset
asset.stat_cat_entry_copy_map Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
asset.stat_cat.id
|
stat_cat |
integer |
UNIQUE#1
NOT NULL
|
asset.stat_cat_entry.id
|
stat_cat_entry |
integer |
NOT NULL
|
|
owning_copy |
bigint |
UNIQUE#1
NOT NULL
|
scecm_owning_copy_idx owning_copy
Index -
Schema asset
asset.stat_cat_entry_transparency_map Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
stat_cat |
integer |
UNIQUE#1
NOT NULL
|
|
stat_cat_entry |
integer |
NOT NULL
|
|
owning_transparency |
integer |
UNIQUE#1
NOT NULL
|
Index -
Schema asset
Asset Statistical Category SIP Fields
Contains the list of valid SIP Field identifiers for
Statistical Categories.
asset.stat_cat_sip_fields Structure
F-Key |
Name |
Type |
Description |
|
field |
character(2) |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
|
one_only |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema asset
asset.uri Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
href |
text |
NOT NULL
|
|
label |
text |
|
|
use_restriction |
text |
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema asset
asset.uri_call_number_map Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
asset.uri.id
|
uri |
integer |
UNIQUE#1
NOT NULL
|
asset.call_number.id
|
call_number |
integer |
UNIQUE#1
NOT NULL
|
asset_uri_call_number_map_cn_idx call_number
Index -
Schema asset
Returns: trigger
Language: PLPGSQL
BEGIN
IF NEW.active_date IS NULL AND NEW.status IN (SELECT id FROM config.copy_status WHERE copy_active = true) THEN
NEW.active_date := now();
END IF;
IF NEW.status_changed_time IS NULL THEN
NEW.status_changed_time := now();
END IF;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF NEW.status <> OLD.status AND NOT (NEW.status = 0 AND OLD.status = 7) THEN
NEW.status_changed_time := now();
IF NEW.active_date IS NULL AND NEW.status IN (SELECT id FROM config.copy_status WHERE copy_active = true) THEN
NEW.active_date := now();
END IF;
END IF;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF NEW.barcode LIKE '@@%' THEN
NEW.barcode := '@@' || NEW.id;
END IF;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
Trigger function to update the copy OPAC visiblity cache.
DECLARE
add_front TEXT;
add_back TEXT;
add_base_query TEXT;
add_peer_query TEXT;
remove_query TEXT;
do_add BOOLEAN := false;
do_remove BOOLEAN := false;
BEGIN
add_base_query := $$
SELECT cp.id, cp.circ_lib, cn.record, cn.id AS call_number, cp.location, cp.status
FROM asset.copy cp
JOIN asset.call_number cn ON (cn.id = cp.call_number)
JOIN actor.org_unit a ON (cp.circ_lib = a.id)
JOIN asset.copy_location cl ON (cp.location = cl.id)
JOIN config.copy_status cs ON (cp.status = cs.id)
JOIN biblio.record_entry b ON (cn.record = b.id)
WHERE NOT cp.deleted
AND NOT cn.deleted
AND NOT b.deleted
AND cs.opac_visible
AND cl.opac_visible
AND cp.opac_visible
AND a.opac_visible
$$;
add_peer_query := $$
SELECT cp.id, cp.circ_lib, pbcm.peer_record AS record, NULL AS call_number, cp.location, cp.status
FROM asset.copy cp
JOIN biblio.peer_bib_copy_map pbcm ON (pbcm.target_copy = cp.id)
JOIN actor.org_unit a ON (cp.circ_lib = a.id)
JOIN asset.copy_location cl ON (cp.location = cl.id)
JOIN config.copy_status cs ON (cp.status = cs.id)
WHERE NOT cp.deleted
AND cs.opac_visible
AND cl.opac_visible
AND cp.opac_visible
AND a.opac_visible
$$;
add_front := $$
INSERT INTO asset.opac_visible_copies (copy_id, circ_lib, record)
SELECT DISTINCT ON (id, record) id, circ_lib, record FROM (
$$;
add_back := $$
) AS x
$$;
remove_query := $$ DELETE FROM asset.opac_visible_copies WHERE copy_id IN ( SELECT id FROM asset.copy WHERE $$;
IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN
IF TG_OP = 'INSERT' THEN
add_peer_query := add_peer_query || ' AND cp.id = ' || NEW.target_copy || ' AND pbcm.peer_record = ' || NEW.peer_record;
EXECUTE add_front || add_peer_query || add_back;
RETURN NEW;
ELSE
remove_query := 'DELETE FROM asset.opac_visible_copies WHERE copy_id = ' || OLD.target_copy || ' AND record = ' || OLD.peer_record || ';';
EXECUTE remove_query;
RETURN OLD;
END IF;
END IF;
IF TG_OP = 'INSERT' THEN
IF TG_TABLE_NAME IN ('copy', 'unit') THEN
add_base_query := add_base_query || ' AND cp.id = ' || NEW.id;
EXECUTE add_front || add_base_query || add_back;
END IF;
RETURN NEW;
END IF;
-- handle items first, since with circulation activity
-- their statuses change frequently
IF TG_TABLE_NAME IN ('copy', 'unit') THEN
IF OLD.location <> NEW.location OR
OLD.call_number <> NEW.call_number OR
OLD.status <> NEW.status OR
OLD.circ_lib <> NEW.circ_lib THEN
-- any of these could change visibility, but
-- we'll save some queries and not try to calculate
-- the change directly
do_remove := true;
do_add := true;
ELSE
IF OLD.deleted <> NEW.deleted THEN
IF NEW.deleted THEN
do_remove := true;
ELSE
do_add := true;
END IF;
END IF;
IF OLD.opac_visible <> NEW.opac_visible THEN
IF OLD.opac_visible THEN
do_remove := true;
ELSIF NOT do_remove THEN -- handle edge case where deleted item
-- is also marked opac_visible
do_add := true;
END IF;
END IF;
END IF;
IF do_remove THEN
DELETE FROM asset.opac_visible_copies WHERE copy_id = NEW.id;
END IF;
IF do_add THEN
add_base_query := add_base_query || ' AND cp.id = ' || NEW.id;
add_peer_query := add_peer_query || ' AND cp.id = ' || NEW.id;
EXECUTE add_front || add_base_query || ' UNION ' || add_peer_query || add_back;
END IF;
RETURN NEW;
END IF;
IF TG_TABLE_NAME IN ('call_number', 'record_entry') THEN -- these have a 'deleted' column
IF OLD.deleted AND NEW.deleted THEN -- do nothing
RETURN NEW;
ELSIF NEW.deleted THEN -- remove rows
IF TG_TABLE_NAME = 'call_number' THEN
DELETE FROM asset.opac_visible_copies WHERE copy_id IN (SELECT id FROM asset.copy WHERE call_number = NEW.id);
ELSIF TG_TABLE_NAME = 'record_entry' THEN
DELETE FROM asset.opac_visible_copies WHERE record = NEW.id;
END IF;
RETURN NEW;
ELSIF OLD.deleted THEN -- add rows
IF TG_TABLE_NAME = 'call_number' THEN
add_base_query := add_base_query || ' AND cn.id = ' || NEW.id;
EXECUTE add_front || add_base_query || add_back;
ELSIF TG_TABLE_NAME = 'record_entry' THEN
add_base_query := add_base_query || ' AND cn.record = ' || NEW.id;
add_peer_query := add_peer_query || ' AND pbcm.peer_record = ' || NEW.id;
EXECUTE add_front || add_base_query || ' UNION ' || add_peer_query || add_back;
END IF;
RETURN NEW;
END IF;
END IF;
IF TG_TABLE_NAME = 'call_number' THEN
IF OLD.record <> NEW.record THEN
-- call number is linked to different bib
remove_query := remove_query || 'call_number = ' || NEW.id || ');';
EXECUTE remove_query;
add_base_query := add_base_query || ' AND cn.id = ' || NEW.id;
EXECUTE add_front || add_base_query || add_back;
END IF;
RETURN NEW;
END IF;
IF TG_TABLE_NAME IN ('record_entry') THEN
RETURN NEW; -- don't have 'opac_visible'
END IF;
-- actor.org_unit, asset.copy_location, asset.copy_status
IF NEW.opac_visible = OLD.opac_visible THEN -- do nothing
RETURN NEW;
ELSIF NEW.opac_visible THEN -- add rows
IF TG_TABLE_NAME = 'org_unit' THEN
add_base_query := add_base_query || ' AND cp.circ_lib = ' || NEW.id;
add_peer_query := add_peer_query || ' AND cp.circ_lib = ' || NEW.id;
ELSIF TG_TABLE_NAME = 'copy_location' THEN
add_base_query := add_base_query || ' AND cp.location = ' || NEW.id;
add_peer_query := add_peer_query || ' AND cp.location = ' || NEW.id;
ELSIF TG_TABLE_NAME = 'copy_status' THEN
add_base_query := add_base_query || ' AND cp.status = ' || NEW.id;
add_peer_query := add_peer_query || ' AND cp.status = ' || NEW.id;
END IF;
EXECUTE add_front || add_base_query || ' UNION ' || add_peer_query || add_back;
ELSE -- delete rows
IF TG_TABLE_NAME = 'org_unit' THEN
remove_query := 'DELETE FROM asset.opac_visible_copies WHERE circ_lib = ' || NEW.id || ';';
ELSIF TG_TABLE_NAME = 'copy_location' THEN
remove_query := remove_query || 'location = ' || NEW.id || ');';
ELSIF TG_TABLE_NAME = 'copy_status' THEN
remove_query := remove_query || 'status = ' || NEW.id || ');';
END IF;
EXECUTE remove_query;
END IF;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
sortkey TEXT := '';
BEGIN
sortkey := NEW.label_sortkey;
IF NEW.label_class IS NULL THEN
NEW.label_class := COALESCE(
(
SELECT substring(value from E'\\d+')::integer
FROM actor.org_unit_ancestor_setting('cat.default_classification_scheme', NEW.owning_lib)
), 1
);
END IF;
EXECUTE 'SELECT ' || acnc.normalizer || '(' ||
quote_literal( NEW.label ) || ')'
FROM asset.call_number_class acnc
WHERE acnc.id = NEW.label_class
INTO sortkey;
NEW.label_sortkey = sortkey;
RETURN NEW;
END;
Returns: text
Language: PLPERLU
# Derived from the Koha C4::ClassSortRoutine::Dewey module
# Copyright (C) 2007 LibLime
# Licensed under the GPL v2 or later
use strict;
use warnings;
my $init = uc(shift);
$init =~ s/^\s+//;
$init =~ s/\s+$//;
$init =~ s!/!!g;
$init =~ s/^([\p{IsAlpha}]+)/$1 /;
my @tokens = split /\.|\s+/, $init;
my $digit_group_count = 0;
for (my $i = 0; $i <= $#tokens; $i++) {
if ($tokens[$i] =~ /^\d+$/) {
$digit_group_count++;
if (2 == $digit_group_count) {
$tokens[$i] = sprintf("%-15.15s", $tokens[$i]);
$tokens[$i] =~ tr/ /0/;
}
}
}
# Pad the first digit_group if there was only one
if (1 == $digit_group_count) {
$tokens[0] .= '_000000000000000'
}
my $key = join("_", @tokens);
$key =~ s/[^\p{IsAlnum}_]//g;
return $key;
Returns: text
Language: PLPERLU
# Created after looking at the Koha C4::ClassSortRoutine::Generic module,
# thus could probably be considered a derived work, although nothing was
# directly copied - but to err on the safe side of providing attribution:
# Copyright (C) 2007 LibLime
# Copyright (C) 2011 Equinox Software, Inc (Steve Callendar)
# Licensed under the GPL v2 or later
use strict;
use warnings;
# Converts the callnumber to uppercase
# Strips spaces from start and end of the call number
# Converts anything other than letters, digits, and periods into spaces
# Collapses multiple spaces into a single underscore
my $callnum = uc(shift);
$callnum =~ s/^\s//g;
$callnum =~ s/\s$//g;
# NOTE: this previously used underscores, but this caused sorting issues
# for the "before" half of page 0 on CN browse, sorting CNs containing a
# decimal before "whole number" CNs
$callnum =~ s/[^A-Z0-9_.]/ /g;
$callnum =~ s/ {2,}/ /g;
return $callnum;
Returns: text
Language: PLPERLU
use strict;
use warnings;
# Library::CallNumber::LC is currently hosted at http://code.google.com/p/library-callnumber-lc/
# The author hopes to upload it to CPAN some day, which would make our lives easier
use Library::CallNumber::LC;
my $callnum = Library::CallNumber::LC->new(shift);
return $callnum->normalize();
Returns: integer
Language: PLPGSQL
DECLARE
moved_objects INT := 0;
source_cn asset.call_number%ROWTYPE;
target_cn asset.call_number%ROWTYPE;
metarec metabib.metarecord%ROWTYPE;
hold action.hold_request%ROWTYPE;
ser_rec serial.record_entry%ROWTYPE;
ser_sub serial.subscription%ROWTYPE;
acq_lineitem acq.lineitem%ROWTYPE;
acq_request acq.user_request%ROWTYPE;
booking booking.resource_type%ROWTYPE;
source_part biblio.monograph_part%ROWTYPE;
target_part biblio.monograph_part%ROWTYPE;
multi_home biblio.peer_bib_copy_map%ROWTYPE;
uri_count INT := 0;
counter INT := 0;
uri_datafield TEXT;
uri_text TEXT := '';
BEGIN
-- move any 856 entries on records that have at least one MARC-mapped URI entry
SELECT INTO uri_count COUNT(*)
FROM asset.uri_call_number_map m
JOIN asset.call_number cn ON (m.call_number = cn.id)
WHERE cn.record = source_record;
IF uri_count > 0 THEN
-- This returns more nodes than you might expect:
-- 7 instead of 1 for an 856 with $u $y $9
SELECT COUNT(*) INTO counter
FROM oils_xpath_table(
'id',
'marc',
'biblio.record_entry',
'//*[@tag="856"]',
'id=' || source_record
) as t(i int,c text);
FOR i IN 1 .. counter LOOP
SELECT '<datafield xmlns="http://www.loc.gov/MARC21/slim"' ||
' tag="856"' ||
' ind1="' || FIRST(ind1) || '"' ||
' ind2="' || FIRST(ind2) || '">' ||
array_to_string(
array_accum(
'<subfield code="' || subfield || '">' ||
regexp_replace(
regexp_replace(
regexp_replace(data,'&','&','g'),
'>', '>', 'g'
),
'<', '<', 'g'
) || '</subfield>'
), ''
) || '</datafield>' INTO uri_datafield
FROM oils_xpath_table(
'id',
'marc',
'biblio.record_entry',
'//*[@tag="856"][position()=' || i || ']/@ind1|' ||
'//*[@tag="856"][position()=' || i || ']/@ind2|' ||
'//*[@tag="856"][position()=' || i || ']/*/@code|' ||
'//*[@tag="856"][position()=' || i || ']/*[@code]',
'id=' || source_record
) as t(id int,ind1 text, ind2 text,subfield text,data text);
-- As most of the results will be NULL, protect against NULLifying
-- the valid content that we do generate
uri_text := uri_text || COALESCE(uri_datafield, '');
END LOOP;
IF uri_text <> '' THEN
UPDATE biblio.record_entry
SET marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
WHERE id = target_record;
END IF;
END IF;
-- Find and move metarecords to the target record
SELECT INTO metarec *
FROM metabib.metarecord
WHERE master_record = source_record;
IF FOUND THEN
UPDATE metabib.metarecord
SET master_record = target_record,
mods = NULL
WHERE id = metarec.id;
moved_objects := moved_objects + 1;
END IF;
-- Find call numbers attached to the source ...
FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
SELECT INTO target_cn *
FROM asset.call_number
WHERE label = source_cn.label
AND owning_lib = source_cn.owning_lib
AND record = target_record;
-- ... and if there's a conflicting one on the target ...
IF FOUND THEN
-- ... move the copies to that, and ...
UPDATE asset.copy
SET call_number = target_cn.id
WHERE call_number = source_cn.id;
-- ... move V holds to the move-target call number
FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
UPDATE action.hold_request
SET target = target_cn.id
WHERE id = hold.id;
moved_objects := moved_objects + 1;
END LOOP;
-- ... if not ...
ELSE
-- ... just move the call number to the target record
UPDATE asset.call_number
SET record = target_record
WHERE id = source_cn.id;
END IF;
moved_objects := moved_objects + 1;
END LOOP;
-- Find T holds targeting the source record ...
FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
-- ... and move them to the target record
UPDATE action.hold_request
SET target = target_record
WHERE id = hold.id;
moved_objects := moved_objects + 1;
END LOOP;
-- Find serial records targeting the source record ...
FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
-- ... and move them to the target record
UPDATE serial.record_entry
SET record = target_record
WHERE id = ser_rec.id;
moved_objects := moved_objects + 1;
END LOOP;
-- Find serial subscriptions targeting the source record ...
FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
-- ... and move them to the target record
UPDATE serial.subscription
SET record_entry = target_record
WHERE id = ser_sub.id;
moved_objects := moved_objects + 1;
END LOOP;
-- Find booking resource types targeting the source record ...
FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
-- ... and move them to the target record
UPDATE booking.resource_type
SET record = target_record
WHERE id = booking.id;
moved_objects := moved_objects + 1;
END LOOP;
-- Find acq lineitems targeting the source record ...
FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
-- ... and move them to the target record
UPDATE acq.lineitem
SET eg_bib_id = target_record
WHERE id = acq_lineitem.id;
moved_objects := moved_objects + 1;
END LOOP;
-- Find acq user purchase requests targeting the source record ...
FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
-- ... and move them to the target record
UPDATE acq.user_request
SET eg_bib = target_record
WHERE id = acq_request.id;
moved_objects := moved_objects + 1;
END LOOP;
-- Find parts attached to the source ...
FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
SELECT INTO target_part *
FROM biblio.monograph_part
WHERE label = source_part.label
AND record = target_record;
-- ... and if there's a conflicting one on the target ...
IF FOUND THEN
-- ... move the copy-part maps to that, and ...
UPDATE asset.copy_part_map
SET part = target_part.id
WHERE part = source_part.id;
-- ... move P holds to the move-target part
FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
UPDATE action.hold_request
SET target = target_part.id
WHERE id = hold.id;
moved_objects := moved_objects + 1;
END LOOP;
-- ... if not ...
ELSE
-- ... just move the part to the target record
UPDATE biblio.monograph_part
SET record = target_record
WHERE id = source_part.id;
END IF;
moved_objects := moved_objects + 1;
END LOOP;
-- Find multi_home items attached to the source ...
FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
-- ... and move them to the target record
UPDATE biblio.peer_bib_copy_map
SET peer_record = target_record
WHERE id = multi_home.id;
moved_objects := moved_objects + 1;
END LOOP;
-- And delete mappings where the item's home bib was merged with the peer bib
DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
FROM asset.copy WHERE id = target_copy
);
-- Finally, "delete" the source record
DELETE FROM biblio.record_entry WHERE id = source_record;
-- That's all, folks!
RETURN moved_objects;
END;
Returns: SET OF record
Language: PLPGSQL
BEGIN
IF staff IS TRUE THEN
IF place > 0 THEN
RETURN QUERY SELECT * FROM asset.staff_ou_metarecord_copy_count( place, rid );
ELSE
RETURN QUERY SELECT * FROM asset.staff_lasso_metarecord_copy_count( -place, rid );
END IF;
ELSE
IF place > 0 THEN
RETURN QUERY SELECT * FROM asset.opac_ou_metarecord_copy_count( place, rid );
ELSE
RETURN QUERY SELECT * FROM asset.opac_lasso_metarecord_copy_count( -place, rid );
END IF;
END IF;
RETURN;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
NEW.label_sortkey := REGEXP_REPLACE(
evergreen.lpad_number_substrings(
naco_normalize(NEW.label),
'0',
10
),
E'\\s+',
'',
'g'
);
RETURN NEW;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
ans RECORD;
trans INT;
BEGIN
SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
RETURN QUERY
SELECT -1,
ans.id,
COUNT( av.id ),
SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
COUNT( av.id ),
trans
FROM
actor.org_unit_descendants(ans.id) d
JOIN asset.opac_visible_copies av ON (av.record = rid AND av.circ_lib = d.id)
JOIN asset.copy cp ON (cp.id = av.copy_id)
JOIN metabib.metarecord_source_map m ON (m.source = av.record)
GROUP BY 1,2,6;
IF NOT FOUND THEN
RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
ans RECORD;
trans INT;
BEGIN
SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
RETURN QUERY
SELECT -1,
ans.id,
COUNT( av.id ),
SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
COUNT( av.id ),
trans
FROM
actor.org_unit_descendants(ans.id) d
JOIN asset.opac_visible_copies av ON (av.record = rid AND av.circ_lib = d.id)
JOIN asset.copy cp ON (cp.id = av.copy_id)
GROUP BY 1,2,6;
IF NOT FOUND THEN
RETURN QUERY SELECT -1, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
ans RECORD;
trans INT;
BEGIN
SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
RETURN QUERY
SELECT ans.depth,
ans.id,
COUNT( av.id ),
SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
COUNT( av.id ),
trans
FROM
actor.org_unit_descendants(ans.id) d
JOIN asset.opac_visible_copies av ON (av.record = rid AND av.circ_lib = d.id)
JOIN asset.copy cp ON (cp.id = av.copy_id)
JOIN metabib.metarecord_source_map m ON (m.source = av.record)
GROUP BY 1,2,6;
IF NOT FOUND THEN
RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
ans RECORD;
trans INT;
BEGIN
SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
RETURN QUERY
SELECT ans.depth,
ans.id,
COUNT( av.id ),
SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
COUNT( av.id ),
trans
FROM
actor.org_unit_descendants(ans.id) d
JOIN asset.opac_visible_copies av ON (av.record = rid AND av.circ_lib = d.id)
JOIN asset.copy cp ON (cp.id = av.copy_id)
GROUP BY 1,2,6;
IF NOT FOUND THEN
RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF record
Language: PLPGSQL
BEGIN
IF staff IS TRUE THEN
IF place > 0 THEN
RETURN QUERY SELECT * FROM asset.staff_ou_record_copy_count( place, rid );
ELSE
RETURN QUERY SELECT * FROM asset.staff_lasso_record_copy_count( -place, rid );
END IF;
ELSE
IF place > 0 THEN
RETURN QUERY SELECT * FROM asset.opac_ou_record_copy_count( place, rid );
ELSE
RETURN QUERY SELECT * FROM asset.opac_lasso_record_copy_count( -place, rid );
END IF;
END IF;
RETURN;
END;
Returns: void
Language: SQL
Rebuild the copy OPAC visibility cache. Useful during migrations.
TRUNCATE TABLE asset.opac_visible_copies;
INSERT INTO asset.opac_visible_copies (copy_id, circ_lib, record)
SELECT cp.id, cp.circ_lib, cn.record
FROM asset.copy cp
JOIN asset.call_number cn ON (cn.id = cp.call_number)
JOIN actor.org_unit a ON (cp.circ_lib = a.id)
JOIN asset.copy_location cl ON (cp.location = cl.id)
JOIN config.copy_status cs ON (cp.status = cs.id)
JOIN biblio.record_entry b ON (cn.record = b.id)
WHERE NOT cp.deleted
AND NOT cn.deleted
AND NOT b.deleted
AND cs.opac_visible
AND cl.opac_visible
AND cp.opac_visible
AND a.opac_visible
UNION
SELECT cp.id, cp.circ_lib, pbcm.peer_record AS record
FROM asset.copy cp
JOIN biblio.peer_bib_copy_map pbcm ON (pbcm.target_copy = cp.id)
JOIN actor.org_unit a ON (cp.circ_lib = a.id)
JOIN asset.copy_location cl ON (cp.location = cl.id)
JOIN config.copy_status cs ON (cp.status = cs.id)
WHERE NOT cp.deleted
AND cs.opac_visible
AND cl.opac_visible
AND cp.opac_visible
AND a.opac_visible;
Returns: SET OF record
Language: PLPGSQL
DECLARE
ans RECORD;
trans INT;
BEGIN
SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
RETURN QUERY
SELECT -1,
ans.id,
COUNT( cp.id ),
SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
COUNT( cp.id ),
trans
FROM
actor.org_unit_descendants(ans.id) d
JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
JOIN metabib.metarecord_source_map m ON (m.source = cn.record)
GROUP BY 1,2,6;
IF NOT FOUND THEN
RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
ans RECORD;
trans INT;
BEGIN
SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
FOR ans IN SELECT u.org_unit AS id FROM actor.org_lasso_map AS u WHERE lasso = i_lasso LOOP
RETURN QUERY
SELECT -1,
ans.id,
COUNT( cp.id ),
SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
SUM( CASE WHEN cl.opac_visible AND cp.opac_visible THEN 1 ELSE 0 END),
trans
FROM
actor.org_unit_descendants(ans.id) d
JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
JOIN asset.copy_location cl ON (cp.location = cl.id)
JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
GROUP BY 1,2,6;
IF NOT FOUND THEN
RETURN QUERY SELECT -1, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
ans RECORD;
trans INT;
BEGIN
SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
RETURN QUERY
SELECT ans.depth,
ans.id,
COUNT( cp.id ),
SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
COUNT( cp.id ),
trans
FROM
actor.org_unit_descendants(ans.id) d
JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
JOIN metabib.metarecord_source_map m ON (m.source = cn.record)
GROUP BY 1,2,6;
IF NOT FOUND THEN
RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
ans RECORD;
trans INT;
BEGIN
SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
RETURN QUERY
SELECT ans.depth,
ans.id,
COUNT( cp.id ),
SUM( CASE WHEN cp.status IN (0,7,12) THEN 1 ELSE 0 END ),
SUM( CASE WHEN cl.opac_visible AND cp.opac_visible THEN 1 ELSE 0 END),
trans
FROM
actor.org_unit_descendants(ans.id) d
JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
JOIN asset.copy_location cl ON (cp.location = cl.id)
JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
GROUP BY 1,2,6;
IF NOT FOUND THEN
RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
END IF;
END LOOP;
RETURN;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
sipfield asset.stat_cat_sip_fields%ROWTYPE;
use_count INT;
BEGIN
IF NEW.sip_field IS NOT NULL THEN
SELECT INTO sipfield * FROM asset.stat_cat_sip_fields WHERE field = NEW.sip_field;
IF sipfield.one_only THEN
SELECT INTO use_count count(id) FROM asset.stat_cat WHERE sip_field = NEW.sip_field AND id != NEW.id;
IF use_count > 0 THEN
RAISE EXCEPTION 'Sip field cannot be used twice';
END IF;
END IF;
END IF;
RETURN NEW;
END;
Schema auditor
auditor.acq_invoice_entry_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
NOT NULL
|
|
invoice |
integer |
NOT NULL
|
|
purchase_order |
integer |
|
|
lineitem |
integer |
|
|
inv_item_count |
integer |
NOT NULL
|
|
phys_item_count |
integer |
|
|
note |
text |
|
|
billed_per_item |
boolean |
|
|
cost_billed |
numeric(8,2) |
|
|
actual_cost |
numeric(8,2) |
|
|
amount_paid |
numeric(8,2) |
|
Index -
Schema auditor
auditor.acq_invoice_entry_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
|
|
invoice |
integer |
|
|
purchase_order |
integer |
|
|
lineitem |
integer |
|
|
inv_item_count |
integer |
|
|
phys_item_count |
integer |
|
|
note |
text |
|
|
billed_per_item |
boolean |
|
|
cost_billed |
numeric(8,2) |
|
|
actual_cost |
numeric(8,2) |
|
|
amount_paid |
numeric(8,2) |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, invoice_entry.id
, invoice_entry.invoice
, invoice_entry.purchase_order
, invoice_entry.lineitem
, invoice_entry.inv_item_count
, invoice_entry.phys_item_count
, invoice_entry.note
, invoice_entry.billed_per_item
, invoice_entry.cost_billed
, invoice_entry.actual_cost
, invoice_entry.amount_paid
FROM acq.invoice_entry
UNION ALLSELECT acq_invoice_entry_history.audit_id
, acq_invoice_entry_history.audit_time
, acq_invoice_entry_history.audit_action
, acq_invoice_entry_history.audit_user
, acq_invoice_entry_history.audit_ws
, acq_invoice_entry_history.id
, acq_invoice_entry_history.invoice
, acq_invoice_entry_history.purchase_order
, acq_invoice_entry_history.lineitem
, acq_invoice_entry_history.inv_item_count
, acq_invoice_entry_history.phys_item_count
, acq_invoice_entry_history.note
, acq_invoice_entry_history.billed_per_item
, acq_invoice_entry_history.cost_billed
, acq_invoice_entry_history.actual_cost
, acq_invoice_entry_history.amount_paid
FROM auditor.acq_invoice_entry_history;
Index -
Schema auditor
auditor.acq_invoice_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
NOT NULL
|
|
receiver |
integer |
NOT NULL
|
|
provider |
integer |
NOT NULL
|
|
shipper |
integer |
NOT NULL
|
|
recv_date |
timestamp with time zone |
NOT NULL
|
|
recv_method |
text |
NOT NULL
|
|
inv_type |
text |
|
|
inv_ident |
text |
NOT NULL
|
|
payment_auth |
text |
|
|
payment_method |
text |
|
|
note |
text |
|
|
complete |
boolean |
NOT NULL
|
Index -
Schema auditor
auditor.acq_invoice_item_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
NOT NULL
|
|
invoice |
integer |
NOT NULL
|
|
purchase_order |
integer |
|
|
fund_debit |
integer |
|
|
inv_item_type |
text |
NOT NULL
|
|
title |
text |
|
|
author |
text |
|
|
note |
text |
|
|
cost_billed |
numeric(8,2) |
|
|
actual_cost |
numeric(8,2) |
|
|
fund |
integer |
|
|
amount_paid |
numeric(8,2) |
|
|
po_item |
integer |
|
|
target |
bigint |
|
Index -
Schema auditor
auditor.acq_invoice_item_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
|
|
invoice |
integer |
|
|
purchase_order |
integer |
|
|
fund_debit |
integer |
|
|
inv_item_type |
text |
|
|
title |
text |
|
|
author |
text |
|
|
note |
text |
|
|
cost_billed |
numeric(8,2) |
|
|
actual_cost |
numeric(8,2) |
|
|
fund |
integer |
|
|
amount_paid |
numeric(8,2) |
|
|
po_item |
integer |
|
|
target |
bigint |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, invoice_item.id
, invoice_item.invoice
, invoice_item.purchase_order
, invoice_item.fund_debit
, invoice_item.inv_item_type
, invoice_item.title
, invoice_item.author
, invoice_item.note
, invoice_item.cost_billed
, invoice_item.actual_cost
, invoice_item.fund
, invoice_item.amount_paid
, invoice_item.po_item
, invoice_item.target
FROM acq.invoice_item
UNION ALLSELECT acq_invoice_item_history.audit_id
, acq_invoice_item_history.audit_time
, acq_invoice_item_history.audit_action
, acq_invoice_item_history.audit_user
, acq_invoice_item_history.audit_ws
, acq_invoice_item_history.id
, acq_invoice_item_history.invoice
, acq_invoice_item_history.purchase_order
, acq_invoice_item_history.fund_debit
, acq_invoice_item_history.inv_item_type
, acq_invoice_item_history.title
, acq_invoice_item_history.author
, acq_invoice_item_history.note
, acq_invoice_item_history.cost_billed
, acq_invoice_item_history.actual_cost
, acq_invoice_item_history.fund
, acq_invoice_item_history.amount_paid
, acq_invoice_item_history.po_item
, acq_invoice_item_history.target
FROM auditor.acq_invoice_item_history;
Index -
Schema auditor
auditor.acq_invoice_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
|
|
receiver |
integer |
|
|
provider |
integer |
|
|
shipper |
integer |
|
|
recv_date |
timestamp with time zone |
|
|
recv_method |
text |
|
|
inv_type |
text |
|
|
inv_ident |
text |
|
|
payment_auth |
text |
|
|
payment_method |
text |
|
|
note |
text |
|
|
complete |
boolean |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, invoice.id
, invoice.receiver
, invoice.provider
, invoice.shipper
, invoice.recv_date
, invoice.recv_method
, invoice.inv_type
, invoice.inv_ident
, invoice.payment_auth
, invoice.payment_method
, invoice.note
, invoice.complete
FROM acq.invoice
UNION ALLSELECT acq_invoice_history.audit_id
, acq_invoice_history.audit_time
, acq_invoice_history.audit_action
, acq_invoice_history.audit_user
, acq_invoice_history.audit_ws
, acq_invoice_history.id
, acq_invoice_history.receiver
, acq_invoice_history.provider
, acq_invoice_history.shipper
, acq_invoice_history.recv_date
, acq_invoice_history.recv_method
, acq_invoice_history.inv_type
, acq_invoice_history.inv_ident
, acq_invoice_history.payment_auth
, acq_invoice_history.payment_method
, acq_invoice_history.note
, acq_invoice_history.complete
FROM auditor.acq_invoice_history;
Index -
Schema auditor
auditor.actor_org_unit_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
NOT NULL
|
|
parent_ou |
integer |
|
|
ou_type |
integer |
NOT NULL
|
|
ill_address |
integer |
|
|
holds_address |
integer |
|
|
mailing_address |
integer |
|
|
billing_address |
integer |
|
|
shortname |
text |
NOT NULL
|
|
name |
text |
NOT NULL
|
|
email |
text |
|
|
phone |
text |
|
|
opac_visible |
boolean |
NOT NULL
|
|
fiscal_calendar |
integer |
NOT NULL
|
Index -
Schema auditor
auditor.actor_org_unit_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
|
|
parent_ou |
integer |
|
|
ou_type |
integer |
|
|
ill_address |
integer |
|
|
holds_address |
integer |
|
|
mailing_address |
integer |
|
|
billing_address |
integer |
|
|
shortname |
text |
|
|
name |
text |
|
|
email |
text |
|
|
phone |
text |
|
|
opac_visible |
boolean |
|
|
fiscal_calendar |
integer |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, org_unit.id
, org_unit.parent_ou
, org_unit.ou_type
, org_unit.ill_address
, org_unit.holds_address
, org_unit.mailing_address
, org_unit.billing_address
, org_unit.shortname
, org_unit.name
, org_unit.email
, org_unit.phone
, org_unit.opac_visible
, org_unit.fiscal_calendar
FROM actor.org_unit
UNION ALLSELECT actor_org_unit_history.audit_id
, actor_org_unit_history.audit_time
, actor_org_unit_history.audit_action
, actor_org_unit_history.audit_user
, actor_org_unit_history.audit_ws
, actor_org_unit_history.id
, actor_org_unit_history.parent_ou
, actor_org_unit_history.ou_type
, actor_org_unit_history.ill_address
, actor_org_unit_history.holds_address
, actor_org_unit_history.mailing_address
, actor_org_unit_history.billing_address
, actor_org_unit_history.shortname
, actor_org_unit_history.name
, actor_org_unit_history.email
, actor_org_unit_history.phone
, actor_org_unit_history.opac_visible
, actor_org_unit_history.fiscal_calendar
FROM auditor.actor_org_unit_history;
Index -
Schema auditor
auditor.actor_usr_address_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
NOT NULL
|
|
valid |
boolean |
NOT NULL
|
|
within_city_limits |
boolean |
NOT NULL
|
|
address_type |
text |
NOT NULL
|
|
usr |
integer |
NOT NULL
|
|
street1 |
text |
NOT NULL
|
|
street2 |
text |
|
|
city |
text |
NOT NULL
|
|
county |
text |
|
|
state |
text |
NOT NULL
|
|
country |
text |
NOT NULL
|
|
post_code |
text |
NOT NULL
|
|
pending |
boolean |
NOT NULL
|
|
replaces |
integer |
|
aud_actor_usr_address_hist_id_idx id
Index -
Schema auditor
auditor.actor_usr_address_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
|
|
valid |
boolean |
|
|
within_city_limits |
boolean |
|
|
address_type |
text |
|
|
usr |
integer |
|
|
street1 |
text |
|
|
street2 |
text |
|
|
city |
text |
|
|
county |
text |
|
|
state |
text |
|
|
country |
text |
|
|
post_code |
text |
|
|
pending |
boolean |
|
|
replaces |
integer |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, usr_address.id
, usr_address.valid
, usr_address.within_city_limits
, usr_address.address_type
, usr_address.usr
, usr_address.street1
, usr_address.street2
, usr_address.city
, usr_address.county
, usr_address.state
, usr_address.country
, usr_address.post_code
, usr_address.pending
, usr_address.replaces
FROM actor.usr_address
UNION ALLSELECT actor_usr_address_history.audit_id
, actor_usr_address_history.audit_time
, actor_usr_address_history.audit_action
, actor_usr_address_history.audit_user
, actor_usr_address_history.audit_ws
, actor_usr_address_history.id
, actor_usr_address_history.valid
, actor_usr_address_history.within_city_limits
, actor_usr_address_history.address_type
, actor_usr_address_history.usr
, actor_usr_address_history.street1
, actor_usr_address_history.street2
, actor_usr_address_history.city
, actor_usr_address_history.county
, actor_usr_address_history.state
, actor_usr_address_history.country
, actor_usr_address_history.post_code
, actor_usr_address_history.pending
, actor_usr_address_history.replaces
FROM auditor.actor_usr_address_history;
Index -
Schema auditor
auditor.actor_usr_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
NOT NULL
|
|
card |
integer |
|
|
profile |
integer |
NOT NULL
|
|
usrname |
text |
NOT NULL
|
|
email |
text |
|
|
passwd |
text |
NOT NULL
|
|
standing |
integer |
NOT NULL
|
|
ident_type |
integer |
NOT NULL
|
|
ident_value |
text |
|
|
ident_type2 |
integer |
|
|
ident_value2 |
text |
|
|
net_access_level |
integer |
NOT NULL
|
|
photo_url |
text |
|
|
prefix |
text |
|
|
first_given_name |
text |
NOT NULL
|
|
second_given_name |
text |
|
|
family_name |
text |
NOT NULL
|
|
suffix |
text |
|
|
alias |
text |
|
|
day_phone |
text |
|
|
evening_phone |
text |
|
|
other_phone |
text |
|
|
mailing_address |
integer |
|
|
billing_address |
integer |
|
|
home_ou |
integer |
NOT NULL
|
|
dob |
timestamp with time zone |
|
|
active |
boolean |
NOT NULL
|
|
master_account |
boolean |
NOT NULL
|
|
super_user |
boolean |
NOT NULL
|
|
barred |
boolean |
NOT NULL
|
|
deleted |
boolean |
NOT NULL
|
|
juvenile |
boolean |
NOT NULL
|
|
usrgroup |
integer |
NOT NULL
|
|
claims_returned_count |
integer |
NOT NULL
|
|
credit_forward_balance |
numeric(6,2) |
NOT NULL
|
|
last_xact_id |
text |
NOT NULL
|
|
alert_message |
text |
|
|
create_date |
timestamp with time zone |
NOT NULL
|
|
expire_date |
timestamp with time zone |
NOT NULL
|
|
claims_never_checked_out_count |
integer |
NOT NULL
|
|
last_update_time |
timestamp with time zone |
|
aud_actor_usr_hist_id_idx id
Index -
Schema auditor
auditor.actor_usr_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
integer |
|
|
card |
integer |
|
|
profile |
integer |
|
|
usrname |
text |
|
|
email |
text |
|
|
passwd |
text |
|
|
standing |
integer |
|
|
ident_type |
integer |
|
|
ident_value |
text |
|
|
ident_type2 |
integer |
|
|
ident_value2 |
text |
|
|
net_access_level |
integer |
|
|
photo_url |
text |
|
|
prefix |
text |
|
|
first_given_name |
text |
|
|
second_given_name |
text |
|
|
family_name |
text |
|
|
suffix |
text |
|
|
alias |
text |
|
|
day_phone |
text |
|
|
evening_phone |
text |
|
|
other_phone |
text |
|
|
mailing_address |
integer |
|
|
billing_address |
integer |
|
|
home_ou |
integer |
|
|
dob |
timestamp with time zone |
|
|
active |
boolean |
|
|
master_account |
boolean |
|
|
super_user |
boolean |
|
|
barred |
boolean |
|
|
deleted |
boolean |
|
|
juvenile |
boolean |
|
|
usrgroup |
integer |
|
|
claims_returned_count |
integer |
|
|
credit_forward_balance |
numeric(6,2) |
|
|
last_xact_id |
text |
|
|
alert_message |
text |
|
|
create_date |
timestamp with time zone |
|
|
expire_date |
timestamp with time zone |
|
|
claims_never_checked_out_count |
integer |
|
|
last_update_time |
timestamp with time zone |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, usr.id
, usr.card
, usr.profile
, usr.usrname
, usr.email
, usr.passwd
, usr.standing
, usr.ident_type
, usr.ident_value
, usr.ident_type2
, usr.ident_value2
, usr.net_access_level
, usr.photo_url
, usr.prefix
, usr.first_given_name
, usr.second_given_name
, usr.family_name
, usr.suffix
, usr.alias
, usr.day_phone
, usr.evening_phone
, usr.other_phone
, usr.mailing_address
, usr.billing_address
, usr.home_ou
, usr.dob
, usr.active
, usr.master_account
, usr.super_user
, usr.barred
, usr.deleted
, usr.juvenile
, usr.usrgroup
, usr.claims_returned_count
, usr.credit_forward_balance
, usr.last_xact_id
, usr.alert_message
, usr.create_date
, usr.expire_date
, usr.claims_never_checked_out_count
, usr.last_update_time
FROM actor.usr
UNION ALLSELECT actor_usr_history.audit_id
, actor_usr_history.audit_time
, actor_usr_history.audit_action
, actor_usr_history.audit_user
, actor_usr_history.audit_ws
, actor_usr_history.id
, actor_usr_history.card
, actor_usr_history.profile
, actor_usr_history.usrname
, actor_usr_history.email
, actor_usr_history.passwd
, actor_usr_history.standing
, actor_usr_history.ident_type
, actor_usr_history.ident_value
, actor_usr_history.ident_type2
, actor_usr_history.ident_value2
, actor_usr_history.net_access_level
, actor_usr_history.photo_url
, actor_usr_history.prefix
, actor_usr_history.first_given_name
, actor_usr_history.second_given_name
, actor_usr_history.family_name
, actor_usr_history.suffix
, actor_usr_history.alias
, actor_usr_history.day_phone
, actor_usr_history.evening_phone
, actor_usr_history.other_phone
, actor_usr_history.mailing_address
, actor_usr_history.billing_address
, actor_usr_history.home_ou
, actor_usr_history.dob
, actor_usr_history.active
, actor_usr_history.master_account
, actor_usr_history.super_user
, actor_usr_history.barred
, actor_usr_history.deleted
, actor_usr_history.juvenile
, actor_usr_history.usrgroup
, actor_usr_history.claims_returned_count
, actor_usr_history.credit_forward_balance
, actor_usr_history.last_xact_id
, actor_usr_history.alert_message
, actor_usr_history.create_date
, actor_usr_history.expire_date
, actor_usr_history.claims_never_checked_out_count
, actor_usr_history.last_update_time
FROM auditor.actor_usr_history;
Index -
Schema auditor
auditor.asset_call_number_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
bigint |
NOT NULL
|
|
creator |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
|
|
editor |
bigint |
NOT NULL
|
|
edit_date |
timestamp with time zone |
|
|
record |
bigint |
NOT NULL
|
|
owning_lib |
integer |
NOT NULL
|
|
label |
text |
NOT NULL
|
|
deleted |
boolean |
NOT NULL
|
|
prefix |
integer |
NOT NULL
|
|
suffix |
integer |
NOT NULL
|
|
label_class |
bigint |
NOT NULL
|
|
label_sortkey |
text |
|
aud_asset_cn_hist_creator_idx creator
aud_asset_cn_hist_editor_idx editor
Index -
Schema auditor
auditor.asset_call_number_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
bigint |
|
|
creator |
bigint |
|
|
create_date |
timestamp with time zone |
|
|
editor |
bigint |
|
|
edit_date |
timestamp with time zone |
|
|
record |
bigint |
|
|
owning_lib |
integer |
|
|
label |
text |
|
|
deleted |
boolean |
|
|
prefix |
integer |
|
|
suffix |
integer |
|
|
label_class |
bigint |
|
|
label_sortkey |
text |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, call_number.id
, call_number.creator
, call_number.create_date
, call_number.editor
, call_number.edit_date
, call_number.record
, call_number.owning_lib
, call_number.label
, call_number.deleted
, call_number.prefix
, call_number.suffix
, call_number.label_class
, call_number.label_sortkey
FROM asset.call_number
UNION ALLSELECT asset_call_number_history.audit_id
, asset_call_number_history.audit_time
, asset_call_number_history.audit_action
, asset_call_number_history.audit_user
, asset_call_number_history.audit_ws
, asset_call_number_history.id
, asset_call_number_history.creator
, asset_call_number_history.create_date
, asset_call_number_history.editor
, asset_call_number_history.edit_date
, asset_call_number_history.record
, asset_call_number_history.owning_lib
, asset_call_number_history.label
, asset_call_number_history.deleted
, asset_call_number_history.prefix
, asset_call_number_history.suffix
, asset_call_number_history.label_class
, asset_call_number_history.label_sortkey
FROM auditor.asset_call_number_history;
Index -
Schema auditor
auditor.asset_copy_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
bigint |
NOT NULL
|
|
circ_lib |
integer |
NOT NULL
|
|
creator |
bigint |
NOT NULL
|
|
call_number |
bigint |
NOT NULL
|
|
editor |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
|
|
edit_date |
timestamp with time zone |
|
|
copy_number |
integer |
|
|
status |
integer |
NOT NULL
|
|
location |
integer |
NOT NULL
|
|
loan_duration |
integer |
NOT NULL
|
|
fine_level |
integer |
NOT NULL
|
|
age_protect |
integer |
|
|
circulate |
boolean |
NOT NULL
|
|
deposit |
boolean |
NOT NULL
|
|
ref |
boolean |
NOT NULL
|
|
holdable |
boolean |
NOT NULL
|
|
deposit_amount |
numeric(6,2) |
NOT NULL
|
|
price |
numeric(8,2) |
|
|
barcode |
text |
NOT NULL
|
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
dummy_title |
text |
|
|
dummy_author |
text |
|
|
alert_message |
text |
|
|
opac_visible |
boolean |
NOT NULL
|
|
deleted |
boolean |
NOT NULL
|
|
floating |
boolean |
NOT NULL
|
|
dummy_isbn |
text |
|
|
status_changed_time |
timestamp with time zone |
|
|
active_date |
timestamp with time zone |
|
|
mint_condition |
boolean |
NOT NULL
|
|
cost |
numeric(8,2) |
|
aud_asset_cp_hist_creator_idx creator
aud_asset_cp_hist_editor_idx editor
Index -
Schema auditor
auditor.asset_copy_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
bigint |
|
|
circ_lib |
integer |
|
|
creator |
bigint |
|
|
call_number |
bigint |
|
|
editor |
bigint |
|
|
create_date |
timestamp with time zone |
|
|
edit_date |
timestamp with time zone |
|
|
copy_number |
integer |
|
|
status |
integer |
|
|
location |
integer |
|
|
loan_duration |
integer |
|
|
fine_level |
integer |
|
|
age_protect |
integer |
|
|
circulate |
boolean |
|
|
deposit |
boolean |
|
|
ref |
boolean |
|
|
holdable |
boolean |
|
|
deposit_amount |
numeric(6,2) |
|
|
price |
numeric(8,2) |
|
|
barcode |
text |
|
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
dummy_title |
text |
|
|
dummy_author |
text |
|
|
alert_message |
text |
|
|
opac_visible |
boolean |
|
|
deleted |
boolean |
|
|
floating |
boolean |
|
|
dummy_isbn |
text |
|
|
status_changed_time |
timestamp with time zone |
|
|
active_date |
timestamp with time zone |
|
|
mint_condition |
boolean |
|
|
cost |
numeric(8,2) |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, copy.id
, copy.circ_lib
, copy.creator
, copy.call_number
, copy.editor
, copy.create_date
, copy.edit_date
, copy.copy_number
, copy.status
, copy.location
, copy.loan_duration
, copy.fine_level
, copy.age_protect
, copy.circulate
, copy.deposit
, copy.ref
, copy.holdable
, copy.deposit_amount
, copy.price
, copy.barcode
, copy.circ_modifier
, copy.circ_as_type
, copy.dummy_title
, copy.dummy_author
, copy.alert_message
, copy.opac_visible
, copy.deleted
, copy.floating
, copy.dummy_isbn
, copy.status_changed_time
, copy.active_date
, copy.mint_condition
, copy.cost
FROM asset.copy
UNION ALLSELECT asset_copy_history.audit_id
, asset_copy_history.audit_time
, asset_copy_history.audit_action
, asset_copy_history.audit_user
, asset_copy_history.audit_ws
, asset_copy_history.id
, asset_copy_history.circ_lib
, asset_copy_history.creator
, asset_copy_history.call_number
, asset_copy_history.editor
, asset_copy_history.create_date
, asset_copy_history.edit_date
, asset_copy_history.copy_number
, asset_copy_history.status
, asset_copy_history.location
, asset_copy_history.loan_duration
, asset_copy_history.fine_level
, asset_copy_history.age_protect
, asset_copy_history.circulate
, asset_copy_history.deposit
, asset_copy_history.ref
, asset_copy_history.holdable
, asset_copy_history.deposit_amount
, asset_copy_history.price
, asset_copy_history.barcode
, asset_copy_history.circ_modifier
, asset_copy_history.circ_as_type
, asset_copy_history.dummy_title
, asset_copy_history.dummy_author
, asset_copy_history.alert_message
, asset_copy_history.opac_visible
, asset_copy_history.deleted
, asset_copy_history.floating
, asset_copy_history.dummy_isbn
, asset_copy_history.status_changed_time
, asset_copy_history.active_date
, asset_copy_history.mint_condition
, asset_copy_history.cost
FROM auditor.asset_copy_history;
Index -
Schema auditor
auditor.biblio_record_entry_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
bigint |
NOT NULL
|
|
creator |
integer |
NOT NULL
|
|
editor |
integer |
NOT NULL
|
|
source |
integer |
|
|
quality |
integer |
|
|
create_date |
timestamp with time zone |
NOT NULL
|
|
edit_date |
timestamp with time zone |
NOT NULL
|
|
active |
boolean |
NOT NULL
|
|
deleted |
boolean |
NOT NULL
|
|
fingerprint |
text |
|
|
tcn_source |
text |
NOT NULL
|
|
tcn_value |
text |
NOT NULL
|
|
marc |
text |
NOT NULL
|
|
last_xact_id |
text |
NOT NULL
|
|
owner |
integer |
|
|
share_depth |
integer |
|
aud_bib_rec_entry_hist_creator_idx creator
aud_bib_rec_entry_hist_editor_idx editor
Index -
Schema auditor
auditor.biblio_record_entry_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
bigint |
|
|
creator |
integer |
|
|
editor |
integer |
|
|
source |
integer |
|
|
quality |
integer |
|
|
create_date |
timestamp with time zone |
|
|
edit_date |
timestamp with time zone |
|
|
active |
boolean |
|
|
deleted |
boolean |
|
|
fingerprint |
text |
|
|
tcn_source |
text |
|
|
tcn_value |
text |
|
|
marc |
text |
|
|
last_xact_id |
text |
|
|
owner |
integer |
|
|
share_depth |
integer |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, record_entry.id
, record_entry.creator
, record_entry.editor
, record_entry.source
, record_entry.quality
, record_entry.create_date
, record_entry.edit_date
, record_entry.active
, record_entry.deleted
, record_entry.fingerprint
, record_entry.tcn_source
, record_entry.tcn_value
, record_entry.marc
, record_entry.last_xact_id
, record_entry.owner
, record_entry.share_depth
FROM biblio.record_entry
UNION ALLSELECT biblio_record_entry_history.audit_id
, biblio_record_entry_history.audit_time
, biblio_record_entry_history.audit_action
, biblio_record_entry_history.audit_user
, biblio_record_entry_history.audit_ws
, biblio_record_entry_history.id
, biblio_record_entry_history.creator
, biblio_record_entry_history.editor
, biblio_record_entry_history.source
, biblio_record_entry_history.quality
, biblio_record_entry_history.create_date
, biblio_record_entry_history.edit_date
, biblio_record_entry_history.active
, biblio_record_entry_history.deleted
, biblio_record_entry_history.fingerprint
, biblio_record_entry_history.tcn_source
, biblio_record_entry_history.tcn_value
, biblio_record_entry_history.marc
, biblio_record_entry_history.last_xact_id
, biblio_record_entry_history.owner
, biblio_record_entry_history.share_depth
FROM auditor.biblio_record_entry_history;
Index -
Schema auditor
auditor.serial_unit_history Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
PRIMARY KEY
|
|
audit_time |
timestamp with time zone |
NOT NULL
|
|
audit_action |
text |
NOT NULL
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
bigint |
NOT NULL
|
|
circ_lib |
integer |
NOT NULL
|
|
creator |
bigint |
NOT NULL
|
|
call_number |
bigint |
NOT NULL
|
|
editor |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
|
|
edit_date |
timestamp with time zone |
|
|
copy_number |
integer |
|
|
status |
integer |
NOT NULL
|
|
location |
integer |
NOT NULL
|
|
loan_duration |
integer |
NOT NULL
|
|
fine_level |
integer |
NOT NULL
|
|
age_protect |
integer |
|
|
circulate |
boolean |
NOT NULL
|
|
deposit |
boolean |
NOT NULL
|
|
ref |
boolean |
NOT NULL
|
|
holdable |
boolean |
NOT NULL
|
|
deposit_amount |
numeric(6,2) |
NOT NULL
|
|
price |
numeric(8,2) |
|
|
barcode |
text |
NOT NULL
|
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
dummy_title |
text |
|
|
dummy_author |
text |
|
|
alert_message |
text |
|
|
opac_visible |
boolean |
NOT NULL
|
|
deleted |
boolean |
NOT NULL
|
|
floating |
boolean |
NOT NULL
|
|
dummy_isbn |
text |
|
|
status_changed_time |
timestamp with time zone |
|
|
active_date |
timestamp with time zone |
|
|
mint_condition |
boolean |
NOT NULL
|
|
cost |
numeric(8,2) |
|
|
sort_key |
text |
|
|
detailed_contents |
text |
NOT NULL
|
|
summary_contents |
text |
NOT NULL
|
aud_serial_unit_hist_creator_idx creator
aud_serial_unit_hist_editor_idx editor
Index -
Schema auditor
auditor.serial_unit_lifecycle Structure
F-Key |
Name |
Type |
Description |
|
audit_id |
bigint |
|
|
audit_time |
timestamp with time zone |
|
|
audit_action |
text |
|
|
audit_user |
integer |
|
|
audit_ws |
integer |
|
|
id |
bigint |
|
|
circ_lib |
integer |
|
|
creator |
bigint |
|
|
call_number |
bigint |
|
|
editor |
bigint |
|
|
create_date |
timestamp with time zone |
|
|
edit_date |
timestamp with time zone |
|
|
copy_number |
integer |
|
|
status |
integer |
|
|
location |
integer |
|
|
loan_duration |
integer |
|
|
fine_level |
integer |
|
|
age_protect |
integer |
|
|
circulate |
boolean |
|
|
deposit |
boolean |
|
|
ref |
boolean |
|
|
holdable |
boolean |
|
|
deposit_amount |
numeric(6,2) |
|
|
price |
numeric(8,2) |
|
|
barcode |
text |
|
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
dummy_title |
text |
|
|
dummy_author |
text |
|
|
alert_message |
text |
|
|
opac_visible |
boolean |
|
|
deleted |
boolean |
|
|
floating |
boolean |
|
|
dummy_isbn |
text |
|
|
status_changed_time |
timestamp with time zone |
|
|
active_date |
timestamp with time zone |
|
|
mint_condition |
boolean |
|
|
cost |
numeric(8,2) |
|
|
sort_key |
text |
|
|
detailed_contents |
text |
|
|
summary_contents |
text |
|
SELECT (-1) AS audit_id
, now
() AS audit_time
,'-'::text AS audit_action
, (-1) AS audit_user
, (-1) AS audit_ws
, unit.id
, unit.circ_lib
, unit.creator
, unit.call_number
, unit.editor
, unit.create_date
, unit.edit_date
, unit.copy_number
, unit.status
, unit.location
, unit.loan_duration
, unit.fine_level
, unit.age_protect
, unit.circulate
, unit.deposit
, unit.ref
, unit.holdable
, unit.deposit_amount
, unit.price
, unit.barcode
, unit.circ_modifier
, unit.circ_as_type
, unit.dummy_title
, unit.dummy_author
, unit.alert_message
, unit.opac_visible
, unit.deleted
, unit.floating
, unit.dummy_isbn
, unit.status_changed_time
, unit.active_date
, unit.mint_condition
, unit.cost
, unit.sort_key
, unit.detailed_contents
, unit.summary_contents
FROM serial.unit
UNION ALLSELECT serial_unit_history.audit_id
, serial_unit_history.audit_time
, serial_unit_history.audit_action
, serial_unit_history.audit_user
, serial_unit_history.audit_ws
, serial_unit_history.id
, serial_unit_history.circ_lib
, serial_unit_history.creator
, serial_unit_history.call_number
, serial_unit_history.editor
, serial_unit_history.create_date
, serial_unit_history.edit_date
, serial_unit_history.copy_number
, serial_unit_history.status
, serial_unit_history.location
, serial_unit_history.loan_duration
, serial_unit_history.fine_level
, serial_unit_history.age_protect
, serial_unit_history.circulate
, serial_unit_history.deposit
, serial_unit_history.ref
, serial_unit_history.holdable
, serial_unit_history.deposit_amount
, serial_unit_history.price
, serial_unit_history.barcode
, serial_unit_history.circ_modifier
, serial_unit_history.circ_as_type
, serial_unit_history.dummy_title
, serial_unit_history.dummy_author
, serial_unit_history.alert_message
, serial_unit_history.opac_visible
, serial_unit_history.deleted
, serial_unit_history.floating
, serial_unit_history.dummy_isbn
, serial_unit_history.status_changed_time
, serial_unit_history.active_date
, serial_unit_history.mint_condition
, serial_unit_history.cost
, serial_unit_history.sort_key
, serial_unit_history.detailed_contents
, serial_unit_history.summary_contents
FROM auditor.serial_unit_history;
Index -
Schema auditor
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.acq_invoice_entry_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, invoice, purchase_order, lineitem, inv_item_count, phys_item_count, note, billed_per_item, cost_billed, actual_cost, amount_paid )
SELECT nextval('auditor.acq_invoice_entry_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.invoice, OLD.purchase_order, OLD.lineitem, OLD.inv_item_count, OLD.phys_item_count, OLD.note, OLD.billed_per_item, OLD.cost_billed, OLD.actual_cost, OLD.amount_paid
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.acq_invoice_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, receiver, provider, shipper, recv_date, recv_method, inv_type, inv_ident, payment_auth, payment_method, note, complete )
SELECT nextval('auditor.acq_invoice_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.receiver, OLD.provider, OLD.shipper, OLD.recv_date, OLD.recv_method, OLD.inv_type, OLD.inv_ident, OLD.payment_auth, OLD.payment_method, OLD.note, OLD.complete
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.acq_invoice_item_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, invoice, purchase_order, fund_debit, inv_item_type, title, author, note, cost_billed, actual_cost, fund, amount_paid, po_item, target )
SELECT nextval('auditor.acq_invoice_item_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.invoice, OLD.purchase_order, OLD.fund_debit, OLD.inv_item_type, OLD.title, OLD.author, OLD.note, OLD.cost_billed, OLD.actual_cost, OLD.fund, OLD.amount_paid, OLD.po_item, OLD.target
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.actor_org_unit_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, parent_ou, ou_type, ill_address, holds_address, mailing_address, billing_address, shortname, name, email, phone, opac_visible, fiscal_calendar )
SELECT nextval('auditor.actor_org_unit_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.parent_ou, OLD.ou_type, OLD.ill_address, OLD.holds_address, OLD.mailing_address, OLD.billing_address, OLD.shortname, OLD.name, OLD.email, OLD.phone, OLD.opac_visible, OLD.fiscal_calendar
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.actor_usr_address_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, valid, within_city_limits, address_type, usr, street1, street2, city, county, state, country, post_code, pending, replaces )
SELECT nextval('auditor.actor_usr_address_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.valid, OLD.within_city_limits, OLD.address_type, OLD.usr, OLD.street1, OLD.street2, OLD.city, OLD.county, OLD.state, OLD.country, OLD.post_code, OLD.pending, OLD.replaces
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.actor_usr_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, card, profile, usrname, email, passwd, standing, ident_type, ident_value, ident_type2, ident_value2, net_access_level, photo_url, prefix, first_given_name, second_given_name, family_name, suffix, alias, day_phone, evening_phone, other_phone, mailing_address, billing_address, home_ou, dob, active, master_account, super_user, barred, deleted, juvenile, usrgroup, claims_returned_count, credit_forward_balance, last_xact_id, alert_message, create_date, expire_date, claims_never_checked_out_count, last_update_time )
SELECT nextval('auditor.actor_usr_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.card, OLD.profile, OLD.usrname, OLD.email, OLD.passwd, OLD.standing, OLD.ident_type, OLD.ident_value, OLD.ident_type2, OLD.ident_value2, OLD.net_access_level, OLD.photo_url, OLD.prefix, OLD.first_given_name, OLD.second_given_name, OLD.family_name, OLD.suffix, OLD.alias, OLD.day_phone, OLD.evening_phone, OLD.other_phone, OLD.mailing_address, OLD.billing_address, OLD.home_ou, OLD.dob, OLD.active, OLD.master_account, OLD.super_user, OLD.barred, OLD.deleted, OLD.juvenile, OLD.usrgroup, OLD.claims_returned_count, OLD.credit_forward_balance, OLD.last_xact_id, OLD.alert_message, OLD.create_date, OLD.expire_date, OLD.claims_never_checked_out_count, OLD.last_update_time
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.asset_call_number_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, creator, create_date, editor, edit_date, record, owning_lib, label, deleted, prefix, suffix, label_class, label_sortkey )
SELECT nextval('auditor.asset_call_number_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.creator, OLD.create_date, OLD.editor, OLD.edit_date, OLD.record, OLD.owning_lib, OLD.label, OLD.deleted, OLD.prefix, OLD.suffix, OLD.label_class, OLD.label_sortkey
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.asset_copy_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, circ_lib, creator, call_number, editor, create_date, edit_date, copy_number, status, location, loan_duration, fine_level, age_protect, circulate, deposit, ref, holdable, deposit_amount, price, barcode, circ_modifier, circ_as_type, dummy_title, dummy_author, alert_message, opac_visible, deleted, floating, dummy_isbn, status_changed_time, active_date, mint_condition, cost )
SELECT nextval('auditor.asset_copy_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.circ_lib, OLD.creator, OLD.call_number, OLD.editor, OLD.create_date, OLD.edit_date, OLD.copy_number, OLD.status, OLD.location, OLD.loan_duration, OLD.fine_level, OLD.age_protect, OLD.circulate, OLD.deposit, OLD.ref, OLD.holdable, OLD.deposit_amount, OLD.price, OLD.barcode, OLD.circ_modifier, OLD.circ_as_type, OLD.dummy_title, OLD.dummy_author, OLD.alert_message, OLD.opac_visible, OLD.deleted, OLD.floating, OLD.dummy_isbn, OLD.status_changed_time, OLD.active_date, OLD.mint_condition, OLD.cost
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.biblio_record_entry_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, creator, editor, source, quality, create_date, edit_date, active, deleted, fingerprint, tcn_source, tcn_value, marc, last_xact_id, owner, share_depth )
SELECT nextval('auditor.biblio_record_entry_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.creator, OLD.editor, OLD.source, OLD.quality, OLD.create_date, OLD.edit_date, OLD.active, OLD.deleted, OLD.fingerprint, OLD.tcn_source, OLD.tcn_value, OLD.marc, OLD.last_xact_id, OLD.owner, OLD.share_depth
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO auditor.serial_unit_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, id, circ_lib, creator, call_number, editor, create_date, edit_date, copy_number, status, location, loan_duration, fine_level, age_protect, circulate, deposit, ref, holdable, deposit_amount, price, barcode, circ_modifier, circ_as_type, dummy_title, dummy_author, alert_message, opac_visible, deleted, floating, dummy_isbn, status_changed_time, active_date, mint_condition, cost, sort_key, detailed_contents, summary_contents )
SELECT nextval('auditor.serial_unit_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.id, OLD.circ_lib, OLD.creator, OLD.call_number, OLD.editor, OLD.create_date, OLD.edit_date, OLD.copy_number, OLD.status, OLD.location, OLD.loan_duration, OLD.fine_level, OLD.age_protect, OLD.circulate, OLD.deposit, OLD.ref, OLD.holdable, OLD.deposit_amount, OLD.price, OLD.barcode, OLD.circ_modifier, OLD.circ_as_type, OLD.dummy_title, OLD.dummy_author, OLD.alert_message, OLD.opac_visible, OLD.deleted, OLD.floating, OLD.dummy_isbn, OLD.status_changed_time, OLD.active_date, OLD.mint_condition, OLD.cost, OLD.sort_key, OLD.detailed_contents, OLD.summary_contents
FROM auditor.get_audit_info();
RETURN NULL;
END;
Returns: void
Language: PLPERLU
delete($_SHARED{"eg_audit_user"});
delete($_SHARED{"eg_audit_ws"});
Returns: boolean
Language: PLPGSQL
BEGIN
PERFORM auditor.create_auditor_seq(sch, tbl);
PERFORM auditor.create_auditor_history(sch, tbl);
PERFORM auditor.create_auditor_func(sch, tbl);
PERFORM auditor.create_auditor_update_trigger(sch, tbl);
PERFORM auditor.create_auditor_lifecycle(sch, tbl);
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
DECLARE
column_list TEXT[];
BEGIN
SELECT INTO column_list array_agg(a.attname)
FROM pg_catalog.pg_attribute a
JOIN pg_catalog.pg_class c ON a.attrelid = c.oid
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE relkind = 'r' AND n.nspname = sch AND c.relname = tbl AND a.attnum > 0 AND NOT a.attisdropped;
EXECUTE $$
CREATE OR REPLACE FUNCTION auditor.audit_$$ || sch || $$_$$ || tbl || $$_func ()
RETURNS TRIGGER AS $func$
BEGIN
INSERT INTO auditor.$$ || sch || $$_$$ || tbl || $$_history ( audit_id, audit_time, audit_action, audit_user, audit_ws, $$
|| array_to_string(column_list, ', ') || $$ )
SELECT nextval('auditor.$$ || sch || $$_$$ || tbl || $$_pkey_seq'),
now(),
SUBSTR(TG_OP,1,1),
eg_user,
eg_ws,
OLD.$$ || array_to_string(column_list, ', OLD.') || $$
FROM auditor.get_audit_info();
RETURN NULL;
END;
$func$ LANGUAGE 'plpgsql';
$$;
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
EXECUTE $$
CREATE TABLE auditor.$$ || sch || $$_$$ || tbl || $$_history (
audit_id BIGINT PRIMARY KEY,
audit_time TIMESTAMP WITH TIME ZONE NOT NULL,
audit_action TEXT NOT NULL,
audit_user INT,
audit_ws INT,
LIKE $$ || sch || $$.$$ || tbl || $$
);
$$;
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
DECLARE
column_list TEXT[];
BEGIN
SELECT INTO column_list array_agg(a.attname)
FROM pg_catalog.pg_attribute a
JOIN pg_catalog.pg_class c ON a.attrelid = c.oid
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE relkind = 'r' AND n.nspname = sch AND c.relname = tbl AND a.attnum > 0 AND NOT a.attisdropped;
EXECUTE $$
CREATE VIEW auditor.$$ || sch || $$_$$ || tbl || $$_lifecycle AS
SELECT -1 AS audit_id,
now() AS audit_time,
'-' AS audit_action,
-1 AS audit_user,
-1 AS audit_ws,
$$ || array_to_string(column_list, ', ') || $$
FROM $$ || sch || $$.$$ || tbl || $$
UNION ALL
SELECT audit_id, audit_time, audit_action, audit_user, audit_ws,
$$ || array_to_string(column_list, ', ') || $$
FROM auditor.$$ || sch || $$_$$ || tbl || $$_history;
$$;
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
EXECUTE $$
CREATE SEQUENCE auditor.$$ || sch || $$_$$ || tbl || $$_pkey_seq;
$$;
RETURN TRUE;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
EXECUTE $$
CREATE TRIGGER audit_$$ || sch || $$_$$ || tbl || $$_update_trigger
AFTER UPDATE OR DELETE ON $$ || sch || $$.$$ || tbl || $$ FOR EACH ROW
EXECUTE PROCEDURE auditor.audit_$$ || sch || $$_$$ || tbl || $$_func ();
$$;
RETURN TRUE;
END;
Returns: void
Language: PLPGSQL
DECLARE
current_table TEXT = ''; -- Storage for post-loop main table name
current_audit_table TEXT = ''; -- Storage for post-loop audit table name
query TEXT = ''; -- Storage for built query
cr RECORD; -- column record object
alter_t BOOL = false; -- Has the alter table command been appended yet
auditor_cores TEXT[] = ARRAY[]::TEXT[]; -- Core auditor function list (filled inside of loop)
core_column TEXT; -- The current core column we are adding
BEGIN
FOR cr IN
WITH audit_tables AS ( -- Basic grab of auditor tables. Anything in the auditor namespace, basically. With oids.
SELECT c.oid AS audit_oid, c.relname AS audit_table
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE relkind='r' AND nspname = 'auditor'
),
table_set AS ( -- Union of auditor tables with their "main" tables. With oids.
SELECT a.audit_oid, a.audit_table, c.oid AS main_oid, n.nspname as main_namespace, c.relname as main_table
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
JOIN audit_tables a ON a.audit_table = n.nspname || '_' || c.relname || '_history'
WHERE relkind = 'r'
),
column_lists AS ( -- All columns associated with the auditor or main table, grouped by the main table's oid.
SELECT DISTINCT ON (main_oid, attname) t.main_oid, a.attname
FROM table_set t
JOIN pg_catalog.pg_attribute a ON a.attrelid IN (t.main_oid, t.audit_oid)
WHERE attnum > 0 AND NOT attisdropped
),
column_defs AS ( -- The motherload, every audit table and main table plus column names and defs.
SELECT audit_table,
main_namespace,
main_table,
a.attname AS main_column, -- These two will be null for columns that have since been deleted, or for auditor core columns
pg_catalog.format_type(a.atttypid, a.atttypmod) AS main_column_def,
b.attname AS audit_column, -- These two will be null for columns that have since been added
pg_catalog.format_type(b.atttypid, b.atttypmod) AS audit_column_def
FROM table_set t
JOIN column_lists c USING (main_oid)
LEFT JOIN pg_catalog.pg_attribute a ON a.attname = c.attname AND a.attrelid = t.main_oid AND a.attnum > 0 AND NOT a.attisdropped
LEFT JOIN pg_catalog.pg_attribute b ON b.attname = c.attname AND b.attrelid = t.audit_oid AND b.attnum > 0 AND NOT b.attisdropped
)
-- Nice sorted output from the above
SELECT * FROM column_defs WHERE main_column_def IS DISTINCT FROM audit_column_def ORDER BY main_namespace, main_table, main_column, audit_column
LOOP
IF current_table <> (cr.main_namespace || '.' || cr.main_table) THEN -- New table?
FOR core_column IN SELECT DISTINCT unnest(auditor_cores) LOOP -- Update missing core auditor columns
IF NOT alter_t THEN -- Add ALTER TABLE if we haven't already
query:=query || $$ALTER TABLE auditor.$$ || current_audit_table;
alter_t:=TRUE;
ELSE
query:=query || $$,$$;
END IF;
-- Bit of a sneaky bit here. Create audit_id as a bigserial so it gets automatic values and doesn't complain about nulls when becoming a PRIMARY KEY.
query:=query || $$ ADD COLUMN $$ || CASE WHEN core_column = 'audit_id bigint' THEN $$audit_id bigserial PRIMARY KEY$$ ELSE core_column END;
END LOOP;
IF alter_t THEN -- Open alter table = needs a semicolon
query:=query || $$; $$;
alter_t:=FALSE;
IF 'audit_id bigint' = ANY(auditor_cores) THEN -- We added a primary key...
-- Fun! Drop the default on audit_id, drop the auto-created sequence, create a new one, and set the current value
-- For added fun, we have to execute in chunks due to the parser checking setval/currval arguments at parse time.
EXECUTE query;
EXECUTE $$ALTER TABLE auditor.$$ || current_audit_table || $$ ALTER COLUMN audit_id DROP DEFAULT; $$ ||
$$CREATE SEQUENCE auditor.$$ || current_audit_table || $$_pkey_seq;$$;
EXECUTE $$SELECT setval('auditor.$$ || current_audit_table || $$_pkey_seq', currval('auditor.$$ || current_audit_table || $$_audit_id_seq')); $$ ||
$$DROP SEQUENCE auditor.$$ || current_audit_table || $$_audit_id_seq;$$;
query:='';
END IF;
END IF;
-- New table means we reset the list of needed auditor core columns
auditor_cores = ARRAY['audit_id bigint', 'audit_time timestamp with time zone', 'audit_action text', 'audit_user integer', 'audit_ws integer'];
-- And store some values for use later, because we can't rely on cr in all places.
current_table:=cr.main_namespace || '.' || cr.main_table;
current_audit_table:=cr.audit_table;
END IF;
IF cr.main_column IS NULL AND cr.audit_column LIKE 'audit_%' THEN -- Core auditor column?
-- Remove core from list of cores
SELECT INTO auditor_cores array_agg(core) FROM unnest(auditor_cores) AS core WHERE core != (cr.audit_column || ' ' || cr.audit_column_def);
ELSIF cr.main_column IS NULL THEN -- Main column doesn't exist, and it isn't an auditor column. Needs dropping from the auditor.
IF NOT alter_t THEN
query:=query || $$ALTER TABLE auditor.$$ || current_audit_table;
alter_t:=TRUE;
ELSE
query:=query || $$,$$;
END IF;
query:=query || $$ DROP COLUMN $$ || cr.audit_column;
ELSIF cr.audit_column IS NULL AND cr.main_column IS NOT NULL THEN -- New column auditor doesn't have. Add it.
IF NOT alter_t THEN
query:=query || $$ALTER TABLE auditor.$$ || current_audit_table;
alter_t:=TRUE;
ELSE
query:=query || $$,$$;
END IF;
query:=query || $$ ADD COLUMN $$ || cr.main_column || $$ $$ || cr.main_column_def;
ELSIF cr.main_column IS NOT NULL AND cr.audit_column IS NOT NULL THEN -- Both sides have this column, but types differ. Fix that.
IF NOT alter_t THEN
query:=query || $$ALTER TABLE auditor.$$ || current_audit_table;
alter_t:=TRUE;
ELSE
query:=query || $$,$$;
END IF;
query:=query || $$ ALTER COLUMN $$ || cr.audit_column || $$ TYPE $$ || cr.main_column_def;
END IF;
END LOOP;
FOR core_column IN SELECT DISTINCT unnest(auditor_cores) LOOP -- Repeat this outside of the loop to catch the last table
IF NOT alter_t THEN
query:=query || $$ALTER TABLE auditor.$$ || current_audit_table;
alter_t:=TRUE;
ELSE
query:=query || $$,$$;
END IF;
-- Bit of a sneaky bit here. Create audit_id as a bigserial so it gets automatic values and doesn't complain about nulls when becoming a PRIMARY KEY.
query:=query || $$ ADD COLUMN $$ || CASE WHEN core_column = 'audit_id bigint' THEN $$audit_id bigserial PRIMARY KEY$$ ELSE core_column END;
END LOOP;
IF alter_t THEN -- Open alter table = needs a semicolon
query:=query || $$;$$;
IF 'audit_id bigint' = ANY(auditor_cores) THEN -- We added a primary key...
-- Fun! Drop the default on audit_id, drop the auto-created sequence, create a new one, and set the current value
-- For added fun, we have to execute in chunks due to the parser checking setval/currval arguments at parse time.
EXECUTE query;
EXECUTE $$ALTER TABLE auditor.$$ || current_audit_table || $$ ALTER COLUMN audit_id DROP DEFAULT; $$ ||
$$CREATE SEQUENCE auditor.$$ || current_audit_table || $$_pkey_seq;$$;
EXECUTE $$SELECT setval('auditor.$$ || current_audit_table || $$_pkey_seq', currval('auditor.$$ || current_audit_table || $$_audit_id_seq')); $$ ||
$$DROP SEQUENCE auditor.$$ || current_audit_table || $$_audit_id_seq;$$;
query:='';
END IF;
END IF;
EXECUTE query;
END;
Returns: SET OF record
Language: PLPERLU
return [{eg_user => $_SHARED{"eg_audit_user"}, eg_ws => $_SHARED{"eg_audit_ws"}}];
Returns: void
Language: PLPERLU
$_SHARED{"eg_audit_user"} = $_[0];
$_SHARED{"eg_audit_ws"} = $_[1];
Returns: boolean
Language: PLPGSQL
DECLARE
auditor_name TEXT;
table_schema TEXT;
table_name TEXT;
BEGIN
-- Drop Lifecycle view(s) before potential column changes
FOR auditor_name IN
SELECT c.relname
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE relkind = 'v' AND n.nspname = 'auditor' LOOP
EXECUTE $$ DROP VIEW auditor.$$ || auditor_name || $$;$$;
END LOOP;
-- Fix all column discrepencies
PERFORM auditor.fix_columns();
-- Re-create trigger functions and lifecycle views
FOR table_schema, table_name IN
WITH audit_tables AS (
SELECT c.oid AS audit_oid, c.relname AS audit_table
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE relkind='r' AND nspname = 'auditor'
),
table_set AS (
SELECT a.audit_oid, a.audit_table, c.oid AS main_oid, n.nspname as main_namespace, c.relname as main_table
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
JOIN audit_tables a ON a.audit_table = n.nspname || '_' || c.relname || '_history'
WHERE relkind = 'r'
)
SELECT main_namespace, main_table FROM table_set LOOP
PERFORM auditor.create_auditor_func(table_schema, table_name);
PERFORM auditor.create_auditor_lifecycle(table_schema, table_name);
END LOOP;
RETURN TRUE;
END;
Schema authority
authority_bl_bib_idx bib
Index -
Schema authority
authority.browse_axis Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
config.record_attr_definition.name
|
sorter |
text |
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema authority
Index -
Schema authority
authority.control_set Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema authority
Tables referencing this one via Foreign Key Constraints:
Index -
Schema authority
Index -
Schema authority
authority.full_rec Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
record |
bigint |
NOT NULL
|
|
tag |
character(3) |
NOT NULL
|
|
ind1 |
text |
|
|
ind2 |
text |
|
|
subfield |
text |
|
|
value |
text |
NOT NULL
|
|
index_vector |
tsvector |
NOT NULL
|
authority_full_rec_index_vector_idx index_vector
authority_full_rec_record_idx record
authority_full_rec_subfield_a_idx value) WHERE (subfield = 'a'::text
authority_full_rec_tag_part_idx "substring"((tag)::text, 2)
authority_full_rec_tag_subfield_idx tag, subfield
authority_full_rec_value_index value
authority_full_rec_value_tpo_index value text_pattern_ops
Index -
Schema authority
authority.rec_descriptor Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
record |
bigint |
|
|
record_status |
text |
|
|
encoding_level |
text |
|
|
thesaurus |
text |
|
authority_rec_descriptor_record_idx record
Index -
Schema authority
authority.record_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
creator |
integer |
NOT NULL
DEFAULT 1
|
|
editor |
integer |
NOT NULL
DEFAULT 1
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
|
deleted |
boolean |
NOT NULL
DEFAULT false
|
|
source |
integer |
|
authority.control_set.id
|
control_set |
integer |
|
|
marc |
text |
NOT NULL
|
|
last_xact_id |
text |
NOT NULL
|
|
owner |
integer |
|
Tables referencing this one via Foreign Key Constraints:
authority_record_deleted_idx deleted) WHERE ((deleted IS FALSE) OR (deleted = false)
authority_record_entry_creator_idx creator
authority_record_entry_editor_idx editor
by_heading authority.simple_normalize_heading(marc)) WHERE ((deleted IS FALSE) OR (deleted = false)
by_heading_and_thesaurus authority.normalize_heading(marc)) WHERE ((deleted IS FALSE) OR (deleted = false)
Index -
Schema authority
authority.record_note Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
authority.record_entry.id
|
record |
bigint |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
creator |
integer |
NOT NULL
DEFAULT 1
|
|
editor |
integer |
NOT NULL
DEFAULT 1
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
authority_record_note_creator_idx creator
authority_record_note_editor_idx editor
authority_record_note_record_idx record
Index -
Schema authority
authority_simple_heading_index_vector_idx index_vector
authority_simple_heading_sort_value_idx sort_value
authority_simple_heading_value_idx value
Index -
Schema authority
authority.thesaurus Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
authority.control_set.id
|
control_set |
integer |
|
|
name |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
Index -
Schema authority
authority.tracing_links Structure
F-Key |
Name |
Type |
Description |
|
record |
bigint |
|
|
main_id |
bigint |
|
|
main_tag |
character(3) |
|
|
main_value |
text |
|
|
relationship |
text |
|
|
use_restriction |
text |
|
|
deprecation |
text |
|
|
display_restriction |
text |
|
|
link_id |
bigint |
|
|
link_tag |
character(3) |
|
|
link_value |
text |
|
|
normalized_main_value |
text |
|
SELECT main.record
, main.id AS main_id
, main.tag AS main_tag
, oils_xpath_string
(
(
('//*[@tag="'::text ||
(main.tag)::text
) ||
'"]/*[local-name()="subfield"]'::text
)
, are.marc
) AS main_value
, substr
( link.value
, 1
, 1
) AS relationship
, substr
( link.value
, 2
, 1
) AS use_restriction
, substr
( link.value
, 3
, 1
) AS deprecation
, substr
( link.value
, 4
, 1
) AS display_restriction
, link.id AS link_id
, link.tag AS link_tag
, oils_xpath_string
(
(
('//*[@tag="'::text ||
(link.tag)::text
) ||
'"]/*[local-name()="subfield"]'::text
)
, are.marc
) AS link_value
, authority.normalize_heading
( are.marc) AS normalized_main_value
FROM (
(
(
(authority.full_rec main
JOIN authority.record_entry are
ON (
(main.record = are.id)
)
)
JOIN authority.control_set_authority_field main_entry
ON (
(
(
(main_entry.tag = main.tag)
AND (main_entry.main_entry IS NULL)
)
AND (main.subfield = 'a'::text)
)
)
)
JOIN authority.control_set_authority_field sub_entry
ON (
(main_entry.id = sub_entry.main_entry)
)
)
JOIN authority.full_rec link
ON (
(
(
(link.record = main.record)
AND (link.tag = sub_entry.tag)
)
AND (link.subfield = 'w'::text)
)
)
) ;
Index -
Schema authority
Returns: integer[]
Language: SQL
SELECT ARRAY_ACCUM(id) FROM authority.control_set_authority_field WHERE tag = $1
Returns: integer[]
Language: SQL
SELECT ARRAY_CAT(
ARRAY[a.id],
(SELECT ARRAY_ACCUM(x.id) FROM authority.control_set_authority_field x WHERE x.main_entry = a.id)
)
FROM authority.control_set_authority_field a
WHERE a.tag = $1
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_center(authority.atag_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_center(authority.atag_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_top(authority.atag_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_top(authority.atag_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_heading(authority.atag_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_heading(authority.atag_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_rank(authority.atag_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_rank(authority.atag_authority_tags_refs($1), $2, $3, $4)
Returns: integer[]
Language: SQL
SELECT ARRAY_ACCUM(field) FROM authority.browse_axis_authority_field_map WHERE axis = $1;
Returns: integer[]
Language: SQL
SELECT ARRAY_CAT(
ARRAY[a.field],
(SELECT ARRAY_ACCUM(x.id) FROM authority.control_set_authority_field x WHERE x.main_entry = a.field)
)
FROM authority.browse_axis_authority_field_map a
WHERE axis = $1
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_center(authority.axis_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_center(authority.axis_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_top(authority.axis_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_top(authority.axis_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_heading(authority.axis_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_heading(authority.axis_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_rank(authority.axis_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_rank(authority.axis_authority_tags_refs($1), $2, $3, $4)
Returns: integer[]
Language: SQL
SELECT ARRAY_ACCUM(authority_field) FROM authority.control_set_bib_field WHERE tag = $1
Returns: integer[]
Language: SQL
SELECT ARRAY_CAT(
ARRAY[a.authority_field],
(SELECT ARRAY_ACCUM(x.id) FROM authority.control_set_authority_field x WHERE x.main_entry = a.authority_field)
)
FROM authority.control_set_bib_field a
WHERE a.tag = $1
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_center(authority.btag_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_center(authority.btag_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_top(authority.btag_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_browse_top(authority.btag_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_heading(authority.btag_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_heading(authority.btag_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_rank(authority.btag_authority_tags($1), $2, $3, $4)
Returns: SET OF bigint
Language: SQL
SELECT * FROM authority.simple_heading_search_rank(authority.btag_authority_tags_refs($1), $2, $3, $4)
Returns: SET OF full_rec
Language: PLPGSQL
DECLARE
auth authority.record_entry%ROWTYPE;
output authority.full_rec%ROWTYPE;
field RECORD;
BEGIN
SELECT INTO auth * FROM authority.record_entry WHERE id = rid;
FOR field IN SELECT * FROM vandelay.flatten_marc( auth.marc ) LOOP
output.record := rid;
output.ind1 := field.ind1;
output.ind2 := field.ind2;
output.tag := field.tag;
output.subfield := field.subfield;
output.value := field.value;
RETURN NEXT output;
END LOOP;
END;
Returns: text
Language: SQL
SELECT authority.generate_overlay_template( marc ) FROM authority.record_entry WHERE id = $1;
Returns: text
Language: PLPGSQL
DECLARE
cset INT;
main_entry authority.control_set_authority_field%ROWTYPE;
bib_field authority.control_set_bib_field%ROWTYPE;
auth_id INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', source_xml)::INT;
replace_data XML[] DEFAULT '{}'::XML[];
replace_rules TEXT[] DEFAULT '{}'::TEXT[];
auth_field XML[];
BEGIN
IF auth_id IS NULL THEN
RETURN NULL;
END IF;
-- Default to the LoC controll set
SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
-- if none, make a best guess
IF cset IS NULL THEN
SELECT control_set INTO cset
FROM authority.control_set_authority_field
WHERE tag IN (
SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marc::XML)::TEXT[])
FROM authority.record_entry
WHERE id = auth_id
)
LIMIT 1;
END IF;
-- if STILL none, no-op change
IF cset IS NULL THEN
RETURN XMLELEMENT(
name record,
XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
XMLELEMENT( name leader, '00881nam a2200193 4500'),
XMLELEMENT(
name datafield,
XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
XMLELEMENT(
name subfield,
XMLATTRIBUTES('d' AS code),
'901c'
)
)
)::TEXT;
END IF;
FOR main_entry IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
auth_field := XPATH('//*[@tag="'||main_entry.tag||'"][1]',source_xml::XML);
IF ARRAY_LENGTH(auth_field,1) > 0 THEN
FOR bib_field IN SELECT * FROM authority.control_set_bib_field WHERE authority_field = main_entry.id LOOP
replace_data := replace_data || XMLELEMENT( name datafield, XMLATTRIBUTES(bib_field.tag AS tag), XPATH('//*[local-name()="subfield"]',auth_field[1])::XML[]);
replace_rules := replace_rules || ( bib_field.tag || main_entry.sf_list || E'[0~\\)' || auth_id || '$]' );
END LOOP;
EXIT;
END IF;
END LOOP;
RETURN XMLELEMENT(
name record,
XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
XMLELEMENT( name leader, '00881nam a2200193 4500'),
replace_data,
XMLELEMENT(
name datafield,
XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
XMLELEMENT(
name subfield,
XMLATTRIBUTES('r' AS code),
ARRAY_TO_STRING(replace_rules,',')
)
)
)::TEXT;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF NEW.deleted IS TRUE THEN -- If this authority is deleted
DELETE FROM authority.bib_linking WHERE authority = NEW.id; -- Avoid updating fields in bibs that are no longer visible
DELETE FROM authority.full_rec WHERE record = NEW.id; -- Avoid validating fields against deleted authority records
DELETE FROM authority.simple_heading WHERE record = NEW.id;
-- Should remove matching $0 from controlled fields at the same time?
RETURN NEW; -- and we're done
END IF;
IF TG_OP = 'UPDATE' THEN -- re-ingest?
PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
RETURN NEW;
END IF;
-- Propagate these updates to any linked bib records
PERFORM authority.propagate_changes(NEW.id) FROM authority.record_entry WHERE id = NEW.id;
DELETE FROM authority.simple_heading WHERE record = NEW.id;
END IF;
INSERT INTO authority.simple_heading (record,atag,value,sort_value)
SELECT record, atag, value, sort_value FROM authority.simple_heading_set(NEW.marc);
-- Flatten and insert the afr data
PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_full_rec' AND enabled;
IF NOT FOUND THEN
PERFORM authority.reingest_authority_full_rec(NEW.id);
PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_rec_descriptor' AND enabled;
IF NOT FOUND THEN
PERFORM authority.reingest_authority_rec_descriptor(NEW.id);
END IF;
END IF;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF NEW.control_set IS NULL THEN
SELECT control_set INTO NEW.control_set
FROM authority.thesaurus
WHERE vandelay.marc21_extract_fixed_field(NEW.marc,'Subj') = code;
END IF;
RETURN NEW;
END;
Returns: integer
Language: PLPGSQL
DECLARE
moved_objects INT := 0;
bib_id INT := 0;
bib_rec biblio.record_entry%ROWTYPE;
auth_link authority.bib_linking%ROWTYPE;
ingest_same boolean;
BEGIN
-- Defining our terms:
-- "target record" = the record that will survive the merge
-- "source record" = the record that is sacrifing its existence and being
-- replaced by the target record
-- 1. Update all bib records with the ID from target_record in their $0
FOR bib_rec IN
SELECT bre.*
FROM biblio.record_entry bre
JOIN authority.bib_linking abl ON abl.bib = bre.id
WHERE abl.authority = source_record
LOOP
UPDATE biblio.record_entry
SET marc = REGEXP_REPLACE(
marc,
E'(<subfield\\s+code="0"\\s*>[^<]*?\\))' || source_record || '<',
E'\\1' || target_record || '<',
'g'
)
WHERE id = bib_rec.id;
moved_objects := moved_objects + 1;
END LOOP;
-- 2. Grab the current value of reingest on same MARC flag
SELECT enabled INTO ingest_same
FROM config.internal_flag
WHERE name = 'ingest.reingest.force_on_same_marc'
;
-- 3. Temporarily set reingest on same to TRUE
UPDATE config.internal_flag
SET enabled = TRUE
WHERE name = 'ingest.reingest.force_on_same_marc'
;
-- 4. Make a harmless update to target_record to trigger auto-update
-- in linked bibliographic records
UPDATE authority.record_entry
SET deleted = FALSE
WHERE id = target_record;
-- 5. "Delete" source_record
DELETE FROM authority.record_entry WHERE id = source_record;
-- 6. Set "reingest on same MARC" flag back to initial value
UPDATE config.internal_flag
SET enabled = ingest_same
WHERE name = 'ingest.reingest.force_on_same_marc'
;
RETURN moved_objects;
END;
Returns: text
Language: SQL
Extract the authority heading, thesaurus, and NACO-normalized values
from an authority record. The primary purpose is to build a unique
index to defend against duplicated authority records from the same
thesaurus.
SELECT authority.normalize_heading($1, FALSE);
Returns: text
Language: PLPGSQL
DECLARE
acsaf authority.control_set_authority_field%ROWTYPE;
tag_used TEXT;
nfi_used TEXT;
sf TEXT;
thes_code TEXT;
cset INT;
heading_text TEXT;
tmp_text TEXT;
first_sf BOOL;
auth_id INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml)::INT;
BEGIN
SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
IF cset IS NULL THEN
SELECT control_set INTO cset
FROM authority.control_set_authority_field
WHERE tag IN ( SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
LIMIT 1;
END IF;
thes_code := vandelay.marc21_extract_fixed_field(marcxml,'Subj');
IF thes_code IS NULL THEN
thes_code := '|';
ELSIF thes_code = 'z' THEN
thes_code := COALESCE( oils_xpath_string('//*[@tag="040"]/*[@code="f"][1]', marcxml), '' );
END IF;
heading_text := '';
FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset AND main_entry IS NULL LOOP
tag_used := acsaf.tag;
nfi_used := acsaf.nfi;
first_sf := TRUE;
FOR sf IN SELECT * FROM regexp_split_to_table(acsaf.sf_list,'') LOOP
tmp_text := oils_xpath_string('//*[@tag="'||tag_used||'"]/*[@code="'||sf||'"]', marcxml);
IF first_sf AND tmp_text IS NOT NULL AND nfi_used IS NOT NULL THEN
tmp_text := SUBSTRING(
tmp_text FROM
COALESCE(
NULLIF(
REGEXP_REPLACE(
oils_xpath_string('//*[@tag="'||tag_used||'"]/@ind'||nfi_used, marcxml),
$$\D+$$,
'',
'g'
),
''
)::INT,
0
) + 1
);
END IF;
first_sf := FALSE;
IF tmp_text IS NOT NULL AND tmp_text <> '' THEN
heading_text := heading_text || E'\u2021' || sf || ' ' || tmp_text;
END IF;
END LOOP;
EXIT WHEN heading_text <> '';
END LOOP;
IF heading_text <> '' THEN
IF no_thesaurus IS TRUE THEN
heading_text := tag_used || ' ' || public.naco_normalize(heading_text);
ELSE
heading_text := tag_used || '_' || COALESCE(nfi_used,'-') || '_' || thes_code || ' ' || public.naco_normalize(heading_text);
END IF;
ELSE
heading_text := 'NOHEADING_' || thes_code || ' ' || MD5(marcxml);
END IF;
RETURN heading_text;
END;
Returns: SET OF bigint
Language: SQL
SELECT authority.propagate_changes( authority, bib ) FROM authority.bib_linking WHERE authority = $1;
Returns: bigint
Language: SQL
UPDATE biblio.record_entry
SET marc = vandelay.merge_record_xml( marc, authority.generate_overlay_template( $1 ) )
WHERE id = $2;
SELECT $1;
Returns: void
Language: PLPGSQL
BEGIN
DELETE FROM authority.full_rec WHERE record = auth_id;
INSERT INTO authority.full_rec (record, tag, ind1, ind2, subfield, value)
SELECT record, tag, ind1, ind2, subfield, value FROM authority.flatten_marc( auth_id );
RETURN;
END;
Returns: void
Language: PLPGSQL
BEGIN
DELETE FROM authority.rec_descriptor WHERE record = auth_id;
INSERT INTO authority.rec_descriptor (record, record_status, encoding_level, thesaurus)
SELECT auth_id,
vandelay.marc21_extract_fixed_field(marc,'RecStat'),
vandelay.marc21_extract_fixed_field(marc,'ELvl'),
vandelay.marc21_extract_fixed_field(marc,'Subj')
FROM authority.record_entry
WHERE id = auth_id;
RETURN;
END;
Returns: SET OF bigint
Language: PLPGSQL
DECLARE
pivot_sort_value TEXT;
boffset INT DEFAULT 0;
aoffset INT DEFAULT 0;
blimit INT DEFAULT 0;
alimit INT DEFAULT 0;
BEGIN
pivot_sort_value := authority.simple_heading_find_pivot(atag_list,q);
IF page = 0 THEN
blimit := pagesize / 2;
alimit := blimit;
IF pagesize % 2 <> 0 THEN
alimit := alimit + 1;
END IF;
ELSE
blimit := pagesize;
alimit := blimit;
boffset := pagesize / 2;
aoffset := boffset;
IF pagesize % 2 <> 0 THEN
boffset := boffset + 1;
END IF;
END IF;
IF page <= 0 THEN
RETURN QUERY
-- "bottom" half of the browse results
SELECT id FROM (
SELECT ash.id,
row_number() over ()
FROM authority.simple_heading ash
WHERE ash.atag = ANY (atag_list)
AND ash.sort_value < pivot_sort_value
ORDER BY ash.sort_value DESC
LIMIT blimit
OFFSET ABS(page) * pagesize - boffset
) x ORDER BY row_number DESC;
END IF;
IF page >= 0 THEN
RETURN QUERY
-- "bottom" half of the browse results
SELECT ash.id
FROM authority.simple_heading ash
WHERE ash.atag = ANY (atag_list)
AND ash.sort_value >= pivot_sort_value
ORDER BY ash.sort_value
LIMIT alimit
OFFSET ABS(page) * pagesize - aoffset;
END IF;
END;
Returns: SET OF bigint
Language: PLPGSQL
DECLARE
pivot_sort_value TEXT;
BEGIN
pivot_sort_value := authority.simple_heading_find_pivot(atag_list,q);
IF page < 0 THEN
RETURN QUERY
-- "bottom" half of the browse results
SELECT id FROM (
SELECT ash.id,
row_number() over ()
FROM authority.simple_heading ash
WHERE ash.atag = ANY (atag_list)
AND ash.sort_value < pivot_sort_value
ORDER BY ash.sort_value DESC
LIMIT pagesize
OFFSET (ABS(page) - 1) * pagesize
) x ORDER BY row_number DESC;
END IF;
IF page >= 0 THEN
RETURN QUERY
-- "bottom" half of the browse results
SELECT ash.id
FROM authority.simple_heading ash
WHERE ash.atag = ANY (atag_list)
AND ash.sort_value >= pivot_sort_value
ORDER BY ash.sort_value
LIMIT pagesize
OFFSET ABS(page) * pagesize ;
END IF;
END;
Returns: text
Language: PLPGSQL
DECLARE
sort_value_row RECORD;
value_row RECORD;
t_term TEXT;
BEGIN
t_term := public.naco_normalize(q);
SELECT CASE WHEN ash.sort_value LIKE t_term || '%' THEN 1 ELSE 0 END
+ CASE WHEN ash.value LIKE t_term || '%' THEN 1 ELSE 0 END AS rank,
ash.sort_value
INTO sort_value_row
FROM authority.simple_heading ash
WHERE ash.atag = ANY (a)
AND ash.sort_value >= t_term
ORDER BY rank DESC, ash.sort_value
LIMIT 1;
SELECT CASE WHEN ash.sort_value LIKE t_term || '%' THEN 1 ELSE 0 END
+ CASE WHEN ash.value LIKE t_term || '%' THEN 1 ELSE 0 END AS rank,
ash.sort_value
INTO value_row
FROM authority.simple_heading ash
WHERE ash.atag = ANY (a)
AND ash.value >= t_term
ORDER BY rank DESC, ash.sort_value
LIMIT 1;
IF value_row.rank > sort_value_row.rank THEN
RETURN value_row.sort_value;
ELSE
RETURN sort_value_row.sort_value;
END IF;
END;
Returns: SET OF bigint
Language: SQL
SELECT ash.id
FROM authority.simple_heading ash,
public.naco_normalize($2) t(term),
plainto_tsquery('keyword'::regconfig,$2) ptsq(term)
WHERE ash.atag = ANY ($1)
AND ash.index_vector @@ ptsq.term
ORDER BY ash.sort_value
LIMIT $4
OFFSET $4 * $3;
Returns: SET OF bigint
Language: SQL
SELECT ash.id
FROM authority.simple_heading ash,
public.naco_normalize($2) t(term),
plainto_tsquery('keyword'::regconfig,$2) ptsq(term)
WHERE ash.atag = ANY ($1)
AND ash.index_vector @@ ptsq.term
ORDER BY ts_rank_cd(ash.index_vector,ptsq.term,14)::numeric
+ CASE WHEN ash.sort_value LIKE t.term || '%' THEN 2 ELSE 0 END
+ CASE WHEN ash.value LIKE t.term || '%' THEN 1 ELSE 0 END DESC
LIMIT $4
OFFSET $4 * $3;
Returns: SET OF simple_heading
Language: PLPGSQL
DECLARE
res authority.simple_heading%ROWTYPE;
acsaf authority.control_set_authority_field%ROWTYPE;
tag_used TEXT;
nfi_used TEXT;
sf TEXT;
cset INT;
heading_text TEXT;
sort_text TEXT;
tmp_text TEXT;
tmp_xml TEXT;
first_sf BOOL;
auth_id INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml)::INT;
BEGIN
res.record := auth_id;
SELECT control_set INTO cset
FROM authority.control_set_authority_field
WHERE tag IN ( SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]) )
LIMIT 1;
FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
res.atag := acsaf.id;
tag_used := acsaf.tag;
nfi_used := acsaf.nfi;
FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)) LOOP
heading_text := '';
FOR sf IN SELECT * FROM regexp_split_to_table(acsaf.sf_list,'') LOOP
heading_text := heading_text || COALESCE( ' ' || oils_xpath_string('//*[@code="'||sf||'"]',tmp_xml::TEXT), '');
END LOOP;
heading_text := public.naco_normalize(heading_text);
IF nfi_used IS NOT NULL THEN
sort_text := SUBSTRING(
heading_text FROM
COALESCE(
NULLIF(
REGEXP_REPLACE(
oils_xpath_string('//*[@tag="'||tag_used||'"]/@ind'||nfi_used, marcxml),
$$\D+$$,
'',
'g'
),
''
)::INT,
0
) + 1
);
ELSE
sort_text := heading_text;
END IF;
IF heading_text IS NOT NULL AND heading_text <> '' THEN
res.value := heading_text;
res.sort_value := sort_text;
RETURN NEXT res;
END IF;
END LOOP;
END LOOP;
RETURN;
END;
Returns: text
Language: SQL
SELECT authority.normalize_heading($1, TRUE);
Schema biblio
biblio.monograph_part Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
biblio.record_entry.id
|
record |
bigint |
UNIQUE#1
NOT NULL
|
|
label |
text |
UNIQUE#1
NOT NULL
|
|
label_sortkey |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema biblio
biblio.peer_bib_copy_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
biblio.peer_type.id
|
peer_type |
integer |
NOT NULL
|
biblio.record_entry.id
|
peer_record |
bigint |
NOT NULL
|
|
target_copy |
bigint |
NOT NULL
|
peer_bib_copy_map_copy_idx target_copy
peer_bib_copy_map_record_idx peer_record
Index -
Schema biblio
biblio.peer_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema biblio
biblio.record_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.usr.id
|
creator |
integer |
NOT NULL
DEFAULT 1
|
actor.usr.id
|
editor |
integer |
NOT NULL
DEFAULT 1
|
|
source |
integer |
|
|
quality |
integer |
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
|
deleted |
boolean |
NOT NULL
DEFAULT false
|
|
fingerprint |
text |
|
|
tcn_source |
text |
NOT NULL
DEFAULT 'AUTOGEN'::text
|
|
tcn_value |
text |
NOT NULL
DEFAULT biblio.next_autogen_tcn_value()
|
|
marc |
text |
NOT NULL
|
|
last_xact_id |
text |
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
|
|
share_depth |
integer |
|
Tables referencing this one via Foreign Key Constraints:
biblio_record_entry_create_date_idx create_date
biblio_record_entry_creator_idx creator
biblio_record_entry_edit_date_idx edit_date
biblio_record_entry_editor_idx editor
biblio_record_entry_fp_idx fingerprint
Index -
Schema biblio
biblio.record_note Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
biblio.record_entry.id
|
record |
bigint |
NOT NULL
|
|
value |
text |
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
DEFAULT 1
|
actor.usr.id
|
editor |
integer |
NOT NULL
DEFAULT 1
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
biblio_record_note_creator_idx creator
biblio_record_note_editor_idx editor
biblio_record_note_record_idx record
Index -
Schema biblio
Returns: trigger
Language: PLPGSQL
BEGIN
IF xml_is_well_formed(NEW.marc) THEN
RETURN NEW;
ELSE
RAISE EXCEPTION 'Attempted to % MARCXML that is not well formed', TG_OP;
END IF;
END;
Returns: text
Language: PLPGSQL
DECLARE
idx config.biblio_fingerprint%ROWTYPE;
xfrm config.xml_transform%ROWTYPE;
prev_xfrm TEXT;
transformed_xml TEXT;
xml_node TEXT;
xml_node_list TEXT[];
raw_text TEXT;
output_text TEXT := '';
BEGIN
IF marc IS NULL OR marc = '' THEN
RETURN NULL;
END IF;
-- Loop over the indexing entries
FOR idx IN SELECT * FROM config.biblio_fingerprint ORDER BY format, id LOOP
SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
-- See if we can skip the XSLT ... it's expensive
IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
-- Can't skip the transform
IF xfrm.xslt <> '---' THEN
transformed_xml := oils_xslt_process(marc,xfrm.xslt);
ELSE
transformed_xml := marc;
END IF;
prev_xfrm := xfrm.name;
END IF;
raw_text := COALESCE(
naco_normalize(
ARRAY_TO_STRING(
oils_xpath(
'//text()',
(oils_xpath(
idx.xpath,
transformed_xml,
ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
))[1]
),
''
)
),
''
);
raw_text := REGEXP_REPLACE(raw_text, E'\\[.+?\\]', E'');
raw_text := REGEXP_REPLACE(raw_text, E'\\mthe\\M|\\man?d?d\\M', E'', 'g'); -- arg! the pain!
IF idx.first_word IS TRUE THEN
raw_text := REGEXP_REPLACE(raw_text, E'^(\\w+).*?$', E'\\1');
END IF;
output_text := output_text || REGEXP_REPLACE(raw_text, E'\\s+', '', 'g');
END LOOP;
RETURN output_text;
END;
Returns: void
Language: PLPGSQL
DECLARE
uris TEXT[];
uri_xml TEXT;
uri_label TEXT;
uri_href TEXT;
uri_use TEXT;
uri_owner_list TEXT[];
uri_owner TEXT;
uri_owner_id INT;
uri_id INT;
uri_cn_id INT;
uri_map_id INT;
BEGIN
-- Clear any URI mappings and call numbers for this bib.
-- This leads to acn / auricnm inflation, but also enables
-- old acn/auricnm's to go away and for bibs to be deleted.
FOR uri_cn_id IN SELECT id FROM asset.call_number WHERE record = bib_id AND label = '##URI##' AND NOT deleted LOOP
DELETE FROM asset.uri_call_number_map WHERE call_number = uri_cn_id;
DELETE FROM asset.call_number WHERE id = uri_cn_id;
END LOOP;
uris := oils_xpath('//*[@tag="856" and (@ind1="4" or @ind1="1") and (@ind2="0" or @ind2="1")]',marcxml);
IF ARRAY_UPPER(uris,1) > 0 THEN
FOR i IN 1 .. ARRAY_UPPER(uris, 1) LOOP
-- First we pull info out of the 856
uri_xml := uris[i];
uri_href := (oils_xpath('//*[@code="u"]/text()',uri_xml))[1];
uri_label := (oils_xpath('//*[@code="y"]/text()|//*[@code="3"]/text()',uri_xml))[1];
uri_use := (oils_xpath('//*[@code="z"]/text()|//*[@code="2"]/text()|//*[@code="n"]/text()',uri_xml))[1];
IF uri_label IS NULL THEN
uri_label := uri_href;
END IF;
CONTINUE WHEN uri_href IS NULL;
-- Get the distinct list of libraries wanting to use
SELECT ARRAY_ACCUM(
DISTINCT REGEXP_REPLACE(
x,
$re$^.*?\((\w+)\).*$$re$,
E'\\1'
)
) INTO uri_owner_list
FROM UNNEST(
oils_xpath(
'//*[@code="9"]/text()|//*[@code="w"]/text()|//*[@code="n"]/text()',
uri_xml
)
)x;
IF ARRAY_UPPER(uri_owner_list,1) > 0 THEN
-- look for a matching uri
IF uri_use IS NULL THEN
SELECT id INTO uri_id
FROM asset.uri
WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active
ORDER BY id LIMIT 1;
IF NOT FOUND THEN -- create one
INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
SELECT id INTO uri_id
FROM asset.uri
WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active;
END IF;
ELSE
SELECT id INTO uri_id
FROM asset.uri
WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active
ORDER BY id LIMIT 1;
IF NOT FOUND THEN -- create one
INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
SELECT id INTO uri_id
FROM asset.uri
WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active;
END IF;
END IF;
FOR j IN 1 .. ARRAY_UPPER(uri_owner_list, 1) LOOP
uri_owner := uri_owner_list[j];
SELECT id INTO uri_owner_id FROM actor.org_unit WHERE shortname = uri_owner;
CONTINUE WHEN NOT FOUND;
-- we need a call number to link through
SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
IF NOT FOUND THEN
INSERT INTO asset.call_number (owning_lib, record, create_date, edit_date, creator, editor, label)
VALUES (uri_owner_id, bib_id, 'now', 'now', editor_id, editor_id, '##URI##');
SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
END IF;
-- now, link them if they're not already
SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
IF NOT FOUND THEN
INSERT INTO asset.uri_call_number_map (call_number, uri) VALUES (uri_cn_id, uri_id);
END IF;
END LOOP;
END IF;
END LOOP;
END IF;
RETURN;
END;
Returns: SET OF field_entry_template
Language: SQL
SELECT * FROM biblio.extract_metabib_field_entry($1, ' ');
Returns: SET OF field_entry_template
Language: PLPGSQL
DECLARE
bib biblio.record_entry%ROWTYPE;
idx config.metabib_field%ROWTYPE;
xfrm config.xml_transform%ROWTYPE;
prev_xfrm TEXT;
transformed_xml TEXT;
xml_node TEXT;
xml_node_list TEXT[];
facet_text TEXT;
browse_text TEXT;
raw_text TEXT;
curr_text TEXT;
joiner TEXT := default_joiner; -- XXX will index defs supply a joiner?
output_row metabib.field_entry_template%ROWTYPE;
BEGIN
-- Get the record
SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
-- Loop over the indexing entries
FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP
SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
-- See if we can skip the XSLT ... it's expensive
IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
-- Can't skip the transform
IF xfrm.xslt <> '---' THEN
transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
ELSE
transformed_xml := bib.marc;
END IF;
prev_xfrm := xfrm.name;
END IF;
xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
raw_text := NULL;
FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
CONTINUE WHEN xml_node !~ E'^\\s*<';
curr_text := ARRAY_TO_STRING(
oils_xpath( '//text()',
REGEXP_REPLACE( -- This escapes all &s not followed by "amp;". Data ise returned from oils_xpath (above) in UTF-8, not entity encoded
REGEXP_REPLACE( -- This escapes embeded <s
xml_node,
$re$(>[^<]+)(<)([^>]+<)$re$,
E'\\1<\\3',
'g'
),
'&(?!amp;)',
'&',
'g'
)
),
' '
);
CONTINUE WHEN curr_text IS NULL OR curr_text = '';
IF raw_text IS NOT NULL THEN
raw_text := raw_text || joiner;
END IF;
raw_text := COALESCE(raw_text,'') || curr_text;
-- autosuggest/metabib.browse_entry
IF idx.browse_field THEN
IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
ELSE
browse_text := curr_text;
END IF;
output_row.field_class = idx.field_class;
output_row.field = idx.id;
output_row.source = rid;
output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
output_row.browse_field = TRUE;
RETURN NEXT output_row;
output_row.browse_field = FALSE;
END IF;
-- insert raw node text for faceting
IF idx.facet_field THEN
IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
ELSE
facet_text := curr_text;
END IF;
output_row.field_class = idx.field_class;
output_row.field = -1 * idx.id;
output_row.source = rid;
output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
output_row.facet_field = TRUE;
RETURN NEXT output_row;
output_row.facet_field = FALSE;
END IF;
END LOOP;
CONTINUE WHEN raw_text IS NULL OR raw_text = '';
-- insert combined node text for searching
IF idx.search_field THEN
output_row.field_class = idx.field_class;
output_row.field = idx.id;
output_row.source = rid;
output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
output_row.search_field = TRUE;
RETURN NEXT output_row;
END IF;
END LOOP;
END;
Returns: integer
Language: PLPGSQL
DECLARE
qual INT;
ldr TEXT;
tval TEXT;
tval_rec RECORD;
bval TEXT;
bval_rec RECORD;
type_map RECORD;
ff_pos RECORD;
ff_tag_data TEXT;
BEGIN
IF marc IS NULL OR marc = '' THEN
RETURN NULL;
END IF;
-- First, the count of tags
qual := ARRAY_UPPER(oils_xpath('*[local-name()="datafield"]', marc), 1);
-- now go through a bunch of pain to get the record type
IF best_type IS NOT NULL THEN
ldr := (oils_xpath('//*[local-name()="leader"]/text()', marc))[1];
IF ldr IS NOT NULL THEN
SELECT * INTO tval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'Type' LIMIT 1; -- They're all the same
SELECT * INTO bval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'BLvl' LIMIT 1; -- They're all the same
tval := SUBSTRING( ldr, tval_rec.start_pos + 1, tval_rec.length );
bval := SUBSTRING( ldr, bval_rec.start_pos + 1, bval_rec.length );
-- RAISE NOTICE 'type %, blvl %, ldr %', tval, bval, ldr;
SELECT * INTO type_map FROM config.marc21_rec_type_map WHERE type_val LIKE '%' || tval || '%' AND blvl_val LIKE '%' || bval || '%';
IF type_map.code IS NOT NULL THEN
IF best_type = type_map.code THEN
qual := qual + qual / 2;
END IF;
FOR ff_pos IN SELECT * FROM config.marc21_ff_pos_map WHERE fixed_field = 'Lang' AND rec_type = type_map.code ORDER BY tag DESC LOOP
ff_tag_data := SUBSTRING((oils_xpath('//*[@tag="' || ff_pos.tag || '"]/text()',marc))[1], ff_pos.start_pos + 1, ff_pos.length);
IF ff_tag_data = best_lang THEN
qual := qual + 100;
END IF;
END LOOP;
END IF;
END IF;
END IF;
-- Now look for some quality metrics
-- DCL record?
IF ARRAY_UPPER(oils_xpath('//*[@tag="040"]/*[@code="a" and contains(.,"DLC")]', marc), 1) = 1 THEN
qual := qual + 10;
END IF;
-- From OCLC?
IF (oils_xpath('//*[@tag="003"]/text()', marc))[1] ~* E'oclo?c' THEN
qual := qual + 10;
END IF;
RETURN qual;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
-- For TG_ARGV, first param is language (like 'eng'), second is record type (like 'BKS')
IF NEW.deleted IS TRUE THEN -- we don't much care, then, do we?
RETURN NEW;
END IF;
NEW.fingerprint := biblio.extract_fingerprint(NEW.marc);
NEW.quality := biblio.extract_quality(NEW.marc, TG_ARGV[0], TG_ARGV[1]);
RETURN NEW;
END;
Returns: SET OF full_rec
Language: PLPGSQL
DECLARE
bib biblio.record_entry%ROWTYPE;
output metabib.full_rec%ROWTYPE;
field RECORD;
BEGIN
SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
FOR field IN SELECT * FROM vandelay.flatten_marc( bib.marc ) LOOP
output.record := rid;
output.ind1 := field.ind1;
output.ind2 := field.ind2;
output.tag := field.tag;
output.subfield := field.subfield;
output.value := field.value;
RETURN NEXT output;
END LOOP;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
transformed_xml TEXT;
prev_xfrm TEXT;
normalizer RECORD;
xfrm config.xml_transform%ROWTYPE;
attr_value TEXT;
new_attrs HSTORE := ''::HSTORE;
attr_def config.record_attr_definition%ROWTYPE;
BEGIN
IF NEW.deleted IS TRUE THEN -- If this bib is deleted
DELETE FROM metabib.metarecord_source_map WHERE source = NEW.id; -- Rid ourselves of the search-estimate-killing linkage
DELETE FROM metabib.record_attr WHERE id = NEW.id; -- Kill the attrs hash, useless on deleted records
DELETE FROM authority.bib_linking WHERE bib = NEW.id; -- Avoid updating fields in bibs that are no longer visible
DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = NEW.id; -- Separate any multi-homed items
DELETE FROM metabib.browse_entry_def_map WHERE source = NEW.id; -- Don't auto-suggest deleted bibs
RETURN NEW; -- and we're done
END IF;
IF TG_OP = 'UPDATE' THEN -- re-ingest?
PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
RETURN NEW;
END IF;
END IF;
-- Record authority linking
PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_linking' AND enabled;
IF NOT FOUND THEN
PERFORM biblio.map_authority_linking( NEW.id, NEW.marc );
END IF;
-- Flatten and insert the mfr data
PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_metabib_full_rec' AND enabled;
IF NOT FOUND THEN
PERFORM metabib.reingest_metabib_full_rec(NEW.id);
-- Now we pull out attribute data, which is dependent on the mfr for all but XPath-based fields
PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_metabib_rec_descriptor' AND enabled;
IF NOT FOUND THEN
FOR attr_def IN SELECT * FROM config.record_attr_definition ORDER BY format LOOP
IF attr_def.tag IS NOT NULL THEN -- tag (and optional subfield list) selection
SELECT ARRAY_TO_STRING(ARRAY_ACCUM(value), COALESCE(attr_def.joiner,' ')) INTO attr_value
FROM (SELECT * FROM metabib.full_rec ORDER BY tag, subfield) AS x
WHERE record = NEW.id
AND tag LIKE attr_def.tag
AND CASE
WHEN attr_def.sf_list IS NOT NULL
THEN POSITION(subfield IN attr_def.sf_list) > 0
ELSE TRUE
END
GROUP BY tag
ORDER BY tag
LIMIT 1;
ELSIF attr_def.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
attr_value := biblio.marc21_extract_fixed_field(NEW.id, attr_def.fixed_field);
ELSIF attr_def.xpath IS NOT NULL THEN -- and xpath expression
SELECT INTO xfrm * FROM config.xml_transform WHERE name = attr_def.format;
-- See if we can skip the XSLT ... it's expensive
IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
-- Can't skip the transform
IF xfrm.xslt <> '---' THEN
transformed_xml := oils_xslt_process(NEW.marc,xfrm.xslt);
ELSE
transformed_xml := NEW.marc;
END IF;
prev_xfrm := xfrm.name;
END IF;
IF xfrm.name IS NULL THEN
-- just grab the marcxml (empty) transform
SELECT INTO xfrm * FROM config.xml_transform WHERE xslt = '---' LIMIT 1;
prev_xfrm := xfrm.name;
END IF;
attr_value := oils_xpath_string(attr_def.xpath, transformed_xml, COALESCE(attr_def.joiner,' '), ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]);
ELSIF attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
SELECT m.value INTO attr_value
FROM biblio.marc21_physical_characteristics(NEW.id) v
JOIN config.marc21_physical_characteristic_value_map m ON (m.id = v.value)
WHERE v.subfield = attr_def.phys_char_sf
LIMIT 1; -- Just in case ...
END IF;
-- apply index normalizers to attr_value
FOR normalizer IN
SELECT n.func AS func,
n.param_count AS param_count,
m.params AS params
FROM config.index_normalizer n
JOIN config.record_attr_index_norm_map m ON (m.norm = n.id)
WHERE attr = attr_def.name
ORDER BY m.pos LOOP
EXECUTE 'SELECT ' || normalizer.func || '(' ||
COALESCE( quote_literal( attr_value ), 'NULL' ) ||
CASE
WHEN normalizer.param_count > 0
THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
ELSE ''
END ||
')' INTO attr_value;
END LOOP;
-- Add the new value to the hstore
new_attrs := new_attrs || hstore( attr_def.name, attr_value );
END LOOP;
IF TG_OP = 'INSERT' OR OLD.deleted THEN -- initial insert OR revivication
INSERT INTO metabib.record_attr (id, attrs) VALUES (NEW.id, new_attrs);
ELSE
UPDATE metabib.record_attr SET attrs = new_attrs WHERE id = NEW.id;
END IF;
END IF;
END IF;
-- Gather and insert the field entry data
PERFORM metabib.reingest_metabib_field_entries(NEW.id);
-- Located URI magic
IF TG_OP = 'INSERT' THEN
PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_located_uri' AND enabled;
IF NOT FOUND THEN
PERFORM biblio.extract_located_uris( NEW.id, NEW.marc, NEW.editor );
END IF;
ELSE
PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_located_uri' AND enabled;
IF NOT FOUND THEN
PERFORM biblio.extract_located_uris( NEW.id, NEW.marc, NEW.editor );
END IF;
END IF;
-- (re)map metarecord-bib linking
IF TG_OP = 'INSERT' THEN -- if not deleted and performing an insert, check for the flag
PERFORM * FROM config.internal_flag WHERE name = 'ingest.metarecord_mapping.skip_on_insert' AND enabled;
IF NOT FOUND THEN
PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint );
END IF;
ELSE -- we're doing an update, and we're not deleted, remap
PERFORM * FROM config.internal_flag WHERE name = 'ingest.metarecord_mapping.skip_on_update' AND enabled;
IF NOT FOUND THEN
PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint );
END IF;
END IF;
RETURN NEW;
END;
Returns: bigint
Language: SQL
DELETE FROM authority.bib_linking WHERE bib = $1;
INSERT INTO authority.bib_linking (bib, authority)
SELECT y.bib,
y.authority
FROM ( SELECT DISTINCT $1 AS bib,
BTRIM(remove_paren_substring(txt))::BIGINT AS authority
FROM unnest(oils_xpath('//*[@code="0"]/text()',$2)) x(txt)
WHERE BTRIM(remove_paren_substring(txt)) ~ $re$^\d+$$re$
) y JOIN authority.record_entry r ON r.id = y.authority;
SELECT $1;
Returns: SET OF record_ff_map
Language: SQL
SELECT $1 AS record, ff_name, ff_value FROM vandelay.marc21_extract_all_fixed_fields( (SELECT marc FROM biblio.record_entry WHERE id = $1) );
Returns: text
Language: SQL
SELECT * FROM vandelay.marc21_extract_fixed_field( (SELECT marc FROM biblio.record_entry WHERE id = $1), $2 );
Returns: SET OF marc21_physical_characteristics
Language: SQL
SELECT id, $1 AS record, ptype, subfield, value FROM vandelay.marc21_physical_characteristics( (SELECT marc FROM biblio.record_entry WHERE id = $1) );
Returns: marc21_rec_type_map
Language: SQL
SELECT * FROM vandelay.marc21_record_type( (SELECT marc FROM biblio.record_entry WHERE id = $1) );
Returns: text
Language: PLPGSQL
BEGIN RETURN 'AUTOGENERATED-' || nextval('biblio.autogen_tcn_value_seq'::TEXT); END;
Returns: trigger
Language: PLPGSQL
BEGIN
NEW.label_sortkey := REGEXP_REPLACE(
evergreen.lpad_number_substrings(
naco_normalize(NEW.label),
'0',
10
),
E'\\s+',
'',
'g'
);
RETURN NEW;
END;
Schema booking
booking.reservation Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.billable_xact_id_seq'::regclass)
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
|
xact_start |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
xact_finish |
timestamp with time zone |
|
|
unrecovered |
boolean |
|
|
request_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
start_time |
timestamp with time zone |
|
|
end_time |
timestamp with time zone |
|
|
capture_time |
timestamp with time zone |
|
|
cancel_time |
timestamp with time zone |
|
|
pickup_time |
timestamp with time zone |
|
|
return_time |
timestamp with time zone |
|
|
booking_interval |
interval |
|
|
fine_interval |
interval |
|
|
fine_amount |
numeric(8,2) |
|
|
max_fine |
numeric(8,2) |
|
booking.resource_type.id
|
target_resource_type |
integer |
NOT NULL
|
booking.resource.id
|
target_resource |
integer |
|
booking.resource.id
|
current_resource |
integer |
|
actor.org_unit.id
|
request_lib |
integer |
NOT NULL
|
actor.org_unit.id
|
pickup_lib |
integer |
|
actor.usr.id
|
capture_staff |
integer |
|
|
email_notify |
boolean |
NOT NULL
DEFAULT false
|
Table booking.reservation Inherits
billable_xact,
Tables referencing this one via Foreign Key Constraints:
Index -
Schema booking
Index -
Schema booking
booking.resource Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
booking.resource_type.id
|
type |
integer |
NOT NULL
|
|
overbook |
boolean |
NOT NULL
DEFAULT false
|
|
barcode |
text |
UNIQUE#1
NOT NULL
|
|
deposit |
boolean |
NOT NULL
DEFAULT false
|
|
deposit_amount |
numeric(8,2) |
NOT NULL
DEFAULT 0.00
|
|
user_fee |
numeric(8,2) |
NOT NULL
DEFAULT 0.00
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema booking
booking.resource_attr Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
booking.resource_type.id
|
resource_type |
integer |
UNIQUE#1
NOT NULL
|
|
required |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema booking
Index -
Schema booking
booking.resource_attr_value Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
booking.resource_attr.id
|
attr |
integer |
UNIQUE#1
NOT NULL
|
|
valid_value |
text |
UNIQUE#1
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema booking
booking.resource_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
elbow_room |
interval |
|
|
fine_interval |
interval |
|
|
fine_amount |
numeric(8,2) |
NOT NULL
|
|
max_fine |
numeric(8,2) |
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
catalog_item |
boolean |
NOT NULL
DEFAULT false
|
|
transferable |
boolean |
NOT NULL
DEFAULT false
|
biblio.record_entry.id
|
record |
bigint |
UNIQUE#1
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema booking
Schema config
The config schema holds static configuration data for the
Evergreen installation.
config.audience_map Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
|
|
value |
text |
|
|
description |
text |
|
SELECT coded_value_map.code
, coded_value_map.value
, coded_value_map.description
FROM config.coded_value_map
WHERE (coded_value_map.ctype = 'audience'::text);
Index -
Schema config
config.barcode_completion Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
actor.org_unit.id
|
org_unit |
integer |
NOT NULL
|
|
prefix |
text |
|
|
suffix |
text |
|
|
length |
integer |
NOT NULL
|
|
padding |
text |
|
|
padding_end |
boolean |
NOT NULL
DEFAULT false
|
|
asset |
boolean |
NOT NULL
DEFAULT true
|
|
actor |
boolean |
NOT NULL
DEFAULT true
|
Index -
Schema config
config.bib_level_map Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
|
|
value |
text |
|
SELECT coded_value_map.code
, coded_value_map.value
FROM config.coded_value_map
WHERE (coded_value_map.ctype = 'bib_level'::text);
Index -
Schema config
This is table is used to set up the relative "quality" of each
MARC source, such as OCLC. Also identifies "transcendant" sources,
i.e., sources of bib records that should display in the OPAC
even if no copies or located URIs are attached. Also indicates if
the source is allowed to have actual copies on its bibs. Volumes
for targeted URIs are unaffected by this setting.
config.bib_source Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
quality |
integer |
|
|
source |
text |
UNIQUE
NOT NULL
|
|
transcendant |
boolean |
NOT NULL
DEFAULT false
|
|
can_have_copies |
boolean |
NOT NULL
DEFAULT true
|
config.bib_source Constraints
Name |
Constraint |
bib_source_quality_check |
CHECK (((quality >= 0) AND (quality <= 100))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.biblio_fingerprint Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
NOT NULL
|
|
xpath |
text |
NOT NULL
|
|
first_word |
boolean |
NOT NULL
DEFAULT false
|
|
format |
text |
NOT NULL
DEFAULT 'marcxml'::text
|
Index -
Schema config
config.billing_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
default_price |
numeric(6,2) |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.circ_limit_group Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.circ_limit_set Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
actor.org_unit.id
|
owning_lib |
integer |
NOT NULL
|
|
items_out |
integer |
NOT NULL
|
|
depth |
integer |
NOT NULL
|
|
global |
boolean |
NOT NULL
DEFAULT false
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Index -
Schema config
config.circ_limit_set_group_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
config.circ_limit_set.id
|
limit_set |
integer |
UNIQUE#1
NOT NULL
|
config.circ_limit_group.id
|
limit_group |
integer |
UNIQUE#1
NOT NULL
|
|
check_only |
boolean |
NOT NULL
DEFAULT false
|
Index -
Schema config
config.circ_matrix_limit_set_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
config.circ_matrix_matchpoint.id
|
matchpoint |
integer |
UNIQUE#1
NOT NULL
|
config.circ_limit_set.id
|
limit_set |
integer |
UNIQUE#1
NOT NULL
|
|
fallthrough |
boolean |
NOT NULL
DEFAULT false
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
Index -
Schema config
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.circ_matrix_weights Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
org_unit |
numeric(6,2) |
NOT NULL
|
|
grp |
numeric(6,2) |
NOT NULL
|
|
circ_modifier |
numeric(6,2) |
NOT NULL
|
|
marc_type |
numeric(6,2) |
NOT NULL
|
|
marc_form |
numeric(6,2) |
NOT NULL
|
|
marc_bib_level |
numeric(6,2) |
NOT NULL
|
|
marc_vr_format |
numeric(6,2) |
NOT NULL
|
|
copy_circ_lib |
numeric(6,2) |
NOT NULL
|
|
copy_owning_lib |
numeric(6,2) |
NOT NULL
|
|
user_home_ou |
numeric(6,2) |
NOT NULL
|
|
ref_flag |
numeric(6,2) |
NOT NULL
|
|
juvenile_flag |
numeric(6,2) |
NOT NULL
|
|
is_renewal |
numeric(6,2) |
NOT NULL
|
|
usr_age_lower_bound |
numeric(6,2) |
NOT NULL
|
|
usr_age_upper_bound |
numeric(6,2) |
NOT NULL
|
|
item_age |
numeric(6,2) |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.circ_modifier Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
description |
text |
NOT NULL
|
|
sip2_media_type |
text |
NOT NULL
|
|
magnetic_media |
boolean |
NOT NULL
DEFAULT true
|
|
avg_wait_time |
interval |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.coded_value_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
config.record_attr_definition.name
|
ctype |
text |
NOT NULL
|
|
code |
text |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
description |
text |
|
Index -
Schema config
Copy Statuses
The available copy statuses, and whether a copy in that
status is available for hold request capture. 0 (zero) is
the only special number in this set, meaning that the item
is available for immediate checkout, and is counted as available
in the OPAC.
Statuses with an ID below 100 are not removable, and have special
meaning in the code. Do not change them except to translate the
textual name.
You may add and remove statuses above 100, and these can be used
to remove items from normal circulation without affecting the rest
of the copy's values or its location.
config.copy_status Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
holdable |
boolean |
NOT NULL
DEFAULT false
|
|
opac_visible |
boolean |
NOT NULL
DEFAULT false
|
|
copy_active |
boolean |
NOT NULL
DEFAULT false
|
|
restrict_copy_delete |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.db_patch_dependencies Structure
F-Key |
Name |
Type |
Description |
|
db_patch |
text |
PRIMARY KEY
|
|
supersedes |
text[] |
|
|
deprecates |
text[] |
|
Index -
Schema config
config.global_flag Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
value |
text |
|
|
enabled |
boolean |
NOT NULL
DEFAULT false
|
|
label |
text |
NOT NULL
|
Table config.global_flag Inherits
internal_flag,
Index -
Schema config
config.hard_due_date Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
ceiling_date |
timestamp with time zone |
NOT NULL
|
|
forceto |
boolean |
NOT NULL
|
|
owner |
integer |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.hard_due_date_values Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
config.hard_due_date.id
|
hard_due_date |
integer |
NOT NULL
|
|
ceiling_date |
timestamp with time zone |
NOT NULL
|
|
active_date |
timestamp with time zone |
NOT NULL
|
Index -
Schema config
Index -
Schema config
config.hold_matrix_weights Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
user_home_ou |
numeric(6,2) |
NOT NULL
|
|
request_ou |
numeric(6,2) |
NOT NULL
|
|
pickup_ou |
numeric(6,2) |
NOT NULL
|
|
item_owning_ou |
numeric(6,2) |
NOT NULL
|
|
item_circ_ou |
numeric(6,2) |
NOT NULL
|
|
usr_grp |
numeric(6,2) |
NOT NULL
|
|
requestor_grp |
numeric(6,2) |
NOT NULL
|
|
circ_modifier |
numeric(6,2) |
NOT NULL
|
|
marc_type |
numeric(6,2) |
NOT NULL
|
|
marc_form |
numeric(6,2) |
NOT NULL
|
|
marc_bib_level |
numeric(6,2) |
NOT NULL
|
|
marc_vr_format |
numeric(6,2) |
NOT NULL
|
|
juvenile_flag |
numeric(6,2) |
NOT NULL
|
|
ref_flag |
numeric(6,2) |
NOT NULL
|
|
item_age |
numeric(6,2) |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.i18n_core Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
fq_field |
text |
NOT NULL
|
|
identity_value |
text |
NOT NULL
|
config.i18n_locale.code
|
translation |
text |
NOT NULL
|
|
string |
text |
NOT NULL
|
Index -
Schema config
config.i18n_locale Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
marc_code |
text |
NOT NULL
|
|
name |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Types of valid patron identification.
Each patron must display at least one valid form of identification
in order to get a library card. This table lists those forms.
config.identification_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.idl_field_doc Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
fm_class |
text |
NOT NULL
|
|
field |
text |
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
NOT NULL
|
|
string |
text |
NOT NULL
|
Index -
Schema config
config.index_normalizer Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
|
func |
text |
NOT NULL
|
|
param_count |
integer |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.internal_flag Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
value |
text |
|
|
enabled |
boolean |
NOT NULL
DEFAULT false
|
Index -
Schema config
config.item_form_map Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
|
|
value |
text |
|
SELECT coded_value_map.code
, coded_value_map.value
FROM config.coded_value_map
WHERE (coded_value_map.ctype = 'item_form'::text);
Index -
Schema config
config.item_type_map Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
|
|
value |
text |
|
SELECT coded_value_map.code
, coded_value_map.value
FROM config.coded_value_map
WHERE (coded_value_map.ctype = 'item_type'::text);
Index -
Schema config
config.language_map Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
|
|
value |
text |
|
SELECT coded_value_map.code
, coded_value_map.value
FROM config.coded_value_map
WHERE (coded_value_map.ctype = 'item_lang'::text);
Index -
Schema config
config.lit_form_map Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
|
|
value |
text |
|
|
description |
text |
|
SELECT coded_value_map.code
, coded_value_map.value
, coded_value_map.description
FROM config.coded_value_map
WHERE (coded_value_map.ctype = 'lit_form'::text);
Index -
Schema config
config.marc21_ff_pos_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
fixed_field |
text |
NOT NULL
|
|
tag |
text |
NOT NULL
|
|
rec_type |
text |
NOT NULL
|
|
start_pos |
integer |
NOT NULL
|
|
length |
integer |
NOT NULL
|
|
default_val |
text |
NOT NULL
DEFAULT ' '::text
|
Index -
Schema config
config.marc21_physical_characteristic_subfield_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
config.marc21_physical_characteristic_type_map.ptype_key
|
ptype_key |
text |
NOT NULL
|
|
subfield |
text |
NOT NULL
|
|
start_pos |
integer |
NOT NULL
|
|
length |
integer |
NOT NULL
|
|
label |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.marc21_physical_characteristic_type_map Structure
F-Key |
Name |
Type |
Description |
|
ptype_key |
text |
PRIMARY KEY
|
|
label |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Index -
Schema config
config.marc21_rec_type_map Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
type_val |
text |
NOT NULL
|
|
blvl_val |
text |
NOT NULL
|
Index -
Schema config
config.metabib_class Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
label |
text |
UNIQUE
NOT NULL
|
|
buoyant |
boolean |
NOT NULL
DEFAULT false
|
|
restrict |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
XPath used for record indexing ingest
This table contains the XPath used to chop up MODS into its
indexable parts. Each XPath entry is named and assigned to
a "class" of either title, subject, author, keyword, series
or identifier.
config.metabib_field Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
config.metabib_class.name
|
field_class |
text |
NOT NULL
|
|
name |
text |
NOT NULL
|
|
label |
text |
NOT NULL
|
|
xpath |
text |
NOT NULL
|
|
weight |
integer |
NOT NULL
DEFAULT 1
|
config.xml_transform.name
|
format |
text |
NOT NULL
DEFAULT 'mods33'::text
|
|
search_field |
boolean |
NOT NULL
DEFAULT true
|
|
facet_field |
boolean |
NOT NULL
DEFAULT false
|
|
browse_field |
boolean |
NOT NULL
DEFAULT true
|
|
browse_xpath |
text |
|
|
facet_xpath |
text |
|
|
restrict |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Index -
Schema config
Index -
Schema config
Patron Network Access level
This will be used to inform the in-library firewall of how much
internet access the using patron should be allowed.
config.net_access_level Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Types of valid non-cataloged items.
config.non_cataloged_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
owning_lib |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
circ_duration |
interval |
NOT NULL
DEFAULT '14 days'::interval
|
|
in_house |
boolean |
NOT NULL
DEFAULT false
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.org_unit_setting_type Constraints
Name |
Constraint |
coust_no_empty_link |
CHECK ((((datatype = 'link'::text) AND (fm_class IS NOT NULL)) OR ((datatype <> 'link'::text) AND (fm_class IS NULL)))) |
coust_valid_datatype |
CHECK ((datatype = ANY (ARRAY['bool'::text, 'integer'::text, 'float'::text, 'currency'::text, 'interval'::text, 'date'::text, 'string'::text, 'object'::text, 'array'::text, 'link'::text]))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Org Unit setting Logs
This table contains the most recent changes to each setting
in actor.org_unit_setting, allowing for mistakes to be undone.
This is NOT meant to be an auditor, but rather an undo/redo.
config.org_unit_setting_type_log Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
date_applied |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
actor.org_unit.id
|
org |
integer |
|
|
original_value |
text |
|
|
new_value |
text |
|
config.org_unit_setting_type.name
|
field_name |
text |
|
Index -
Schema config
config.record_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
label |
text |
NOT NULL
|
|
description |
text |
|
|
filter |
boolean |
NOT NULL
DEFAULT true
|
|
sorter |
boolean |
NOT NULL
DEFAULT false
|
|
tag |
text |
|
|
sf_list |
text |
|
|
joiner |
text |
|
|
xpath |
text |
|
config.xml_transform.name
|
format |
text |
|
|
start_pos |
integer |
|
|
string_len |
integer |
|
|
fixed_field |
text |
|
config.marc21_physical_characteristic_subfield_map.id
|
phys_char_sf |
integer |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Index -
Schema config
config.remote_account Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
label |
text |
NOT NULL
|
|
host |
text |
NOT NULL
|
|
username |
text |
|
|
password |
text |
|
|
account |
text |
|
|
path |
text |
|
actor.org_unit.id
|
owner |
integer |
NOT NULL
|
|
last_activity |
timestamp with time zone |
|
Index -
Schema config
Hold Item Age Protection rules
A hold request can only capture new(ish) items when they are
within a particular proximity of the pickup_lib of the request.
The proximity ('prox' column) is calculated by counting
the number of tree edges between the pickup_lib and either the
owning_lib or circ_lib of the copy that could fulfill the hold,
as determined by the distance_is_from_owner value of the hold matrix
rule controlling the hold request.
config.rule_age_hold_protect Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
age |
interval |
NOT NULL
|
|
prox |
integer |
NOT NULL
|
config.rule_age_hold_protect Constraints
Name |
Constraint |
rule_age_hold_protect_name_check |
CHECK ((name ~ '^\w+$'::text)) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Circulation Duration rules
Each circulation is given a duration based on one of these rules.
config.rule_circ_duration Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
extended |
interval |
NOT NULL
|
|
normal |
interval |
NOT NULL
|
|
shrt |
interval |
NOT NULL
|
|
max_renewals |
integer |
NOT NULL
|
config.rule_circ_duration Constraints
Name |
Constraint |
rule_circ_duration_name_check |
CHECK ((name ~ '^\w+$'::text)) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Circulation Max Fine rules
Each circulation is given a maximum fine based on one of
these rules.
config.rule_max_fine Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
is_percent |
boolean |
NOT NULL
DEFAULT false
|
config.rule_max_fine Constraints
Name |
Constraint |
rule_max_fine_name_check |
CHECK ((name ~ '^\w+$'::text)) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Circulation Recurring Fine rules
Each circulation is given a recurring fine amount based on one of
these rules. Note that it is recommended to run the fine generator
(from cron) at least as frequently as the lowest recurrence interval
used by your circulation rules so that accrued fines will be up
to date.
config.rule_recurring_fine Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
high |
numeric(6,2) |
NOT NULL
|
|
normal |
numeric(6,2) |
NOT NULL
|
|
low |
numeric(6,2) |
NOT NULL
|
|
recurrence_interval |
interval |
NOT NULL
DEFAULT '1 day'::interval
|
|
grace_period |
interval |
NOT NULL
DEFAULT '1 day'::interval
|
config.rule_recurring_fine Constraints
Name |
Constraint |
rule_recurring_fine_name_check |
CHECK ((name ~ '^\w+$'::text)) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.settings_group Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
label |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.sms_carrier Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
region |
text |
|
|
name |
text |
|
|
email_gateway |
text |
|
|
active |
boolean |
DEFAULT true
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Patron Standings
This table contains the values that can be applied to a patron
by a staff member. These values should not be changed, other
than for translation, as the ID column is currently a "magic
number" in the source. :(
config.standing Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
value |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.standing_penalty Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
|
label |
text |
NOT NULL
|
|
block_list |
text |
|
|
staff_alert |
boolean |
NOT NULL
DEFAULT false
|
|
org_depth |
integer |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.upgrade_log Structure
F-Key |
Name |
Type |
Description |
|
version |
text |
PRIMARY KEY
|
|
install_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
applied_to |
text |
|
Index -
Schema config
config.usr_activity_type Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
ewho |
text |
|
|
ewhat |
text |
|
|
ehow |
text |
|
|
label |
text |
NOT NULL
|
|
egroup |
config.usr_activity_group |
NOT NULL
|
|
enabled |
boolean |
NOT NULL
DEFAULT true
|
|
transient |
boolean |
NOT NULL
DEFAULT false
|
config.usr_activity_type Constraints
Name |
Constraint |
one_of_wwh |
CHECK ((COALESCE(ewho, ewhat, ehow) IS NOT NULL)) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.usr_setting_type Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
opac_visible |
boolean |
NOT NULL
DEFAULT false
|
|
label |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
config.settings_group.name
|
grp |
text |
|
|
datatype |
text |
NOT NULL
DEFAULT 'string'::text
|
|
fm_class |
text |
|
config.usr_setting_type Constraints
Name |
Constraint |
coust_no_empty_link |
CHECK ((((datatype = 'link'::text) AND (fm_class IS NOT NULL)) OR ((datatype <> 'link'::text) AND (fm_class IS NULL)))) |
coust_valid_datatype |
CHECK ((datatype = ANY (ARRAY['bool'::text, 'integer'::text, 'float'::text, 'currency'::text, 'interval'::text, 'date'::text, 'string'::text, 'object'::text, 'array'::text, 'link'::text]))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.videorecording_format_map Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
|
|
value |
text |
|
SELECT coded_value_map.code
, coded_value_map.value
FROM config.coded_value_map
WHERE (coded_value_map.ctype = 'vr_format'::text);
Index -
Schema config
Index -
Schema config
config.xml_transform Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
namespace_uri |
text |
NOT NULL
|
|
prefix |
text |
NOT NULL
|
|
xslt |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
config.z3950_attr Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
config.z3950_source.name
|
source |
text |
UNIQUE#1
NOT NULL
|
|
name |
text |
NOT NULL
|
|
label |
text |
NOT NULL
|
|
code |
integer |
UNIQUE#1
NOT NULL
|
|
format |
integer |
UNIQUE#1
NOT NULL
|
|
truncation |
integer |
NOT NULL
|
Index -
Schema config
Z39.50 Sources
Each row in this table represents a database searchable via Z39.50.
config.z3950_source Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
label |
text |
UNIQUE
NOT NULL
|
|
host |
text |
NOT NULL
|
|
port |
integer |
NOT NULL
|
|
db |
text |
NOT NULL
|
|
record_format |
text |
NOT NULL
DEFAULT 'FI'::text
Z39.50 element set.
|
|
transmission_format |
text |
NOT NULL
DEFAULT 'usmarc'::text
Z39.50 preferred record syntax..
|
|
auth |
boolean |
NOT NULL
DEFAULT true
|
permission.perm_list.id
|
use_perm |
integer |
If set, this permission is required for the source to be listed in the staff
client Z39.50 interface. Similar to permission.grp_tree.application_perm.
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema config
Returns: integer
Language: PLPGSQL
BEGIN
RETURN config.interval_to_seconds( interval_string::INTERVAL );
END;
Returns: integer
Language: PLPGSQL
BEGIN
RETURN EXTRACT( EPOCH FROM interval_val );
END;
Returns: integer
Language: PLPGSQL
DECLARE
temp_value config.hard_due_date_values%ROWTYPE;
updated INT := 0;
BEGIN
FOR temp_value IN
SELECT DISTINCT ON (hard_due_date) *
FROM config.hard_due_date_values
WHERE active_date <= NOW() -- We've passed (or are at) the rollover time
ORDER BY hard_due_date, active_date DESC -- Latest (nearest to us) active time
LOOP
UPDATE config.hard_due_date
SET ceiling_date = temp_value.ceiling_date
WHERE id = temp_value.hard_due_date
AND ceiling_date <> temp_value.ceiling_date; -- Time is equal if we've already updated the chdd
IF FOUND THEN
updated := updated + 1;
END IF;
END LOOP;
RETURN updated;
END;
Schema container
container.biblio_record_entry_bucket Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
container.biblio_record_entry_bucket_type.code
|
btype |
text |
UNIQUE#1
NOT NULL
DEFAULT 'misc'::text
|
|
description |
text |
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
Index -
Schema container
Index -
Schema container
container.biblio_record_entry_bucket_type Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
label |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
container.call_number_bucket Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
container.call_number_bucket_type.code
|
btype |
text |
UNIQUE#1
NOT NULL
DEFAULT 'misc'::text
|
|
description |
text |
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
container.call_number_bucket_item Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
container.call_number_bucket.id
|
bucket |
integer |
NOT NULL
|
asset.call_number.id
|
target_call_number |
integer |
NOT NULL
|
|
pos |
integer |
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
Index -
Schema container
container.call_number_bucket_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
container.call_number_bucket.id
|
bucket |
integer |
NOT NULL
|
|
note |
text |
NOT NULL
|
Index -
Schema container
container.call_number_bucket_type Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
label |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
container.copy_bucket Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
container.copy_bucket_type.code
|
btype |
text |
UNIQUE#1
NOT NULL
DEFAULT 'misc'::text
|
|
description |
text |
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
container.copy_bucket_item Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
container.copy_bucket.id
|
bucket |
integer |
NOT NULL
|
asset.copy.id
|
target_copy |
integer |
NOT NULL
|
|
pos |
integer |
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
copy_bucket_item_bucket_idx bucket
Index -
Schema container
container.copy_bucket_item_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
container.copy_bucket_item.id
|
item |
integer |
NOT NULL
|
|
note |
text |
NOT NULL
|
Index -
Schema container
container.copy_bucket_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
container.copy_bucket.id
|
bucket |
integer |
NOT NULL
|
|
note |
text |
NOT NULL
|
Index -
Schema container
container.copy_bucket_type Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
label |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
container.user_bucket Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
container.user_bucket_type.code
|
btype |
text |
UNIQUE#1
NOT NULL
DEFAULT 'misc'::text
|
|
description |
text |
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
container.user_bucket_item Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
container.user_bucket.id
|
bucket |
integer |
NOT NULL
|
actor.usr.id
|
target_user |
integer |
NOT NULL
|
|
pos |
integer |
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
Tables referencing this one via Foreign Key Constraints:
user_bucket_item_target_user_idx target_user
Index -
Schema container
container.user_bucket_item_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
container.user_bucket_item.id
|
item |
integer |
NOT NULL
|
|
note |
text |
NOT NULL
|
Index -
Schema container
container.user_bucket_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
container.user_bucket.id
|
bucket |
integer |
NOT NULL
|
|
note |
text |
NOT NULL
|
Index -
Schema container
container.user_bucket_type Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
label |
text |
UNIQUE
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema container
Returns: void
Language: PLPGSQL
Delete expired circulation bucket items for all users that have
a setting for patron.max_reading_list_interval.
--
-- Delete expired circulation bucket items for all users that have
-- a setting for patron.max_reading_list_interval.
--
DECLARE
today TIMESTAMP WITH TIME ZONE;
threshold TIMESTAMP WITH TIME ZONE;
usr_setting RECORD;
BEGIN
SELECT date_trunc( 'day', now() ) INTO today;
--
FOR usr_setting in
SELECT
usr,
value
FROM
actor.usr_setting
WHERE
name = 'patron.max_reading_list_interval'
LOOP
--
-- Make sure the setting is a valid interval
--
BEGIN
threshold := today - CAST( translate( usr_setting.value, '"', '' ) AS INTERVAL );
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Invalid setting patron.max_reading_list_interval for user %: ''%''',
usr_setting.usr, usr_setting.value;
CONTINUE;
END;
--
--RAISE NOTICE 'User % threshold %', usr_setting.usr, threshold;
--
DELETE FROM container.copy_bucket_item
WHERE
bucket IN
(
SELECT
id
FROM
container.copy_bucket
WHERE
owner = usr_setting.usr
AND btype = 'circ_history'
)
AND create_time < threshold;
END LOOP;
--
END;
Returns: void
Language: PLPGSQL
Delete old circulation bucket items for a specified user.
"Old" means older than the interval specified by a
user-level setting, if it is so specified.
--
-- Delete old circulation bucket items for a specified user.
-- "Old" means older than the interval specified by a
-- user-level setting, if it is so specified.
--
DECLARE
threshold TIMESTAMP WITH TIME ZONE;
BEGIN
-- Sanity check
IF ac_usr IS NULL THEN
RETURN;
END IF;
-- Determine the threshold date that defines "old". Subtract the
-- interval from the system date, then truncate to midnight.
SELECT
date_trunc(
'day',
now() - CAST( translate( value, '"', '' ) AS INTERVAL )
)
INTO
threshold
FROM
actor.usr_setting
WHERE
usr = ac_usr
AND name = 'patron.max_reading_list_interval';
--
IF threshold is null THEN
-- No interval defined; don't delete anything
-- RAISE NOTICE 'No interval defined for user %', ac_usr;
return;
END IF;
--
-- RAISE NOTICE 'Date threshold: %', threshold;
--
-- Threshold found; do the delete
delete from container.copy_bucket_item
where
bucket in
(
select
id
from
container.copy_bucket
where
owner = ac_usr
and btype = 'circ_history'
)
and create_time < threshold;
--
RETURN;
END;
Schema evergreen
Returns: anyarray
Language: INTERNAL
aggregate_dummy
Returns: trigger
Language: PLPGSQL
DECLARE
fld TEXT;
cnt INT;
BEGIN
fld := TG_ARGV[1];
EXECUTE 'SELECT COUNT(*) FROM '|| TG_TABLE_SCHEMA ||'.'|| TG_TABLE_NAME ||' WHERE '|| fld ||' && ($1).'|| fld INTO cnt USING NEW;
IF cnt > 0 THEN
RAISE EXCEPTION 'Cannot insert duplicate array into field % of table %', fld, TG_TABLE_SCHEMA ||'.'|| TG_TABLE_NAME;
END IF;
RETURN NEW;
END;
Returns: anyarray
Language: SQL
SELECT ARRAY_ACCUM(x.e) FROM UNNEST( $1 ) x(e) WHERE x.e <> $2;
Returns: void
Language: PLPGSQL
BEGIN
EXECUTE 'ALTER DATABASE ' || quote_ident(current_database()) || ' SET ' || quote_ident(setting_name) || ' = ' || array_to_string(settings, ',');
END;
Returns: text
Language: SQL
SELECT COALESCE(value,$1)
FROM config.coded_value_map
WHERE ctype = $2 AND code = $1;
Returns: text
Language: SQL
SELECT extract_marc_field($1,$2,$3,'');
Returns: text
Language: PLPGSQL
DECLARE
query TEXT;
output TEXT;
BEGIN
query := $q$
SELECT regexp_replace(
oils_xpath_string(
$q$ || quote_literal($3) || $q$,
marc,
' '
),
$q$ || quote_literal($4) || $q$,
'',
'g')
FROM $q$ || $1 || $q$
WHERE id = $q$ || $2;
EXECUTE query INTO output;
-- RAISE NOTICE 'query: %, output; %', query, output;
RETURN output;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
NEW.value := force_unicode_normal_form(NEW.value,'NFC');
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
copy_id BIGINT;
BEGIN
EXECUTE 'SELECT ($1).' || quote_ident(TG_ARGV[0]) INTO copy_id USING NEW;
PERFORM * FROM asset.copy WHERE id = copy_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'Key (%.%=%) does not exist in asset.copy', TG_TABLE_SCHEMA, TG_TABLE_NAME, copy_id;
END IF;
RETURN NULL;
END;
Returns: text
Language: PLPERLU
use Unicode::Normalize 'normalize';
return normalize($_[1],$_[0]); # reverse the params
Returns: text
Language: PLPERLU
my $string = shift;
my %map;
my $default = $string;
$_ = shift;
while (/^\s*?(.*?)\s*?=>\s*?(\S+)\s*/) {
if ($1 eq '') {
$default = $2;
} else {
$map{$2} = [split(/\s*,\s*/, $1)];
}
$_ = $';
}
for my $key ( keys %map ) {
return $key if (grep { $_ eq $string } @{ $map{$key} });
}
return $default;
Returns: SET OF barcode_set
Language: PLPGSQL
Given user input, find an appropriate barcode in the proper class.
Will add prefix/suffix information to do so, and return all results.
DECLARE
cur_barcode TEXT;
barcode_len INT;
completion_len INT;
asset_barcodes TEXT[];
actor_barcodes TEXT[];
do_asset BOOL = false;
do_serial BOOL = false;
do_booking BOOL = false;
do_actor BOOL = false;
completion_set config.barcode_completion%ROWTYPE;
BEGIN
IF position('asset' in type) > 0 THEN
do_asset = true;
END IF;
IF position('serial' in type) > 0 THEN
do_serial = true;
END IF;
IF position('booking' in type) > 0 THEN
do_booking = true;
END IF;
IF do_asset OR do_serial OR do_booking THEN
asset_barcodes = asset_barcodes || in_barcode;
END IF;
IF position('actor' in type) > 0 THEN
do_actor = true;
actor_barcodes = actor_barcodes || in_barcode;
END IF;
barcode_len := length(in_barcode);
FOR completion_set IN
SELECT * FROM config.barcode_completion
WHERE active
AND org_unit IN (SELECT aou.id FROM actor.org_unit_ancestors(select_ou) aou)
LOOP
IF completion_set.prefix IS NULL THEN
completion_set.prefix := '';
END IF;
IF completion_set.suffix IS NULL THEN
completion_set.suffix := '';
END IF;
IF completion_set.length = 0 OR completion_set.padding IS NULL OR length(completion_set.padding) = 0 THEN
cur_barcode = completion_set.prefix || in_barcode || completion_set.suffix;
ELSE
completion_len = completion_set.length - length(completion_set.prefix) - length(completion_set.suffix);
IF completion_len >= barcode_len THEN
IF completion_set.padding_end THEN
cur_barcode = rpad(in_barcode, completion_len, completion_set.padding);
ELSE
cur_barcode = lpad(in_barcode, completion_len, completion_set.padding);
END IF;
cur_barcode = completion_set.prefix || cur_barcode || completion_set.suffix;
END IF;
END IF;
IF completion_set.actor THEN
actor_barcodes = actor_barcodes || cur_barcode;
END IF;
IF completion_set.asset THEN
asset_barcodes = asset_barcodes || cur_barcode;
END IF;
END LOOP;
IF do_asset AND do_serial THEN
RETURN QUERY SELECT 'asset'::TEXT, id, barcode FROM ONLY asset.copy WHERE barcode = ANY(asset_barcodes) AND deleted = false;
RETURN QUERY SELECT 'serial'::TEXT, id, barcode FROM serial.unit WHERE barcode = ANY(asset_barcodes) AND deleted = false;
ELSIF do_asset THEN
RETURN QUERY SELECT 'asset'::TEXT, id, barcode FROM asset.copy WHERE barcode = ANY(asset_barcodes) AND deleted = false;
ELSIF do_serial THEN
RETURN QUERY SELECT 'serial'::TEXT, id, barcode FROM serial.unit WHERE barcode = ANY(asset_barcodes) AND deleted = false;
END IF;
IF do_booking THEN
RETURN QUERY SELECT 'booking'::TEXT, id::BIGINT, barcode FROM booking.resource WHERE barcode = ANY(asset_barcodes);
END IF;
IF do_actor THEN
RETURN QUERY SELECT 'actor'::TEXT, c.usr::BIGINT, c.barcode FROM actor.card c JOIN actor.usr u ON c.usr = u.id WHERE c.barcode = ANY(actor_barcodes) AND c.active AND NOT u.deleted ORDER BY usr;
END IF;
RETURN;
END;
Returns: record
Language: PLPGSQL
DECLARE
eg_locale TEXT;
BEGIN
eg_locale := LOWER(SUBSTRING(locale FROM 1 FOR 2)) || '-' || UPPER(SUBSTRING(locale FROM 4 FOR 2));
SELECT i18nc.string INTO name
FROM config.i18n_locale i18nl
INNER JOIN config.i18n_core i18nc ON i18nl.code = i18nc.translation
WHERE i18nc.identity_value = eg_locale
AND code = eg_locale
AND i18nc.fq_field = 'i18n_l.name';
IF name IS NULL THEN
SELECT i18nl.name INTO name
FROM config.i18n_locale i18nl
WHERE code = eg_locale;
END IF;
SELECT i18nc.string INTO description
FROM config.i18n_locale i18nl
INNER JOIN config.i18n_core i18nc ON i18nl.code = i18nc.translation
WHERE i18nc.identity_value = eg_locale
AND code = eg_locale
AND i18nc.fq_field = 'i18n_l.description';
IF description IS NULL THEN
SELECT i18nl.description INTO description
FROM config.i18n_locale i18nl
WHERE code = eg_locale;
END IF;
END;
Returns: boolean
Language: PLPERLU
use JSON::XS;
my $json = shift();
eval { JSON::XS->new->allow_nonref->decode( $json ) };
return $@ ? 0 : 1;
Returns: trigger
Language: PLPGSQL
BEGIN
-- Only keeps the most recent five settings changes.
DELETE FROM config.org_unit_setting_type_log WHERE field_name = NEW.field_name AND date_applied NOT IN
(SELECT date_applied FROM config.org_unit_setting_type_log WHERE field_name = NEW.field_name ORDER BY date_applied DESC LIMIT 4);
IF (TG_OP = 'UPDATE') THEN
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
RETURN NEW;
END IF;
RETURN NULL;
END;
Returns: SET OF record
Language: SQL
SELECT acn.id, aou.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
INNER JOIN actor.org_unit_ancestors( COALESCE($3, $2) ) aou ON (acn.owning_lib = aou.id)
WHERE acn.record = $1
AND acn.deleted IS FALSE
AND auri.active IS TRUE
UNION
SELECT acn.id, aou.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
INNER JOIN actor.org_unit_ancestors( $2 ) aou ON (acn.owning_lib = aou.id)
WHERE acn.record = $1
AND acn.deleted IS FALSE
AND auri.active IS TRUE;
Returns: text
Language: PLPERLU
return lc(shift);
Returns: text
Language: PLPERLU
my $string = shift;
my $pad = shift;
my $len = shift;
my $find = $len - 1;
while ($string =~ /(?:^|\D)(\d{1,$find})(?:$|\D)/) {
my $padded = $1;
$padded = $pad x ($len - length($padded)) . $padded;
$string =~ s/$1/$padded/sg;
}
return $string;
Returns: trigger
Language: PLPERLU
use strict;
use MARC::Record;
use MARC::File::XML (BinaryEncoding => 'UTF-8');
use MARC::Charset;
use Encode;
use Unicode::Normalize;
MARC::Charset->assume_unicode(1);
my $schema = $_TD->{table_schema};
my $marc = MARC::Record->new_from_xml($_TD->{new}{marc});
my @old901s = $marc->field('901');
$marc->delete_fields(@old901s);
if ($schema eq 'biblio') {
my $tcn_value = $_TD->{new}{tcn_value};
# Set TCN value to record ID?
my $id_as_tcn = spi_exec_query("
SELECT enabled
FROM config.global_flag
WHERE name = 'cat.bib.use_id_for_tcn'
");
if (($id_as_tcn->{processed}) && $id_as_tcn->{rows}[0]->{enabled} eq 't') {
$tcn_value = $_TD->{new}{id};
}
my $new_901 = MARC::Field->new("901", " ", " ",
"a" => $tcn_value,
"b" => $_TD->{new}{tcn_source},
"c" => $_TD->{new}{id},
"t" => $schema
);
if ($_TD->{new}{owner}) {
$new_901->add_subfields("o" => $_TD->{new}{owner});
}
if ($_TD->{new}{share_depth}) {
$new_901->add_subfields("d" => $_TD->{new}{share_depth});
}
$marc->append_fields($new_901);
} elsif ($schema eq 'authority') {
my $new_901 = MARC::Field->new("901", " ", " ",
"c" => $_TD->{new}{id},
"t" => $schema,
);
$marc->append_fields($new_901);
} elsif ($schema eq 'serial') {
my $new_901 = MARC::Field->new("901", " ", " ",
"c" => $_TD->{new}{id},
"t" => $schema,
"o" => $_TD->{new}{owning_lib},
);
if ($_TD->{new}{record}) {
$new_901->add_subfields("r" => $_TD->{new}{record});
}
$marc->append_fields($new_901);
} else {
my $new_901 = MARC::Field->new("901", " ", " ",
"c" => $_TD->{new}{id},
"t" => $schema,
);
$marc->append_fields($new_901);
}
my $xml = $marc->as_xml_record();
$xml =~ s/\n//sgo;
$xml =~ s/^<\?xml.+\?\s*>//go;
$xml =~ s/>\s+</></go;
$xml =~ s/\p{Cc}//go;
# Embed a version of OpenILS::Application::AppUtils->entityize()
# to avoid having to set PERL5LIB for PostgreSQL as well
# If we are going to convert non-ASCII characters to XML entities,
# we had better be dealing with a UTF8 string to begin with
$xml = decode_utf8($xml);
$xml = NFC($xml);
# Convert raw ampersands to entities
$xml =~ s/&(?!\S+;)/&/gso;
# Convert Unicode characters to entities
$xml =~ s/([\x{0080}-\x{fffd}])/sprintf('&#x%X;',ord($1))/sgoe;
$xml =~ s/[\x00-\x1f]//go;
$_TD->{new}{marc} = $xml;
return "MODIFY";
Returns: trigger
Language: PLPERLU
use strict;
use MARC::Record;
use MARC::File::XML (BinaryEncoding => 'UTF-8');
use MARC::Charset;
use Encode;
use Unicode::Normalize;
MARC::Charset->assume_unicode(1);
my $record = MARC::Record->new_from_xml($_TD->{new}{marc});
my $schema = $_TD->{table_schema};
my $rec_id = $_TD->{new}{id};
# Short-circuit if maintaining control numbers per MARC21 spec is not enabled
my $enable = spi_exec_query("SELECT enabled FROM config.global_flag WHERE name = 'cat.maintain_control_numbers'");
if (!($enable->{processed}) or $enable->{rows}[0]->{enabled} eq 'f') {
return;
}
# Get the control number identifier from an OU setting based on $_TD->{new}{owner}
my $ou_cni = 'EVRGRN';
my $owner;
if ($schema eq 'serial') {
$owner = $_TD->{new}{owning_lib};
} else {
# are.owner and bre.owner can be null, so fall back to the consortial setting
$owner = $_TD->{new}{owner} || 1;
}
my $ous_rv = spi_exec_query("SELECT value FROM actor.org_unit_ancestor_setting('cat.marc_control_number_identifier', $owner)");
if ($ous_rv->{processed}) {
$ou_cni = $ous_rv->{rows}[0]->{value};
$ou_cni =~ s/"//g; # Stupid VIM syntax highlighting"
} else {
# Fall back to the shortname of the OU if there was no OU setting
$ous_rv = spi_exec_query("SELECT shortname FROM actor.org_unit WHERE id = $owner");
if ($ous_rv->{processed}) {
$ou_cni = $ous_rv->{rows}[0]->{shortname};
}
}
my ($create, $munge) = (0, 0);
my @scns = $record->field('035');
foreach my $id_field ('001', '003') {
my $spec_value;
my @controls = $record->field($id_field);
if ($id_field eq '001') {
$spec_value = $rec_id;
} else {
$spec_value = $ou_cni;
}
# Create the 001/003 if none exist
if (scalar(@controls) == 1) {
# Only one field; check to see if we need to munge it
unless (grep $_->data() eq $spec_value, @controls) {
$munge = 1;
}
} else {
# Delete the other fields, as with more than 1 001/003 we do not know which 003/001 to match
foreach my $control (@controls) {
$record->delete_field($control);
}
$record->insert_fields_ordered(MARC::Field->new($id_field, $spec_value));
$create = 1;
}
}
my $cn = $record->field('001')->data();
# Special handling of OCLC numbers, often found in records that lack 003
if ($cn =~ /^oc[nm]/) {
$cn =~ s/^oc[nm]0*(\d+)/$1/;
$record->field('003')->data('OCoLC');
$create = 0;
}
# Now, if we need to munge the 001, we will first push the existing 001/003
# into the 035; but if the record did not have one (and one only) 001 and 003
# to begin with, skip this process
if ($munge and not $create) {
my $scn = "(" . $record->field('003')->data() . ")" . $cn;
# Do not create duplicate 035 fields
unless (grep $_->subfield('a') eq $scn, @scns) {
$record->insert_fields_ordered(MARC::Field->new('035', '', '', 'a' => $scn));
}
}
# Set the 001/003 and update the MARC
if ($create or $munge) {
$record->field('001')->data($rec_id);
$record->field('003')->data($ou_cni);
my $xml = $record->as_xml_record();
$xml =~ s/\n//sgo;
$xml =~ s/^<\?xml.+\?\s*>//go;
$xml =~ s/>\s+</></go;
$xml =~ s/\p{Cc}//go;
# Embed a version of OpenILS::Application::AppUtils->entityize()
# to avoid having to set PERL5LIB for PostgreSQL as well
# If we are going to convert non-ASCII characters to XML entities,
# we had better be dealing with a UTF8 string to begin with
$xml = decode_utf8($xml);
$xml = NFC($xml);
# Convert raw ampersands to entities
$xml =~ s/&(?!\S+;)/&/gso;
# Convert Unicode characters to entities
$xml =~ s/([\x{0080}-\x{fffd}])/sprintf('&#x%X;',ord($1))/sgoe;
$xml =~ s/[\x00-\x1f]//go;
$_TD->{new}{marc} = $xml;
return "MODIFY";
}
return;
Returns: trigger
Language: PLPGSQL
BEGIN
PERFORM oils_i18n_update_apply( OLD.code::TEXT, NEW.code::TEXT, TG_ARGV[0]::TEXT );
RETURN NEW;
END;
Returns: text
Language: SQL
SELECT $2;
Returns: text
Language: SQL
SELECT $2;
Returns: trigger
Language: PLPGSQL
BEGIN
PERFORM oils_i18n_update_apply( OLD.id::TEXT, NEW.id::TEXT, TG_ARGV[0]::TEXT );
RETURN NEW;
END;
Returns: void
Language: PLPGSQL
BEGIN
EXECUTE $$
UPDATE config.i18n_core
SET identity_value = $$ || quote_literal(new_ident) || $$
WHERE fq_field LIKE '$$ || hint || $$.%'
AND identity_value = $$ || quote_literal(old_ident) || $$::TEXT;$$;
RETURN;
END;
Returns: text
Language: PLPGSQL
DECLARE
locale TEXT := REGEXP_REPLACE( REGEXP_REPLACE( raw_locale, E'[;, ].+$', '' ), E'_', '-', 'g' );
language TEXT := REGEXP_REPLACE( locale, E'-.+$', '' );
result config.i18n_core%ROWTYPE;
fallback TEXT;
keyfield TEXT := keyclass || '.' || keycol;
BEGIN
-- Try the full locale
SELECT * INTO result
FROM config.i18n_core
WHERE fq_field = keyfield
AND identity_value = keyvalue
AND translation = locale;
-- Try just the language
IF NOT FOUND THEN
SELECT * INTO result
FROM config.i18n_core
WHERE fq_field = keyfield
AND identity_value = keyvalue
AND translation = language;
END IF;
-- Fall back to the string we passed in in the first place
IF NOT FOUND THEN
EXECUTE
'SELECT ' ||
keycol ||
' FROM ' || keytable ||
' WHERE ' || identcol || ' = ' || quote_literal(keyvalue)
INTO fallback;
RETURN fallback;
END IF;
RETURN result.string;
END;
Returns: text
Language: PLPERLU
use JSON::XS;
my $json = shift();
my $txt;
eval { $txt = JSON::XS->new->allow_nonref->decode( $json ) };
return undef if ($@);
return $txt
Returns: bytea
Language: SQL
SELECT CAST(REGEXP_REPLACE(UPPER($1), $$\\$$, $$\\\\$$, 'g') AS BYTEA);
Returns: trigger
Language: PLPGSQL
DECLARE
normalizer RECORD;
value TEXT := '';
BEGIN
value := NEW.value;
IF TG_TABLE_NAME::TEXT ~ 'field_entry$' THEN
FOR normalizer IN
SELECT n.func AS func,
n.param_count AS param_count,
m.params AS params
FROM config.index_normalizer n
JOIN config.metabib_field_index_norm_map m ON (m.norm = n.id)
WHERE field = NEW.field AND m.pos < 0
ORDER BY m.pos LOOP
EXECUTE 'SELECT ' || normalizer.func || '(' ||
quote_literal( value ) ||
CASE
WHEN normalizer.param_count > 0
THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
ELSE ''
END ||
')' INTO value;
END LOOP;
NEW.value := value;
END IF;
IF NEW.index_vector = ''::tsvector THEN
RETURN NEW;
END IF;
IF TG_TABLE_NAME::TEXT ~ 'field_entry$' THEN
FOR normalizer IN
SELECT n.func AS func,
n.param_count AS param_count,
m.params AS params
FROM config.index_normalizer n
JOIN config.metabib_field_index_norm_map m ON (m.norm = n.id)
WHERE field = NEW.field AND m.pos >= 0
ORDER BY m.pos LOOP
EXECUTE 'SELECT ' || normalizer.func || '(' ||
quote_literal( value ) ||
CASE
WHEN normalizer.param_count > 0
THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
ELSE ''
END ||
')' INTO value;
END LOOP;
END IF;
IF TG_TABLE_NAME::TEXT ~ 'browse_entry$' THEN
value := ARRAY_TO_STRING(
evergreen.regexp_split_to_array(value, E'\\W+'), ' '
);
value := public.search_normalize(value);
END IF;
NEW.index_vector = to_tsvector((TG_ARGV[0])::regconfig, value);
RETURN NEW;
END;
Returns: text[]
Language: SQL
SELECT XPATH( $1, $2::XML )::TEXT[];
Returns: text[]
Language: SQL
SELECT XPATH( $1, $2::XML, $3 )::TEXT[];
Returns: text
Language: SQL
SELECT oils_xpath_string( $1, $2, '{}'::TEXT[] );
Returns: text
Language: SQL
SELECT oils_xpath_string( $1, $2, '', $3 );
Returns: text
Language: SQL
SELECT oils_xpath_string( $1, $2, $3, '{}'::TEXT[] );
Returns: text
Language: SQL
SELECT ARRAY_TO_STRING(
oils_xpath(
$1 ||
CASE WHEN $1 ~ $re$/[^/[]*@[^]]+$$re$ OR $1 ~ $re$text\(\)$$re$ THEN '' ELSE '//text()' END,
$2,
$4
),
$3
);
Returns: SET OF record
Language: PLPGSQL
DECLARE
xpath_list TEXT[];
select_list TEXT[];
where_list TEXT[];
q TEXT;
out_record RECORD;
empty_test RECORD;
BEGIN
xpath_list := STRING_TO_ARRAY( xpaths, '|' );
select_list := ARRAY_APPEND( select_list, key || '::INT AS key' );
FOR i IN 1 .. ARRAY_UPPER(xpath_list,1) LOOP
IF xpath_list[i] = 'null()' THEN
select_list := ARRAY_APPEND( select_list, 'NULL::TEXT AS c_' || i );
ELSE
select_list := ARRAY_APPEND(
select_list,
$sel$
unnest(
COALESCE(
NULLIF(
oils_xpath(
$sel$ ||
quote_literal(
CASE
WHEN xpath_list[i] ~ $re$/[^/[]*@[^/]+$$re$ OR xpath_list[i] ~ $re$text\(\)$$re$ THEN xpath_list[i]
ELSE xpath_list[i] || '//text()'
END
) ||
$sel$,
$sel$ || document_field || $sel$
),
'{}'::TEXT[]
),
'{NULL}'::TEXT[]
)
) AS c_$sel$ || i
);
where_list := ARRAY_APPEND(
where_list,
'c_' || i || ' IS NOT NULL'
);
END IF;
END LOOP;
q := $q$
SELECT * FROM (
SELECT $q$ || ARRAY_TO_STRING( select_list, ', ' ) || $q$ FROM $q$ || relation_name || $q$ WHERE ($q$ || criteria || $q$)
)x WHERE $q$ || ARRAY_TO_STRING( where_list, ' OR ' );
-- RAISE NOTICE 'query: %', q;
FOR out_record IN EXECUTE q LOOP
RETURN NEXT out_record;
END LOOP;
RETURN;
END;
Returns: text
Language: PLPERLU
use strict;
use XML::LibXSLT;
use XML::LibXML;
my $doc = shift;
my $xslt = shift;
# The following approach uses the older XML::LibXML 1.69 / XML::LibXSLT 1.68
# methods of parsing XML documents and stylesheets, in the hopes of broader
# compatibility with distributions
my $parser = $_SHARED{'_xslt_process'}{parsers}{xml} || XML::LibXML->new();
# Cache the XML parser, if we do not already have one
$_SHARED{'_xslt_process'}{parsers}{xml} = $parser
unless ($_SHARED{'_xslt_process'}{parsers}{xml});
my $xslt_parser = $_SHARED{'_xslt_process'}{parsers}{xslt} || XML::LibXSLT->new();
# Cache the XSLT processor, if we do not already have one
$_SHARED{'_xslt_process'}{parsers}{xslt} = $xslt_parser
unless ($_SHARED{'_xslt_process'}{parsers}{xslt});
my $stylesheet = $_SHARED{'_xslt_process'}{stylesheets}{$xslt} ||
$xslt_parser->parse_stylesheet( $parser->parse_string($xslt) );
$_SHARED{'_xslt_process'}{stylesheets}{$xslt} = $stylesheet
unless ($_SHARED{'_xslt_process'}{stylesheets}{$xslt});
return $stylesheet->output_string(
$stylesheet->transform(
$parser->parse_string($doc)
)
);
Returns: SET OF org_unit
Language: SQL
SELECT * FROM actor.org_unit WHERE parent_ou IS NULL LIMIT 1;
Returns: trigger
Language: PLPGSQL
DECLARE
original TEXT;
BEGIN
-- Check for which setting is being updated, and log it.
SELECT INTO original value FROM actor.org_unit_setting WHERE name = NEW.name AND org_unit = NEW.org_unit;
INSERT INTO config.org_unit_setting_type_log (org,original_value,new_value,field_name) VALUES (NEW.org_unit, original, NEW.value, NEW.name);
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
original TEXT;
BEGIN
-- Check for which setting is being updated, and log it.
SELECT INTO original value FROM actor.org_unit_setting WHERE name = OLD.name AND org_unit = OLD.org_unit;
INSERT INTO config.org_unit_setting_type_log (org,original_value,new_value,field_name) VALUES (OLD.org_unit, original, 'null', OLD.name);
RETURN OLD;
END;
Returns: integer
Language: SQL
WITH totally_available AS (
SELECT id, 0 AS avail_rank
FROM config.copy_status
WHERE opac_visible IS TRUE
AND copy_active IS TRUE
AND id != 1 -- "Checked out"
), almost_available AS (
SELECT id, 10 AS avail_rank
FROM config.copy_status
WHERE holdable IS TRUE
AND opac_visible IS TRUE
AND copy_active IS FALSE
OR id = 1 -- "Checked out"
)
SELECT COALESCE(
(SELECT avail_rank FROM totally_available WHERE $1 IN (id)),
(SELECT avail_rank FROM almost_available WHERE $1 IN (id)),
100
);
Returns: integer
Language: SQL
WITH search_libs AS (
SELECT id, distance FROM actor.org_unit_descendants_distance($2)
)
SELECT COALESCE(
(SELECT -10000 FROM actor.org_unit
WHERE $1 = $3 AND id = $3 AND $2 IN (
SELECT id FROM actor.org_unit WHERE parent_ou IS NULL
)
),
(SELECT distance FROM search_libs WHERE id = $1),
10000
);
Returns: SET OF record
Language: SQL
SELECT ua.id, ua.name, ua.label_sortkey, MIN(ua.rank) AS rank FROM (
SELECT acn.id, aou.name, acn.label_sortkey,
evergreen.rank_ou(aou.id, $2, $6), evergreen.rank_cp_status(acp.status),
RANK() OVER w
FROM asset.call_number acn
JOIN asset.copy acp ON (acn.id = acp.call_number)
JOIN actor.org_unit_descendants( $2, COALESCE(
$3, (
SELECT depth
FROM actor.org_unit_type aout
INNER JOIN actor.org_unit ou ON ou_type = aout.id
WHERE ou.id = $2
), $6)
) AS aou ON (acp.circ_lib = aou.id)
WHERE acn.record = $1
AND acn.deleted IS FALSE
AND acp.deleted IS FALSE
GROUP BY acn.id, acp.status, aou.name, acn.label_sortkey, aou.id
WINDOW w AS (
ORDER BY evergreen.rank_ou(aou.id, $2, $6), evergreen.rank_cp_status(acp.status)
)
) AS ua
GROUP BY ua.id, ua.name, ua.label_sortkey
ORDER BY rank, ua.name, ua.label_sortkey
LIMIT ($4 -> 'acn')::INT
OFFSET ($5 -> 'acn')::INT;
Returns: text[]
Language: PLPERLU
return encode_array_literal([split $_[1], $_[0]]);
Returns: text
Language: PLPGSQL
BEGIN
RETURN $1::regclass;
END;
Returns: boolean
Language: PLPGSQL
DECLARE
deprecates TEXT;
supersedes TEXT;
BEGIN
IF NOT evergreen.upgrade_verify_no_dep_conflicts( my_db_patch ) THEN
SELECT STRING_AGG(patch, ', ') INTO deprecates FROM evergreen.upgrade_list_applied_deprecates(my_db_patch);
SELECT STRING_AGG(patch, ', ') INTO supersedes FROM evergreen.upgrade_list_applied_supersedes(my_db_patch);
RAISE EXCEPTION '
Upgrade script % can not be applied:
applied deprecated scripts %
applied superseded scripts %
deprecated by %
superseded by %',
my_db_patch,
ARRAY_AGG(evergreen.upgrade_list_applied_deprecates(my_db_patch)),
ARRAY_AGG(evergreen.upgrade_list_applied_supersedes(my_db_patch)),
evergreen.upgrade_list_applied_deprecated(my_db_patch),
evergreen.upgrade_list_applied_superseded(my_db_patch);
END IF;
INSERT INTO config.upgrade_log (version, applied_to) VALUES (my_db_patch, my_applied_to);
RETURN TRUE;
END;
Returns: SET OF text
Language: SQL
SELECT db_patch
FROM config.db_patch_dependencies
WHERE ARRAY[$1]::TEXT[] && deprecates
Returns: SET OF patch
Language: SQL
SELECT DISTINCT l.version
FROM config.upgrade_log l
JOIN config.db_patch_dependencies d ON (l.version::TEXT[] && d.deprecates)
WHERE d.db_patch = $1
Returns: SET OF text
Language: SQL
SELECT db_patch
FROM config.db_patch_dependencies
WHERE ARRAY[$1]::TEXT[] && supersedes
Returns: SET OF patch
Language: SQL
SELECT DISTINCT l.version
FROM config.upgrade_log l
JOIN config.db_patch_dependencies d ON (l.version::TEXT[] && d.supersedes)
WHERE d.db_patch = $1
Returns: boolean
Language: SQL
SELECT COUNT(*) = 0
FROM (SELECT * FROM evergreen.upgrade_list_applied_deprecates( $1 )
UNION
SELECT * FROM evergreen.upgrade_list_applied_supersedes( $1 )
UNION
SELECT * FROM evergreen.upgrade_list_applied_deprecated( $1 )
UNION
SELECT * FROM evergreen.upgrade_list_applied_superseded( $1 ))x
Returns: text
Language: SQL
SELECT REPLACE(REPLACE(REPLACE($1,
'&', '&'),
'<', '<'),
'>', '>');
Schema extend_reporter
extend_reporter.full_circ_count Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
circ_count |
bigint |
|
SELECT cp.id
, (
(COALESCE
(
(c.circ_count)::bigint
, (0)::bigint
) + COALESCE
(count
(DISTINCT circ.id)
, (0)::bigint
)
) + COALESCE
(count
(DISTINCT acirc.id)
, (0)::bigint
)
) AS circ_count
FROM (
(
(asset.copy cp
LEFT JOIN extend_reporter.legacy_circ_count c
USING (id)
)
LEFT JOIN action.circulation circ
ON (
(circ.target_copy = cp.id)
)
)
LEFT JOIN action.aged_circulation acirc
ON (
(acirc.target_copy = cp.id)
)
)
GROUP BY cp.id
, c.circ_count;
Index -
Schema extend_reporter
extend_reporter.global_bibs_by_holding_update Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
holding_update |
timestamp with time zone |
|
|
update_type |
text |
|
SELECT DISTINCT
ON (x.id) x.id
, x.holding_update
, x.update_type
FROM (
SELECT b.id
, last
(cp.create_date) AS holding_update
,'add'::text AS update_type
FROM (
(biblio.record_entry b
JOIN asset.call_number cn
ON (
(cn.record = b.id)
)
)
JOIN asset.copy cp
ON (
(cp.call_number = cn.id)
)
)
WHERE (
(NOT cp.deleted)
AND (b.id > 0)
)
GROUP BY b.id
UNIONSELECT b.id
, last
(cp.edit_date) AS holding_update
,'delete'::text AS update_type
FROM (
(biblio.record_entry b
JOIN asset.call_number cn
ON (
(cn.record = b.id)
)
)
JOIN asset.copy cp
ON (
(cp.call_number = cn.id)
)
)
WHERE (cp.deleted
AND (b.id > 0)
)
GROUP BY b.id
) x
ORDER BY x.id
, x.holding_update;
Index -
Schema extend_reporter
extend_reporter.legacy_circ_count Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
|
|
circ_count |
integer |
NOT NULL
|
Index -
Schema extend_reporter
Schema metabib
metabib.author_field_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
biblio.record_entry.id
|
source |
bigint |
NOT NULL
|
config.metabib_field.id
|
field |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
index_vector |
tsvector |
NOT NULL
|
metabib_author_field_entry_index_vector_idx index_vector
metabib_author_field_entry_source_idx source
metabib_author_field_entry_value_idx "substring"(value, 1, 1024)) WHERE ((index_vector)::pg_catalog.tsvector = ((''::pg_catalog.tsvector)::tsvector)::pg_catalog.tsvector
Index -
Schema metabib
metabib.browse_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
value |
text |
UNIQUE
|
|
index_vector |
tsvector |
|
Tables referencing this one via Foreign Key Constraints:
metabib_browse_entry_index_vector_idx index_vector
Index -
Schema metabib
browse_entry_def_map_def_idx def
browse_entry_def_map_entry_idx entry
browse_entry_def_map_source_idx source
Index -
Schema metabib
metabib.facet_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
source |
bigint |
NOT NULL
|
|
field |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
metabib_facet_entry_field_idx field
metabib_facet_entry_source_idx source
metabib_facet_entry_value_idx "substring"(value, 1, 1024)
Index -
Schema metabib
metabib.full_rec Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
record |
bigint |
|
|
tag |
character(3) |
|
|
ind1 |
text |
|
|
ind2 |
text |
|
|
subfield |
text |
|
|
value |
text |
|
|
index_vector |
tsvector |
|
SELECT real_full_rec.id
, real_full_rec.record
, real_full_rec.tag
, real_full_rec.ind1
, real_full_rec.ind2
, real_full_rec.subfield
,"substring"
(real_full_rec.value
, 1
, 1024
) AS value
, real_full_rec.index_vector
FROM metabib.real_full_rec;
Index -
Schema metabib
metabib.identifier_field_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
biblio.record_entry.id
|
source |
bigint |
NOT NULL
|
config.metabib_field.id
|
field |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
index_vector |
tsvector |
NOT NULL
|
metabib_identifier_field_entry_index_vector_idx index_vector
metabib_identifier_field_entry_source_idx source
metabib_identifier_field_entry_value_idx "substring"(value, 1, 1024)) WHERE ((index_vector)::pg_catalog.tsvector = ((''::pg_catalog.tsvector)::tsvector)::pg_catalog.tsvector
Index -
Schema metabib
metabib.keyword_field_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
biblio.record_entry.id
|
source |
bigint |
NOT NULL
|
config.metabib_field.id
|
field |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
index_vector |
tsvector |
NOT NULL
|
metabib_keyword_field_entry_index_vector_idx index_vector
metabib_keyword_field_entry_source_idx source
metabib_keyword_field_entry_value_idx "substring"(value, 1, 1024)) WHERE ((index_vector)::pg_catalog.tsvector = ((''::pg_catalog.tsvector)::tsvector)::pg_catalog.tsvector
Index -
Schema metabib
metabib.metarecord Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
fingerprint |
text |
NOT NULL
|
biblio.record_entry.id
|
master_record |
bigint |
|
|
mods |
text |
|
Tables referencing this one via Foreign Key Constraints:
metabib_metarecord_fingerprint_idx fingerprint
metabib_metarecord_master_record_idx master_record
Index -
Schema metabib
metabib_metarecord_source_map_metarecord_idx metarecord
metabib_metarecord_source_map_source_record_idx source
Index -
Schema metabib
metabib.real_full_rec Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('metabib.full_rec_id_seq'::regclass)
|
biblio.record_entry.id
|
record |
bigint |
NOT NULL
|
|
tag |
character(3) |
NOT NULL
|
|
ind1 |
text |
|
|
ind2 |
text |
|
|
subfield |
text |
|
|
value |
text |
NOT NULL
|
|
index_vector |
tsvector |
NOT NULL
|
metabib_full_rec_index_vector_idx index_vector
metabib_full_rec_isxn_caseless_idx lower(value)) WHERE (tag = ANY (ARRAY['020'::bpchar, '022'::bpchar, '024'::bpchar])
metabib_full_rec_record_idx record
metabib_full_rec_tag_subfield_idx tag, subfield
metabib_full_rec_value_idx "substring"(value, 1, 1024)
metabib_full_rec_value_tpo_index "substring"(value, 1, 1024) text_pattern_ops
Index -
Schema metabib
metabib.rec_descriptor Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
record |
bigint |
|
|
item_type |
text |
|
|
item_form |
text |
|
|
bib_level |
text |
|
|
control_type |
text |
|
|
char_encoding |
text |
|
|
enc_level |
text |
|
|
audience |
text |
|
|
lit_form |
text |
|
|
type_mat |
text |
|
|
cat_form |
text |
|
|
pub_status |
text |
|
|
item_lang |
text |
|
|
vr_format |
text |
|
|
date1 |
text |
|
|
date2 |
text |
|
SELECT record_attr.id
, record_attr.id AS record
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).item_type AS item_type
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).item_form AS item_form
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).bib_level AS bib_level
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).control_type AS control_type
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).char_encoding AS char_encoding
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).enc_level AS enc_level
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).audience AS audience
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).lit_form AS lit_form
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).type_mat AS type_mat
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).cat_form AS cat_form
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).pub_status AS pub_status
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).item_lang AS item_lang
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).vr_format AS vr_format
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).date1 AS date1
, (populate_record
(NULL::metabib.rec_desc_type
, record_attr.attrs
)
).date2 AS date2
FROM metabib.record_attr;
Index -
Schema metabib
metabib.record_attr Structure
F-Key |
Name |
Type |
Description |
biblio.record_entry.id
|
id |
bigint |
PRIMARY KEY
|
|
attrs |
hstore |
NOT NULL
DEFAULT ''::hstore
|
metabib_svf_attrs_idx attrs
metabib_svf_date1_idx ((attrs -> 'date1'::text))
metabib_svf_dates_idx ((attrs -> 'date1'::text)), ((attrs -> 'date2'::text))
Index -
Schema metabib
metabib.series_field_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
biblio.record_entry.id
|
source |
bigint |
NOT NULL
|
config.metabib_field.id
|
field |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
index_vector |
tsvector |
NOT NULL
|
metabib_series_field_entry_index_vector_idx index_vector
metabib_series_field_entry_source_idx source
metabib_series_field_entry_value_idx "substring"(value, 1, 1024)) WHERE ((index_vector)::pg_catalog.tsvector = ((''::pg_catalog.tsvector)::tsvector)::pg_catalog.tsvector
Index -
Schema metabib
metabib.subject_field_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
biblio.record_entry.id
|
source |
bigint |
NOT NULL
|
config.metabib_field.id
|
field |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
index_vector |
tsvector |
NOT NULL
|
metabib_subject_field_entry_index_vector_idx index_vector
metabib_subject_field_entry_source_idx source
metabib_subject_field_entry_value_idx "substring"(value, 1, 1024)) WHERE ((index_vector)::pg_catalog.tsvector = ((''::pg_catalog.tsvector)::tsvector)::pg_catalog.tsvector
Index -
Schema metabib
metabib.title_field_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
biblio.record_entry.id
|
source |
bigint |
NOT NULL
|
config.metabib_field.id
|
field |
integer |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
index_vector |
tsvector |
NOT NULL
|
metabib_title_field_entry_index_vector_idx index_vector
metabib_title_field_entry_source_idx source
metabib_title_field_entry_value_idx "substring"(value, 1, 1024)) WHERE ((index_vector)::pg_catalog.tsvector = ((''::pg_catalog.tsvector)::tsvector)::pg_catalog.tsvector
Index -
Schema metabib
Returns: text[]
Language: PLPGSQL
DECLARE
orig_ended_in_space BOOLEAN;
result RECORD;
plain TEXT;
normalized TEXT;
BEGIN
orig_ended_in_space := orig ~ E'\\s$';
orig := ARRAY_TO_STRING(
evergreen.regexp_split_to_array(orig, E'\\W+'), ' '
);
normalized := public.search_normalize(orig); -- also trim()s
plain := trim(orig);
IF NOT orig_ended_in_space THEN
plain := plain || ':*';
normalized := normalized || ':*';
END IF;
plain := ARRAY_TO_STRING(
evergreen.regexp_split_to_array(plain, E'\\s+'), ' & '
);
normalized := ARRAY_TO_STRING(
evergreen.regexp_split_to_array(normalized, E'\\s+'), ' & '
);
RETURN ARRAY[normalized, plain];
END;
Returns: text
Language: PLPGSQL
DECLARE
normalizer RECORD;
BEGIN
FOR normalizer IN
SELECT n.func AS func,
n.param_count AS param_count,
m.params AS params
FROM config.index_normalizer n
JOIN config.metabib_field_index_norm_map m ON (m.norm = n.id)
WHERE m.field = mapped_field AND m.pos < 0
ORDER BY m.pos LOOP
EXECUTE 'SELECT ' || normalizer.func || '(' ||
quote_literal( facet_text ) ||
CASE
WHEN normalizer.param_count > 0
THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
ELSE ''
END ||
')' INTO facet_text;
END LOOP;
RETURN facet_text;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
normalizer RECORD;
facet_text TEXT;
BEGIN
facet_text := NEW.value;
FOR normalizer IN
SELECT n.func AS func,
n.param_count AS param_count,
m.params AS params
FROM config.index_normalizer n
JOIN config.metabib_field_index_norm_map m ON (m.norm = n.id)
WHERE m.field = NEW.field AND m.pos < 0
ORDER BY m.pos LOOP
EXECUTE 'SELECT ' || normalizer.func || '(' ||
quote_literal( facet_text ) ||
CASE
WHEN normalizer.param_count > 0
THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
ELSE ''
END ||
')' INTO facet_text;
END LOOP;
NEW.value = facet_text;
RETURN NEW;
END;
Returns: void
Language: PLPGSQL
DECLARE
fclass RECORD;
ind_data metabib.field_entry_template%ROWTYPE;
mbe_row metabib.browse_entry%ROWTYPE;
mbe_id BIGINT;
BEGIN
PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
IF NOT FOUND THEN
IF NOT skip_search THEN
FOR fclass IN SELECT * FROM config.metabib_class LOOP
-- RAISE NOTICE 'Emptying out %', fclass.name;
EXECUTE $$DELETE FROM metabib.$$ || fclass.name || $$_field_entry WHERE source = $$ || bib_id;
END LOOP;
END IF;
IF NOT skip_facet THEN
DELETE FROM metabib.facet_entry WHERE source = bib_id;
END IF;
IF NOT skip_browse THEN
DELETE FROM metabib.browse_entry_def_map WHERE source = bib_id;
END IF;
END IF;
FOR ind_data IN SELECT * FROM biblio.extract_metabib_field_entry( bib_id ) LOOP
IF ind_data.field < 0 THEN
ind_data.field = -1 * ind_data.field;
END IF;
IF ind_data.facet_field AND NOT skip_facet THEN
INSERT INTO metabib.facet_entry (field, source, value)
VALUES (ind_data.field, ind_data.source, ind_data.value);
END IF;
IF ind_data.browse_field AND NOT skip_browse THEN
-- A caveat about this SELECT: this should take care of replacing
-- old mbe rows when data changes, but not if normalization (by
-- which I mean specifically the output of
-- evergreen.oils_tsearch2()) changes. It may or may not be
-- expensive to add a comparison of index_vector to index_vector
-- to the WHERE clause below.
SELECT INTO mbe_row * FROM metabib.browse_entry WHERE value = ind_data.value;
IF FOUND THEN
mbe_id := mbe_row.id;
ELSE
INSERT INTO metabib.browse_entry (value) VALUES
(metabib.browse_normalize(ind_data.value, ind_data.field));
mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
END IF;
INSERT INTO metabib.browse_entry_def_map (entry, def, source)
VALUES (mbe_id, ind_data.field, ind_data.source);
END IF;
IF ind_data.search_field AND NOT skip_search THEN
EXECUTE $$
INSERT INTO metabib.$$ || ind_data.field_class || $$_field_entry (field, source, value)
VALUES ($$ ||
quote_literal(ind_data.field) || $$, $$ ||
quote_literal(ind_data.source) || $$, $$ ||
quote_literal(ind_data.value) ||
$$);$$;
END IF;
END LOOP;
RETURN;
END;
Returns: void
Language: PLPGSQL
BEGIN
PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
IF NOT FOUND THEN
DELETE FROM metabib.real_full_rec WHERE record = bib_id;
END IF;
INSERT INTO metabib.real_full_rec (record, tag, ind1, ind2, subfield, value)
SELECT record, tag, ind1, ind2, subfield, value FROM biblio.flatten_marc( bib_id );
RETURN;
END;
Returns: bigint
Language: PLPGSQL
DECLARE
source_count INT;
old_mr BIGINT;
tmp_mr metabib.metarecord%ROWTYPE;
deleted_mrs BIGINT[];
BEGIN
DELETE FROM metabib.metarecord_source_map WHERE source = bib_id; -- Rid ourselves of the search-estimate-killing linkage
FOR tmp_mr IN SELECT m.* FROM metabib.metarecord m JOIN metabib.metarecord_source_map s ON (s.metarecord = m.id) WHERE s.source = bib_id LOOP
IF old_mr IS NULL AND fp = tmp_mr.fingerprint THEN -- Find the first fingerprint-matching
old_mr := tmp_mr.id;
ELSE
SELECT COUNT(*) INTO source_count FROM metabib.metarecord_source_map WHERE metarecord = tmp_mr.id;
IF source_count = 0 THEN -- No other records
deleted_mrs := ARRAY_APPEND(deleted_mrs, tmp_mr.id);
DELETE FROM metabib.metarecord WHERE id = tmp_mr.id;
END IF;
END IF;
END LOOP;
IF old_mr IS NULL THEN -- we found no suitable, preexisting MR based on old source maps
SELECT id INTO old_mr FROM metabib.metarecord WHERE fingerprint = fp; -- is there one for our current fingerprint?
IF old_mr IS NULL THEN -- nope, create one and grab its id
INSERT INTO metabib.metarecord ( fingerprint, master_record ) VALUES ( fp, bib_id );
SELECT id INTO old_mr FROM metabib.metarecord WHERE fingerprint = fp;
ELSE -- indeed there is. update it with a null cache and recalcualated master record
UPDATE metabib.metarecord
SET mods = NULL,
master_record = ( SELECT id FROM biblio.record_entry WHERE fingerprint = fp ORDER BY quality DESC LIMIT 1)
WHERE id = old_mr;
END IF;
ELSE -- there was one we already attached to, update its mods cache and master_record
UPDATE metabib.metarecord
SET mods = NULL,
master_record = ( SELECT id FROM biblio.record_entry WHERE fingerprint = fp ORDER BY quality DESC LIMIT 1)
WHERE id = old_mr;
END IF;
INSERT INTO metabib.metarecord_source_map (metarecord, source) VALUES (old_mr, bib_id); -- new source mapping
IF ARRAY_UPPER(deleted_mrs,1) > 0 THEN
UPDATE action.hold_request SET target = old_mr WHERE target IN ( SELECT unnest(deleted_mrs) ) AND hold_type = 'M'; -- if we had to delete any MRs above, make sure their holds are moved
END IF;
RETURN old_mr;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
search_parts TEXT[];
field_name TEXT;
search_part_count INTEGER;
rec RECORD;
registered_class config.metabib_class%ROWTYPE;
registered_alias config.metabib_search_alias%ROWTYPE;
registered_field config.metabib_field%ROWTYPE;
BEGIN
search_parts := REGEXP_SPLIT_TO_ARRAY(search_class, E'\\|');
search_part_count := ARRAY_LENGTH(search_parts, 1);
IF search_part_count = 0 THEN
RETURN;
ELSE
SELECT INTO registered_class
* FROM config.metabib_class WHERE name = search_parts[1];
IF FOUND THEN
IF search_part_count < 2 THEN -- all fields
rec := (registered_class.name, NULL::INTEGER);
RETURN NEXT rec;
RETURN; -- done
END IF;
FOR field_name IN SELECT *
FROM UNNEST(search_parts[2:search_part_count]) LOOP
SELECT INTO registered_field
* FROM config.metabib_field
WHERE name = field_name AND
field_class = registered_class.name;
IF FOUND THEN
rec := (registered_class.name, registered_field.id);
RETURN NEXT rec;
END IF;
END LOOP;
ELSE
-- maybe we have an alias?
SELECT INTO registered_alias
* FROM config.metabib_search_alias WHERE alias=search_parts[1];
IF NOT FOUND THEN
RETURN;
ELSE
IF search_part_count < 2 THEN -- return w/e the alias says
rec := (
registered_alias.field_class, registered_alias.field
);
RETURN NEXT rec;
RETURN; -- done
ELSE
FOR field_name IN SELECT *
FROM UNNEST(search_parts[2:search_part_count]) LOOP
SELECT INTO registered_field
* FROM config.metabib_field
WHERE name = field_name AND
field_class = registered_alias.field_class;
IF FOUND THEN
rec := (
registered_alias.field_class,
registered_field.id
);
RETURN NEXT rec;
END IF;
END LOOP;
END IF;
END IF;
END IF;
END IF;
END;
Returns: SET OF record
Language: PLPGSQL
DECLARE
prepared_query_texts TEXT[];
query TSQUERY;
plain_query TSQUERY;
opac_visibility_join TEXT;
search_class_join TEXT;
r_fields RECORD;
BEGIN
prepared_query_texts := metabib.autosuggest_prepare_tsquery(raw_query_text);
query := TO_TSQUERY('keyword', prepared_query_texts[1]);
plain_query := TO_TSQUERY('keyword', prepared_query_texts[2]);
IF visibility_org IS NOT NULL THEN
opac_visibility_join := '
JOIN asset.opac_visible_copies aovc ON (
aovc.record = x.source AND
aovc.circ_lib IN (SELECT id FROM actor.org_unit_descendants($4))
)';
ELSE
opac_visibility_join := '';
END IF;
-- The following determines whether we only provide suggestsons matching
-- the user's selected search_class, or whether we show other suggestions
-- too. The reason for MIN() is that for search_classes like
-- 'title|proper|uniform' you would otherwise get multiple rows. The
-- implication is that if title as a class doesn't have restrict,
-- nor does the proper field, but the uniform field does, you're going
-- to get 'false' for your overall evaluation of 'should we restrict?'
-- To invert that, change from MIN() to MAX().
SELECT
INTO r_fields
MIN(cmc.restrict::INT) AS restrict_class,
MIN(cmf.restrict::INT) AS restrict_field
FROM metabib.search_class_to_registered_components(search_class)
AS _registered (field_class TEXT, field INT)
JOIN
config.metabib_class cmc ON (cmc.name = _registered.field_class)
LEFT JOIN
config.metabib_field cmf ON (cmf.id = _registered.field);
-- evaluate 'should we restrict?'
IF r_fields.restrict_field::BOOL OR r_fields.restrict_class::BOOL THEN
search_class_join := '
JOIN
metabib.search_class_to_registered_components($2)
AS _registered (field_class TEXT, field INT) ON (
(_registered.field IS NULL AND
_registered.field_class = cmf.field_class) OR
(_registered.field = cmf.id)
)
';
ELSE
search_class_join := '
LEFT JOIN
metabib.search_class_to_registered_components($2)
AS _registered (field_class TEXT, field INT) ON (
_registered.field_class = cmc.name
)
';
END IF;
RETURN QUERY EXECUTE '
SELECT DISTINCT
x.value,
x.id,
x.push,
x.restrict,
x.weight,
x.ts_rank_cd,
x.buoyant,
TS_HEADLINE(value, $7, $3)
FROM (SELECT DISTINCT
mbe.value,
cmf.id,
cmc.buoyant AND _registered.field_class IS NOT NULL AS push,
_registered.field = cmf.id AS restrict,
cmf.weight,
TS_RANK_CD(mbe.index_vector, $1, $6),
cmc.buoyant,
mbedm.source
FROM metabib.browse_entry_def_map mbedm
JOIN (SELECT * FROM metabib.browse_entry WHERE index_vector @@ $1 LIMIT 10000) mbe ON (mbe.id = mbedm.entry)
JOIN config.metabib_field cmf ON (cmf.id = mbedm.def)
JOIN config.metabib_class cmc ON (cmf.field_class = cmc.name)
' || search_class_join || '
ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
LIMIT 1000) AS x
' || opac_visibility_join || '
ORDER BY 3 DESC, 4 DESC NULLS LAST, 5 DESC, 6 DESC, 7 DESC, 1 ASC
LIMIT $5
' -- sic, repeat the order by clause in the outer select too
USING
query, search_class, headline_opts,
visibility_org, query_limit, normalization, plain_query
;
-- sort order:
-- buoyant AND chosen class = match class
-- chosen field = match field
-- field weight
-- rank
-- buoyancy
-- value itself
END;
Schema money
money.billable_xact Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
|
xact_start |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
xact_finish |
timestamp with time zone |
|
|
unrecovered |
boolean |
|
m_b_x_open_xacts_idx usr
Index -
Schema money
money.billable_xact_summary Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
usr |
integer |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
total_paid |
numeric |
|
|
last_payment_ts |
timestamp with time zone |
|
|
last_payment_note |
text |
|
|
last_payment_type |
name |
|
|
total_owed |
numeric |
|
|
last_billing_ts |
timestamp with time zone |
|
|
last_billing_note |
text |
|
|
last_billing_type |
text |
|
|
balance_owed |
numeric |
|
|
xact_type |
name |
|
SELECT materialized_billable_xact_summary.id
, materialized_billable_xact_summary.usr
, materialized_billable_xact_summary.xact_start
, materialized_billable_xact_summary.xact_finish
, materialized_billable_xact_summary.total_paid
, materialized_billable_xact_summary.last_payment_ts
, materialized_billable_xact_summary.last_payment_note
, materialized_billable_xact_summary.last_payment_type
, materialized_billable_xact_summary.total_owed
, materialized_billable_xact_summary.last_billing_ts
, materialized_billable_xact_summary.last_billing_note
, materialized_billable_xact_summary.last_billing_type
, materialized_billable_xact_summary.balance_owed
, materialized_billable_xact_summary.xact_type
FROM money.materialized_billable_xact_summary;
Index -
Schema money
money.billable_xact_summary_location_view Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
usr |
integer |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
total_paid |
numeric |
|
|
last_payment_ts |
timestamp with time zone |
|
|
last_payment_note |
text |
|
|
last_payment_type |
name |
|
|
total_owed |
numeric |
|
|
last_billing_ts |
timestamp with time zone |
|
|
last_billing_note |
text |
|
|
last_billing_type |
text |
|
|
balance_owed |
numeric |
|
|
xact_type |
name |
|
|
billing_location |
integer |
|
SELECT m.id
, m.usr
, m.xact_start
, m.xact_finish
, m.total_paid
, m.last_payment_ts
, m.last_payment_note
, m.last_payment_type
, m.total_owed
, m.last_billing_ts
, m.last_billing_note
, m.last_billing_type
, m.balance_owed
, m.xact_type
, COALESCE
(c.circ_lib
, g.billing_location
, r.pickup_lib
) AS billing_location
FROM (
(
(money.materialized_billable_xact_summary m
LEFT JOIN action.circulation c
ON (
(c.id = m.id)
)
)
LEFT JOIN money.grocery g
ON (
(g.id = m.id)
)
)
LEFT JOIN booking.reservation r
ON (
(r.id = m.id)
)
);
Index -
Schema money
money.billable_xact_with_void_summary Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
usr |
integer |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
total_paid |
numeric |
|
|
last_payment_ts |
timestamp with time zone |
|
|
last_payment_note |
text |
|
|
last_payment_type |
name |
|
|
total_owed |
numeric |
|
|
last_billing_ts |
timestamp with time zone |
|
|
last_billing_note |
text |
|
|
last_billing_type |
text |
|
|
balance_owed |
numeric |
|
|
xact_type |
name |
|
SELECT xact.id
, xact.usr
, xact.xact_start
, xact.xact_finish
, sum
(credit.amount) AS total_paid
, max
(credit.payment_ts) AS last_payment_ts
, last
(credit.note) AS last_payment_note
, last
(credit.payment_type) AS last_payment_type
, sum
(debit.amount) AS total_owed
, max
(debit.billing_ts) AS last_billing_ts
, last
(debit.note) AS last_billing_note
, last
(debit.billing_type) AS last_billing_type
, (COALESCE
(sum
(debit.amount)
, (0)::numeric
) - COALESCE
(sum
(credit.amount)
, (0)::numeric
)
) AS balance_owed
, p.relname AS xact_type
FROM (
(
(money.billable_xact xact
JOIN pg_class p
ON (
(xact.tableoid = p.oid)
)
)
LEFT JOIN money.billing debit
ON (
(xact.id = debit.xact)
)
)
LEFT JOIN money.payment_view credit
ON (
(xact.id = credit.xact)
)
)
GROUP BY xact.id
, xact.usr
, xact.xact_start
, xact.xact_finish
, p.relname
ORDER BY max
(debit.billing_ts)
, max
(credit.payment_ts);
Index -
Schema money
money.billing Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
xact |
bigint |
NOT NULL
|
|
billing_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
voider |
integer |
|
|
void_time |
timestamp with time zone |
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
billing_type |
text |
NOT NULL
|
config.billing_type.id
|
btype |
integer |
NOT NULL
|
|
note |
text |
|
m_b_time_idx billing_ts
m_b_xact_idx xact
Index -
Schema money
money.bnm_desk_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
actor.workstation.id
|
cash_drawer |
integer |
|
Table money.bnm_desk_payment Inherits
bnm_payment,
Index -
Schema money
money.bnm_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
Table money.bnm_payment Inherits
payment,
Index -
Schema money
money.bnm_payment_view Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
xact |
bigint |
|
|
payment_ts |
timestamp with time zone |
|
|
voided |
boolean |
|
|
amount |
numeric(6,2) |
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
|
|
accepting_usr |
integer |
|
|
payment_type |
name |
|
SELECT p.id
, p.xact
, p.payment_ts
, p.voided
, p.amount
, p.note
, p.amount_collected
, p.accepting_usr
, c.relname AS payment_type
FROM (money.bnm_payment p
JOIN pg_class c
ON (
(p.tableoid = c.oid)
)
);
Index -
Schema money
money.cash_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
|
cash_drawer |
integer |
|
Table money.cash_payment Inherits
bnm_desk_payment,
money_cash_id_idx id
money_cash_payment_accepting_usr_idx accepting_usr
money_cash_payment_cash_drawer_idx cash_drawer
money_cash_payment_ts_idx payment_ts
money_cash_payment_xact_idx xact
Index -
Schema money
money.cashdrawer_payment_view Structure
F-Key |
Name |
Type |
Description |
|
org_unit |
integer |
|
|
cashdrawer |
integer |
|
|
payment_type |
name |
|
|
payment_ts |
timestamp with time zone |
|
|
amount |
numeric(6,2) |
|
|
voided |
boolean |
|
|
note |
text |
|
SELECT ou.id AS org_unit
, ws.id AS cashdrawer
, t.payment_type
, p.payment_ts
, p.amount
, p.voided
, p.note
FROM (
(
(actor.org_unit ou
JOIN actor.workstation ws
ON (
(ou.id = ws.owning_lib)
)
)
LEFT JOIN money.bnm_desk_payment p
ON (
(ws.id = p.cash_drawer)
)
)
LEFT JOIN money.payment_view t
ON (
(p.id = t.id)
)
);
Index -
Schema money
money.check_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
|
cash_drawer |
integer |
|
|
check_number |
text |
NOT NULL
|
Table money.check_payment Inherits
bnm_desk_payment,
money_check_id_idx id
money_check_payment_accepting_usr_idx accepting_usr
money_check_payment_cash_drawer_idx cash_drawer
money_check_payment_ts_idx payment_ts
money_check_payment_xact_idx xact
Index -
Schema money
money.collections_tracker Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
NOT NULL
|
actor.usr.id
|
collector |
integer |
NOT NULL
|
actor.org_unit.id
|
location |
integer |
NOT NULL
|
|
enter_time |
timestamp with time zone |
|
m_c_t_collector_idx collector
Index -
Schema money
money.credit_card_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
|
cash_drawer |
integer |
|
|
cc_type |
text |
|
|
cc_number |
text |
|
|
cc_processor |
text |
|
|
cc_first_name |
text |
|
|
cc_last_name |
text |
|
|
cc_order_number |
text |
|
|
expire_month |
integer |
|
|
expire_year |
integer |
|
|
approval_code |
text |
|
Table money.credit_card_payment Inherits
bnm_desk_payment,
money_credit_card_id_idx id
money_credit_card_payment_accepting_usr_idx accepting_usr
money_credit_card_payment_cash_drawer_idx cash_drawer
money_credit_card_payment_ts_idx payment_ts
money_credit_card_payment_xact_idx xact
Index -
Schema money
money.credit_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
Table money.credit_payment Inherits
bnm_payment,
money_credit_id_idx id
money_credit_payment_accepting_usr_idx accepting_usr
money_credit_payment_payment_ts_idx payment_ts
money_credit_payment_xact_idx xact
Index -
Schema money
money.desk_payment_view Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
xact |
bigint |
|
|
payment_ts |
timestamp with time zone |
|
|
voided |
boolean |
|
|
amount |
numeric(6,2) |
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
|
|
accepting_usr |
integer |
|
|
cash_drawer |
integer |
|
|
payment_type |
name |
|
SELECT p.id
, p.xact
, p.payment_ts
, p.voided
, p.amount
, p.note
, p.amount_collected
, p.accepting_usr
, p.cash_drawer
, c.relname AS payment_type
FROM (money.bnm_desk_payment p
JOIN pg_class c
ON (
(p.tableoid = c.oid)
)
);
Index -
Schema money
money.forgive_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
Table money.forgive_payment Inherits
bnm_payment,
money_forgive_id_idx id
money_forgive_payment_accepting_usr_idx accepting_usr
money_forgive_payment_payment_ts_idx payment_ts
money_forgive_payment_xact_idx xact
Index -
Schema money
money.goods_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
Table money.goods_payment Inherits
bnm_payment,
money_goods_id_idx id
money_goods_payment_accepting_usr_idx accepting_usr
money_goods_payment_payment_ts_idx payment_ts
money_goods_payment_xact_idx xact
Index -
Schema money
money.grocery Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.billable_xact_id_seq'::regclass)
|
|
usr |
integer |
NOT NULL
|
|
xact_start |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
xact_finish |
timestamp with time zone |
|
|
unrecovered |
boolean |
|
|
billing_location |
integer |
NOT NULL
|
|
note |
text |
|
Table money.grocery Inherits
billable_xact,
circ_open_date_idx xact_start) WHERE (xact_finish IS NULL
m_g_usr_idx usr
Index -
Schema money
money.materialized_billable_xact_summary Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
|
|
usr |
integer |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
total_paid |
numeric |
|
|
last_payment_ts |
timestamp with time zone |
|
|
last_payment_note |
text |
|
|
last_payment_type |
name |
|
|
total_owed |
numeric |
|
|
last_billing_ts |
timestamp with time zone |
|
|
last_billing_note |
text |
|
|
last_billing_type |
text |
|
|
balance_owed |
numeric |
|
|
xact_type |
name |
|
money_mat_summary_usr_idx usr
money_mat_summary_xact_start_idx xact_start
Index -
Schema money
money.non_drawer_payment_view Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
xact |
bigint |
|
|
payment_ts |
timestamp with time zone |
|
|
voided |
boolean |
|
|
amount |
numeric(6,2) |
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
|
|
accepting_usr |
integer |
|
|
payment_type |
name |
|
SELECT p.id
, p.xact
, p.payment_ts
, p.voided
, p.amount
, p.note
, p.amount_collected
, p.accepting_usr
, c.relname AS payment_type
FROM (money.bnm_payment p
JOIN pg_class c
ON (
(p.tableoid = c.oid)
)
)
WHERE (c.relname <> ALL
(ARRAY['cash_payment'::name
,'check_payment'::name
,'credit_card_payment'::name]
)
);
Index -
Schema money
money.open_billable_xact_summary Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
usr |
integer |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
total_paid |
numeric |
|
|
last_payment_ts |
timestamp with time zone |
|
|
last_payment_note |
text |
|
|
last_payment_type |
name |
|
|
total_owed |
numeric |
|
|
last_billing_ts |
timestamp with time zone |
|
|
last_billing_note |
text |
|
|
last_billing_type |
text |
|
|
balance_owed |
numeric |
|
|
xact_type |
name |
|
|
billing_location |
integer |
|
SELECT billable_xact_summary_location_view.id
, billable_xact_summary_location_view.usr
, billable_xact_summary_location_view.xact_start
, billable_xact_summary_location_view.xact_finish
, billable_xact_summary_location_view.total_paid
, billable_xact_summary_location_view.last_payment_ts
, billable_xact_summary_location_view.last_payment_note
, billable_xact_summary_location_view.last_payment_type
, billable_xact_summary_location_view.total_owed
, billable_xact_summary_location_view.last_billing_ts
, billable_xact_summary_location_view.last_billing_note
, billable_xact_summary_location_view.last_billing_type
, billable_xact_summary_location_view.balance_owed
, billable_xact_summary_location_view.xact_type
, billable_xact_summary_location_view.billing_location
FROM money.billable_xact_summary_location_view
WHERE (billable_xact_summary_location_view.xact_finish IS NULL);
Index -
Schema money
money.open_transaction_billing_summary Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
last_billing_type |
text |
|
|
last_billing_note |
text |
|
|
last_billing_ts |
timestamp with time zone |
|
|
total_owed |
numeric |
|
SELECT billing.xact
, last
(billing.billing_type) AS last_billing_type
, last
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
(billing.amount
, (0)::numeric
)
) AS total_owed
FROM money.billing
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact
ORDER BY max
(billing.billing_ts);
Index -
Schema money
money.open_transaction_billing_type_summary Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
last_billing_type |
text |
|
|
last_billing_note |
text |
|
|
last_billing_ts |
timestamp with time zone |
|
|
total_owed |
numeric |
|
SELECT billing.xact
, billing.billing_type AS last_billing_type
, last
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
(billing.amount
, (0)::numeric
)
) AS total_owed
FROM money.billing
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact
, billing.billing_type
ORDER BY max
(billing.billing_ts);
Index -
Schema money
money.open_transaction_payment_summary Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
last_payment_type |
name |
|
|
last_payment_note |
text |
|
|
last_payment_ts |
timestamp with time zone |
|
|
total_paid |
numeric |
|
SELECT payment_view.xact
, last
(payment_view.payment_type) AS last_payment_type
, last
(payment_view.note) AS last_payment_note
, max
(payment_view.payment_ts) AS last_payment_ts
, sum
(COALESCE
(payment_view.amount
, (0)::numeric
)
) AS total_paid
FROM money.payment_view
WHERE (payment_view.voided IS FALSE)
GROUP BY payment_view.xact
ORDER BY max
(payment_view.payment_ts);
Index -
Schema money
money.open_usr_circulation_summary Structure
F-Key |
Name |
Type |
Description |
|
usr |
integer |
|
|
total_paid |
numeric |
|
|
total_owed |
numeric |
|
|
balance_owed |
numeric |
|
SELECT materialized_billable_xact_summary.usr
, sum
(materialized_billable_xact_summary.total_paid) AS total_paid
, sum
(materialized_billable_xact_summary.total_owed) AS total_owed
, sum
(materialized_billable_xact_summary.balance_owed) AS balance_owed
FROM money.materialized_billable_xact_summary
WHERE (
(materialized_billable_xact_summary.xact_type = 'circulation'::name)
AND (materialized_billable_xact_summary.xact_finish IS NULL)
)
GROUP BY materialized_billable_xact_summary.usr;
Index -
Schema money
money.open_usr_summary Structure
F-Key |
Name |
Type |
Description |
|
usr |
integer |
|
|
total_paid |
numeric |
|
|
total_owed |
numeric |
|
|
balance_owed |
numeric |
|
SELECT materialized_billable_xact_summary.usr
, sum
(materialized_billable_xact_summary.total_paid) AS total_paid
, sum
(materialized_billable_xact_summary.total_owed) AS total_owed
, sum
(materialized_billable_xact_summary.balance_owed) AS balance_owed
FROM money.materialized_billable_xact_summary
WHERE (materialized_billable_xact_summary.xact_finish IS NULL)
GROUP BY materialized_billable_xact_summary.usr;
Index -
Schema money
money.payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
m_p_time_idx payment_ts
m_p_xact_idx xact
Index -
Schema money
money.payment_view Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
xact |
bigint |
|
|
payment_ts |
timestamp with time zone |
|
|
voided |
boolean |
|
|
amount |
numeric(6,2) |
|
|
note |
text |
|
|
payment_type |
name |
|
SELECT p.id
, p.xact
, p.payment_ts
, p.voided
, p.amount
, p.note
, c.relname AS payment_type
FROM (money.payment p
JOIN pg_class c
ON (
(p.tableoid = c.oid)
)
);
Index -
Schema money
money.transaction_billing_summary Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
last_billing_type |
text |
|
|
last_billing_note |
text |
|
|
last_billing_ts |
timestamp with time zone |
|
|
total_owed |
numeric |
|
SELECT billing.xact
, last
(billing.billing_type) AS last_billing_type
, last
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
(billing.amount
, (0)::numeric
)
) AS total_owed
FROM money.billing
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact
ORDER BY max
(billing.billing_ts);
Index -
Schema money
money.transaction_billing_type_summary Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
last_billing_type |
text |
|
|
last_billing_note |
text |
|
|
last_billing_ts |
timestamp with time zone |
|
|
total_owed |
numeric |
|
SELECT billing.xact
, billing.billing_type AS last_billing_type
, last
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(COALESCE
(billing.amount
, (0)::numeric
)
) AS total_owed
FROM money.billing
WHERE (billing.voided IS FALSE)
GROUP BY billing.xact
, billing.billing_type
ORDER BY max
(billing.billing_ts);
Index -
Schema money
money.transaction_billing_with_void_summary Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
last_billing_type |
text |
|
|
last_billing_note |
text |
|
|
last_billing_ts |
timestamp with time zone |
|
|
total_owed |
numeric |
|
SELECT billing.xact
, last
(billing.billing_type) AS last_billing_type
, last
(billing.note) AS last_billing_note
, max
(billing.billing_ts) AS last_billing_ts
, sum
(CASE WHEN billing.voided THEN
(0)::numeric ELSE COALESCE
(billing.amount
, (0)::numeric
) END
) AS total_owed
FROM money.billing
GROUP BY billing.xact
ORDER BY max
(billing.billing_ts);
Index -
Schema money
money.transaction_payment_summary Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
last_payment_type |
name |
|
|
last_payment_note |
text |
|
|
last_payment_ts |
timestamp with time zone |
|
|
total_paid |
numeric |
|
SELECT payment_view.xact
, last
(payment_view.payment_type) AS last_payment_type
, last
(payment_view.note) AS last_payment_note
, max
(payment_view.payment_ts) AS last_payment_ts
, sum
(COALESCE
(payment_view.amount
, (0)::numeric
)
) AS total_paid
FROM money.payment_view
WHERE (payment_view.voided IS FALSE)
GROUP BY payment_view.xact
ORDER BY max
(payment_view.payment_ts);
Index -
Schema money
money.transaction_payment_with_void_summary Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
last_payment_type |
name |
|
|
last_payment_note |
text |
|
|
last_payment_ts |
timestamp with time zone |
|
|
total_paid |
numeric |
|
SELECT payment_view.xact
, last
(payment_view.payment_type) AS last_payment_type
, last
(payment_view.note) AS last_payment_note
, max
(payment_view.payment_ts) AS last_payment_ts
, sum
(CASE WHEN payment_view.voided THEN
(0)::numeric ELSE COALESCE
(payment_view.amount
, (0)::numeric
) END
) AS total_paid
FROM money.payment_view
GROUP BY payment_view.xact
ORDER BY max
(payment_view.payment_ts);
Index -
Schema money
money.usr_circulation_summary Structure
F-Key |
Name |
Type |
Description |
|
usr |
integer |
|
|
total_paid |
numeric |
|
|
total_owed |
numeric |
|
|
balance_owed |
numeric |
|
SELECT billable_xact_summary.usr
, sum
(billable_xact_summary.total_paid) AS total_paid
, sum
(billable_xact_summary.total_owed) AS total_owed
, sum
(billable_xact_summary.balance_owed) AS balance_owed
FROM money.billable_xact_summary
WHERE (billable_xact_summary.xact_type = 'circulation'::name)
GROUP BY billable_xact_summary.usr;
Index -
Schema money
money.usr_summary Structure
F-Key |
Name |
Type |
Description |
|
usr |
integer |
|
|
total_paid |
numeric |
|
|
total_owed |
numeric |
|
|
balance_owed |
numeric |
|
SELECT materialized_billable_xact_summary.usr
, sum
(materialized_billable_xact_summary.total_paid) AS total_paid
, sum
(materialized_billable_xact_summary.total_owed) AS total_owed
, sum
(materialized_billable_xact_summary.balance_owed) AS balance_owed
FROM money.materialized_billable_xact_summary
GROUP BY materialized_billable_xact_summary.usr;
Index -
Schema money
money.work_payment Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('money.payment_id_seq'::regclass)
|
|
xact |
bigint |
NOT NULL
|
|
payment_ts |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
voided |
boolean |
NOT NULL
DEFAULT false
|
|
amount |
numeric(6,2) |
NOT NULL
|
|
note |
text |
|
|
amount_collected |
numeric(6,2) |
NOT NULL
|
|
accepting_usr |
integer |
NOT NULL
|
Table money.work_payment Inherits
bnm_payment,
money_work_id_idx id
money_work_payment_accepting_usr_idx accepting_usr
money_work_payment_payment_ts_idx payment_ts
money_work_payment_xact_idx xact
Index -
Schema money
Returns: trigger
Language: PLPGSQL
BEGIN
INSERT INTO money.materialized_billable_xact_summary (id, usr, xact_start, xact_finish, total_paid, total_owed, balance_owed, xact_type)
VALUES ( NEW.id, NEW.usr, NEW.xact_start, NEW.xact_finish, 0.0, 0.0, 0.0, TG_ARGV[0]);
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
DELETE FROM money.materialized_billable_xact_summary WHERE id = OLD.id;
RETURN OLD;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
UPDATE money.materialized_billable_xact_summary
SET usr = NEW.usr,
xact_start = NEW.xact_start,
xact_finish = NEW.xact_finish
WHERE id = NEW.id;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF NOT NEW.voided THEN
UPDATE money.materialized_billable_xact_summary
SET total_owed = COALESCE(total_owed, 0.0::numeric) + NEW.amount,
last_billing_ts = NEW.billing_ts,
last_billing_note = NEW.note,
last_billing_type = NEW.billing_type,
balance_owed = balance_owed + NEW.amount
WHERE id = NEW.xact;
END IF;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
prev_billing money.billing%ROWTYPE;
old_billing money.billing%ROWTYPE;
BEGIN
SELECT * INTO prev_billing FROM money.billing WHERE xact = OLD.xact AND NOT voided ORDER BY billing_ts DESC LIMIT 1 OFFSET 1;
SELECT * INTO old_billing FROM money.billing WHERE xact = OLD.xact AND NOT voided ORDER BY billing_ts DESC LIMIT 1;
IF OLD.id = old_billing.id THEN
UPDATE money.materialized_billable_xact_summary
SET last_billing_ts = prev_billing.billing_ts,
last_billing_note = prev_billing.note,
last_billing_type = prev_billing.billing_type
WHERE id = OLD.xact;
END IF;
IF NOT OLD.voided THEN
UPDATE money.materialized_billable_xact_summary
SET total_owed = total_owed - OLD.amount,
balance_owed = balance_owed + OLD.amount
WHERE id = OLD.xact;
END IF;
RETURN OLD;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
old_billing money.billing%ROWTYPE;
old_voided money.billing%ROWTYPE;
BEGIN
SELECT * INTO old_billing FROM money.billing WHERE xact = NEW.xact AND NOT voided ORDER BY billing_ts DESC LIMIT 1;
SELECT * INTO old_voided FROM money.billing WHERE xact = NEW.xact ORDER BY billing_ts DESC LIMIT 1;
IF NEW.voided AND NOT OLD.voided THEN
IF OLD.id = old_voided.id THEN
UPDATE money.materialized_billable_xact_summary
SET last_billing_ts = old_billing.billing_ts,
last_billing_note = old_billing.note,
last_billing_type = old_billing.billing_type
WHERE id = OLD.xact;
END IF;
UPDATE money.materialized_billable_xact_summary
SET total_owed = total_owed - NEW.amount,
balance_owed = balance_owed - NEW.amount
WHERE id = NEW.xact;
ELSIF NOT NEW.voided AND OLD.voided THEN
IF OLD.id = old_billing.id THEN
UPDATE money.materialized_billable_xact_summary
SET last_billing_ts = old_billing.billing_ts,
last_billing_note = old_billing.note,
last_billing_type = old_billing.billing_type
WHERE id = OLD.xact;
END IF;
UPDATE money.materialized_billable_xact_summary
SET total_owed = total_owed + NEW.amount,
balance_owed = balance_owed + NEW.amount
WHERE id = NEW.xact;
ELSE
UPDATE money.materialized_billable_xact_summary
SET total_owed = total_owed - (OLD.amount - NEW.amount),
balance_owed = balance_owed - (OLD.amount - NEW.amount)
WHERE id = NEW.xact;
END IF;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF NOT NEW.voided THEN
UPDATE money.materialized_billable_xact_summary
SET total_paid = COALESCE(total_paid, 0.0::numeric) + NEW.amount,
last_payment_ts = NEW.payment_ts,
last_payment_note = NEW.note,
last_payment_type = TG_ARGV[0],
balance_owed = balance_owed - NEW.amount
WHERE id = NEW.xact;
END IF;
RETURN NEW;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
prev_payment money.payment_view%ROWTYPE;
old_payment money.payment_view%ROWTYPE;
BEGIN
SELECT * INTO prev_payment FROM money.payment_view WHERE xact = OLD.xact AND NOT voided ORDER BY payment_ts DESC LIMIT 1 OFFSET 1;
SELECT * INTO old_payment FROM money.payment_view WHERE xact = OLD.xact AND NOT voided ORDER BY payment_ts DESC LIMIT 1;
IF OLD.id = old_payment.id THEN
UPDATE money.materialized_billable_xact_summary
SET last_payment_ts = prev_payment.payment_ts,
last_payment_note = prev_payment.note,
last_payment_type = prev_payment.payment_type
WHERE id = OLD.xact;
END IF;
IF NOT OLD.voided THEN
UPDATE money.materialized_billable_xact_summary
SET total_paid = total_paid - OLD.amount,
balance_owed = balance_owed + OLD.amount
WHERE id = OLD.xact;
END IF;
RETURN OLD;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
old_payment money.payment_view%ROWTYPE;
old_voided money.payment_view%ROWTYPE;
BEGIN
SELECT * INTO old_payment FROM money.payment_view WHERE xact = NEW.xact AND NOT voided ORDER BY payment_ts DESC LIMIT 1;
SELECT * INTO old_voided FROM money.payment_view WHERE xact = NEW.xact ORDER BY payment_ts DESC LIMIT 1;
IF NEW.voided AND NOT OLD.voided THEN
IF OLD.id = old_voided.id THEN
UPDATE money.materialized_billable_xact_summary
SET last_payment_ts = old_payment.payment_ts,
last_payment_note = old_payment.note,
last_payment_type = old_payment.payment_type
WHERE id = OLD.xact;
END IF;
UPDATE money.materialized_billable_xact_summary
SET total_paid = total_paid - NEW.amount,
balance_owed = balance_owed + NEW.amount
WHERE id = NEW.xact;
ELSIF NOT NEW.voided AND OLD.voided THEN
IF OLD.id = old_payment.id THEN
UPDATE money.materialized_billable_xact_summary
SET last_payment_ts = old_payment.payment_ts,
last_payment_note = old_payment.note,
last_payment_type = old_payment.payment_type
WHERE id = OLD.xact;
END IF;
UPDATE money.materialized_billable_xact_summary
SET total_paid = total_paid + NEW.amount,
balance_owed = balance_owed - NEW.amount
WHERE id = NEW.xact;
ELSE
UPDATE money.materialized_billable_xact_summary
SET total_paid = total_paid - (OLD.amount - NEW.amount),
balance_owed = balance_owed + (OLD.amount - NEW.amount)
WHERE id = NEW.xact;
END IF;
RETURN NEW;
END;
Schema offline
offline.script Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
session |
text |
NOT NULL
|
|
requestor |
integer |
NOT NULL
|
|
create_time |
integer |
NOT NULL
|
|
workstation |
text |
NOT NULL
|
|
logfile |
text |
NOT NULL
|
|
time_delta |
integer |
NOT NULL
|
|
count |
integer |
NOT NULL
|
offline_script_pkey id
offline_script_session session
offline_script_ws workstation
Index -
Schema offline
offline.session Structure
F-Key |
Name |
Type |
Description |
|
key |
text |
PRIMARY KEY
|
|
org |
integer |
NOT NULL
|
|
description |
text |
|
|
creator |
integer |
NOT NULL
|
|
create_time |
integer |
NOT NULL
|
|
in_process |
integer |
NOT NULL
|
|
start_time |
integer |
|
|
end_time |
integer |
|
|
num_complete |
integer |
NOT NULL
|
offline_session_creation create_time
offline_session_org org
offline_session_pkey key
Index -
Schema offline
Schema permission
Index -
Schema permission
permission.grp_perm_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
permission.grp_tree.id
|
grp |
integer |
UNIQUE#1
NOT NULL
|
permission.perm_list.id
|
perm |
integer |
UNIQUE#1
NOT NULL
|
|
depth |
integer |
NOT NULL
|
|
grantable |
boolean |
NOT NULL
DEFAULT false
|
Index -
Schema permission
permission.grp_tree Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE
NOT NULL
|
permission.grp_tree.id
|
parent |
integer |
|
|
usergroup |
boolean |
NOT NULL
DEFAULT true
|
|
perm_interval |
interval |
NOT NULL
DEFAULT '3 years'::interval
|
|
description |
text |
|
|
application_perm |
text |
|
|
hold_priority |
integer |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
grp_tree_parent_idx parent
Index -
Schema permission
permission.perm_list Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
code |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
Tables referencing this one via Foreign Key Constraints:
perm_list_code_idx code
Index -
Schema permission
permission.usr_grp_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
UNIQUE#1
NOT NULL
|
permission.grp_tree.id
|
grp |
integer |
UNIQUE#1
NOT NULL
|
Index -
Schema permission
permission.usr_object_perm_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
UNIQUE#1
NOT NULL
|
permission.perm_list.id
|
perm |
integer |
UNIQUE#1
NOT NULL
|
|
object_type |
text |
UNIQUE#1
NOT NULL
|
|
object_id |
text |
UNIQUE#1
NOT NULL
|
|
grantable |
boolean |
NOT NULL
DEFAULT false
|
uopm_usr_idx usr
Index -
Schema permission
permission.usr_perm_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
UNIQUE#1
NOT NULL
|
permission.perm_list.id
|
perm |
integer |
UNIQUE#1
NOT NULL
|
|
depth |
integer |
NOT NULL
|
|
grantable |
boolean |
NOT NULL
DEFAULT false
|
Index -
Schema permission
permission.usr_work_ou_map Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
usr |
integer |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
work_ou |
integer |
UNIQUE#1
NOT NULL
|
Index -
Schema permission
Returns: SET OF grp_tree
Language: SQL
SELECT a.*
FROM connectby('permission.grp_tree'::text,'parent'::text,'id'::text,'name'::text,$1::text,100,'.'::text)
AS t(keyid text, parent_keyid text, level int, branch text,pos int)
JOIN permission.grp_tree a ON a.id::text = t.keyid::text
ORDER BY
CASE WHEN a.parent IS NULL
THEN 0
ELSE 1
END, a.name;
Returns: SET OF record
Language: SQL
WITH RECURSIVE grp_ancestors_distance(id, distance) AS (
SELECT $1, 0
UNION
SELECT pgt.parent, gad.distance+1
FROM permission.grp_tree pgt JOIN grp_ancestors_distance gad ON (pgt.id = gad.id)
WHERE pgt.parent IS NOT NULL
)
SELECT * FROM grp_ancestors_distance;
Returns: SET OF record
Language: SQL
WITH RECURSIVE grp_descendants_distance(id, distance) AS (
SELECT $1, 0
UNION
SELECT pgt.id, gdd.distance+1
FROM permission.grp_tree pgt JOIN grp_descendants_distance gdd ON (pgt.parent = gdd.id)
)
SELECT * FROM grp_descendants_distance;
Returns: boolean
Language: PLPGSQL
DECLARE
r_usr actor.usr%ROWTYPE;
r_perm permission.usr_perm_map%ROWTYPE;
BEGIN
SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;
IF r_usr.active = FALSE THEN
RETURN FALSE;
END IF;
IF r_usr.super_user = TRUE THEN
RETURN TRUE;
END IF;
FOR r_perm IN SELECT *
FROM permission.usr_perms(iuser) p
JOIN permission.perm_list l
ON (l.id = p.perm)
WHERE (l.code = tperm AND p.grantable IS TRUE)
LOOP
PERFORM *
FROM actor.org_unit_descendants(target_ou,r_perm.depth)
WHERE id = r_usr.home_ou;
IF FOUND THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END LOOP;
RETURN FALSE;
END;
Returns: boolean
Language: PLPGSQL
DECLARE
r_usr actor.usr%ROWTYPE;
r_perm permission.usr_perm_map%ROWTYPE;
BEGIN
SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;
IF r_usr.active = FALSE THEN
RETURN FALSE;
END IF;
IF r_usr.super_user = TRUE THEN
RETURN TRUE;
END IF;
FOR r_perm IN SELECT *
FROM permission.usr_perms(iuser) p
JOIN permission.perm_list l
ON (l.id = p.perm)
WHERE l.code = tperm
OR p.perm = -1 LOOP
PERFORM *
FROM actor.org_unit_descendants(target_ou,r_perm.depth)
WHERE id = r_usr.home_ou;
IF FOUND THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END LOOP;
RETURN FALSE;
END;
Returns: boolean
Language: SQL
SELECT permission.usr_has_object_perm( $1, $2, $3, $4, -1 );
Returns: boolean
Language: PLPGSQL
DECLARE
r_usr actor.usr%ROWTYPE;
res BOOL;
BEGIN
SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;
IF r_usr.active = FALSE THEN
RETURN FALSE;
END IF;
IF r_usr.super_user = TRUE THEN
RETURN TRUE;
END IF;
SELECT TRUE INTO res FROM permission.usr_object_perm_map WHERE usr = r_usr.id AND object_type = obj_type AND object_id = obj_id;
IF FOUND THEN
RETURN TRUE;
END IF;
IF target_ou > -1 THEN
RETURN permission.usr_has_perm( iuser, tperm, target_ou);
END IF;
RETURN FALSE;
END;
Returns: boolean
Language: SQL
SELECT CASE
WHEN permission.usr_has_home_perm( $1, $2, $3 ) THEN TRUE
WHEN permission.usr_has_work_perm( $1, $2, $3 ) THEN TRUE
ELSE FALSE
END;
Returns: SET OF integer
Language: SQL
SELECT DISTINCT * FROM permission.usr_has_perm_at_nd( $1, $2 );
Returns: SET OF integer
Language: SQL
SELECT DISTINCT * FROM permission.usr_has_perm_at_all_nd( $1, $2 );
Returns: SET OF integer
Language: PLPGSQL
--
-- Return a set of all the org units for which a given user has a given
-- permission, granted either directly or through inheritance from a parent
-- org unit.
--
-- The permissions apply to a minimum depth of the org unit hierarchy, and
-- to the subordinates of those org units, for the org unit(s) to which the
-- user is assigned.
--
-- For purposes of this function, the permission.usr_work_ou_map table
-- assigns users to org units. I.e. we ignore the home_ou column of actor.usr.
--
-- The result set may contain duplicates, which should be eliminated
-- by a DISTINCT clause.
--
DECLARE
n_head_ou INTEGER;
n_child_ou INTEGER;
BEGIN
FOR n_head_ou IN
SELECT DISTINCT * FROM permission.usr_has_perm_at_nd( user_id, perm_code )
LOOP
--
-- The permission applies only at a depth greater than the work org unit.
-- Use connectby() to find all dependent org units at the specified depth.
--
FOR n_child_ou IN
SELECT ou::INTEGER
FROM connectby(
'actor.org_unit', -- table name
'id', -- key column
'parent_ou', -- recursive foreign key
n_head_ou::TEXT, -- id of starting point
0 -- no limit on search depth
)
AS t(
ou text, -- dependent org unit
parent_ou text, -- (ignore)
level int -- (ignore)
)
LOOP
RETURN NEXT n_child_ou;
END LOOP;
END LOOP;
--
RETURN;
--
END;
Returns: SET OF integer
Language: PLPGSQL
--
-- Return a set of all the org units for which a given user has a given
-- permission, granted directly (not through inheritance from a parent
-- org unit).
--
-- The permissions apply to a minimum depth of the org unit hierarchy,
-- for the org unit(s) to which the user is assigned. (They also apply
-- to the subordinates of those org units, but we don't report the
-- subordinates here.)
--
-- For purposes of this function, the permission.usr_work_ou_map table
-- defines which users belong to which org units. I.e. we ignore the
-- home_ou column of actor.usr.
--
-- The result set may contain duplicates, which should be eliminated
-- by a DISTINCT clause.
--
DECLARE
b_super BOOLEAN;
n_perm INTEGER;
n_min_depth INTEGER;
n_work_ou INTEGER;
n_curr_ou INTEGER;
n_depth INTEGER;
n_curr_depth INTEGER;
BEGIN
--
-- Check for superuser
--
SELECT INTO b_super
super_user
FROM
actor.usr
WHERE
id = user_id;
--
IF NOT FOUND THEN
return; -- No user? No permissions.
ELSIF b_super THEN
--
-- Super user has all permissions everywhere
--
FOR n_work_ou IN
SELECT
id
FROM
actor.org_unit
WHERE
parent_ou IS NULL
LOOP
RETURN NEXT n_work_ou;
END LOOP;
RETURN;
END IF;
--
-- Translate the permission name
-- to a numeric permission id
--
SELECT INTO n_perm
id
FROM
permission.perm_list
WHERE
code = perm_code;
--
IF NOT FOUND THEN
RETURN; -- No such permission
END IF;
--
-- Find the highest-level org unit (i.e. the minimum depth)
-- to which the permission is applied for this user
--
-- This query is modified from the one in permission.usr_perms().
--
SELECT INTO n_min_depth
min( depth )
FROM (
SELECT depth
FROM permission.usr_perm_map upm
WHERE upm.usr = user_id
AND (upm.perm = n_perm OR upm.perm = -1)
UNION
SELECT gpm.depth
FROM permission.grp_perm_map gpm
WHERE (gpm.perm = n_perm OR gpm.perm = -1)
AND gpm.grp IN (
SELECT (permission.grp_ancestors(
(SELECT profile FROM actor.usr WHERE id = user_id)
)).id
)
UNION
SELECT p.depth
FROM permission.grp_perm_map p
WHERE (p.perm = n_perm OR p.perm = -1)
AND p.grp IN (
SELECT (permission.grp_ancestors(m.grp)).id
FROM permission.usr_grp_map m
WHERE m.usr = user_id
)
) AS x;
--
IF NOT FOUND THEN
RETURN; -- No such permission for this user
END IF;
--
-- Identify the org units to which the user is assigned. Note that
-- we pay no attention to the home_ou column in actor.usr.
--
FOR n_work_ou IN
SELECT
work_ou
FROM
permission.usr_work_ou_map
WHERE
usr = user_id
LOOP -- For each org unit to which the user is assigned
--
-- Determine the level of the org unit by a lookup in actor.org_unit_type.
-- We take it on faith that this depth agrees with the actual hierarchy
-- defined in actor.org_unit.
--
SELECT INTO n_depth
type.depth
FROM
actor.org_unit_type type
INNER JOIN actor.org_unit ou
ON ( ou.ou_type = type.id )
WHERE
ou.id = n_work_ou;
--
IF NOT FOUND THEN
CONTINUE; -- Maybe raise exception?
END IF;
--
-- Compare the depth of the work org unit to the
-- minimum depth, and branch accordingly
--
IF n_depth = n_min_depth THEN
--
-- The org unit is at the right depth, so return it.
--
RETURN NEXT n_work_ou;
ELSIF n_depth > n_min_depth THEN
--
-- Traverse the org unit tree toward the root,
-- until you reach the minimum depth determined above
--
n_curr_depth := n_depth;
n_curr_ou := n_work_ou;
WHILE n_curr_depth > n_min_depth LOOP
SELECT INTO n_curr_ou
parent_ou
FROM
actor.org_unit
WHERE
id = n_curr_ou;
--
IF FOUND THEN
n_curr_depth := n_curr_depth - 1;
ELSE
--
-- This can happen only if the hierarchy defined in
-- actor.org_unit is corrupted, or out of sync with
-- the depths defined in actor.org_unit_type.
-- Maybe we should raise an exception here, instead
-- of silently ignoring the problem.
--
n_curr_ou = NULL;
EXIT;
END IF;
END LOOP;
--
IF n_curr_ou IS NOT NULL THEN
RETURN NEXT n_curr_ou;
END IF;
ELSE
--
-- The permission applies only at a depth greater than the work org unit.
-- Use connectby() to find all dependent org units at the specified depth.
--
FOR n_curr_ou IN
SELECT ou::INTEGER
FROM connectby(
'actor.org_unit', -- table name
'id', -- key column
'parent_ou', -- recursive foreign key
n_work_ou::TEXT, -- id of starting point
(n_min_depth - n_depth) -- max depth to search, relative
) -- to starting point
AS t(
ou text, -- dependent org unit
parent_ou text, -- (ignore)
level int -- depth relative to starting point
)
WHERE
level = n_min_depth - n_depth
LOOP
RETURN NEXT n_curr_ou;
END LOOP;
END IF;
--
END LOOP;
--
RETURN;
--
END;
Returns: boolean
Language: PLPGSQL
DECLARE
r_woum permission.usr_work_ou_map%ROWTYPE;
r_usr actor.usr%ROWTYPE;
r_perm permission.usr_perm_map%ROWTYPE;
BEGIN
SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;
IF r_usr.active = FALSE THEN
RETURN FALSE;
END IF;
IF r_usr.super_user = TRUE THEN
RETURN TRUE;
END IF;
FOR r_perm IN SELECT *
FROM permission.usr_perms(iuser) p
JOIN permission.perm_list l
ON (l.id = p.perm)
WHERE l.code = tperm
OR p.perm = -1
LOOP
FOR r_woum IN SELECT *
FROM permission.usr_work_ou_map
WHERE usr = iuser
LOOP
PERFORM *
FROM actor.org_unit_descendants(target_ou,r_perm.depth)
WHERE id = r_woum.work_ou;
IF FOUND THEN
RETURN TRUE;
END IF;
END LOOP;
END LOOP;
RETURN FALSE;
END;
Returns: SET OF usr_perm_map
Language: SQL
SELECT DISTINCT ON (usr,perm) *
FROM (
(SELECT * FROM permission.usr_perm_map WHERE usr = $1)
UNION ALL
(SELECT -p.id, $1 AS usr, p.perm, p.depth, p.grantable
FROM permission.grp_perm_map p
WHERE p.grp IN (
SELECT (permission.grp_ancestors(
(SELECT profile FROM actor.usr WHERE id = $1)
)).id
)
)
UNION ALL
(SELECT -p.id, $1 AS usr, p.perm, p.depth, p.grantable
FROM permission.grp_perm_map p
WHERE p.grp IN (SELECT (permission.grp_ancestors(m.grp)).id FROM permission.usr_grp_map m WHERE usr = $1))
) AS x
ORDER BY 2, 3, 1 DESC, 5 DESC ;
Schema public
standard public schema
Returns: text
Language: SQL
select prsname::text from pg_catalog.pg_ts_parser p join pg_ts_config c on cfgparser = p.oid where c.oid = show_curcfg();
Returns: text
Language: INTERNAL
aggregate_dummy
Returns: text[]
Language: C
hstore_akeys
Returns: text
Language: SQL
SELECT REGEXP_REPLACE( $1, E'\\D', $2, 'g' );
Returns: text
Language: SQL
SELECT approximate_date( $1, '9');
Returns: text
Language: SQL
SELECT approximate_date( $1, '0');
Returns: text[]
Language: C
hstore_avals
Returns: text
Language: PLPERLU
my $txt = shift;
$txt =~ s/^\s+//o;
$txt =~ s/[\[\]\{\}\(\)`'"#<>\*\?\-\+\$\\]+//og;
$txt =~ s/\s+$//o;
if ($txt =~ /(\d{3}(?:\.\d+)?)/o) {
return $1;
} else {
return (split /\s+/, $txt)[0];
}
Returns: text
Language: SQL
SELECT SUBSTRING(call_number_dewey($1) FROM 1 FOR $2);
Returns: trigger
Language: PLPGSQL
BEGIN
IF TG_OP = 'UPDATE' THEN
DELETE FROM acq.lineitem_attr
WHERE lineitem = OLD.id AND attr_type IN ('lineitem_provider_attr_definition', 'lineitem_marc_attr_definition','lineitem_generated_attr_definition');
RETURN NEW;
ELSE
DELETE FROM acq.lineitem_attr WHERE lineitem = OLD.id;
RETURN OLD;
END IF;
END;
Returns: tsvector
Language: INTERNAL
tsvector_concat
Returns: SET OF record
Language: C
connectby_text
Returns: SET OF record
Language: C
connectby_text
Returns: SET OF record
Language: C
connectby_text_serial
Returns: SET OF record
Language: C
connectby_text_serial
Returns: text
Language: SQL
SELECT CASE WHEN $1 ~ E'^\\s*$' THEN NULL ELSE $1 END
Returns: SET OF record
Language: C
crosstab
Returns: SET OF record
Language: C
crosstab
Returns: SET OF record
Language: C
crosstab_hash
Returns: SET OF tablefunc_crosstab_2
Language: C
crosstab
Returns: SET OF tablefunc_crosstab_3
Language: C
crosstab
Returns: SET OF tablefunc_crosstab_4
Language: C
crosstab
Returns: boolean
Language: C
hstore_defined
Returns: hstore
Language: C
hstore_delete_hstore
Returns: hstore
Language: C
hstore_delete
Returns: hstore
Language: C
hstore_delete_array
Returns: internal
Language: C
tsa_dex_init
Returns: internal
Language: C
tsa_dex_lexize
Returns: SET OF record
Language: C
hstore_each
Returns: text
Language: PLPERLU
use Unicode::Normalize;
my $x = NFC(shift);
$x =~ s/([\x{0080}-\x{fffd}])/sprintf('&#x%X;',ord($1))/sgoe;
return $x;
Returns: boolean
Language: C
hstore_exists
Returns: boolean
Language: C
hstore_exists_all
Returns: boolean
Language: C
hstore_exists_any
Returns: text
Language: SQL
SELECT extract_marc_field('acq.lineitem', $1, $2, $3);
Returns: text
Language: C
hstore_fetchval
Returns: anyelement
Language: INTERNAL
aggregate_dummy
Returns: text
Language: SQL
SELECT SUBSTRING( $1, 1, 5);
Returns: anyelement
Language: SQL
SELECT CASE WHEN $1 IS NULL THEN $2 ELSE $1 END;
Returns: text
Language: SQL
SELECT COALESCE(SUBSTRING( $1 FROM $_$^\S+$_$), '');
Returns: text
Language: PLPERLU
Inspired by translate_isbn1013
The force_to_isbn13 function takes an input ISBN and returns the ISBN13
version without hypens and with a repaired checksum if the checksum was bad
use Business::ISBN;
use strict;
use warnings;
# Find the first ISBN, force it to ISBN13 and return it
my $input = shift;
foreach my $word (split(/\s/, $input)) {
my $isbn = Business::ISBN->new($word);
# First check the checksum; if it is not valid, fix it and add the original
# bad-checksum ISBN to the output
if ($isbn && $isbn->is_valid_checksum() == Business::ISBN::BAD_CHECKSUM) {
$isbn->fix_checksum();
}
# If we now have a valid ISBN, force it to ISBN13 and return it
return $isbn->as_isbn13->isbn if ($isbn && $isbn->is_valid());
}
return undef;
Returns: text
Language: C
tsa_get_covers
Returns: internal
Language: C
ghstore_compress
Returns: boolean
Language: C
ghstore_consistent
Returns: internal
Language: C
ghstore_decompress
Returns: ghstore
Language: C
ghstore_in
Returns: cstring
Language: C
ghstore_out
Returns: internal
Language: C
ghstore_penalty
Returns: internal
Language: C
ghstore_picksplit
Returns: internal
Language: C
ghstore_same
Returns: internal
Language: C
ghstore_union
Returns: boolean
Language: C
gin_consistent_hstore
Returns: internal
Language: C
gin_extract_hstore
Returns: internal
Language: C
gin_extract_hstore_query
Returns: text
Language: INTERNAL
ts_headline_byid
Returns: text
Language: INTERNAL
ts_headline_byid_opt
Returns: text
Language: C
tsa_headline_byname
Returns: text
Language: C
tsa_headline_byname
Returns: text
Language: INTERNAL
ts_headline
Returns: text
Language: INTERNAL
ts_headline_opt
Returns: hstore
Language: C
hstore_concat
Returns: boolean
Language: C
hstore_contained
Returns: boolean
Language: C
hstore_contains
Returns: hstore
Language: C
hstore_from_record
Returns: hstore
Language: C
hstore_from_text
Returns: hstore
Language: C
hstore_from_array
Returns: hstore
Language: C
hstore_from_arrays
Returns: integer
Language: C
hstore_cmp
Returns: boolean
Language: C
hstore_eq
Returns: boolean
Language: C
hstore_ge
Returns: boolean
Language: C
hstore_gt
Returns: integer
Language: C
hstore_hash
Returns: hstore
Language: C
hstore_in
Returns: boolean
Language: C
hstore_le
Returns: boolean
Language: C
hstore_lt
Returns: boolean
Language: C
hstore_ne
Returns: cstring
Language: C
hstore_out
Returns: hstore
Language: C
hstore_recv
Returns: bytea
Language: C
hstore_send
Returns: text[]
Language: C
hstore_to_array
Returns: text[]
Language: C
hstore_to_matrix
Returns: integer
Language: C
hstore_version_diag
Returns: trigger
Language: PLPGSQL
DECLARE
value TEXT;
atype TEXT;
prov INT;
pos INT;
adef RECORD;
xpath_string TEXT;
BEGIN
FOR adef IN SELECT *,tableoid FROM acq.lineitem_attr_definition LOOP
SELECT relname::TEXT INTO atype FROM pg_class WHERE oid = adef.tableoid;
IF (atype NOT IN ('lineitem_usr_attr_definition','lineitem_local_attr_definition')) THEN
IF (atype = 'lineitem_provider_attr_definition') THEN
SELECT provider INTO prov FROM acq.lineitem_provider_attr_definition WHERE id = adef.id;
CONTINUE WHEN NEW.provider IS NULL OR prov <> NEW.provider;
END IF;
IF (atype = 'lineitem_provider_attr_definition') THEN
SELECT xpath INTO xpath_string FROM acq.lineitem_provider_attr_definition WHERE id = adef.id;
ELSIF (atype = 'lineitem_marc_attr_definition') THEN
SELECT xpath INTO xpath_string FROM acq.lineitem_marc_attr_definition WHERE id = adef.id;
ELSIF (atype = 'lineitem_generated_attr_definition') THEN
SELECT xpath INTO xpath_string FROM acq.lineitem_generated_attr_definition WHERE id = adef.id;
END IF;
xpath_string := REGEXP_REPLACE(xpath_string,$re$//?text\(\)$$re$,'');
IF (adef.code = 'title' OR adef.code = 'author') THEN
-- title and author should not be split
-- FIXME: once oils_xpath can grok XPATH 2.0 functions, we can use
-- string-join in the xpath and remove this special case
SELECT extract_acq_marc_field(id, xpath_string, adef.remove) INTO value FROM acq.lineitem WHERE id = NEW.id;
IF (value IS NOT NULL AND value <> '') THEN
INSERT INTO acq.lineitem_attr (lineitem, definition, attr_type, attr_name, attr_value)
VALUES (NEW.id, adef.id, atype, adef.code, value);
END IF;
ELSE
pos := 1;
LOOP
SELECT extract_acq_marc_field(id, xpath_string || '[' || pos || ']', adef.remove) INTO value FROM acq.lineitem WHERE id = NEW.id;
IF (value IS NOT NULL AND value <> '') THEN
INSERT INTO acq.lineitem_attr (lineitem, definition, attr_type, attr_name, attr_value)
VALUES (NEW.id, adef.id, atype, adef.code, value);
ELSE
EXIT;
END IF;
pos := pos + 1;
END LOOP;
END IF;
END IF;
END LOOP;
RETURN NULL;
END;
Returns: text
Language: SQL
SELECT CASE WHEN $1 ~ E'^\\d+$' THEN $1 ELSE NULL END
Returns: boolean
Language: C
hstore_defined
Returns: boolean
Language: C
hstore_exists
Returns: anyelement
Language: INTERNAL
aggregate_dummy
Returns: anyelement
Language: SQL
SELECT $2;
Returns: text
Language: SQL
SELECT SUBSTRING($1,$2);
Returns: integer
Language: INTERNAL
tsvector_length
Returns: text[]
Language: INTERNAL
ts_lexize
Returns: text[]
Language: C
tsa_lexize_bycurrent
Returns: text[]
Language: C
tsa_lexize_byname
Returns: text
Language: PLPERLU
return lc(shift);
Returns: text
Language: SQL
SELECT public.naco_normalize($1,'');
Returns: text
Language: PLPERLU
use strict;
use Unicode::Normalize;
use Encode;
my $str = decode_utf8(shift);
my $sf = shift;
# Apply NACO normalization to input string; based on
# http://www.loc.gov/catdir/pcc/naco/SCA_PccNormalization_Final_revised.pdf
#
# Note that unlike a strict reading of the NACO normalization rules,
# output is returned as lowercase instead of uppercase for compatibility
# with previous versions of the Evergreen naco_normalize routine.
# Convert to upper-case first; even though final output will be lowercase, doing this will
# ensure that the German eszett (ß) and certain ligatures (ff, fi, ffl, etc.) will be handled correctly.
# If there are any bugs in Perl's implementation of upcasing, they will be passed through here.
$str = uc $str;
# remove non-filing strings
$str =~ s/\x{0098}.*?\x{009C}//g;
$str = NFKD($str);
# additional substitutions - 3.6.
$str =~ s/\x{00C6}/AE/g;
$str =~ s/\x{00DE}/TH/g;
$str =~ s/\x{0152}/OE/g;
$str =~ tr/\x{0110}\x{00D0}\x{00D8}\x{0141}\x{2113}\x{02BB}\x{02BC}]['/DDOLl/d;
# transformations based on Unicode category codes
$str =~ s/[\p{Cc}\p{Cf}\p{Co}\p{Cs}\p{Lm}\p{Mc}\p{Me}\p{Mn}]//g;
if ($sf && $sf =~ /^a/o) {
my $commapos = index($str, ',');
if ($commapos > -1) {
if ($commapos != length($str) - 1) {
$str =~ s/,/\x07/; # preserve first comma
}
}
}
# since we've stripped out the control characters, we can now
# use a few as placeholders temporarily
$str =~ tr/+&@\x{266D}\x{266F}#/\x01\x02\x03\x04\x05\x06/;
$str =~ s/[\p{Pc}\p{Pd}\p{Pe}\p{Pf}\p{Pi}\p{Po}\p{Ps}\p{Sk}\p{Sm}\p{So}\p{Zl}\p{Zp}\p{Zs}]/ /g;
$str =~ tr/\x01\x02\x03\x04\x05\x06\x07/+&@\x{266D}\x{266F}#,/;
# decimal digits
$str =~ tr/\x{0660}-\x{0669}\x{06F0}-\x{06F9}\x{07C0}-\x{07C9}\x{0966}-\x{096F}\x{09E6}-\x{09EF}\x{0A66}-\x{0A6F}\x{0AE6}-\x{0AEF}\x{0B66}-\x{0B6F}\x{0BE6}-\x{0BEF}\x{0C66}-\x{0C6F}\x{0CE6}-\x{0CEF}\x{0D66}-\x{0D6F}\x{0E50}-\x{0E59}\x{0ED0}-\x{0ED9}\x{0F20}-\x{0F29}\x{1040}-\x{1049}\x{1090}-\x{1099}\x{17E0}-\x{17E9}\x{1810}-\x{1819}\x{1946}-\x{194F}\x{19D0}-\x{19D9}\x{1A80}-\x{1A89}\x{1A90}-\x{1A99}\x{1B50}-\x{1B59}\x{1BB0}-\x{1BB9}\x{1C40}-\x{1C49}\x{1C50}-\x{1C59}\x{A620}-\x{A629}\x{A8D0}-\x{A8D9}\x{A900}-\x{A909}\x{A9D0}-\x{A9D9}\x{AA50}-\x{AA59}\x{ABF0}-\x{ABF9}\x{FF10}-\x{FF19}/0-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-9/;
# intentionally skipping step 8 of the NACO algorithm; if the string
# gets normalized away, that's fine.
# leading and trailing spaces
$str =~ s/\s+/ /g;
$str =~ s/^\s+//;
$str =~ s/\s+$//g;
return lc $str;
Returns: text
Language: SQL
SELECT public.naco_normalize($1,'a');
Returns: text
Language: SQL
SELECT SUBSTRING(
REGEXP_REPLACE(
REGEXP_REPLACE(
$1,
E'\W*$',
''
),
' ',
' '
),
CASE
WHEN $2::INT NOT BETWEEN 48 AND 57 THEN 1
ELSE $2::TEXT::INT + 1
END
);
Returns: SET OF double precision
Language: C
normal_rand
Returns: text
Language: SQL
SELECT regexp_replace(regexp_replace(regexp_replace($1, E'\\n', ' ', 'g'), E'(?:^\\s+)|(\\s+$)', '', 'g'), E'\\s+', ' ', 'g');
Returns: integer
Language: INTERNAL
tsquery_numnode
Returns: trigger
Language: PLPGSQL
BEGIN
NEW.index_vector = to_tsvector((TG_ARGV[0])::regconfig, NEW.value);
RETURN NEW;
END;
Returns: SET OF tokenout
Language: INTERNAL
ts_parse_byid
Returns: SET OF tokenout
Language: C
tsa_parse_current
Returns: SET OF tokenout
Language: INTERNAL
ts_parse_byname
Returns: tsquery
Language: INTERNAL
plainto_tsquery_byid
Returns: tsquery
Language: INTERNAL
plainto_tsquery
Returns: tsquery
Language: C
tsa_plainto_tsquery_name
Returns: anyelement
Language: C
hstore_populate_record
Returns: void
Language: C
tsa_prsd_end
Returns: integer
Language: C
tsa_prsd_getlexeme
Returns: internal
Language: C
tsa_prsd_headline
Returns: internal
Language: C
tsa_prsd_lextype
Returns: internal
Language: C
tsa_prsd_start
Returns: text
Language: INTERNAL
tsquerytree
Returns: real
Language: INTERNAL
ts_rank_wtt
Returns: real
Language: INTERNAL
ts_rank_wttf
Returns: real
Language: INTERNAL
ts_rank_tt
Returns: real
Language: INTERNAL
ts_rank_ttf
Returns: real
Language: INTERNAL
ts_rankcd_wtt
Returns: real
Language: INTERNAL
ts_rankcd_wttf
Returns: real
Language: INTERNAL
ts_rankcd_tt
Returns: real
Language: INTERNAL
ts_rankcd_ttf
Returns: text
Language: SQL
SELECT regexp_replace($1, ',', '', 'g');
Returns: text
Language: PLPERLU
use Unicode::Normalize;
my $x = NFD(shift);
$x =~ s/\pM+//go;
return $x;
Returns: text
Language: SQL
SELECT regexp_replace($1, $$\([^)]+\)$$, '', 'g');
Returns: text
Language: SQL
SELECT regexp_replace(normalize_space($1), E'\\s+', '', 'g');
Returns: void
Language: C
tsa_reset_tsearch
Returns: tsquery
Language: INTERNAL
tsquery_rewrite_query
Returns: tsquery
Language: INTERNAL
tsquery_rewrite
Returns: tsquery
Language: INTERNAL
aggregate_dummy
Returns: tsquery
Language: C
tsa_rewrite_accum
Returns: tsquery
Language: C
tsa_rewrite_finish
Returns: text
Language: SQL
SELECT SUBSTRING($1,1,$2);
Returns: text
Language: SQL
SELECT public.search_normalize($1,'');
Returns: text
Language: PLPERLU
use strict;
use Unicode::Normalize;
use Encode;
my $str = decode_utf8(shift);
my $sf = shift;
# Apply NACO normalization to input string; based on
# http://www.loc.gov/catdir/pcc/naco/SCA_PccNormalization_Final_revised.pdf
#
# Note that unlike a strict reading of the NACO normalization rules,
# output is returned as lowercase instead of uppercase for compatibility
# with previous versions of the Evergreen naco_normalize routine.
# Convert to upper-case first; even though final output will be lowercase, doing this will
# ensure that the German eszett (ß) and certain ligatures (ff, fi, ffl, etc.) will be handled correctly.
# If there are any bugs in Perl's implementation of upcasing, they will be passed through here.
$str = uc $str;
# remove non-filing strings
$str =~ s/\x{0098}.*?\x{009C}//g;
$str = NFKD($str);
# additional substitutions - 3.6.
$str =~ s/\x{00C6}/AE/g;
$str =~ s/\x{00DE}/TH/g;
$str =~ s/\x{0152}/OE/g;
$str =~ tr/\x{0110}\x{00D0}\x{00D8}\x{0141}\x{2113}\x{02BB}\x{02BC}][/DDOLl/d;
# transformations based on Unicode category codes
$str =~ s/[\p{Cc}\p{Cf}\p{Co}\p{Cs}\p{Lm}\p{Mc}\p{Me}\p{Mn}]//g;
if ($sf && $sf =~ /^a/o) {
my $commapos = index($str, ',');
if ($commapos > -1) {
if ($commapos != length($str) - 1) {
$str =~ s/,/\x07/; # preserve first comma
}
}
}
# since we've stripped out the control characters, we can now
# use a few as placeholders temporarily
$str =~ tr/+&@\x{266D}\x{266F}#/\x01\x02\x03\x04\x05\x06/;
$str =~ s/[\p{Pc}\p{Pd}\p{Pe}\p{Pf}\p{Pi}\p{Po}\p{Ps}\p{Sk}\p{Sm}\p{So}\p{Zl}\p{Zp}\p{Zs}]/ /g;
$str =~ tr/\x01\x02\x03\x04\x05\x06\x07/+&@\x{266D}\x{266F}#,/;
# decimal digits
$str =~ tr/\x{0660}-\x{0669}\x{06F0}-\x{06F9}\x{07C0}-\x{07C9}\x{0966}-\x{096F}\x{09E6}-\x{09EF}\x{0A66}-\x{0A6F}\x{0AE6}-\x{0AEF}\x{0B66}-\x{0B6F}\x{0BE6}-\x{0BEF}\x{0C66}-\x{0C6F}\x{0CE6}-\x{0CEF}\x{0D66}-\x{0D6F}\x{0E50}-\x{0E59}\x{0ED0}-\x{0ED9}\x{0F20}-\x{0F29}\x{1040}-\x{1049}\x{1090}-\x{1099}\x{17E0}-\x{17E9}\x{1810}-\x{1819}\x{1946}-\x{194F}\x{19D0}-\x{19D9}\x{1A80}-\x{1A89}\x{1A90}-\x{1A99}\x{1B50}-\x{1B59}\x{1BB0}-\x{1BB9}\x{1C40}-\x{1C49}\x{1C50}-\x{1C59}\x{A620}-\x{A629}\x{A8D0}-\x{A8D9}\x{A900}-\x{A909}\x{A9D0}-\x{A9D9}\x{AA50}-\x{AA59}\x{ABF0}-\x{ABF9}\x{FF10}-\x{FF19}/0-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-9/;
# intentionally skipping step 8 of the NACO algorithm; if the string
# gets normalized away, that's fine.
# leading and trailing spaces
$str =~ s/\s+/ /g;
$str =~ s/^\s+//;
$str =~ s/\s+$//g;
return lc $str;
Returns: text
Language: SQL
SELECT public.search_normalize($1,'a');
Returns: void
Language: C
tsa_set_curcfg
Returns: void
Language: C
tsa_set_curcfg_byname
Returns: void
Language: C
tsa_set_curdict
Returns: void
Language: C
tsa_set_curdict_byname
Returns: void
Language: C
tsa_set_curprs
Returns: void
Language: C
tsa_set_curprs_byname
Returns: tsvector
Language: INTERNAL
tsvector_setweight
Returns: oid
Language: INTERNAL
get_current_ts_config
Returns: SET OF text
Language: C
hstore_skeys
Returns: hstore
Language: C
hstore_slice_to_hstore
Returns: text[]
Language: C
hstore_slice_to_array
Returns: internal
Language: C
tsa_snb_en_init
Returns: internal
Language: C
tsa_snb_lexize
Returns: internal
Language: C
tsa_snb_ru_init
Returns: internal
Language: C
tsa_snb_ru_init_koi8
Returns: internal
Language: C
tsa_snb_ru_init_utf8
Returns: internal
Language: C
tsa_spell_init
Returns: internal
Language: C
tsa_spell_lexize
Returns: text
Language: SQL
SELECT REGEXP_REPLACE( $1, E'(\\d{4})-(\\d{4})', E'\\1 \\2', 'g' );
Returns: SET OF statinfo
Language: INTERNAL
ts_stat1
Returns: SET OF statinfo
Language: INTERNAL
ts_stat2
Returns: tsvector
Language: INTERNAL
tsvector_strip
Returns: SET OF text
Language: C
hstore_svals
Returns: internal
Language: C
tsa_syn_init
Returns: internal
Language: C
tsa_syn_lexize
Returns: hstore
Language: C
hstore_from_text
Returns: text
Language: SQL
SELECT
CASE WHEN $1 IS NULL
THEN $2
WHEN $2 IS NULL
THEN $1
ELSE $1 || ' ' || $2
END;
Returns: internal
Language: C
tsa_thesaurus_init
Returns: internal
Language: C
tsa_thesaurus_lexize
Returns: tsquery
Language: INTERNAL
to_tsquery_byid
Returns: tsquery
Language: INTERNAL
to_tsquery
Returns: tsquery
Language: C
tsa_to_tsquery_name
Returns: tsvector
Language: INTERNAL
to_tsvector_byid
Returns: tsvector
Language: INTERNAL
to_tsvector
Returns: tsvector
Language: C
tsa_to_tsvector_name
Returns: SET OF tokentype
Language: C
tsa_token_type_current
Returns: SET OF tokentype
Language: INTERNAL
ts_token_type_byid
Returns: SET OF tokentype
Language: INTERNAL
ts_token_type_byname
Returns: text
Language: PLPERLU
The translate_isbn1013 function takes an input ISBN and returns the
following in a single space-delimited string if the input ISBN is valid:
- The normalized input ISBN (hyphens stripped)
- The normalized input ISBN with a fixed checksum if the checksum was bad
- The ISBN converted to its ISBN10 or ISBN13 counterpart, if possible
use Business::ISBN;
use strict;
use warnings;
# For each ISBN found in a single string containing a set of ISBNs:
# * Normalize an incoming ISBN to have the correct checksum and no hyphens
# * Convert an incoming ISBN10 or ISBN13 to its counterpart and return
my $input = shift;
my $output = '';
foreach my $word (split(/\s/, $input)) {
my $isbn = Business::ISBN->new($word);
# First check the checksum; if it is not valid, fix it and add the original
# bad-checksum ISBN to the output
if ($isbn && $isbn->is_valid_checksum() == Business::ISBN::BAD_CHECKSUM) {
$output .= $isbn->isbn() . " ";
$isbn->fix_checksum();
}
# If we now have a valid ISBN, convert it to its counterpart ISBN10/ISBN13
# and add the normalized original ISBN to the output
if ($isbn && $isbn->is_valid()) {
my $isbn_xlated = ($isbn->type eq "ISBN13") ? $isbn->as_isbn10 : $isbn->as_isbn13;
$output .= $isbn->isbn . " ";
# If we successfully converted the ISBN to its counterpart, add the
# converted ISBN to the output as well
$output .= ($isbn_xlated->isbn . " ") if ($isbn_xlated);
}
}
return $output if $output;
# If there were no valid ISBNs, just return the raw input
return $input;
Returns: SET OF tsdebug
Language: SQL
select
(select c.cfgname::text from pg_catalog.pg_ts_config as c
where c.oid = show_curcfg()),
t.alias as tok_type,
t.descr as description,
p.token,
ARRAY ( SELECT m.mapdict::pg_catalog.regdictionary::pg_catalog.text
FROM pg_catalog.pg_ts_config_map AS m
WHERE m.mapcfg = show_curcfg() AND m.maptokentype = p.tokid
ORDER BY m.mapseqno )
AS dict_name,
strip(to_tsvector(p.token)) as tsvector
from
parse( _get_parser_from_curcfg(), $1 ) as p,
token_type() as t
where
t.tokid = p.tokid
Returns: trigger
Language: C
tsa_tsearch2
Returns: boolean
Language: INTERNAL
tsq_mcontained
Returns: boolean
Language: INTERNAL
tsq_mcontains
Returns: tsquery
Language: INTERNAL
tsquery_and
Returns: tsquery
Language: INTERNAL
tsquery_not
Returns: tsquery
Language: INTERNAL
tsquery_or
Returns: text
Language: PLPERLU
return uc(shift);
Returns: text
Language: C
xml_encode_special_chars
Returns: boolean
Language: INTERNAL
xml_is_well_formed
Returns: boolean
Language: C
xpath_bool
Returns: text
Language: SQL
SELECT xpath_list($1,$2,',')
Returns: text
Language: C
xpath_list
Returns: text
Language: SQL
SELECT xpath_nodeset($1,$2,'','')
Returns: text
Language: SQL
SELECT xpath_nodeset($1,$2,'',$3)
Returns: text
Language: C
xpath_nodeset
Returns: real
Language: C
xpath_number
Returns: text
Language: C
xpath_string
Returns: SET OF record
Language: C
xpath_table
Returns: text
Language: C
xslt_process
Returns: text
Language: C
xslt_process
Schema query
Contains tables designed to represent user-defined queries for
reports and the like.
query.bind_variable Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
|
type |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
|
default_value |
text |
|
|
label |
text |
NOT NULL
|
query.bind_variable Constraints
Name |
Constraint |
bind_variable_type |
CHECK ((type = ANY (ARRAY['string'::text, 'number'::text, 'string_list'::text, 'number_list'::text]))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema query
Index -
Schema query
query.datatype Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
datatype_name |
text |
UNIQUE
NOT NULL
|
|
is_numeric |
boolean |
NOT NULL
DEFAULT false
|
|
is_composite |
boolean |
NOT NULL
DEFAULT false
|
query.datatype Constraints
Name |
Constraint |
qdt_comp_not_num |
CHECK (((is_numeric IS FALSE) OR (is_composite IS FALSE))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema query
query.expr_xbet Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
left_operand |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.left_operand
, expression.negate
FROM query.expression
WHERE (expression.type = 'xbet'::text);
Index -
Schema query
query.expr_xbind Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
bind_variable |
text |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.bind_variable
FROM query.expression
WHERE (expression.type = 'xbind'::text);
Index -
Schema query
query.expr_xbool Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
literal |
text |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.literal
, expression.negate
FROM query.expression
WHERE (expression.type = 'xbool'::text);
Index -
Schema query
query.expr_xcase Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
left_operand |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.left_operand
, expression.negate
FROM query.expression
WHERE (expression.type = 'xcase'::text);
Index -
Schema query
query.expr_xcast Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
left_operand |
integer |
|
|
cast_type |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.left_operand
, expression.cast_type
, expression.negate
FROM query.expression
WHERE (expression.type = 'xcast'::text);
Index -
Schema query
query.expr_xcol Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
table_alias |
text |
|
|
column_name |
text |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.table_alias
, expression.column_name
, expression.negate
FROM query.expression
WHERE (expression.type = 'xcol'::text);
Index -
Schema query
query.expr_xex Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
subquery |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.subquery
, expression.negate
FROM query.expression
WHERE (expression.type = 'xex'::text);
Index -
Schema query
query.expr_xfunc Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
column_name |
text |
|
|
function_id |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.column_name
, expression.function_id
, expression.negate
FROM query.expression
WHERE (expression.type = 'xfunc'::text);
Index -
Schema query
query.expr_xin Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
left_operand |
integer |
|
|
subquery |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.left_operand
, expression.subquery
, expression.negate
FROM query.expression
WHERE (expression.type = 'xin'::text);
Index -
Schema query
query.expr_xisnull Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
left_operand |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.left_operand
, expression.negate
FROM query.expression
WHERE (expression.type = 'xisnull'::text);
Index -
Schema query
query.expr_xnull Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.negate
FROM query.expression
WHERE (expression.type = 'xnull'::text);
Index -
Schema query
query.expr_xnum Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
literal |
text |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.literal
FROM query.expression
WHERE (expression.type = 'xnum'::text);
Index -
Schema query
query.expr_xop Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
left_operand |
integer |
|
|
operator |
text |
|
|
right_operand |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.left_operand
, expression.operator
, expression.right_operand
, expression.negate
FROM query.expression
WHERE (expression.type = 'xop'::text);
Index -
Schema query
query.expr_xser Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
operator |
text |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.operator
, expression.negate
FROM query.expression
WHERE (expression.type = 'xser'::text);
Index -
Schema query
query.expr_xstr Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
literal |
text |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.literal
FROM query.expression
WHERE (expression.type = 'xstr'::text);
Index -
Schema query
query.expr_xsubq Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
parenthesize |
boolean |
|
|
parent_expr |
integer |
|
|
seq_no |
integer |
|
|
subquery |
integer |
|
|
negate |
boolean |
|
SELECT expression.id
, expression.parenthesize
, expression.parent_expr
, expression.seq_no
, expression.subquery
, expression.negate
FROM query.expression
WHERE (expression.type = 'xsubq'::text);
Index -
Schema query
query.expression Constraints
Name |
Constraint |
expression_type |
CHECK ((type = ANY (ARRAY['xbet'::text, 'xbind'::text, 'xbool'::text, 'xcase'::text, 'xcast'::text, 'xcol'::text, 'xex'::text, 'xfunc'::text, 'xin'::text, 'xisnull'::text, 'xnull'::text, 'xnum'::text, 'xop'::text, 'xser'::text, 'xstr'::text, 'xsubq'::text]))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema query
query.from_relation Constraints
Name |
Constraint |
good_join_type |
CHECK (((join_type IS NULL) OR (join_type = ANY (ARRAY['INNER'::text, 'LEFT'::text, 'RIGHT'::text, 'FULL'::text])))) |
join_or_core |
CHECK (((((parent_relation IS NULL) AND (join_type IS NULL)) AND (on_clause IS NULL)) OR (((parent_relation IS NOT NULL) AND (join_type IS NOT NULL)) AND (on_clause IS NOT NULL)))) |
relation_type |
CHECK ((type = ANY (ARRAY['RELATION'::text, 'SUBQUERY'::text, 'FUNCTION'::text]))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema query
query.function_param_def Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
query.function_sig.id
|
function_id |
integer |
UNIQUE#1
NOT NULL
|
|
seq_no |
integer |
UNIQUE#1
NOT NULL
|
query.datatype.id
|
datatype |
integer |
NOT NULL
|
query.function_param_def Constraints
Name |
Constraint |
qfpd_pos_seq_no |
CHECK ((seq_no > 0)) |
Index -
Schema query
query.function_sig Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
function_name |
text |
NOT NULL
|
query.datatype.id
|
return_type |
integer |
|
|
is_aggregate |
boolean |
NOT NULL
DEFAULT false
|
query.function_sig Constraints
Name |
Constraint |
qfd_rtn_or_aggr |
CHECK (((return_type IS NULL) OR (is_aggregate = false))) |
Tables referencing this one via Foreign Key Constraints:
query_function_sig_name_idx function_name
Index -
Schema query
query.order_by_item Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
query.stored_query.id
|
stored_query |
integer |
UNIQUE#1
NOT NULL
|
|
seq_no |
integer |
UNIQUE#1
NOT NULL
|
query.expression.id
|
expression |
integer |
NOT NULL
|
Index -
Schema query
query.query_sequence Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
query.stored_query.id
|
parent_query |
integer |
UNIQUE#1
NOT NULL
|
|
seq_no |
integer |
UNIQUE#1
NOT NULL
|
query.stored_query.id
|
child_query |
integer |
NOT NULL
|
Index -
Schema query
query.record_column Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
query.from_relation.id
|
from_relation |
integer |
UNIQUE#1
NOT NULL
|
|
seq_no |
integer |
UNIQUE#1
NOT NULL
|
|
column_name |
text |
NOT NULL
|
query.datatype.id
|
column_type |
integer |
NOT NULL
|
Index -
Schema query
query.select_item Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
query.stored_query.id
|
stored_query |
integer |
UNIQUE#1
NOT NULL
|
|
seq_no |
integer |
UNIQUE#1
NOT NULL
|
query.expression.id
|
expression |
integer |
NOT NULL
|
|
column_alias |
text |
|
|
grouped_by |
boolean |
NOT NULL
DEFAULT false
|
Index -
Schema query
query.stored_query Constraints
Name |
Constraint |
query_type |
CHECK ((type = ANY (ARRAY['SELECT'::text, 'UNION'::text, 'INTERSECT'::text, 'EXCEPT'::text]))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema query
query.subfield Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
query.datatype.id
|
composite_type |
integer |
UNIQUE#1
NOT NULL
|
|
seq_no |
integer |
UNIQUE#1
NOT NULL
|
query.datatype.id
|
subfield_type |
integer |
NOT NULL
|
query.subfield Constraints
Name |
Constraint |
qsf_pos_seq_no |
CHECK ((seq_no > 0)) |
Index -
Schema query
Schema reporter
reporter.circ_type Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
type |
text |
|
SELECT circulation.id
, CASE WHEN
(
(circulation.opac_renewal
OR circulation.phone_renewal
)
OR circulation.desk_renewal
) THEN 'RENEWAL'::text ELSE 'CHECKOUT'::text END AS type
FROM action.circulation;
Index -
Schema reporter
reporter.currently_running Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
runner_barcode |
text |
|
|
name |
text |
|
|
run_time |
timestamp with time zone |
|
|
scheduled_wait_time |
interval |
|
SELECT s.id
, c.barcode AS runner_barcode
, r.name
, s.run_time
, (s.run_time - now
()
) AS scheduled_wait_time
FROM (
(
(reporter.schedule s
JOIN reporter.report r
ON (
(r.id = s.report)
)
)
JOIN actor.usr u
ON (
(s.runner = u.id)
)
)
JOIN actor.card c
ON (
(c.id = u.card)
)
)
WHERE (
(s.start_time IS NOT NULL)
AND (s.complete_time IS NULL)
);
Index -
Schema reporter
reporter.demographic Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
dob |
timestamp with time zone |
|
|
general_division |
text |
|
SELECT u.id
, u.dob
, CASE WHEN
(u.dob IS NULL) THEN 'Adult'::text WHEN
(age
(u.dob) > '18 years'::interval
) THEN 'Adult'::text ELSE 'Juvenile'::text END AS general_division
FROM actor.usr u;
Index -
Schema reporter
reporter.hold_request_record Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
target |
bigint |
|
|
hold_type |
text |
|
|
bib_record |
bigint |
|
SELECT ahr.id
, ahr.target
, ahr.hold_type
, CASE WHEN
(ahr.hold_type = 'T'::text) THEN ahr.target WHEN
(ahr.hold_type = 'I'::text) THEN
(
SELECT ssub.record_entry
FROM (serial.subscription ssub
JOIN serial.issuance si
ON (
(si.subscription = ssub.id)
)
)
WHERE (si.id = ahr.target)
) WHEN
(ahr.hold_type = 'V'::text) THEN
(
SELECT cn.record
FROM asset.call_number cn
WHERE (cn.id = ahr.target)
) WHEN
(ahr.hold_type = ANY
(ARRAY['C'::text
,'R'::text
,'F'::text]
)
) THEN
(
SELECT cn.record
FROM (asset.call_number cn
JOIN asset.copy cp
ON (
(cn.id = cp.call_number)
)
)
WHERE (cp.id = ahr.target)
) WHEN
(ahr.hold_type = 'M'::text) THEN
(
SELECT mr.master_record
FROM metabib.metarecord mr
WHERE (mr.id = ahr.target)
) WHEN
(ahr.hold_type = 'P'::text) THEN
(
SELECT bmp.record
FROM biblio.monograph_part bmp
WHERE (bmp.id = ahr.target)
) ELSE NULL::bigint END AS bib_record
FROM action.hold_request ahr;
Index -
Schema reporter
reporter.materialized_simple_record Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
|
|
fingerprint |
text |
|
|
quality |
integer |
|
|
tcn_source |
text |
|
|
tcn_value |
text |
|
|
title |
text |
|
|
author |
text |
|
|
publisher |
text |
|
|
pubdate |
text |
|
|
isbn |
text[] |
|
|
issn |
text[] |
|
Index -
Schema reporter
reporter.old_super_simple_record Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
fingerprint |
text |
|
|
quality |
integer |
|
|
tcn_source |
text |
|
|
tcn_value |
text |
|
|
title |
text |
|
|
author |
text |
|
|
publisher |
text |
|
|
pubdate |
text |
|
|
isbn |
text[] |
|
|
issn |
text[] |
|
SELECT r.id
, r.fingerprint
, r.quality
, r.tcn_source
, r.tcn_value
, first
(title.value) AS title
, first
(author.value) AS author
, array_to_string
(array_accum
(DISTINCT publisher.value)
,', '::text
) AS publisher
, array_to_string
(array_accum
(DISTINCT "substring"
(pubdate.value
,'\d+'::text
)
)
,', '::text
) AS pubdate
, array_accum
(DISTINCT replace
("substring"
(isbn.value
,'^\S+'::text
)
,'-'::text
,''::text
)
) AS isbn
, array_accum
(DISTINCT regexp_replace
(issn.value
,'^\S*(\d{4})[-\s](\d{3,4}x?)'::text
,'\1 \2'::text
)
) AS issn
FROM (
(
(
(
(
(biblio.record_entry r
LEFT JOIN metabib.full_rec title
ON (
(
(
(r.id = title.record)
AND (title.tag = '245'::bpchar)
)
AND (title.subfield = 'a'::text)
)
)
)
LEFT JOIN metabib.full_rec author
ON (
(
(
(r.id = author.record)
AND (author.tag = ANY
(ARRAY['100'::bpchar
,'110'::bpchar
,'111'::bpchar]
)
)
)
AND (author.subfield = 'a'::text)
)
)
)
LEFT JOIN metabib.full_rec publisher
ON (
(
(
(r.id = publisher.record)
AND (publisher.tag = '260'::bpchar)
)
AND (publisher.subfield = 'b'::text)
)
)
)
LEFT JOIN metabib.full_rec pubdate
ON (
(
(
(r.id = pubdate.record)
AND (pubdate.tag = '260'::bpchar)
)
AND (pubdate.subfield = 'c'::text)
)
)
)
LEFT JOIN metabib.full_rec isbn
ON (
(
(
(r.id = isbn.record)
AND (isbn.tag = ANY
(ARRAY['024'::bpchar
,'020'::bpchar]
)
)
)
AND (isbn.subfield = ANY
(ARRAY['a'::text
,'z'::text]
)
)
)
)
)
LEFT JOIN metabib.full_rec issn
ON (
(
(
(r.id = issn.record)
AND (issn.tag = '022'::bpchar)
)
AND (issn.subfield = 'a'::text)
)
)
)
GROUP BY r.id
, r.fingerprint
, r.quality
, r.tcn_source
, r.tcn_value;
Index -
Schema reporter
reporter.output_folder Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
reporter.output_folder.id
|
parent |
integer |
|
actor.usr.id
|
owner |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
name |
text |
NOT NULL
|
|
shared |
boolean |
NOT NULL
DEFAULT false
|
actor.org_unit.id
|
share_with |
integer |
|
Tables referencing this one via Foreign Key Constraints:
rpt_output_fldr_owner_idx owner
Index -
Schema reporter
reporter.overdue_circs Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
usr |
integer |
|
|
xact_start |
timestamp with time zone |
|
|
xact_finish |
timestamp with time zone |
|
|
unrecovered |
boolean |
|
|
target_copy |
bigint |
|
|
circ_lib |
integer |
|
|
circ_staff |
integer |
|
|
checkin_staff |
integer |
|
|
checkin_lib |
integer |
|
|
renewal_remaining |
integer |
|
|
grace_period |
interval |
|
|
due_date |
timestamp with time zone |
|
|
stop_fines_time |
timestamp with time zone |
|
|
checkin_time |
timestamp with time zone |
|
|
create_time |
timestamp with time zone |
|
|
duration |
interval |
|
|
fine_interval |
interval |
|
|
recurring_fine |
numeric(6,2) |
|
|
max_fine |
numeric(6,2) |
|
|
phone_renewal |
boolean |
|
|
desk_renewal |
boolean |
|
|
opac_renewal |
boolean |
|
|
duration_rule |
text |
|
|
recurring_fine_rule |
text |
|
|
max_fine_rule |
text |
|
|
stop_fines |
text |
|
|
workstation |
integer |
|
|
checkin_workstation |
integer |
|
|
copy_location |
integer |
|
|
checkin_scan_time |
timestamp with time zone |
|
|
parent_circ |
bigint |
|
SELECT circulation.id
, circulation.usr
, circulation.xact_start
, circulation.xact_finish
, circulation.unrecovered
, circulation.target_copy
, circulation.circ_lib
, circulation.circ_staff
, circulation.checkin_staff
, circulation.checkin_lib
, circulation.renewal_remaining
, circulation.grace_period
, circulation.due_date
, circulation.stop_fines_time
, circulation.checkin_time
, circulation.create_time
, circulation.duration
, circulation.fine_interval
, circulation.recurring_fine
, circulation.max_fine
, circulation.phone_renewal
, circulation.desk_renewal
, circulation.opac_renewal
, circulation.duration_rule
, circulation.recurring_fine_rule
, circulation.max_fine_rule
, circulation.stop_fines
, circulation.workstation
, circulation.checkin_workstation
, circulation.copy_location
, circulation.checkin_scan_time
, circulation.parent_circ
FROM action.circulation
WHERE (
(
(circulation.checkin_time IS NULL)
AND (
(circulation.stop_fines <> ALL
(ARRAY['LOST'::text
,'CLAIMSRETURNED'::text]
)
)
OR (circulation.stop_fines IS NULL)
)
)
AND (circulation.due_date < now
()
)
);
Index -
Schema reporter
reporter.overdue_reports Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
runner_barcode |
text |
|
|
name |
text |
|
|
run_time |
timestamp with time zone |
|
|
scheduled_wait_time |
interval |
|
SELECT s.id
, c.barcode AS runner_barcode
, r.name
, s.run_time
, (s.run_time - now
()
) AS scheduled_wait_time
FROM (
(
(reporter.schedule s
JOIN reporter.report r
ON (
(r.id = s.report)
)
)
JOIN actor.usr u
ON (
(s.runner = u.id)
)
)
JOIN actor.card c
ON (
(c.id = u.card)
)
)
WHERE (
(s.start_time IS NULL)
AND (s.run_time < now
()
)
);
Index -
Schema reporter
reporter.pending_reports Structure
F-Key |
Name |
Type |
Description |
|
id |
integer |
|
|
runner_barcode |
text |
|
|
name |
text |
|
|
run_time |
timestamp with time zone |
|
|
scheduled_wait_time |
interval |
|
SELECT s.id
, c.barcode AS runner_barcode
, r.name
, s.run_time
, (s.run_time - now
()
) AS scheduled_wait_time
FROM (
(
(reporter.schedule s
JOIN reporter.report r
ON (
(r.id = s.report)
)
)
JOIN actor.usr u
ON (
(s.runner = u.id)
)
)
JOIN actor.card c
ON (
(c.id = u.card)
)
)
WHERE (s.start_time IS NULL);
Index -
Schema reporter
reporter.report Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
name |
text |
NOT NULL
DEFAULT ''::text
|
|
description |
text |
NOT NULL
DEFAULT ''::text
|
reporter.template.id
|
template |
integer |
NOT NULL
|
|
data |
text |
NOT NULL
|
reporter.report_folder.id
|
folder |
integer |
NOT NULL
|
|
recur |
boolean |
NOT NULL
DEFAULT false
|
|
recurrence |
interval |
|
Tables referencing this one via Foreign Key Constraints:
rpt_rpt_fldr_idx folder
rpt_rpt_owner_idx owner
Index -
Schema reporter
reporter.report_folder Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
reporter.report_folder.id
|
parent |
integer |
|
actor.usr.id
|
owner |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
name |
text |
NOT NULL
|
|
shared |
boolean |
NOT NULL
DEFAULT false
|
actor.org_unit.id
|
share_with |
integer |
|
Tables referencing this one via Foreign Key Constraints:
rpt_rpt_fldr_owner_idx owner
Index -
Schema reporter
reporter.schedule Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
reporter.report.id
|
report |
integer |
NOT NULL
|
reporter.output_folder.id
|
folder |
integer |
NOT NULL
|
actor.usr.id
|
runner |
integer |
NOT NULL
|
|
run_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
start_time |
timestamp with time zone |
|
|
complete_time |
timestamp with time zone |
|
|
email |
text |
|
|
excel_format |
boolean |
NOT NULL
DEFAULT true
|
|
html_format |
boolean |
NOT NULL
DEFAULT true
|
|
csv_format |
boolean |
NOT NULL
DEFAULT true
|
|
chart_pie |
boolean |
NOT NULL
DEFAULT false
|
|
chart_bar |
boolean |
NOT NULL
DEFAULT false
|
|
chart_line |
boolean |
NOT NULL
DEFAULT false
|
|
error_code |
integer |
|
|
error_text |
text |
|
rpt_sched_folder_idx folder
rpt_sched_runner_idx runner
Index -
Schema reporter
reporter.simple_record Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
metarecord |
bigint |
|
|
fingerprint |
text |
|
|
quality |
integer |
|
|
tcn_source |
text |
|
|
tcn_value |
text |
|
|
title |
text |
|
|
uniform_title |
text |
|
|
author |
text |
|
|
publisher |
text |
|
|
pubdate |
text |
|
|
series_title |
text |
|
|
series_statement |
text |
|
|
summary |
text |
|
|
isbn |
text[] |
|
|
issn |
text[] |
|
|
topic_subject |
text[] |
|
|
geographic_subject |
text[] |
|
|
genre |
text[] |
|
|
name_subject |
text[] |
|
|
corporate_subject |
text[] |
|
|
external_uri |
text[] |
|
SELECT r.id
, s.metarecord
, r.fingerprint
, r.quality
, r.tcn_source
, r.tcn_value
, title.value AS title
, uniform_title.value AS uniform_title
, author.value AS author
, publisher.value AS publisher
,"substring"
(pubdate.value
,'\d+'::text
) AS pubdate
, series_title.value AS series_title
, series_statement.value AS series_statement
, summary.value AS summary
, array_accum
(DISTINCT replace
("substring"
(isbn.value
,'^\S+'::text
)
,'-'::text
,''::text
)
) AS isbn
, array_accum
(DISTINCT regexp_replace
(issn.value
,'^\S*(\d{4})[-\s](\d{3,4}x?)'::text
,'\1 \2'::text
)
) AS issn
, ARRAY
(
SELECT DISTINCT full_rec.value
FROM metabib.full_rec
WHERE (
(
(full_rec.tag = '650'::bpchar)
AND (full_rec.subfield = 'a'::text)
)
AND (full_rec.record = r.id)
)
) AS topic_subject
, ARRAY
(
SELECT DISTINCT full_rec.value
FROM metabib.full_rec
WHERE (
(
(full_rec.tag = '651'::bpchar)
AND (full_rec.subfield = 'a'::text)
)
AND (full_rec.record = r.id)
)
) AS geographic_subject
, ARRAY
(
SELECT DISTINCT full_rec.value
FROM metabib.full_rec
WHERE (
(
(full_rec.tag = '655'::bpchar)
AND (full_rec.subfield = 'a'::text)
)
AND (full_rec.record = r.id)
)
) AS genre
, ARRAY
(
SELECT DISTINCT full_rec.value
FROM metabib.full_rec
WHERE (
(
(full_rec.tag = '600'::bpchar)
AND (full_rec.subfield = 'a'::text)
)
AND (full_rec.record = r.id)
)
) AS name_subject
, ARRAY
(
SELECT DISTINCT full_rec.value
FROM metabib.full_rec
WHERE (
(
(full_rec.tag = '610'::bpchar)
AND (full_rec.subfield = 'a'::text)
)
AND (full_rec.record = r.id)
)
) AS corporate_subject
, ARRAY
(
SELECT full_rec.value
FROM metabib.full_rec
WHERE (
(
(full_rec.tag = '856'::bpchar)
AND (full_rec.subfield = ANY
(ARRAY['3'::text
,'y'::text
,'u'::text]
)
)
)
AND (full_rec.record = r.id)
)
ORDER BY CASE WHEN
(full_rec.subfield = ANY
(ARRAY['3'::text
,'y'::text]
)
) THEN 0 ELSE 1 END
) AS external_uri
FROM (
(
(
(
(
(
(
(
(
(
(biblio.record_entry r
JOIN metabib.metarecord_source_map s
ON (
(s.source = r.id)
)
)
LEFT JOIN metabib.full_rec uniform_title
ON (
(
(
(r.id = uniform_title.record)
AND (uniform_title.tag = '240'::bpchar)
)
AND (uniform_title.subfield = 'a'::text)
)
)
)
LEFT JOIN metabib.full_rec title
ON (
(
(
(r.id = title.record)
AND (title.tag = '245'::bpchar)
)
AND (title.subfield = 'a'::text)
)
)
)
LEFT JOIN metabib.full_rec author
ON (
(
(
(r.id = author.record)
AND (author.tag = '100'::bpchar)
)
AND (author.subfield = 'a'::text)
)
)
)
LEFT JOIN metabib.full_rec publisher
ON (
(
(
(r.id = publisher.record)
AND (publisher.tag = '260'::bpchar)
)
AND (publisher.subfield = 'b'::text)
)
)
)
LEFT JOIN metabib.full_rec pubdate
ON (
(
(
(r.id = pubdate.record)
AND (pubdate.tag = '260'::bpchar)
)
AND (pubdate.subfield = 'c'::text)
)
)
)
LEFT JOIN metabib.full_rec isbn
ON (
(
(
(r.id = isbn.record)
AND (isbn.tag = ANY
(ARRAY['024'::bpchar
,'020'::bpchar]
)
)
)
AND (isbn.subfield = ANY
(ARRAY['a'::text
,'z'::text]
)
)
)
)
)
LEFT JOIN metabib.full_rec issn
ON (
(
(
(r.id = issn.record)
AND (issn.tag = '022'::bpchar)
)
AND (issn.subfield = 'a'::text)
)
)
)
LEFT JOIN metabib.full_rec series_title
ON (
(
(
(r.id = series_title.record)
AND (series_title.tag = ANY
(ARRAY['830'::bpchar
,'440'::bpchar]
)
)
)
AND (series_title.subfield = 'a'::text)
)
)
)
LEFT JOIN metabib.full_rec series_statement
ON (
(
(
(r.id = series_statement.record)
AND (series_statement.tag = '490'::bpchar)
)
AND (series_statement.subfield = 'a'::text)
)
)
)
LEFT JOIN metabib.full_rec summary
ON (
(
(
(r.id = summary.record)
AND (summary.tag = '520'::bpchar)
)
AND (summary.subfield = 'a'::text)
)
)
)
GROUP BY r.id
, s.metarecord
, r.fingerprint
, r.quality
, r.tcn_source
, r.tcn_value
, title.value
, uniform_title.value
, author.value
, publisher.value
, "substring"
( pubdate.value
,'\d+'::text
)
, series_title.value
, series_statement.value
, summary.value;
Index -
Schema reporter
reporter.super_simple_record Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
|
|
fingerprint |
text |
|
|
quality |
integer |
|
|
tcn_source |
text |
|
|
tcn_value |
text |
|
|
title |
text |
|
|
author |
text |
|
|
publisher |
text |
|
|
pubdate |
text |
|
|
isbn |
text[] |
|
|
issn |
text[] |
|
SELECT materialized_simple_record.id
, materialized_simple_record.fingerprint
, materialized_simple_record.quality
, materialized_simple_record.tcn_source
, materialized_simple_record.tcn_value
, materialized_simple_record.title
, materialized_simple_record.author
, materialized_simple_record.publisher
, materialized_simple_record.pubdate
, materialized_simple_record.isbn
, materialized_simple_record.issn
FROM reporter.materialized_simple_record;
Index -
Schema reporter
reporter.template Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
name |
text |
NOT NULL
|
|
description |
text |
NOT NULL
|
|
data |
text |
NOT NULL
|
reporter.template_folder.id
|
folder |
integer |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
rpt_tmpl_fldr_idx folder
rpt_tmpl_owner_idx owner
Index -
Schema reporter
reporter.template_folder Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
reporter.template_folder.id
|
parent |
integer |
|
actor.usr.id
|
owner |
integer |
NOT NULL
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
name |
text |
NOT NULL
|
|
shared |
boolean |
NOT NULL
DEFAULT false
|
actor.org_unit.id
|
share_with |
integer |
|
Tables referencing this one via Foreign Key Constraints:
rpt_tmpl_fldr_owner_idx owner
Index -
Schema reporter
reporter.xact_billing_totals Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
unvoided |
numeric |
|
|
voided |
numeric |
|
|
total |
numeric |
|
SELECT b.xact
, sum
(CASE WHEN b.voided THEN
(0)::numeric ELSE b.amount END
) AS unvoided
, sum
(CASE WHEN b.voided THEN b.amount ELSE
(0)::numeric END
) AS voided
, sum
(b.amount) AS total
FROM money.billing b
GROUP BY b.xact;
Index -
Schema reporter
reporter.xact_paid_totals Structure
F-Key |
Name |
Type |
Description |
|
xact |
bigint |
|
|
unvoided |
numeric |
|
|
voided |
numeric |
|
|
total |
numeric |
|
SELECT b.xact
, sum
(CASE WHEN b.voided THEN
(0)::numeric ELSE b.amount END
) AS unvoided
, sum
(CASE WHEN b.voided THEN b.amount ELSE
(0)::numeric END
) AS voided
, sum
(b.amount) AS total
FROM money.payment b
GROUP BY b.xact;
Index -
Schema reporter
Returns: void
Language: SQL
DROP TRIGGER IF EXISTS bbb_simple_rec_trigger ON biblio.record_entry;
Returns: void
Language: SQL
DELETE FROM reporter.materialized_simple_record;
INSERT INTO reporter.materialized_simple_record
(id,fingerprint,quality,tcn_source,tcn_value,title,author,publisher,pubdate,isbn,issn)
SELECT DISTINCT ON (id) * FROM reporter.old_super_simple_record;
CREATE TRIGGER bbb_simple_rec_trigger
AFTER INSERT OR UPDATE OR DELETE ON biblio.record_entry
FOR EACH ROW EXECUTE PROCEDURE reporter.simple_rec_trigger();
Returns: void
Language: SQL
SELECT reporter.disable_materialized_simple_record_trigger();
SELECT reporter.enable_materialized_simple_record_trigger();
Returns: boolean
Language: SQL
SELECT reporter.simple_rec_update($1, TRUE);
Returns: trigger
Language: PLPGSQL
BEGIN
IF TG_OP = 'DELETE' THEN
PERFORM reporter.simple_rec_delete(NEW.id);
ELSE
PERFORM reporter.simple_rec_update(NEW.id);
END IF;
RETURN NEW;
END;
Returns: boolean
Language: PLPGSQL
BEGIN
DELETE FROM reporter.materialized_simple_record WHERE id = r_id;
IF NOT deleted THEN
INSERT INTO reporter.materialized_simple_record SELECT DISTINCT ON (id) * FROM reporter.old_super_simple_record WHERE id = r_id;
END IF;
RETURN TRUE;
END;
Returns: boolean
Language: SQL
SELECT reporter.simple_rec_update($1, FALSE);
Schema search
search.relevance_adjustment Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
config.metabib_field.id
|
field |
integer |
NOT NULL
|
|
bump_type |
text |
NOT NULL
|
|
multiplier |
numeric |
NOT NULL
DEFAULT 1.0
|
search.relevance_adjustment Constraints
Name |
Constraint |
relevance_adjustment_bump_type_check |
CHECK ((bump_type = ANY (ARRAY['word_order'::text, 'first_word'::text, 'full_match'::text]))) |
Index -
Schema search
Returns: SET OF search_result
Language: PLPGSQL
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;
BEGIN
check_limit := COALESCE( param_check, 1000 );
core_limit := COALESCE( param_limit, 25000 );
core_offset := COALESCE( param_offset, 0 );
-- core_skip_chk := COALESCE( param_skip_chk, 1 );
IF param_search_ou > 0 THEN
IF param_depth IS NOT NULL THEN
SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou, param_depth );
ELSE
SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou );
END IF;
SELECT array_accum(distinct id) INTO luri_org_list FROM actor.org_unit_ancestors( param_search_ou );
ELSIF param_search_ou < 0 THEN
SELECT array_accum(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
SELECT array_accum(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestors( tmp_int );
luri_org_list := luri_org_list || tmp_int_list;
END LOOP;
SELECT array_accum(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
SELECT array_accum(distinct id) INTO tmp_int_list FROM actor.org_unit_ancestors(param_pref_ou);
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;
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 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;
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;
Schema serial
serial.any_summary Structure
F-Key |
Name |
Type |
Description |
|
summary_type |
text |
|
|
id |
integer |
|
|
distribution |
integer |
|
|
generated_coverage |
text |
|
|
textual_holdings |
text |
|
|
show_generated |
boolean |
|
(
SELECT'basic'::text AS summary_type
, basic_summary.id
, basic_summary.distribution
, basic_summary.generated_coverage
, basic_summary.textual_holdings
, basic_summary.show_generated
FROM serial.basic_summary
UNIONSELECT'index'::text AS summary_type
, index_summary.id
, index_summary.distribution
, index_summary.generated_coverage
, index_summary.textual_holdings
, index_summary.show_generated
FROM serial.index_summary
)
UNIONSELECT'supplement'::text AS summary_type
, supplement_summary.id
, supplement_summary.distribution
, supplement_summary.generated_coverage
, supplement_summary.textual_holdings
, supplement_summary.show_generated
FROM serial.supplement_summary;
Index -
Schema serial
serial.basic_summary Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.distribution.id
|
distribution |
integer |
NOT NULL
|
|
generated_coverage |
text |
NOT NULL
|
|
textual_holdings |
text |
|
|
show_generated |
boolean |
NOT NULL
DEFAULT true
|
serial_basic_summary_dist_idx distribution
Index -
Schema serial
serial.caption_and_pattern Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.subscription.id
|
subscription |
integer |
NOT NULL
|
|
type |
text |
NOT NULL
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
start_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
end_date |
timestamp with time zone |
|
|
active |
boolean |
NOT NULL
DEFAULT false
|
|
pattern_code |
text |
NOT NULL
|
|
enum_1 |
text |
|
|
enum_2 |
text |
|
|
enum_3 |
text |
|
|
enum_4 |
text |
|
|
enum_5 |
text |
|
|
enum_6 |
text |
|
|
chron_1 |
text |
|
|
chron_2 |
text |
|
|
chron_3 |
text |
|
|
chron_4 |
text |
|
|
chron_5 |
text |
|
serial.caption_and_pattern Constraints
Name |
Constraint |
cap_type |
CHECK ((type = ANY (ARRAY['basic'::text, 'supplement'::text, 'index'::text]))) |
Tables referencing this one via Foreign Key Constraints:
serial_caption_and_pattern_sub_idx subscription
Index -
Schema serial
serial.distribution Constraints
Name |
Constraint |
distribution_display_grouping_check |
CHECK ((display_grouping = ANY (ARRAY['enum'::text, 'chron'::text]))) |
sdist_summary_method_check |
CHECK (((summary_method IS NULL) OR (summary_method = ANY (ARRAY['add_to_sre'::text, 'merge_with_sre'::text, 'use_sre_only'::text, 'use_sdist_only'::text])))) |
Tables referencing this one via Foreign Key Constraints:
serial_distribution_holding_lib_idx holding_lib
serial_distribution_sub_idx subscription
Index -
Schema serial
serial.distribution_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.distribution.id
|
distribution |
integer |
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
title |
text |
NOT NULL
|
|
value |
text |
NOT NULL
|
serial_distribution_note_dist_idx distribution
Index -
Schema serial
serial.index_summary Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.distribution.id
|
distribution |
integer |
NOT NULL
|
|
generated_coverage |
text |
NOT NULL
|
|
textual_holdings |
text |
|
|
show_generated |
boolean |
NOT NULL
DEFAULT true
|
serial_index_summary_dist_idx distribution
Index -
Schema serial
serial.issuance Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
actor.usr.id
|
editor |
integer |
NOT NULL
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
serial.subscription.id
|
subscription |
integer |
NOT NULL
|
|
label |
text |
|
|
date_published |
timestamp with time zone |
|
serial.caption_and_pattern.id
|
caption_and_pattern |
integer |
|
|
holding_code |
text |
|
|
holding_type |
text |
|
|
holding_link_id |
integer |
|
serial.issuance Constraints
Name |
Constraint |
issuance_holding_code_check |
CHECK (((holding_code IS NULL) OR is_json(holding_code))) |
valid_holding_type |
CHECK (((holding_type IS NULL) OR (holding_type = ANY (ARRAY['basic'::text, 'supplement'::text, 'index'::text])))) |
Tables referencing this one via Foreign Key Constraints:
serial_issuance_caption_and_pattern_idx caption_and_pattern
serial_issuance_date_published_idx date_published
serial_issuance_sub_idx subscription
Index -
Schema serial
serial.item Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
actor.usr.id
|
editor |
integer |
NOT NULL
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
serial.issuance.id
|
issuance |
integer |
NOT NULL
|
serial.stream.id
|
stream |
integer |
NOT NULL
|
serial.unit.id
|
unit |
integer |
|
asset.uri.id
|
uri |
integer |
|
|
date_expected |
timestamp with time zone |
|
|
date_received |
timestamp with time zone |
|
|
status |
text |
DEFAULT 'Expected'::text
|
|
shadowed |
boolean |
NOT NULL
DEFAULT false
|
serial.item Constraints
Name |
Constraint |
valid_status |
CHECK ((status = ANY (ARRAY['Bindery'::text, 'Bound'::text, 'Claimed'::text, 'Discarded'::text, 'Expected'::text, 'Not Held'::text, 'Not Published'::text, 'Received'::text]))) |
Tables referencing this one via Foreign Key Constraints:
serial_item_date_received_idx date_received
serial_item_issuance_idx issuance
serial_item_status_idx status
serial_item_stream_idx stream
serial_item_unit_idx unit
serial_item_uri_idx uri
Index -
Schema serial
serial.item_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.item.id
|
item |
integer |
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
title |
text |
NOT NULL
|
|
value |
text |
NOT NULL
|
serial_item_note_item_idx item
Index -
Schema serial
serial.materialized_holding_code Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
serial.issuance.id
|
issuance |
integer |
NOT NULL
|
|
subfield |
character(1) |
|
|
value |
text |
|
assist_holdings_display issuance, subfield
Index -
Schema serial
serial.record_entry Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
biblio.record_entry.id
|
record |
bigint |
|
actor.org_unit.id
|
owning_lib |
integer |
NOT NULL
DEFAULT 1
|
|
creator |
integer |
NOT NULL
DEFAULT 1
|
|
editor |
integer |
NOT NULL
DEFAULT 1
|
|
source |
integer |
|
|
create_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
active |
boolean |
NOT NULL
DEFAULT true
|
|
deleted |
boolean |
NOT NULL
DEFAULT false
|
|
marc |
text |
|
|
last_xact_id |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
serial_record_entry_creator_idx creator
serial_record_entry_editor_idx editor
serial_record_entry_owning_lib_idx owning_lib, deleted
Index -
Schema serial
serial.routing_list_user Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.stream.id
|
stream |
integer |
UNIQUE#1
NOT NULL
|
|
pos |
integer |
UNIQUE#1
NOT NULL
DEFAULT 1
|
actor.usr.id
|
reader |
integer |
|
|
department |
text |
|
|
note |
text |
|
serial.routing_list_user Constraints
Name |
Constraint |
reader_or_dept |
CHECK ((((reader IS NOT NULL) AND (department IS NULL)) OR ((reader IS NULL) AND (department IS NOT NULL)))) |
serial_routing_list_user_reader_idx reader
serial_routing_list_user_stream_idx stream
Index -
Schema serial
serial.stream Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.distribution.id
|
distribution |
integer |
NOT NULL
|
|
routing_label |
text |
|
Tables referencing this one via Foreign Key Constraints:
serial_stream_dist_idx distribution
Index -
Schema serial
serial.subscription Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
actor.org_unit.id
|
owning_lib |
integer |
NOT NULL
DEFAULT 1
|
|
start_date |
timestamp with time zone |
NOT NULL
|
|
end_date |
timestamp with time zone |
|
biblio.record_entry.id
|
record_entry |
bigint |
|
|
expected_date_offset |
interval |
|
Tables referencing this one via Foreign Key Constraints:
serial_subscription_owner_idx owning_lib
serial_subscription_record_idx record_entry
Index -
Schema serial
serial.subscription_note Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.subscription.id
|
subscription |
integer |
NOT NULL
|
actor.usr.id
|
creator |
integer |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
pub |
boolean |
NOT NULL
DEFAULT false
|
|
title |
text |
NOT NULL
|
|
value |
text |
NOT NULL
|
serial_subscription_note_sub_idx subscription
Index -
Schema serial
serial.supplement_summary Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
serial.distribution.id
|
distribution |
integer |
NOT NULL
|
|
generated_coverage |
text |
NOT NULL
|
|
textual_holdings |
text |
|
|
show_generated |
boolean |
NOT NULL
DEFAULT true
|
serial_supplement_summary_dist_idx distribution
Index -
Schema serial
serial.unit Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('asset.copy_id_seq'::regclass)
|
|
circ_lib |
integer |
NOT NULL
|
actor.usr.id
|
creator |
bigint |
NOT NULL
|
asset.call_number.id
|
call_number |
bigint |
NOT NULL
|
actor.usr.id
|
editor |
bigint |
NOT NULL
|
|
create_date |
timestamp with time zone |
DEFAULT now()
|
|
edit_date |
timestamp with time zone |
DEFAULT now()
|
|
copy_number |
integer |
|
|
status |
integer |
NOT NULL
|
|
location |
integer |
NOT NULL
DEFAULT 1
|
|
loan_duration |
integer |
NOT NULL
|
|
fine_level |
integer |
NOT NULL
|
|
age_protect |
integer |
|
|
circulate |
boolean |
NOT NULL
DEFAULT true
|
|
deposit |
boolean |
NOT NULL
DEFAULT false
|
|
ref |
boolean |
NOT NULL
DEFAULT false
|
|
holdable |
boolean |
NOT NULL
DEFAULT true
|
|
deposit_amount |
numeric(6,2) |
NOT NULL
DEFAULT 0.00
|
|
price |
numeric(8,2) |
|
|
barcode |
text |
NOT NULL
|
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
dummy_title |
text |
|
|
dummy_author |
text |
|
|
alert_message |
text |
|
|
opac_visible |
boolean |
NOT NULL
DEFAULT true
|
|
deleted |
boolean |
NOT NULL
DEFAULT false
|
|
floating |
boolean |
NOT NULL
DEFAULT false
|
|
dummy_isbn |
text |
|
|
status_changed_time |
timestamp with time zone |
|
|
active_date |
timestamp with time zone |
|
|
mint_condition |
boolean |
NOT NULL
DEFAULT true
|
|
cost |
numeric(8,2) |
|
|
sort_key |
text |
|
|
detailed_contents |
text |
NOT NULL
|
|
summary_contents |
text |
NOT NULL
|
Table serial.unit Inherits
copy,
serial.unit Constraints
Name |
Constraint |
copy_fine_level_check |
CHECK ((fine_level = ANY (ARRAY[1, 2, 3]))) |
copy_loan_duration_check |
CHECK ((loan_duration = ANY (ARRAY[1, 2, 3]))) |
Tables referencing this one via Foreign Key Constraints:
unit_avail_cn_idx call_number
unit_cn_idx call_number
unit_creator_idx creator
unit_editor_idx editor
Index -
Schema serial
Returns: trigger
Language: PLPERLU
use strict;
use MARC::Field;
use JSON::XS;
if (not defined $_TD->{new}{holding_code}) {
elog(WARNING, 'NULL in "holding_code" column of serial.issuance allowed for now, but may not be useful');
return;
}
# Do nothing if holding_code has not changed...
if ($_TD->{new}{holding_code} eq $_TD->{old}{holding_code}) {
# ... unless the following internal flag is set.
my $flag_rv = spi_exec_query(q{
SELECT * FROM config.internal_flag
WHERE name = 'serial.rematerialize_on_same_holding_code' AND enabled
}, 1);
return unless $flag_rv->{processed};
}
my $holding_code = (new JSON::XS)->decode($_TD->{new}{holding_code});
my $field = new MARC::Field('999', @$holding_code); # tag doesnt matter
my $dstmt = spi_prepare(
'DELETE FROM serial.materialized_holding_code WHERE issuance = $1',
'INT'
);
spi_exec_prepared($dstmt, $_TD->{new}{id});
my $istmt = spi_prepare(
q{
INSERT INTO serial.materialized_holding_code (
issuance, subfield, value
) VALUES ($1, $2, $3)
}, qw{INT CHAR TEXT}
);
foreach ($field->subfields) {
spi_exec_prepared(
$istmt,
$_TD->{new}{id},
$_->[0],
$_->[1]
);
}
return;
Schema staging
staging.billing_address_stage Structure
F-Key |
Name |
Type |
Description |
|
row_id |
bigint |
PRIMARY KEY
DEFAULT nextval('staging.mailing_address_stage_row_id_seq'::regclass)
|
|
row_date |
timestamp with time zone |
DEFAULT now()
|
|
usrname |
text |
NOT NULL
|
|
street1 |
text |
|
|
street2 |
text |
|
|
city |
text |
NOT NULL
DEFAULT ''::text
|
|
state |
text |
NOT NULL
DEFAULT 'OK'::text
|
|
country |
text |
NOT NULL
DEFAULT 'US'::text
|
|
post_code |
text |
NOT NULL
|
|
complete |
boolean |
DEFAULT false
|
Index -
Schema staging
staging.card_stage Structure
F-Key |
Name |
Type |
Description |
|
row_id |
bigserial |
PRIMARY KEY
|
|
row_date |
timestamp with time zone |
DEFAULT now()
|
|
usrname |
text |
NOT NULL
|
|
barcode |
text |
NOT NULL
|
|
complete |
boolean |
DEFAULT false
|
Index -
Schema staging
staging.mailing_address_stage Structure
F-Key |
Name |
Type |
Description |
|
row_id |
bigserial |
PRIMARY KEY
|
|
row_date |
timestamp with time zone |
DEFAULT now()
|
|
usrname |
text |
NOT NULL
|
|
street1 |
text |
|
|
street2 |
text |
|
|
city |
text |
NOT NULL
DEFAULT ''::text
|
|
state |
text |
NOT NULL
DEFAULT 'OK'::text
|
|
country |
text |
NOT NULL
DEFAULT 'US'::text
|
|
post_code |
text |
NOT NULL
|
|
complete |
boolean |
DEFAULT false
|
Index -
Schema staging
staging.statcat_stage Structure
F-Key |
Name |
Type |
Description |
|
row_id |
bigserial |
PRIMARY KEY
|
|
row_date |
timestamp with time zone |
DEFAULT now()
|
|
usrname |
text |
NOT NULL
|
|
statcat |
text |
NOT NULL
|
|
value |
text |
NOT NULL
|
|
complete |
boolean |
DEFAULT false
|
Index -
Schema staging
staging.user_stage Structure
F-Key |
Name |
Type |
Description |
|
row_id |
bigserial |
PRIMARY KEY
|
|
row_date |
timestamp with time zone |
DEFAULT now()
|
|
usrname |
text |
NOT NULL
|
|
profile |
text |
|
|
email |
text |
|
|
passwd |
text |
|
|
ident_type |
integer |
DEFAULT 3
|
|
first_given_name |
text |
|
|
second_given_name |
text |
|
|
family_name |
text |
|
|
day_phone |
text |
|
|
evening_phone |
text |
|
|
home_ou |
integer |
DEFAULT 2
|
|
dob |
text |
|
|
complete |
boolean |
DEFAULT false
|
Index -
Schema staging
Schema stats
Schema unapi
unapi.bre_output_layout Structure
F-Key |
Name |
Type |
Description |
|
name |
text |
PRIMARY KEY
|
config.xml_transform.name
|
transform |
text |
|
|
mime_type |
text |
NOT NULL
|
|
feed_top |
text |
NOT NULL
|
|
holdings_element |
text |
|
|
title_element |
text |
|
|
description_element |
text |
|
|
creator_element |
text |
|
|
update_ts_element |
text |
|
Index -
Schema unapi
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name location,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
id AS ident,
holdable,
opac_visible,
label_prefix AS prefix,
label_suffix AS suffix
),
name
)
FROM asset.copy_location
WHERE id = $1;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name volume,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@acn/' || acn.id AS id,
acn.id AS vol_id, o.shortname AS lib,
o.opac_visible AS opac_visible,
deleted, label, label_sortkey, label_class, record
),
unapi.aou( owning_lib, $2, 'owning_lib', evergreen.array_remove_item_by_value($4,'acn'), $5, $6, $7, $8),
CASE
WHEN ('acp' = ANY ($4)) THEN
CASE WHEN $6 IS NOT NULL THEN
XMLELEMENT( name copies,
(SELECT XMLAGG(acp ORDER BY rank_avail) FROM (
SELECT unapi.acp( cp.id, 'xml', 'copy', evergreen.array_remove_item_by_value($4,'acn'), $5, $6, $7, $8, FALSE),
evergreen.rank_cp_status(cp.status) AS rank_avail
FROM asset.copy cp
JOIN actor.org_unit_descendants( (SELECT id FROM actor.org_unit WHERE shortname = $5), $6) aoud ON (cp.circ_lib = aoud.id)
WHERE cp.call_number = acn.id
AND cp.deleted IS FALSE
ORDER BY rank_avail, COALESCE(cp.copy_number,0), cp.barcode
LIMIT ($7 -> 'acp')::INT
OFFSET ($8 -> 'acp')::INT
)x)
)
ELSE
XMLELEMENT( name copies,
(SELECT XMLAGG(acp ORDER BY rank_avail) FROM (
SELECT unapi.acp( cp.id, 'xml', 'copy', evergreen.array_remove_item_by_value($4,'acn'), $5, $6, $7, $8, FALSE),
evergreen.rank_cp_status(cp.status) AS rank_avail
FROM asset.copy cp
JOIN actor.org_unit_descendants( (SELECT id FROM actor.org_unit WHERE shortname = $5) ) aoud ON (cp.circ_lib = aoud.id)
WHERE cp.call_number = acn.id
AND cp.deleted IS FALSE
ORDER BY rank_avail, COALESCE(cp.copy_number,0), cp.barcode
LIMIT ($7 -> 'acp')::INT
OFFSET ($8 -> 'acp')::INT
)x)
)
END
ELSE NULL
END,
XMLELEMENT(
name uris,
(SELECT XMLAGG(auri) FROM (SELECT unapi.auri(uri,'xml','uri', evergreen.array_remove_item_by_value($4,'acn'), $5, $6, $7, $8, FALSE) FROM asset.uri_call_number_map WHERE call_number = acn.id)x)
),
unapi.acnp( acn.prefix, 'marcxml', 'prefix', evergreen.array_remove_item_by_value($4,'acn'), $5, $6, $7, $8, FALSE),
unapi.acns( acn.suffix, 'marcxml', 'suffix', evergreen.array_remove_item_by_value($4,'acn'), $5, $6, $7, $8, FALSE),
CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( acn.record, 'marcxml', 'record', evergreen.array_remove_item_by_value($4,'acn'), $5, $6, $7, $8, FALSE) ELSE NULL END
) AS x
FROM asset.call_number acn
JOIN actor.org_unit o ON (o.id = acn.owning_lib)
WHERE acn.id = $1
AND acn.deleted IS FALSE
GROUP BY acn.id, o.shortname, o.opac_visible, deleted, label, label_sortkey, label_class, owning_lib, record, acn.prefix, acn.suffix;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name call_number_prefix,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
id AS ident,
label,
'tag:open-ils.org:U2@aou/' || owning_lib AS owning_lib,
label_sortkey
)
)
FROM asset.call_number_prefix
WHERE id = $1;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name call_number_suffix,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
id AS ident,
label,
'tag:open-ils.org:U2@aou/' || owning_lib AS owning_lib,
label_sortkey
)
)
FROM asset.call_number_suffix
WHERE id = $1;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name copy,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@acp/' || id AS id, id AS copy_id,
create_date, edit_date, copy_number, circulate, deposit,
ref, holdable, deleted, deposit_amount, price, barcode,
circ_modifier, circ_as_type, opac_visible, age_protect
),
unapi.ccs( status, $2, 'status', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE),
unapi.acl( location, $2, 'location', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE),
unapi.aou( circ_lib, $2, 'circ_lib', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
unapi.aou( circ_lib, $2, 'circlib', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
CASE WHEN ('acn' = ANY ($4)) THEN unapi.acn( call_number, $2, 'call_number', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE) ELSE NULL END,
CASE
WHEN ('acpn' = ANY ($4)) THEN
XMLELEMENT( name copy_notes,
(SELECT XMLAGG(acpn) FROM (
SELECT unapi.acpn( id, 'xml', 'copy_note', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE)
FROM asset.copy_note
WHERE owning_copy = cp.id AND pub
)x)
)
ELSE NULL
END,
CASE
WHEN ('ascecm' = ANY ($4)) THEN
XMLELEMENT( name statcats,
(SELECT XMLAGG(ascecm) FROM (
SELECT unapi.ascecm( stat_cat_entry, 'xml', 'statcat', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE)
FROM asset.stat_cat_entry_copy_map
WHERE owning_copy = cp.id
)x)
)
ELSE NULL
END,
CASE
WHEN ('bre' = ANY ($4)) THEN
XMLELEMENT( name foreign_records,
(SELECT XMLAGG(bre) FROM (
SELECT unapi.bre(peer_record,'marcxml','record','{}'::TEXT[], $5, $6, $7, $8, FALSE)
FROM biblio.peer_bib_copy_map
WHERE target_copy = cp.id
)x)
)
ELSE NULL
END,
CASE
WHEN ('bmp' = ANY ($4)) THEN
XMLELEMENT( name monograph_parts,
(SELECT XMLAGG(bmp) FROM (
SELECT unapi.bmp( part, 'xml', 'monograph_part', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE)
FROM asset.copy_part_map
WHERE target_copy = cp.id
)x)
)
ELSE NULL
END,
CASE
WHEN ('circ' = ANY ($4)) THEN
XMLELEMENT( name current_circulation,
(SELECT XMLAGG(circ) FROM (
SELECT unapi.circ( id, 'xml', 'circ', evergreen.array_remove_item_by_value($4,'circ'), $5, $6, $7, $8, FALSE)
FROM action.circulation
WHERE target_copy = cp.id
AND checkin_time IS NULL
)x)
)
ELSE NULL
END
)
FROM asset.copy cp
WHERE id = $1
AND cp.deleted IS FALSE
GROUP BY id, status, location, circ_lib, call_number, create_date,
edit_date, copy_number, circulate, deposit, ref, holdable,
deleted, deposit_amount, price, barcode, circ_modifier,
circ_as_type, opac_visible, age_protect;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name copy_note,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
create_date AS date,
title
),
value
)
FROM asset.copy_note
WHERE id = $1;
Returns: xml
Language: PLPGSQL
DECLARE
output XML;
BEGIN
IF ename = 'circlib' THEN
SELECT XMLELEMENT(
name circlib,
XMLATTRIBUTES(
'http://open-ils.org/spec/actors/v1' AS xmlns,
id AS ident
),
name
) INTO output
FROM actor.org_unit aou
WHERE id = obj_id;
ELSE
EXECUTE $$SELECT XMLELEMENT(
name $$ || ename || $$,
XMLATTRIBUTES(
'http://open-ils.org/spec/actors/v1' AS xmlns,
'tag:open-ils.org:U2@aou/' || id AS id,
shortname, name, opac_visible
)
)
FROM actor.org_unit aou
WHERE id = $1 $$ INTO output USING obj_id;
END IF;
RETURN output;
END;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name statcat,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
sc.name,
sc.opac_visible
),
asce.value
)
FROM asset.stat_cat_entry asce
JOIN asset.stat_cat sc ON (sc.id = asce.stat_cat)
WHERE asce.id = $1;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name uri,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@auri/' || uri.id AS id,
use_restriction,
href,
label
),
CASE
WHEN ('acn' = ANY ($4)) THEN
XMLELEMENT( name copies,
(SELECT XMLAGG(acn) FROM (SELECT unapi.acn( call_number, 'xml', 'copy', evergreen.array_remove_item_by_value($4,'auri'), $5, $6, $7, $8, FALSE) FROM asset.uri_call_number_map WHERE uri = uri.id)x)
)
ELSE NULL
END
) AS x
FROM asset.uri uri
WHERE uri.id = $1
GROUP BY uri.id, use_restriction, href, label;
Returns: xml
Language: PLPGSQL
DECLARE
layout unapi.bre_output_layout%ROWTYPE;
transform config.xml_transform%ROWTYPE;
item_format TEXT;
tmp_xml TEXT;
xmlns_uri TEXT := 'http://open-ils.org/spec/feed-xml/v1';
ouid INT;
element_list TEXT[];
BEGIN
IF org = '-' OR org IS NULL THEN
SELECT shortname INTO org FROM evergreen.org_top();
END IF;
SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
IF layout.name IS NULL THEN
RETURN NULL::XML;
END IF;
SELECT * INTO transform FROM config.xml_transform WHERE name = layout.transform;
xmlns_uri := COALESCE(transform.namespace_uri,xmlns_uri);
-- Gather the bib xml
SELECT XMLAGG( unapi.bre(i, format, '', includes, org, depth, slimit, soffset, include_xmlns)) INTO tmp_xml FROM UNNEST( id_list ) i;
IF layout.title_element IS NOT NULL THEN
EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.title_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, title;
END IF;
IF layout.description_element IS NOT NULL THEN
EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.description_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, description;
END IF;
IF layout.creator_element IS NOT NULL THEN
EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.creator_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, creator;
END IF;
IF layout.update_ts_element IS NOT NULL THEN
EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.update_ts_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, update_ts;
END IF;
IF unapi_url IS NOT NULL THEN
EXECUTE $$SELECT XMLCONCAT( XMLELEMENT( name link, XMLATTRIBUTES( 'http://www.w3.org/1999/xhtml' AS xmlns, 'unapi-server' AS rel, $1 AS href, 'unapi' AS title)), $2)$$ INTO tmp_xml USING unapi_url, tmp_xml::XML;
END IF;
IF header_xml IS NOT NULL THEN tmp_xml := XMLCONCAT(header_xml,tmp_xml::XML); END IF;
element_list := regexp_split_to_array(layout.feed_top,E'\\.');
FOR i IN REVERSE ARRAY_UPPER(element_list, 1) .. 1 LOOP
EXECUTE 'SELECT XMLELEMENT( name '|| quote_ident(element_list[i]) ||', XMLATTRIBUTES( $1 AS xmlns), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML;
END LOOP;
RETURN tmp_xml::XML;
END;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name monograph_part,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@bmp/' || id AS id,
id AS ident,
label,
label_sortkey,
'tag:open-ils.org:U2@bre/' || record AS record
),
CASE
WHEN ('acp' = ANY ($4)) THEN
XMLELEMENT( name copies,
(SELECT XMLAGG(acp) FROM (
SELECT unapi.acp( cp.id, 'xml', 'copy', evergreen.array_remove_item_by_value($4,'bmp'), $5, $6, $7, $8, FALSE)
FROM asset.copy cp
JOIN asset.copy_part_map cpm ON (cpm.target_copy = cp.id)
WHERE cpm.part = $1
AND cp.deleted IS FALSE
ORDER BY COALESCE(cp.copy_number,0), cp.barcode
LIMIT ($7 -> 'acp')::INT
OFFSET ($8 -> 'acp')::INT
)x)
)
ELSE NULL
END,
CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( record, 'marcxml', 'record', evergreen.array_remove_item_by_value($4,'bmp'), $5, $6, $7, $8, FALSE) ELSE NULL END
)
FROM biblio.monograph_part
WHERE id = $1
GROUP BY id, label, label_sortkey, record;
Returns: xml
Language: PLPGSQL
DECLARE
me biblio.record_entry%ROWTYPE;
layout unapi.bre_output_layout%ROWTYPE;
xfrm config.xml_transform%ROWTYPE;
ouid INT;
tmp_xml TEXT;
top_el TEXT;
output XML;
hxml XML;
axml XML;
BEGIN
IF org = '-' OR org IS NULL THEN
SELECT shortname INTO org FROM evergreen.org_top();
END IF;
SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
IF ouid IS NULL THEN
RETURN NULL::XML;
END IF;
IF format = 'holdings_xml' THEN -- the special case
output := unapi.holdings_xml( obj_id, ouid, org, depth, includes, slimit, soffset, include_xmlns);
RETURN output;
END IF;
SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
IF layout.name IS NULL THEN
RETURN NULL::XML;
END IF;
SELECT * INTO xfrm FROM config.xml_transform WHERE name = layout.transform;
SELECT * INTO me FROM biblio.record_entry WHERE id = obj_id;
-- grab SVF if we need them
IF ('mra' = ANY (includes)) THEN
axml := unapi.mra(obj_id,NULL,NULL,NULL,NULL);
ELSE
axml := NULL::XML;
END IF;
-- grab holdings if we need them
IF ('holdings_xml' = ANY (includes)) THEN
hxml := unapi.holdings_xml(obj_id, ouid, org, depth, evergreen.array_remove_item_by_value(includes,'holdings_xml'), slimit, soffset, include_xmlns, pref_lib);
ELSE
hxml := NULL::XML;
END IF;
-- generate our item node
IF format = 'marcxml' THEN
tmp_xml := me.marc;
IF tmp_xml !~ E'<marc:' THEN -- If we're not using the prefixed namespace in this record, then remove all declarations of it
tmp_xml := REGEXP_REPLACE(tmp_xml, ' xmlns:marc="http://www.loc.gov/MARC21/slim"', '', 'g');
END IF;
ELSE
tmp_xml := oils_xslt_process(me.marc, xfrm.xslt)::XML;
END IF;
top_el := REGEXP_REPLACE(tmp_xml, E'^.*?<((?:\\S+:)?' || layout.holdings_element || ').*$', E'\\1');
IF axml IS NOT NULL THEN
tmp_xml := REGEXP_REPLACE(tmp_xml, '</' || top_el || '>(.*?)$', axml || '</' || top_el || E'>\\1');
END IF;
IF hxml IS NOT NULL THEN -- XXX how do we configure the holdings position?
tmp_xml := REGEXP_REPLACE(tmp_xml, '</' || top_el || '>(.*?)$', hxml || '</' || top_el || E'>\\1');
END IF;
IF ('bre.unapi' = ANY (includes)) THEN
output := REGEXP_REPLACE(
tmp_xml,
'</' || top_el || '>(.*?)',
XMLELEMENT(
name abbr,
XMLATTRIBUTES(
'http://www.w3.org/1999/xhtml' AS xmlns,
'unapi-id' AS class,
'tag:open-ils.org:U2@bre/' || obj_id || '/' || org AS title
)
)::TEXT || '</' || top_el || E'>\\1'
);
ELSE
output := tmp_xml;
END IF;
output := REGEXP_REPLACE(output::TEXT,E'>\\s+<','><','gs')::XML;
RETURN output;
END;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name status,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
id AS ident,
holdable,
opac_visible
),
name
)
FROM config.copy_status
WHERE id = $1;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name circ,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@circ/' || id AS id,
xact_start,
due_date
),
CASE WHEN ('aou' = ANY ($4)) THEN unapi.aou( circ_lib, $2, 'circ_lib', evergreen.array_remove_item_by_value($4,'circ'), $5, $6, $7, $8, FALSE) ELSE NULL END,
CASE WHEN ('acp' = ANY ($4)) THEN unapi.acp( circ_lib, $2, 'target_copy', evergreen.array_remove_item_by_value($4,'circ'), $5, $6, $7, $8, FALSE) ELSE NULL END
)
FROM action.circulation
WHERE id = $1;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name holdings,
XMLATTRIBUTES(
CASE WHEN $8 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
CASE WHEN ('bre' = ANY ($5)) THEN 'tag:open-ils.org:U2@bre/' || $1 || '/' || $3 ELSE NULL END AS id
),
XMLELEMENT(
name counts,
(SELECT XMLAGG(XMLELEMENT::XML) FROM (
SELECT XMLELEMENT(
name count,
XMLATTRIBUTES('public' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
)::text
FROM asset.opac_ou_record_copy_count($2, $1)
UNION
SELECT XMLELEMENT(
name count,
XMLATTRIBUTES('staff' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
)::text
FROM asset.staff_ou_record_copy_count($2, $1)
UNION
SELECT XMLELEMENT(
name count,
XMLATTRIBUTES('pref_lib' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
)::text
FROM asset.opac_ou_record_copy_count($9, $1)
ORDER BY 1
)x)
),
CASE
WHEN ('bmp' = ANY ($5)) THEN
XMLELEMENT(
name monograph_parts,
(SELECT XMLAGG(bmp) FROM (
SELECT unapi.bmp( id, 'xml', 'monograph_part', evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($5,'bre'), 'holdings_xml'), $3, $4, $6, $7, FALSE)
FROM biblio.monograph_part
WHERE record = $1
)x)
)
ELSE NULL
END,
XMLELEMENT(
name volumes,
(SELECT XMLAGG(acn ORDER BY rank, name, label_sortkey) FROM (
-- Physical copies
SELECT unapi.acn(y.id,'xml','volume',evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($5,'holdings_xml'),'bre'), $3, $4, $6, $7, FALSE), y.rank, name, label_sortkey
FROM evergreen.ranked_volumes($1, $2, $4, $6, $7, $9) AS y
UNION ALL
-- Located URIs
SELECT unapi.acn(uris.id,'xml','volume',evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($5,'holdings_xml'),'bre'), $3, $4, $6, $7, FALSE), 0, name, label_sortkey
FROM evergreen.located_uris($1, $2, $9) AS uris
)x)
),
CASE WHEN ('ssub' = ANY ($5)) THEN
XMLELEMENT(
name subscriptions,
(SELECT XMLAGG(ssub) FROM (
SELECT unapi.ssub(id,'xml','subscription','{}'::TEXT[], $3, $4, $6, $7, FALSE)
FROM serial.subscription
WHERE record_entry = $1
)x)
)
ELSE NULL END,
CASE WHEN ('acp' = ANY ($5)) THEN
XMLELEMENT(
name foreign_copies,
(SELECT XMLAGG(acp) FROM (
SELECT unapi.acp(p.target_copy,'xml','copy',evergreen.array_remove_item_by_value($5,'acp'), $3, $4, $6, $7, FALSE)
FROM biblio.peer_bib_copy_map p
JOIN asset.copy c ON (p.target_copy = c.id)
WHERE NOT c.deleted AND p.peer_record = $1
LIMIT ($6 -> 'acp')::INT
OFFSET ($7 -> 'acp')::INT
)x)
)
ELSE NULL END
);
Returns: xml
Language: PLPGSQL
DECLARE
key TEXT;
output XML;
BEGIN
key :=
'id' || COALESCE(obj_id::TEXT,'') ||
'format' || COALESCE(format::TEXT,'') ||
'ename' || COALESCE(ename::TEXT,'') ||
'includes' || COALESCE(includes::TEXT,'{}'::TEXT[]::TEXT) ||
'org' || COALESCE(org::TEXT,'') ||
'depth' || COALESCE(depth::TEXT,'') ||
'slimit' || COALESCE(slimit::TEXT,'') ||
'soffset' || COALESCE(soffset::TEXT,'') ||
'include_xmlns' || COALESCE(include_xmlns::TEXT,'');
-- RAISE NOTICE 'memoize key: %', key;
key := MD5(key);
-- RAISE NOTICE 'memoize hash: %', key;
-- XXX cache logic ... memcached? table?
EXECUTE $$SELECT unapi.$$ || classname || $$( $1, $2, $3, $4, $5, $6, $7, $8, $9);$$ INTO output USING obj_id, format, ename, includes, org, depth, slimit, soffset, include_xmlns;
RETURN output;
END;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name attributes,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/indexing/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@mra/' || mra.id AS id,
'tag:open-ils.org:U2@bre/' || mra.id AS record
),
(SELECT XMLAGG(foo.y)
FROM (SELECT XMLELEMENT(
name field,
XMLATTRIBUTES(
key AS name,
cvm.value AS "coded-value",
rad.filter,
rad.sorter
),
x.value
)
FROM EACH(mra.attrs) AS x
JOIN config.record_attr_definition rad ON (x.key = rad.name)
LEFT JOIN config.coded_value_map cvm ON (cvm.ctype = x.key AND code = x.value)
)foo(y)
)
)
FROM metabib.record_attr mra
WHERE mra.id = $1;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name serial_summary,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@sbsum/' || id AS id,
'sbsum' AS type, generated_coverage, textual_holdings, show_generated
),
CASE WHEN ('sdist' = ANY ($4)) THEN unapi.sdist( distribution, 'xml', 'distribtion', evergreen.array_remove_item_by_value($4,'ssum'), $5, $6, $7, $8, FALSE) ELSE NULL END
)
FROM serial.basic_summary ssum
WHERE id = $1
GROUP BY id, generated_coverage, textual_holdings, distribution, show_generated;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name distribution,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@sdist/' || id AS id,
'tag:open-ils.org:U2@acn/' || receive_call_number AS receive_call_number,
'tag:open-ils.org:U2@acn/' || bind_call_number AS bind_call_number,
unit_label_prefix, label, unit_label_suffix, summary_method
),
unapi.aou( holding_lib, $2, 'holding_lib', evergreen.array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8),
CASE WHEN subscription IS NOT NULL AND ('ssub' = ANY ($4)) THEN unapi.ssub( subscription, 'xml', 'subscription', evergreen.array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8, FALSE) ELSE NULL END,
CASE
WHEN ('sstr' = ANY ($4)) THEN
XMLELEMENT( name streams,
(SELECT XMLAGG(sstr) FROM (
SELECT unapi.sstr( id, 'xml', 'stream', evergreen.array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8, FALSE)
FROM serial.stream
WHERE distribution = sdist.id
)x)
)
ELSE NULL
END,
XMLELEMENT( name summaries,
CASE
WHEN ('sbsum' = ANY ($4)) THEN
(SELECT XMLAGG(sbsum) FROM (
SELECT unapi.sbsum( id, 'xml', 'serial_summary', evergreen.array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8, FALSE)
FROM serial.basic_summary
WHERE distribution = sdist.id
)x)
ELSE NULL
END,
CASE
WHEN ('sisum' = ANY ($4)) THEN
(SELECT XMLAGG(sisum) FROM (
SELECT unapi.sisum( id, 'xml', 'serial_summary', evergreen.array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8, FALSE)
FROM serial.index_summary
WHERE distribution = sdist.id
)x)
ELSE NULL
END,
CASE
WHEN ('sssum' = ANY ($4)) THEN
(SELECT XMLAGG(sssum) FROM (
SELECT unapi.sssum( id, 'xml', 'serial_summary', evergreen.array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8, FALSE)
FROM serial.supplement_summary
WHERE distribution = sdist.id
)x)
ELSE NULL
END
)
)
FROM serial.distribution sdist
WHERE id = $1
GROUP BY id, label, unit_label_prefix, unit_label_suffix, holding_lib, summary_method, subscription, receive_call_number, bind_call_number;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name issuance,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@siss/' || id AS id,
create_date, edit_date, label, date_published,
holding_code, holding_type, holding_link_id
),
CASE WHEN subscription IS NOT NULL AND ('ssub' = ANY ($4)) THEN unapi.ssub( subscription, 'xml', 'subscription', evergreen.array_remove_item_by_value($4,'siss'), $5, $6, $7, $8, FALSE) ELSE NULL END,
CASE
WHEN ('sitem' = ANY ($4)) THEN
XMLELEMENT( name items,
(SELECT XMLAGG(sitem) FROM (
SELECT unapi.sitem( id, 'xml', 'serial_item', evergreen.array_remove_item_by_value($4,'siss'), $5, $6, $7, $8, FALSE)
FROM serial.item
WHERE issuance = sstr.id
)x)
)
ELSE NULL
END
)
FROM serial.issuance sstr
WHERE id = $1
GROUP BY id, create_date, edit_date, label, date_published, holding_code, holding_type, holding_link_id, subscription;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name serial_summary,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@sbsum/' || id AS id,
'sisum' AS type, generated_coverage, textual_holdings, show_generated
),
CASE WHEN ('sdist' = ANY ($4)) THEN unapi.sdist( distribution, 'xml', 'distribtion', evergreen.array_remove_item_by_value($4,'ssum'), $5, $6, $7, $8, FALSE) ELSE NULL END
)
FROM serial.index_summary ssum
WHERE id = $1
GROUP BY id, generated_coverage, textual_holdings, distribution, show_generated;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name serial_item,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@sitem/' || id AS id,
'tag:open-ils.org:U2@siss/' || issuance AS issuance,
date_expected, date_received
),
CASE WHEN issuance IS NOT NULL AND ('siss' = ANY ($4)) THEN unapi.siss( issuance, $2, 'issuance', evergreen.array_remove_item_by_value($4,'sitem'), $5, $6, $7, $8, FALSE) ELSE NULL END,
CASE WHEN stream IS NOT NULL AND ('sstr' = ANY ($4)) THEN unapi.sstr( stream, $2, 'stream', evergreen.array_remove_item_by_value($4,'sitem'), $5, $6, $7, $8, FALSE) ELSE NULL END,
CASE WHEN unit IS NOT NULL AND ('sunit' = ANY ($4)) THEN unapi.sunit( unit, $2, 'serial_unit', evergreen.array_remove_item_by_value($4,'sitem'), $5, $6, $7, $8, FALSE) ELSE NULL END,
CASE WHEN uri IS NOT NULL AND ('auri' = ANY ($4)) THEN unapi.auri( uri, $2, 'uri', evergreen.array_remove_item_by_value($4,'sitem'), $5, $6, $7, $8, FALSE) ELSE NULL END
-- XMLELEMENT( name notes,
-- CASE
-- WHEN ('acpn' = ANY ($4)) THEN
-- (SELECT XMLAGG(acpn) FROM (
-- SELECT unapi.acpn( id, 'xml', 'copy_note', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8)
-- FROM asset.copy_note
-- WHERE owning_copy = cp.id AND pub
-- )x)
-- ELSE NULL
-- END
-- )
)
FROM serial.item sitem
WHERE id = $1;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name serial_summary,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@sbsum/' || id AS id,
'sssum' AS type, generated_coverage, textual_holdings, show_generated
),
CASE WHEN ('sdist' = ANY ($4)) THEN unapi.sdist( distribution, 'xml', 'distribtion', evergreen.array_remove_item_by_value($4,'ssum'), $5, $6, $7, $8, FALSE) ELSE NULL END
)
FROM serial.supplement_summary ssum
WHERE id = $1
GROUP BY id, generated_coverage, textual_holdings, distribution, show_generated;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name stream,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@sstr/' || id AS id,
routing_label
),
CASE WHEN distribution IS NOT NULL AND ('sdist' = ANY ($4)) THEN unapi.sssum( distribution, 'xml', 'distribtion', evergreen.array_remove_item_by_value($4,'sstr'), $5, $6, $7, $8, FALSE) ELSE NULL END,
CASE
WHEN ('sitem' = ANY ($4)) THEN
XMLELEMENT( name items,
(SELECT XMLAGG(sitem) FROM (
SELECT unapi.sitem( id, 'xml', 'serial_item', evergreen.array_remove_item_by_value($4,'sstr'), $5, $6, $7, $8, FALSE)
FROM serial.item
WHERE stream = sstr.id
)x)
)
ELSE NULL
END
)
FROM serial.stream sstr
WHERE id = $1
GROUP BY id, routing_label, distribution;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name subscription,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@ssub/' || id AS id,
'tag:open-ils.org:U2@aou/' || owning_lib AS owning_lib,
start_date AS start, end_date AS end, expected_date_offset
),
CASE
WHEN ('sdist' = ANY ($4)) THEN
XMLELEMENT( name distributions,
(SELECT XMLAGG(sdist) FROM (
SELECT unapi.sdist( id, 'xml', 'distribution', evergreen.array_remove_item_by_value($4,'ssub'), $5, $6, $7, $8, FALSE)
FROM serial.distribution
WHERE subscription = ssub.id
)x)
)
ELSE NULL
END
)
FROM serial.subscription ssub
WHERE id = $1
GROUP BY id, start_date, end_date, expected_date_offset, owning_lib;
Returns: xml
Language: SQL
SELECT XMLELEMENT(
name serial_unit,
XMLATTRIBUTES(
CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
'tag:open-ils.org:U2@acp/' || id AS id, id AS copy_id,
create_date, edit_date, copy_number, circulate, deposit,
ref, holdable, deleted, deposit_amount, price, barcode,
circ_modifier, circ_as_type, opac_visible, age_protect,
status_changed_time, floating, mint_condition,
detailed_contents, sort_key, summary_contents, cost
),
unapi.ccs( status, $2, 'status', evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8, FALSE),
unapi.acl( location, $2, 'location', evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8, FALSE),
unapi.aou( circ_lib, $2, 'circ_lib', evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8),
unapi.aou( circ_lib, $2, 'circlib', evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8),
CASE WHEN ('acn' = ANY ($4)) THEN unapi.acn( call_number, $2, 'call_number', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE) ELSE NULL END,
XMLELEMENT( name copy_notes,
CASE
WHEN ('acpn' = ANY ($4)) THEN
(SELECT XMLAGG(acpn) FROM (
SELECT unapi.acpn( id, 'xml', 'copy_note', evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8, FALSE)
FROM asset.copy_note
WHERE owning_copy = cp.id AND pub
)x)
ELSE NULL
END
),
XMLELEMENT( name statcats,
CASE
WHEN ('ascecm' = ANY ($4)) THEN
(SELECT XMLAGG(ascecm) FROM (
SELECT unapi.ascecm( stat_cat_entry, 'xml', 'statcat', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE)
FROM asset.stat_cat_entry_copy_map
WHERE owning_copy = cp.id
)x)
ELSE NULL
END
),
XMLELEMENT( name foreign_records,
CASE
WHEN ('bre' = ANY ($4)) THEN
(SELECT XMLAGG(bre) FROM (
SELECT unapi.bre(peer_record,'marcxml','record','{}'::TEXT[], $5, $6, $7, $8, FALSE)
FROM biblio.peer_bib_copy_map
WHERE target_copy = cp.id
)x)
ELSE NULL
END
),
CASE
WHEN ('bmp' = ANY ($4)) THEN
XMLELEMENT( name monograph_parts,
(SELECT XMLAGG(bmp) FROM (
SELECT unapi.bmp( part, 'xml', 'monograph_part', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE)
FROM asset.copy_part_map
WHERE target_copy = cp.id
)x)
)
ELSE NULL
END,
CASE
WHEN ('circ' = ANY ($4)) THEN
XMLELEMENT( name current_circulation,
(SELECT XMLAGG(circ) FROM (
SELECT unapi.circ( id, 'xml', 'circ', evergreen.array_remove_item_by_value($4,'circ'), $5, $6, $7, $8, FALSE)
FROM action.circulation
WHERE target_copy = cp.id
AND checkin_time IS NULL
)x)
)
ELSE NULL
END
)
FROM serial.unit cp
WHERE id = $1
AND cp.deleted IS FALSE
GROUP BY id, status, location, circ_lib, call_number, create_date,
edit_date, copy_number, circulate, floating, mint_condition,
deposit, ref, holdable, deleted, deposit_amount, price,
barcode, circ_modifier, circ_as_type, opac_visible,
status_changed_time, detailed_contents, sort_key,
summary_contents, cost, age_protect;
Schema vandelay
vandelay.authority_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
code |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
|
xpath |
text |
NOT NULL
|
|
remove |
text |
NOT NULL
DEFAULT ''::text
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema vandelay
Index -
Schema vandelay
vandelay.authority_queue Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('vandelay.queue_id_seq'::regclass)
|
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
complete |
boolean |
NOT NULL
DEFAULT false
|
|
match_set |
integer |
|
|
queue_type |
vandelay.authority_queue_queue_type |
UNIQUE#1
NOT NULL
DEFAULT 'authority'::vandelay.authority_queue_queue_type
|
Table vandelay.authority_queue Inherits
queue,
Tables referencing this one via Foreign Key Constraints:
Index -
Schema vandelay
vandelay.bib_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
code |
text |
UNIQUE
NOT NULL
|
|
description |
text |
|
|
xpath |
text |
NOT NULL
|
|
remove |
text |
NOT NULL
DEFAULT ''::text
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema vandelay
Index -
Schema vandelay
vandelay.bib_queue Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('vandelay.queue_id_seq'::regclass)
|
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
complete |
boolean |
NOT NULL
DEFAULT false
|
|
match_set |
integer |
|
|
queue_type |
vandelay.bib_queue_queue_type |
UNIQUE#1
NOT NULL
DEFAULT 'bib'::vandelay.bib_queue_queue_type
|
vandelay.import_item_attr_definition.id
|
item_attr_def |
bigint |
|
Table vandelay.bib_queue Inherits
queue,
Tables referencing this one via Foreign Key Constraints:
Index -
Schema vandelay
vandelay.import_bib_trash_fields Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
field |
text |
UNIQUE#1
NOT NULL
|
Index -
Schema vandelay
vandelay.import_error Structure
F-Key |
Name |
Type |
Description |
|
code |
text |
PRIMARY KEY
|
|
description |
text |
NOT NULL
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema vandelay
vandelay.import_item Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
vandelay.queued_bib_record.id
|
record |
bigint |
NOT NULL
|
vandelay.import_item_attr_definition.id
|
definition |
bigint |
NOT NULL
|
vandelay.import_error.code
|
import_error |
text |
|
|
error_detail |
text |
|
asset.copy.id
|
imported_as |
bigint |
|
|
import_time |
timestamp with time zone |
|
|
owning_lib |
integer |
|
|
circ_lib |
integer |
|
|
call_number |
text |
|
|
copy_number |
integer |
|
|
status |
integer |
|
|
location |
integer |
|
|
circulate |
boolean |
|
|
deposit |
boolean |
|
|
deposit_amount |
numeric(8,2) |
|
|
ref |
boolean |
|
|
holdable |
boolean |
|
|
price |
numeric(8,2) |
|
|
barcode |
text |
|
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
alert_message |
text |
|
|
pub_note |
text |
|
|
priv_note |
text |
|
|
opac_visible |
boolean |
|
Index -
Schema vandelay
vandelay.import_item_attr_definition Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
tag |
text |
NOT NULL
|
|
keep |
boolean |
NOT NULL
DEFAULT false
|
|
owning_lib |
text |
|
|
circ_lib |
text |
|
|
call_number |
text |
|
|
copy_number |
text |
|
|
status |
text |
|
|
location |
text |
|
|
circulate |
text |
|
|
deposit |
text |
|
|
deposit_amount |
text |
|
|
ref |
text |
|
|
holdable |
text |
|
|
price |
text |
|
|
barcode |
text |
|
|
circ_modifier |
text |
|
|
circ_as_type |
text |
|
|
alert_message |
text |
|
|
opac_visible |
text |
|
|
pub_note_title |
text |
|
|
pub_note |
text |
|
|
priv_note_title |
text |
|
|
priv_note |
text |
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema vandelay
vandelay.match_set Structure
F-Key |
Name |
Type |
Description |
|
id |
serial |
PRIMARY KEY
|
|
name |
text |
UNIQUE#1
NOT NULL
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
mtype |
text |
UNIQUE#1
NOT NULL
DEFAULT 'biblio'::text
|
Tables referencing this one via Foreign Key Constraints:
Index -
Schema vandelay
vandelay.match_set_point Constraints
Name |
Constraint |
match_set_point_bool_op_check |
CHECK (((bool_op IS NULL) OR (bool_op = ANY (ARRAY['AND'::text, 'OR'::text, 'NOT'::text])))) |
vmsp_need_a_subfield_with_a_tag |
CHECK ((((tag IS NOT NULL) AND (subfield IS NOT NULL)) OR (tag IS NULL))) |
vmsp_need_a_tag_or_a_ff_or_a_bo |
CHECK ((((((tag IS NOT NULL) AND (svf IS NULL)) AND (bool_op IS NULL)) OR (((tag IS NULL) AND (svf IS NOT NULL)) AND (bool_op IS NULL))) OR (((tag IS NULL) AND (svf IS NULL)) AND (bool_op IS NOT NULL)))) |
Tables referencing this one via Foreign Key Constraints:
Index -
Schema vandelay
vandelay.match_set_quality Constraints
Name |
Constraint |
vmsq_need_a_subfield_with_a_tag |
CHECK ((((tag IS NOT NULL) AND (subfield IS NOT NULL)) OR (tag IS NULL))) |
vmsq_need_a_tag_or_a_ff |
CHECK ((((tag IS NOT NULL) AND (svf IS NULL)) OR ((tag IS NULL) AND (svf IS NOT NULL)))) |
Index -
Schema vandelay
vandelay.merge_profile Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.org_unit.id
|
owner |
integer |
UNIQUE#1
NOT NULL
|
|
name |
text |
UNIQUE#1
NOT NULL
|
|
add_spec |
text |
|
|
replace_spec |
text |
|
|
strip_spec |
text |
|
|
preserve_spec |
text |
|
|
lwm_ratio |
numeric |
|
vandelay.merge_profile Constraints
Name |
Constraint |
add_replace_strip_or_preserve |
CHECK ((((preserve_spec IS NOT NULL) OR (replace_spec IS NOT NULL)) OR ((preserve_spec IS NULL) AND (replace_spec IS NULL)))) |
Index -
Schema vandelay
vandelay.queue Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
actor.usr.id
|
owner |
integer |
NOT NULL
|
|
name |
text |
NOT NULL
|
|
complete |
boolean |
NOT NULL
DEFAULT false
|
vandelay.match_set.id
|
match_set |
integer |
|
Index -
Schema vandelay
vandelay.queued_authority_record Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('vandelay.queued_record_id_seq'::regclass)
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
import_time |
timestamp with time zone |
|
|
purpose |
text |
NOT NULL
DEFAULT 'import'::text
|
|
marc |
text |
NOT NULL
|
|
quality |
integer |
NOT NULL
|
vandelay.authority_queue.id
|
queue |
integer |
NOT NULL
|
authority.record_entry.id
|
imported_as |
integer |
|
vandelay.import_error.code
|
import_error |
text |
|
|
error_detail |
text |
|
Table vandelay.queued_authority_record Inherits
queued_record,
vandelay.queued_authority_record Constraints
Name |
Constraint |
queued_record_purpose_check |
CHECK ((purpose = ANY (ARRAY['import'::text, 'overlay'::text]))) |
Tables referencing this one via Foreign Key Constraints:
queued_authority_record_queue_idx queue
Index -
Schema vandelay
queued_authority_record_attr_record_idx record
Index -
Schema vandelay
vandelay.queued_bib_record Structure
F-Key |
Name |
Type |
Description |
|
id |
bigint |
PRIMARY KEY
DEFAULT nextval('vandelay.queued_record_id_seq'::regclass)
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
import_time |
timestamp with time zone |
|
|
purpose |
text |
NOT NULL
DEFAULT 'import'::text
|
|
marc |
text |
NOT NULL
|
|
quality |
integer |
NOT NULL
|
vandelay.bib_queue.id
|
queue |
integer |
NOT NULL
|
config.bib_source.id
|
bib_source |
integer |
|
biblio.record_entry.id
|
imported_as |
bigint |
|
vandelay.import_error.code
|
import_error |
text |
|
|
error_detail |
text |
|
Table vandelay.queued_bib_record Inherits
queued_record,
vandelay.queued_bib_record Constraints
Name |
Constraint |
queued_record_purpose_check |
CHECK ((purpose = ANY (ARRAY['import'::text, 'overlay'::text]))) |
Tables referencing this one via Foreign Key Constraints:
queued_bib_record_queue_idx queue
Index -
Schema vandelay
queued_bib_record_attr_record_idx record
Index -
Schema vandelay
vandelay.queued_record Structure
F-Key |
Name |
Type |
Description |
|
id |
bigserial |
PRIMARY KEY
|
|
create_time |
timestamp with time zone |
NOT NULL
DEFAULT now()
|
|
import_time |
timestamp with time zone |
|
|
purpose |
text |
NOT NULL
DEFAULT 'import'::text
|
|
marc |
text |
NOT NULL
|
|
quality |
integer |
NOT NULL
|
vandelay.queued_record Constraints
Name |
Constraint |
queued_record_purpose_check |
CHECK ((purpose = ANY (ARRAY['import'::text, 'overlay'::text]))) |
Index -
Schema vandelay
Returns: void
Language: PLPGSQL
DECLARE
jrow TEXT;
my_alias TEXT;
op TEXT;
tagkey TEXT;
caseless BOOL;
BEGIN
-- remember $1 is tags_rstore, and $2 is svf_rstore
caseless := FALSE;
IF node.tag IS NOT NULL THEN
caseless := (node.tag IN ('020', '022', '024'));
tagkey := node.tag;
IF node.subfield IS NOT NULL THEN
tagkey := tagkey || node.subfield;
END IF;
END IF;
IF node.negate THEN
IF caseless THEN
op := 'NOT LIKE';
ELSE
op := '<>';
END IF;
ELSE
IF caseless THEN
op := 'LIKE';
ELSE
op := '=';
END IF;
END IF;
my_alias := 'n' || node.id::TEXT;
jrow := 'LEFT JOIN (SELECT *, ' || node.quality ||
' AS quality FROM metabib.';
IF node.tag IS NOT NULL THEN
jrow := jrow || 'full_rec) ' || my_alias || ' ON (' ||
my_alias || '.record = bre.id AND ' || my_alias || '.tag = ''' ||
node.tag || '''';
IF node.subfield IS NOT NULL THEN
jrow := jrow || ' AND ' || my_alias || '.subfield = ''' ||
node.subfield || '''';
END IF;
jrow := jrow || ' AND (';
IF caseless THEN
jrow := jrow || 'LOWER(' || my_alias || '.value) ' || op;
ELSE
jrow := jrow || my_alias || '.value ' || op;
END IF;
jrow := jrow || ' ANY(($1->''' || tagkey || ''')::TEXT[])))';
ELSE -- svf
jrow := jrow || 'record_attr) ' || my_alias || ' ON (' ||
my_alias || '.id = bre.id AND (' ||
my_alias || '.attrs->''' || node.svf ||
''' ' || op || ' $2->''' || node.svf || '''))';
END IF;
INSERT INTO _vandelay_tmp_jrows (j) VALUES (jrow);
END;
Returns: void
Language: PLPGSQL
DECLARE
BEGIN
INSERT INTO _vandelay_tmp_qrows (q) VALUES (node.id);
END;
Returns: text
Language: PLPGSQL
DECLARE
s TEXT;
BEGIN
IF node.bool_op IS NOT NULL THEN
RETURN node.bool_op;
ELSE
RETURN '(n' || node.id::TEXT || '.id IS NOT NULL)';
END IF;
END;
Returns: text
Language: SQL
SELECT vandelay.add_field( $1, $2, $3, 0 );
Returns: text
Language: PLPERLU
use MARC::Record;
use MARC::File::XML (BinaryEncoding => 'UTF-8');
use MARC::Charset;
use strict;
MARC::Charset->assume_unicode(1);
my $target_xml = shift;
my $source_xml = shift;
my $field_spec = shift;
my $force_add = shift || 0;
my $target_r = MARC::Record->new_from_xml( $target_xml );
my $source_r = MARC::Record->new_from_xml( $source_xml );
return $target_xml unless ($target_r && $source_r);
my @field_list = split(',', $field_spec);
my %fields;
for my $f (@field_list) {
$f =~ s/^\s*//; $f =~ s/\s*$//;
if ($f =~ /^(.{3})(\w*)(?:\[([^]]*)\])?$/) {
my $field = $1;
$field =~ s/\s+//;
my $sf = $2;
$sf =~ s/\s+//;
my $match = $3;
$match =~ s/^\s*//; $match =~ s/\s*$//;
$fields{$field} = { sf => [ split('', $sf) ] };
if ($match) {
my ($msf,$mre) = split('~', $match);
if (length($msf) > 0 and length($mre) > 0) {
$msf =~ s/^\s*//; $msf =~ s/\s*$//;
$mre =~ s/^\s*//; $mre =~ s/\s*$//;
$fields{$field}{match} = { sf => $msf, re => qr/$mre/ };
}
}
}
}
for my $f ( keys %fields) {
if ( @{$fields{$f}{sf}} ) {
for my $from_field ($source_r->field( $f )) {
my @tos = $target_r->field( $f );
if (!@tos) {
next if (exists($fields{$f}{match}) and !$force_add);
my @new_fields = map { $_->clone } $source_r->field( $f );
$target_r->insert_fields_ordered( @new_fields );
} else {
for my $to_field (@tos) {
if (exists($fields{$f}{match})) {
next unless (grep { $_ =~ $fields{$f}{match}{re} } $to_field->subfield($fields{$f}{match}{sf}));
}
my @new_sf = map { ($_ => $from_field->subfield($_)) } grep { defined($from_field->subfield($_)) } @{$fields{$f}{sf}};
$to_field->add_subfields( @new_sf );
}
}
}
} else {
my @new_fields = map { $_->clone } $source_r->field( $f );
$target_r->insert_fields_ordered( @new_fields );
}
}
$target_xml = $target_r->as_xml_record;
$target_xml =~ s/^<\?.+?\?>$//mo;
$target_xml =~ s/\n//sgo;
$target_xml =~ s/>\s+</></sgo;
return $target_xml;
Returns: SET OF bigint
Language: PLPGSQL
DECLARE
queued_record vandelay.queued_authority_record%ROWTYPE;
BEGIN
FOR queued_record IN SELECT * FROM vandelay.queued_authority_record WHERE queue = queue_id AND import_time IS NULL LOOP
IF vandelay.auto_overlay_authority_record( queued_record.id, merge_profile_id ) THEN
RETURN NEXT queued_record.id;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF bigint
Language: SQL
SELECT * FROM vandelay.auto_overlay_authority_queue( $1, NULL );
Returns: boolean
Language: PLPGSQL
DECLARE
eg_id BIGINT;
match_count INT;
BEGIN
SELECT COUNT(*) INTO match_count FROM vandelay.authority_match WHERE queued_record = import_id;
IF match_count <> 1 THEN
-- RAISE NOTICE 'not an exact match';
RETURN FALSE;
END IF;
SELECT m.eg_record INTO eg_id
FROM vandelay.authority_match m
WHERE m.queued_record = import_id
LIMIT 1;
IF eg_id IS NULL THEN
RETURN FALSE;
END IF;
RETURN vandelay.overlay_authority_record( import_id, eg_id, merge_profile_id );
END;
Returns: SET OF bigint
Language: PLPGSQL
DECLARE
queued_record vandelay.queued_bib_record%ROWTYPE;
BEGIN
FOR queued_record IN SELECT * FROM vandelay.queued_bib_record WHERE queue = queue_id AND import_time IS NULL LOOP
IF vandelay.auto_overlay_bib_record( queued_record.id, merge_profile_id ) THEN
RETURN NEXT queued_record.id;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF bigint
Language: SQL
SELECT * FROM vandelay.auto_overlay_bib_queue( $1, NULL );
Returns: SET OF bigint
Language: PLPGSQL
DECLARE
queued_record vandelay.queued_bib_record%ROWTYPE;
BEGIN
FOR queued_record IN SELECT * FROM vandelay.queued_bib_record WHERE queue = queue_id AND import_time IS NULL LOOP
IF vandelay.auto_overlay_bib_record_with_best( queued_record.id, merge_profile_id, lwm_ratio_value ) THEN
RETURN NEXT queued_record.id;
END IF;
END LOOP;
RETURN;
END;
Returns: SET OF bigint
Language: SQL
SELECT vandelay.auto_overlay_bib_queue_with_best( $1, $2, p.lwm_ratio ) FROM vandelay.merge_profile p WHERE id = $2;
Returns: boolean
Language: PLPGSQL
DECLARE
eg_id BIGINT;
match_count INT;
BEGIN
PERFORM * FROM vandelay.queued_bib_record WHERE import_time IS NOT NULL AND id = import_id;
IF FOUND THEN
-- RAISE NOTICE 'already imported, cannot auto-overlay'
RETURN FALSE;
END IF;
SELECT COUNT(*) INTO match_count FROM vandelay.bib_match WHERE queued_record = import_id;
IF match_count <> 1 THEN
-- RAISE NOTICE 'not an exact match';
RETURN FALSE;
END IF;
-- Check that the one match is on the first 901c
SELECT m.eg_record INTO eg_id
FROM vandelay.queued_bib_record q
JOIN vandelay.bib_match m ON (m.queued_record = q.id)
WHERE q.id = import_id
AND m.eg_record = oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]',marc)::BIGINT;
IF NOT FOUND THEN
-- RAISE NOTICE 'not a 901c match';
RETURN FALSE;
END IF;
RETURN vandelay.overlay_bib_record( import_id, eg_id, merge_profile_id );
END;
Returns: boolean
Language: PLPGSQL
DECLARE
eg_id BIGINT;
lwm_ratio_value NUMERIC;
BEGIN
lwm_ratio_value := COALESCE(lwm_ratio_value_p, 0.0);
PERFORM * FROM vandelay.queued_bib_record WHERE import_time IS NOT NULL AND id = import_id;
IF FOUND THEN
-- RAISE NOTICE 'already imported, cannot auto-overlay'
RETURN FALSE;
END IF;
SELECT m.eg_record INTO eg_id
FROM vandelay.bib_match m
JOIN vandelay.queued_bib_record qr ON (m.queued_record = qr.id)
JOIN vandelay.bib_queue q ON (qr.queue = q.id)
JOIN biblio.record_entry r ON (r.id = m.eg_record)
WHERE m.queued_record = import_id
AND qr.quality::NUMERIC / COALESCE(NULLIF(m.quality,0),1)::NUMERIC >= lwm_ratio_value
ORDER BY m.match_score DESC, -- required match score
qr.quality::NUMERIC / COALESCE(NULLIF(m.quality,0),1)::NUMERIC DESC, -- quality tie breaker
m.id -- when in doubt, use the first match
LIMIT 1;
IF eg_id IS NULL THEN
-- RAISE NOTICE 'incoming record is not of high enough quality';
RETURN FALSE;
END IF;
RETURN vandelay.overlay_bib_record( import_id, eg_id, merge_profile_id );
END;
Returns: boolean
Language: SQL
SELECT vandelay.auto_overlay_bib_record_with_best( $1, $2, p.lwm_ratio ) FROM vandelay.merge_profile p WHERE id = $2;
Returns: trigger
Language: PLPGSQL
BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
END IF;
DELETE FROM vandelay.queued_authority_record_attr WHERE record = OLD.id;
IF TG_OP = 'UPDATE' THEN
RETURN NEW;
END IF;
RETURN OLD;
END;
Returns: trigger
Language: PLPGSQL
BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
END IF;
DELETE FROM vandelay.queued_bib_record_attr WHERE record = OLD.id;
DELETE FROM vandelay.import_item WHERE record = OLD.id;
IF TG_OP = 'UPDATE' THEN
RETURN NEW;
END IF;
RETURN OLD;
END;
Returns: compile_profile
Language: PLPGSQL
DECLARE
output vandelay.compile_profile%ROWTYPE;
profile vandelay.merge_profile%ROWTYPE;
profile_tmpl TEXT;
profile_tmpl_owner TEXT;
add_rule TEXT := '';
strip_rule TEXT := '';
replace_rule TEXT := '';
preserve_rule TEXT := '';
BEGIN
profile_tmpl := (oils_xpath('//*[@tag="905"]/*[@code="t"]/text()',incoming_xml))[1];
profile_tmpl_owner := (oils_xpath('//*[@tag="905"]/*[@code="o"]/text()',incoming_xml))[1];
IF profile_tmpl IS NOT NULL AND profile_tmpl <> '' AND profile_tmpl_owner IS NOT NULL AND profile_tmpl_owner <> '' THEN
SELECT p.* INTO profile
FROM vandelay.merge_profile p
JOIN actor.org_unit u ON (u.id = p.owner)
WHERE p.name = profile_tmpl
AND u.shortname = profile_tmpl_owner;
IF profile.id IS NOT NULL THEN
add_rule := COALESCE(profile.add_spec,'');
strip_rule := COALESCE(profile.strip_spec,'');
replace_rule := COALESCE(profile.replace_spec,'');
preserve_rule := COALESCE(profile.preserve_spec,'');
END IF;
END IF;
add_rule := add_rule || ',' || COALESCE(ARRAY_TO_STRING(oils_xpath('//*[@tag="905"]/*[@code="a"]/text()',incoming_xml),','),'');
strip_rule := strip_rule || ',' || COALESCE(ARRAY_TO_STRING(oils_xpath('//*[@tag="905"]/*[@code="d"]/text()',incoming_xml),','),'');
replace_rule := replace_rule || ',' || COALESCE(ARRAY_TO_STRING(oils_xpath('//*[@tag="905"]/*[@code="r"]/text()',incoming_xml),','),'');
preserve_rule := preserve_rule || ',' || COALESCE(ARRAY_TO_STRING(oils_xpath('//*[@tag="905"]/*[@code="p"]/text()',incoming_xml),','),'');
output.add_rule := BTRIM(add_rule,',');
output.replace_rule := BTRIM(replace_rule,',');
output.strip_rule := BTRIM(strip_rule,',');
output.preserve_rule := BTRIM(preserve_rule,',');
RETURN output;
END;
Returns: hstore
Language: PLPGSQL
DECLARE
transformed_xml TEXT;
prev_xfrm TEXT;
normalizer RECORD;
xfrm config.xml_transform%ROWTYPE;
attr_value TEXT;
new_attrs HSTORE := ''::HSTORE;
attr_def config.record_attr_definition%ROWTYPE;
BEGIN
FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE name IN (SELECT * FROM UNNEST(attr_defs)) ORDER BY format LOOP
IF attr_def.tag IS NOT NULL THEN -- tag (and optional subfield list) selection
SELECT ARRAY_TO_STRING(ARRAY_ACCUM(x.value), COALESCE(attr_def.joiner,' ')) INTO attr_value
FROM vandelay.flatten_marc(xml) AS x
WHERE x.tag LIKE attr_def.tag
AND CASE
WHEN attr_def.sf_list IS NOT NULL
THEN POSITION(x.subfield IN attr_def.sf_list) > 0
ELSE TRUE
END
GROUP BY x.tag
ORDER BY x.tag
LIMIT 1;
ELSIF attr_def.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
attr_value := vandelay.marc21_extract_fixed_field(xml, attr_def.fixed_field);
ELSIF attr_def.xpath IS NOT NULL THEN -- and xpath expression
SELECT INTO xfrm * FROM config.xml_transform WHERE name = attr_def.format;
-- See if we can skip the XSLT ... it's expensive
IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
-- Can't skip the transform
IF xfrm.xslt <> '---' THEN
transformed_xml := oils_xslt_process(xml,xfrm.xslt);
ELSE
transformed_xml := xml;
END IF;
prev_xfrm := xfrm.name;
END IF;
IF xfrm.name IS NULL THEN
-- just grab the marcxml (empty) transform
SELECT INTO xfrm * FROM config.xml_transform WHERE xslt = '---' LIMIT 1;
prev_xfrm := xfrm.name;
END IF;
attr_value := oils_xpath_string(attr_def.xpath, transformed_xml, COALESCE(attr_def.joiner,' '), ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]);
ELSIF attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
SELECT m.value::TEXT INTO attr_value
FROM vandelay.marc21_physical_characteristics(xml) v
JOIN config.marc21_physical_characteristic_value_map m ON (m.id = v.value)
WHERE v.subfield = attr_def.phys_char_sf
LIMIT 1; -- Just in case ...
END IF;
-- apply index normalizers to attr_value
FOR normalizer IN
SELECT n.func AS func,
n.param_count AS param_count,
m.params AS params
FROM config.index_normalizer n
JOIN config.record_attr_index_norm_map m ON (m.norm = n.id)
WHERE attr = attr_def.name
ORDER BY m.pos LOOP
EXECUTE 'SELECT ' || normalizer.func || '(' ||
quote_literal( attr_value ) ||
CASE
WHEN normalizer.param_count > 0
THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
ELSE ''
END ||
')' INTO attr_value;
END LOOP;
-- Add the new value to the hstore
new_attrs := new_attrs || hstore( attr_def.name, attr_value );
END LOOP;
RETURN new_attrs;
END;
Returns: hstore
Language: SQL
SELECT vandelay.extract_rec_attrs( $1, (SELECT ARRAY_ACCUM(name) FROM config.record_attr_definition));
Returns: SET OF tcn_data
Language: PLPGSQL
DECLARE
eg_tcn TEXT;
eg_tcn_source TEXT;
output vandelay.tcn_data%ROWTYPE;
BEGIN
-- 001/003
eg_tcn := BTRIM((oils_xpath('//*[@tag="001"]/text()',xml))[1]);
IF eg_tcn IS NOT NULL AND eg_tcn <> '' THEN
eg_tcn_source := BTRIM((oils_xpath('//*[@tag="003"]/text()',xml))[1]);
IF eg_tcn_source IS NULL OR eg_tcn_source = '' THEN
eg_tcn_source := 'System Local';
END IF;
PERFORM id FROM biblio.record_entry WHERE tcn_value = eg_tcn AND NOT deleted;
IF NOT FOUND THEN
output.used := FALSE;
ELSE
output.used := TRUE;
END IF;
output.tcn := eg_tcn;
output.tcn_source := eg_tcn_source;
RETURN NEXT output;
END IF;
-- 901 ab
eg_tcn := BTRIM((oils_xpath('//*[@tag="901"]/*[@code="a"]/text()',xml))[1]);
IF eg_tcn IS NOT NULL AND eg_tcn <> '' THEN
eg_tcn_source := BTRIM((oils_xpath('//*[@tag="901"]/*[@code="b"]/text()',xml))[1]);
IF eg_tcn_source IS NULL OR eg_tcn_source = '' THEN
eg_tcn_source := 'System Local';
END IF;
PERFORM id FROM biblio.record_entry WHERE tcn_value = eg_tcn AND NOT deleted;
IF NOT FOUND THEN
output.used := FALSE;
ELSE
output.used := TRUE;
END IF;
output.tcn := eg_tcn;
output.tcn_source := eg_tcn_source;
RETURN NEXT output;
END IF;
-- 039 ab
eg_tcn := BTRIM((oils_xpath('//*[@tag="039"]/*[@code="a"]/text()',xml))[1]);
IF eg_tcn IS NOT NULL AND eg_tcn <> '' THEN
eg_tcn_source := BTRIM((oils_xpath('//*[@tag="039"]/*[@code="b"]/text()',xml))[1]);
IF eg_tcn_source IS NULL OR eg_tcn_source = '' THEN
eg_tcn_source := 'System Local';
END IF;
PERFORM id FROM biblio.record_entry WHERE tcn_value = eg_tcn AND NOT deleted;
IF NOT FOUND THEN
output.used := FALSE;
ELSE
output.used := TRUE;
END IF;
output.tcn := eg_tcn;
output.tcn_source := eg_tcn_source;
RETURN NEXT output;
END IF;
-- 020 a
eg_tcn := REGEXP_REPLACE((oils_xpath('//*[@tag="020"]/*[@code="a"]/text()',xml))[1], $re$^(\w+).*?$$re$, $re$\1$re$);
IF eg_tcn IS NOT NULL AND eg_tcn <> '' THEN
eg_tcn_source := 'ISBN';
PERFORM id FROM biblio.record_entry WHERE tcn_value = eg_tcn AND NOT deleted;
IF NOT FOUND THEN
output.used := FALSE;
ELSE
output.used := TRUE;
END IF;
output.tcn := eg_tcn;
output.tcn_source := eg_tcn_source;
RETURN NEXT output;
END IF;
-- 022 a
eg_tcn := REGEXP_REPLACE((oils_xpath('//*[@tag="022"]/*[@code="a"]/text()',xml))[1], $re$^(\w+).*?$$re$, $re$\1$re$);
IF eg_tcn IS NOT NULL AND eg_tcn <> '' THEN
eg_tcn_source := 'ISSN';
PERFORM id FROM biblio.record_entry WHERE tcn_value = eg_tcn AND NOT deleted;
IF NOT FOUND THEN
output.used := FALSE;
ELSE
output.used := TRUE;
END IF;
output.tcn := eg_tcn;
output.tcn_source := eg_tcn_source;
RETURN NEXT output;
END IF;
-- 010 a
eg_tcn := REGEXP_REPLACE((oils_xpath('//*[@tag="010"]/*[@code="a"]/text()',xml))[1], $re$^(\w+).*?$$re$, $re$\1$re$);
IF eg_tcn IS NOT NULL AND eg_tcn <> '' THEN
eg_tcn_source := 'LCCN';
PERFORM id FROM biblio.record_entry WHERE tcn_value = eg_tcn AND NOT deleted;
IF NOT FOUND THEN
output.used := FALSE;
ELSE
output.used := TRUE;
END IF;
output.tcn := eg_tcn;
output.tcn_source := eg_tcn_source;
RETURN NEXT output;
END IF;
-- 035 a
eg_tcn := REGEXP_REPLACE((oils_xpath('//*[@tag="035"]/*[@code="a"]/text()',xml))[1], $re$^.*?(\w+)$$re$, $re$\1$re$);
IF eg_tcn IS NOT NULL AND eg_tcn <> '' THEN
eg_tcn_source := 'System Legacy';
PERFORM id FROM biblio.record_entry WHERE tcn_value = eg_tcn AND NOT deleted;
IF NOT FOUND THEN
output.used := FALSE;
ELSE
output.used := TRUE;
END IF;
output.tcn := eg_tcn;
output.tcn_source := eg_tcn_source;
RETURN NEXT output;
END IF;
RETURN;
END;
Returns: SET OF flat_marc
Language: PLPGSQL
DECLARE
output vandelay.flat_marc%ROWTYPE;
field RECORD;
BEGIN
FOR field IN SELECT * FROM vandelay.flay_marc( marc ) LOOP
output.ind1 := field.ind1;
output.ind2 := field.ind2;
output.tag := field.tag;
output.subfield := field.subfield;
IF field.subfield IS NOT NULL AND field.tag NOT IN ('020','022','024') THEN -- exclude standard numbers and control fields
output.value := naco_normalize(field.value, field.subfield);
ELSE
output.value := field.value;
END IF;
CONTINUE WHEN output.value IS NULL;
RETURN NEXT output;
END LOOP;
END;
Returns: hstore
Language: PLPGSQL
BEGIN
RETURN (SELECT
HSTORE(
ARRAY_ACCUM(tag || (COALESCE(subfield, ''))),
ARRAY_ACCUM(value)
)
FROM (
SELECT tag, subfield, ARRAY_ACCUM(value)::TEXT AS value
FROM (SELECT tag,
subfield,
CASE WHEN tag = '020' THEN -- caseless -- isbn
LOWER((REGEXP_MATCHES(value,$$^(\S{10,17})$$))[1] || '%')
WHEN tag = '022' THEN -- caseless -- issn
LOWER((REGEXP_MATCHES(value,$$^(\S{4}[- ]?\S{4})$$))[1] || '%')
WHEN tag = '024' THEN -- caseless -- upc (other)
LOWER(value || '%')
ELSE
value
END AS value
FROM vandelay.flatten_marc(record_xml)) x
GROUP BY tag, subfield ORDER BY tag, subfield
) subquery
);
END;
Returns: SET OF flat_marc
Language: PLPERLU
use MARC::Record;
use MARC::File::XML (BinaryEncoding => 'UTF-8');
use MARC::Charset;
use strict;
MARC::Charset->assume_unicode(1);
my $xml = shift;
my $r = MARC::Record->new_from_xml( $xml );
return_next( { tag => 'LDR', value => $r->leader } );
for my $f ( $r->fields ) {
if ($f->is_control_field) {
return_next({ tag => $f->tag, value => $f->data });
} else {
for my $s ($f->subfields) {
return_next({
tag => $f->tag,
ind1 => $f->indicator(1),
ind2 => $f->indicator(2),
subfield => $s->[0],
value => $s->[1]
});
if ( $f->tag eq '245' and $s->[0] eq 'a' ) {
my $trim = $f->indicator(2) || 0;
return_next({
tag => 'tnf',
ind1 => $f->indicator(1),
ind2 => $f->indicator(2),
subfield => 'a',
value => substr( $s->[1], $trim )
});
}
}
}
}
return undef;
Returns: text
Language: PLPGSQL
DECLARE
root vandelay.match_set_point;
BEGIN
SELECT * INTO root FROM vandelay.match_set_point
WHERE parent IS NULL AND match_set = match_set_id;
RETURN vandelay.get_expr_from_match_set_point(root);
END;
Returns: text
Language: PLPGSQL
DECLARE
q TEXT;
i INTEGER;
this_op TEXT;
children INTEGER[];
child vandelay.match_set_point;
BEGIN
SELECT ARRAY_ACCUM(id) INTO children FROM vandelay.match_set_point
WHERE parent = node.id;
IF ARRAY_LENGTH(children, 1) > 0 THEN
this_op := vandelay._get_expr_render_one(node);
q := '(';
i := 1;
WHILE children[i] IS NOT NULL LOOP
SELECT * INTO child FROM vandelay.match_set_point
WHERE id = children[i];
IF i > 1 THEN
q := q || ' ' || this_op || ' ';
END IF;
i := i + 1;
q := q || vandelay.get_expr_from_match_set_point(child);
END LOOP;
q := q || ')';
RETURN q;
ELSIF node.bool_op IS NULL THEN
PERFORM vandelay._get_expr_push_qrow(node);
PERFORM vandelay._get_expr_push_jrow(node);
RETURN vandelay._get_expr_render_one(node);
ELSE
RETURN '';
END IF;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
value TEXT;
atype TEXT;
adef RECORD;
BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
END IF;
FOR adef IN SELECT * FROM vandelay.authority_attr_definition LOOP
SELECT extract_marc_field('vandelay.queued_authority_record', id, adef.xpath, adef.remove) INTO value FROM vandelay.queued_authority_record WHERE id = NEW.id;
IF (value IS NOT NULL AND value <> '') THEN
INSERT INTO vandelay.queued_authority_record_attr (record, field, attr_value) VALUES (NEW.id, adef.id, value);
END IF;
END LOOP;
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
attr_def BIGINT;
item_data vandelay.import_item%ROWTYPE;
BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
END IF;
SELECT item_attr_def INTO attr_def FROM vandelay.bib_queue WHERE id = NEW.queue;
FOR item_data IN SELECT * FROM vandelay.ingest_items( NEW.id::BIGINT, attr_def ) LOOP
INSERT INTO vandelay.import_item (
record,
definition,
owning_lib,
circ_lib,
call_number,
copy_number,
status,
location,
circulate,
deposit,
deposit_amount,
ref,
holdable,
price,
barcode,
circ_modifier,
circ_as_type,
alert_message,
pub_note,
priv_note,
opac_visible,
import_error,
error_detail
) VALUES (
NEW.id,
item_data.definition,
item_data.owning_lib,
item_data.circ_lib,
item_data.call_number,
item_data.copy_number,
item_data.status,
item_data.location,
item_data.circulate,
item_data.deposit,
item_data.deposit_amount,
item_data.ref,
item_data.holdable,
item_data.price,
item_data.barcode,
item_data.circ_modifier,
item_data.circ_as_type,
item_data.alert_message,
item_data.pub_note,
item_data.priv_note,
item_data.opac_visible,
item_data.import_error,
item_data.error_detail
);
END LOOP;
RETURN NULL;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
value TEXT;
atype TEXT;
adef RECORD;
BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
END IF;
FOR adef IN SELECT * FROM vandelay.bib_attr_definition LOOP
SELECT extract_marc_field('vandelay.queued_bib_record', id, adef.xpath, adef.remove) INTO value FROM vandelay.queued_bib_record WHERE id = NEW.id;
IF (value IS NOT NULL AND value <> '') THEN
INSERT INTO vandelay.queued_bib_record_attr (record, field, attr_value) VALUES (NEW.id, adef.id, value);
END IF;
END LOOP;
RETURN NULL;
END;
Returns: SET OF import_item
Language: PLPGSQL
DECLARE
owning_lib TEXT;
circ_lib TEXT;
call_number TEXT;
copy_number TEXT;
status TEXT;
location TEXT;
circulate TEXT;
deposit TEXT;
deposit_amount TEXT;
ref TEXT;
holdable TEXT;
price TEXT;
barcode TEXT;
circ_modifier TEXT;
circ_as_type TEXT;
alert_message TEXT;
opac_visible TEXT;
pub_note TEXT;
priv_note TEXT;
attr_def RECORD;
tmp_attr_set RECORD;
attr_set vandelay.import_item%ROWTYPE;
xpath TEXT;
tmp_str TEXT;
BEGIN
SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
IF FOUND THEN
attr_set.definition := attr_def.id;
-- Build the combined XPath
owning_lib :=
CASE
WHEN attr_def.owning_lib IS NULL THEN 'null()'
WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.owning_lib || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.owning_lib
END;
circ_lib :=
CASE
WHEN attr_def.circ_lib IS NULL THEN 'null()'
WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_lib || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_lib
END;
call_number :=
CASE
WHEN attr_def.call_number IS NULL THEN 'null()'
WHEN LENGTH( attr_def.call_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.call_number || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.call_number
END;
copy_number :=
CASE
WHEN attr_def.copy_number IS NULL THEN 'null()'
WHEN LENGTH( attr_def.copy_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.copy_number || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.copy_number
END;
status :=
CASE
WHEN attr_def.status IS NULL THEN 'null()'
WHEN LENGTH( attr_def.status ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.status || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.status
END;
location :=
CASE
WHEN attr_def.location IS NULL THEN 'null()'
WHEN LENGTH( attr_def.location ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.location || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.location
END;
circulate :=
CASE
WHEN attr_def.circulate IS NULL THEN 'null()'
WHEN LENGTH( attr_def.circulate ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circulate || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circulate
END;
deposit :=
CASE
WHEN attr_def.deposit IS NULL THEN 'null()'
WHEN LENGTH( attr_def.deposit ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit
END;
deposit_amount :=
CASE
WHEN attr_def.deposit_amount IS NULL THEN 'null()'
WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit_amount || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit_amount
END;
ref :=
CASE
WHEN attr_def.ref IS NULL THEN 'null()'
WHEN LENGTH( attr_def.ref ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.ref || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.ref
END;
holdable :=
CASE
WHEN attr_def.holdable IS NULL THEN 'null()'
WHEN LENGTH( attr_def.holdable ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.holdable || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.holdable
END;
price :=
CASE
WHEN attr_def.price IS NULL THEN 'null()'
WHEN LENGTH( attr_def.price ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.price || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.price
END;
barcode :=
CASE
WHEN attr_def.barcode IS NULL THEN 'null()'
WHEN LENGTH( attr_def.barcode ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.barcode || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.barcode
END;
circ_modifier :=
CASE
WHEN attr_def.circ_modifier IS NULL THEN 'null()'
WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_modifier || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_modifier
END;
circ_as_type :=
CASE
WHEN attr_def.circ_as_type IS NULL THEN 'null()'
WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_as_type || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_as_type
END;
alert_message :=
CASE
WHEN attr_def.alert_message IS NULL THEN 'null()'
WHEN LENGTH( attr_def.alert_message ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.alert_message || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.alert_message
END;
opac_visible :=
CASE
WHEN attr_def.opac_visible IS NULL THEN 'null()'
WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.opac_visible || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.opac_visible
END;
pub_note :=
CASE
WHEN attr_def.pub_note IS NULL THEN 'null()'
WHEN LENGTH( attr_def.pub_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.pub_note || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.pub_note
END;
priv_note :=
CASE
WHEN attr_def.priv_note IS NULL THEN 'null()'
WHEN LENGTH( attr_def.priv_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.priv_note || '"]'
ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.priv_note
END;
xpath :=
owning_lib || '|' ||
circ_lib || '|' ||
call_number || '|' ||
copy_number || '|' ||
status || '|' ||
location || '|' ||
circulate || '|' ||
deposit || '|' ||
deposit_amount || '|' ||
ref || '|' ||
holdable || '|' ||
price || '|' ||
barcode || '|' ||
circ_modifier || '|' ||
circ_as_type || '|' ||
alert_message || '|' ||
pub_note || '|' ||
priv_note || '|' ||
opac_visible;
FOR tmp_attr_set IN
SELECT *
FROM oils_xpath_table( 'id', 'marc', 'vandelay.queued_bib_record', xpath, 'id = ' || import_id )
AS t( id INT, ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, opac_vis TEXT )
LOOP
attr_set.import_error := NULL;
attr_set.error_detail := NULL;
attr_set.deposit_amount := NULL;
attr_set.copy_number := NULL;
attr_set.price := NULL;
IF tmp_attr_set.pr != '' THEN
tmp_str = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
IF tmp_str = '' THEN
attr_set.import_error := 'import.item.invalid.price';
attr_set.error_detail := tmp_attr_set.pr; -- original value
RETURN NEXT attr_set; CONTINUE;
END IF;
attr_set.price := tmp_str::NUMERIC(8,2);
END IF;
IF tmp_attr_set.dep_amount != '' THEN
tmp_str = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
IF tmp_str = '' THEN
attr_set.import_error := 'import.item.invalid.deposit_amount';
attr_set.error_detail := tmp_attr_set.dep_amount;
RETURN NEXT attr_set; CONTINUE;
END IF;
attr_set.deposit_amount := tmp_str::NUMERIC(8,2);
END IF;
IF tmp_attr_set.cnum != '' THEN
tmp_str = REGEXP_REPLACE(tmp_attr_set.cnum, E'[^0-9]', '', 'g');
IF tmp_str = '' THEN
attr_set.import_error := 'import.item.invalid.copy_number';
attr_set.error_detail := tmp_attr_set.cnum;
RETURN NEXT attr_set; CONTINUE;
END IF;
attr_set.copy_number := tmp_str::INT;
END IF;
IF tmp_attr_set.ol != '' THEN
SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
IF NOT FOUND THEN
attr_set.import_error := 'import.item.invalid.owning_lib';
attr_set.error_detail := tmp_attr_set.ol;
RETURN NEXT attr_set; CONTINUE;
END IF;
END IF;
IF tmp_attr_set.clib != '' THEN
SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
IF NOT FOUND THEN
attr_set.import_error := 'import.item.invalid.circ_lib';
attr_set.error_detail := tmp_attr_set.clib;
RETURN NEXT attr_set; CONTINUE;
END IF;
END IF;
IF tmp_attr_set.cs != '' THEN
SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
IF NOT FOUND THEN
attr_set.import_error := 'import.item.invalid.status';
attr_set.error_detail := tmp_attr_set.cs;
RETURN NEXT attr_set; CONTINUE;
END IF;
END IF;
IF tmp_attr_set.circ_mod != '' THEN
SELECT code INTO attr_set.circ_modifier FROM config.circ_modifier WHERE code = tmp_attr_set.circ_mod;
IF NOT FOUND THEN
attr_set.import_error := 'import.item.invalid.circ_modifier';
attr_set.error_detail := tmp_attr_set.circ_mod;
RETURN NEXT attr_set; CONTINUE;
END IF;
END IF;
IF tmp_attr_set.circ_as != '' THEN
SELECT code INTO attr_set.circ_as_type FROM config.coded_value_map WHERE ctype = 'item_type' AND code = tmp_attr_set.circ_as;
IF NOT FOUND THEN
attr_set.import_error := 'import.item.invalid.circ_as_type';
attr_set.error_detail := tmp_attr_set.circ_as;
RETURN NEXT attr_set; CONTINUE;
END IF;
END IF;
IF tmp_attr_set.cl != '' THEN
-- search up the org unit tree for a matching copy location
WITH RECURSIVE anscestor_depth AS (
SELECT ou.id,
out.depth AS depth,
ou.parent_ou
FROM actor.org_unit ou
JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
WHERE ou.id = COALESCE(attr_set.owning_lib, attr_set.circ_lib)
UNION ALL
SELECT ou.id,
out.depth,
ou.parent_ou
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 cpl.id INTO attr_set.location
FROM anscestor_depth a
JOIN asset.copy_location cpl ON (cpl.owning_lib = a.id)
WHERE LOWER(cpl.name) = LOWER(tmp_attr_set.cl)
ORDER BY a.depth DESC
LIMIT 1;
IF NOT FOUND THEN
attr_set.import_error := 'import.item.invalid.location';
attr_set.error_detail := tmp_attr_set.cs;
RETURN NEXT attr_set; CONTINUE;
END IF;
END IF;
attr_set.circulate :=
LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
attr_set.deposit :=
LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
attr_set.holdable :=
LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
attr_set.opac_visible :=
LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
attr_set.ref :=
LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
attr_set.call_number := tmp_attr_set.cn; -- TEXT
attr_set.barcode := tmp_attr_set.bc; -- TEXT,
attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
attr_set.pub_note := tmp_attr_set.note; -- TEXT,
attr_set.priv_note := tmp_attr_set.pnote; -- TEXT,
attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
RETURN NEXT attr_set;
END LOOP;
END IF;
RETURN;
END;
Returns: SET OF record_ff_map
Language: PLPGSQL
DECLARE
tag_data TEXT;
rtype TEXT;
ff_pos RECORD;
output biblio.record_ff_map%ROWTYPE;
BEGIN
rtype := (vandelay.marc21_record_type( marc )).code;
FOR ff_pos IN SELECT * FROM config.marc21_ff_pos_map WHERE rec_type = rtype ORDER BY tag DESC LOOP
output.ff_name := ff_pos.fixed_field;
output.ff_value := NULL;
IF ff_pos.tag = 'ldr' THEN
output.ff_value := oils_xpath_string('//*[local-name()="leader"]', marc);
IF output.ff_value IS NOT NULL THEN
output.ff_value := SUBSTRING( output.ff_value, ff_pos.start_pos + 1, ff_pos.length );
RETURN NEXT output;
output.ff_value := NULL;
END IF;
ELSE
FOR tag_data IN SELECT value FROM UNNEST( oils_xpath( '//*[@tag="' || UPPER(ff_pos.tag) || '"]/text()', marc ) ) x(value) LOOP
output.ff_value := SUBSTRING( tag_data, ff_pos.start_pos + 1, ff_pos.length );
IF output.ff_value IS NULL THEN output.ff_value := REPEAT( ff_pos.default_val, ff_pos.length ); END IF;
RETURN NEXT output;
output.ff_value := NULL;
END LOOP;
END IF;
END LOOP;
RETURN;
END;
Returns: text
Language: PLPGSQL
DECLARE
rtype TEXT;
ff_pos RECORD;
tag_data RECORD;
val TEXT;
BEGIN
rtype := (vandelay.marc21_record_type( marc )).code;
FOR ff_pos IN SELECT * FROM config.marc21_ff_pos_map WHERE fixed_field = ff AND rec_type = rtype ORDER BY tag DESC LOOP
IF ff_pos.tag = 'ldr' THEN
val := oils_xpath_string('//*[local-name()="leader"]', marc);
IF val IS NOT NULL THEN
val := SUBSTRING( val, ff_pos.start_pos + 1, ff_pos.length );
RETURN val;
END IF;
ELSE
FOR tag_data IN SELECT value FROM UNNEST( oils_xpath( '//*[@tag="' || UPPER(ff_pos.tag) || '"]/text()', marc ) ) x(value) LOOP
val := SUBSTRING( tag_data.value, ff_pos.start_pos + 1, ff_pos.length );
RETURN val;
END LOOP;
END IF;
val := REPEAT( ff_pos.default_val, ff_pos.length );
RETURN val;
END LOOP;
RETURN NULL;
END;
Returns: SET OF marc21_physical_characteristics
Language: PLPGSQL
DECLARE
rowid INT := 0;
_007 TEXT;
ptype config.marc21_physical_characteristic_type_map%ROWTYPE;
psf config.marc21_physical_characteristic_subfield_map%ROWTYPE;
pval config.marc21_physical_characteristic_value_map%ROWTYPE;
retval biblio.marc21_physical_characteristics%ROWTYPE;
BEGIN
_007 := oils_xpath_string( '//*[@tag="007"]', marc );
IF _007 IS NOT NULL AND _007 <> '' THEN
SELECT * INTO ptype FROM config.marc21_physical_characteristic_type_map WHERE ptype_key = SUBSTRING( _007, 1, 1 );
IF ptype.ptype_key IS NOT NULL THEN
FOR psf IN SELECT * FROM config.marc21_physical_characteristic_subfield_map WHERE ptype_key = ptype.ptype_key LOOP
SELECT * INTO pval FROM config.marc21_physical_characteristic_value_map WHERE ptype_subfield = psf.id AND value = SUBSTRING( _007, psf.start_pos + 1, psf.length );
IF pval.id IS NOT NULL THEN
rowid := rowid + 1;
retval.id := rowid;
retval.ptype := ptype.ptype_key;
retval.subfield := psf.id;
retval.value := pval.id;
RETURN NEXT retval;
END IF;
END LOOP;
END IF;
END IF;
RETURN;
END;
Returns: marc21_rec_type_map
Language: PLPGSQL
DECLARE
ldr TEXT;
tval TEXT;
tval_rec RECORD;
bval TEXT;
bval_rec RECORD;
retval config.marc21_rec_type_map%ROWTYPE;
BEGIN
ldr := oils_xpath_string( '//*[local-name()="leader"]', marc );
IF ldr IS NULL OR ldr = '' THEN
SELECT * INTO retval FROM config.marc21_rec_type_map WHERE code = 'BKS';
RETURN retval;
END IF;
SELECT * INTO tval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'Type' LIMIT 1; -- They're all the same
SELECT * INTO bval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'BLvl' LIMIT 1; -- They're all the same
tval := SUBSTRING( ldr, tval_rec.start_pos + 1, tval_rec.length );
bval := SUBSTRING( ldr, bval_rec.start_pos + 1, bval_rec.length );
-- RAISE NOTICE 'type %, blvl %, ldr %', tval, bval, ldr;
SELECT * INTO retval FROM config.marc21_rec_type_map WHERE type_val LIKE '%' || tval || '%' AND blvl_val LIKE '%' || bval || '%';
IF retval.code IS NULL THEN
SELECT * INTO retval FROM config.marc21_rec_type_map WHERE code = 'BKS';
END IF;
RETURN retval;
END;
Returns: trigger
Language: PLPGSQL
DECLARE
incoming_existing_id TEXT;
test_result vandelay.match_set_test_result%ROWTYPE;
tmp_rec BIGINT;
match_set INT;
BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
END IF;
DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
SELECT q.match_set INTO match_set FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
IF match_set IS NOT NULL THEN
NEW.quality := vandelay.measure_record_quality( NEW.marc, match_set );
END IF;
-- Perfect matches on 901$c exit early with a match with high quality.
incoming_existing_id :=
oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]', NEW.marc);
IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id::bigint;
IF tmp_rec IS NOT NULL THEN
INSERT INTO vandelay.bib_match (queued_record, eg_record, match_score, quality)
SELECT
NEW.id,
b.id,
9999,
-- note: no match_set means quality==0
vandelay.measure_record_quality( b.marc, match_set )
FROM biblio.record_entry b
WHERE id = incoming_existing_id::bigint;
END IF;
END IF;
IF match_set IS NULL THEN
RETURN NEW;
END IF;
FOR test_result IN SELECT * FROM
vandelay.match_set_test_marcxml(match_set, NEW.marc) LOOP
INSERT INTO vandelay.bib_match ( queued_record, eg_record, match_score, quality )
SELECT
NEW.id,
test_result.record,
test_result.quality,
vandelay.measure_record_quality( b.marc, match_set )
FROM biblio.record_entry b
WHERE id = test_result.record;
END LOOP;
RETURN NEW;
END;
Returns: SET OF match_set_test_result
Language: PLPGSQL
DECLARE
tags_rstore HSTORE;
svf_rstore HSTORE;
coal TEXT;
joins TEXT;
query_ TEXT;
wq TEXT;
qvalue INTEGER;
rec RECORD;
BEGIN
tags_rstore := vandelay.flatten_marc_hstore(record_xml);
svf_rstore := vandelay.extract_rec_attrs(record_xml);
CREATE TEMPORARY TABLE _vandelay_tmp_qrows (q INTEGER);
CREATE TEMPORARY TABLE _vandelay_tmp_jrows (j TEXT);
-- generate the where clause and return that directly (into wq), and as
-- a side-effect, populate the _vandelay_tmp_[qj]rows tables.
wq := vandelay.get_expr_from_match_set(match_set_id);
query_ := 'SELECT DISTINCT(bre.id) AS record, ';
-- qrows table is for the quality bits we add to the SELECT clause
SELECT ARRAY_TO_STRING(
ARRAY_ACCUM('COALESCE(n' || q::TEXT || '.quality, 0)'), ' + '
) INTO coal FROM _vandelay_tmp_qrows;
-- our query string so far is the SELECT clause and the inital FROM.
-- no JOINs yet nor the WHERE clause
query_ := query_ || coal || ' AS quality ' || E'\n' ||
'FROM biblio.record_entry bre ';
-- jrows table is for the joins we must make (and the real text conditions)
SELECT ARRAY_TO_STRING(ARRAY_ACCUM(j), E'\n') INTO joins
FROM _vandelay_tmp_jrows;
-- add those joins and the where clause to our query.
query_ := query_ || joins || E'\n' || 'WHERE ' || wq || ' AND not bre.deleted';
-- this will return rows of record,quality
FOR rec IN EXECUTE query_ USING tags_rstore, svf_rstore LOOP
RETURN NEXT rec;
END LOOP;
DROP TABLE _vandelay_tmp_qrows;
DROP TABLE _vandelay_tmp_jrows;
RETURN;
END;
Returns: integer
Language: PLPGSQL
DECLARE
out_q INT := 0;
rvalue TEXT;
test vandelay.match_set_quality%ROWTYPE;
BEGIN
FOR test IN SELECT * FROM vandelay.match_set_quality WHERE match_set = match_set_id LOOP
IF test.tag IS NOT NULL THEN
FOR rvalue IN SELECT value FROM vandelay.flatten_marc( xml ) WHERE tag = test.tag AND subfield = test.subfield LOOP
IF test.value = rvalue THEN
out_q := out_q + test.quality;
END IF;
END LOOP;
ELSE
IF test.value = vandelay.extract_rec_attrs(xml, ARRAY[test.svf]) -> test.svf THEN
out_q := out_q + test.quality;
END IF;
END IF;
END LOOP;
RETURN out_q;
END;
Returns: text
Language: SQL
SELECT vandelay.replace_field( vandelay.add_field( vandelay.strip_field( $1, $5) , $2, $3 ), $2, $4);
Returns: text
Language: PLPGSQL
DECLARE
dyn_profile vandelay.compile_profile%ROWTYPE;
replace_rule TEXT;
tmp_marc TEXT;
trgt_marc TEXT;
tmpl_marc TEXT;
match_count INT;
BEGIN
IF target_marc IS NULL OR template_marc IS NULL THEN
-- RAISE NOTICE 'no marc for target or template record';
RETURN NULL;
END IF;
dyn_profile := vandelay.compile_profile( template_marc );
IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN
-- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule;
RETURN NULL;
END IF;
IF dyn_profile.replace_rule <> '' THEN
trgt_marc = target_marc;
tmpl_marc = template_marc;
replace_rule = dyn_profile.replace_rule;
ELSE
tmp_marc = target_marc;
trgt_marc = template_marc;
tmpl_marc = tmp_marc;
replace_rule = dyn_profile.preserve_rule;
END IF;
RETURN vandelay.merge_record_xml( trgt_marc, tmpl_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule );
END;
Returns: boolean
Language: PLPGSQL
DECLARE
merge_profile vandelay.merge_profile%ROWTYPE;
dyn_profile vandelay.compile_profile%ROWTYPE;
source_marc TEXT;
target_marc TEXT;
eg_marc TEXT;
v_marc TEXT;
replace_rule TEXT;
match_count INT;
BEGIN
SELECT b.marc INTO eg_marc
FROM authority.record_entry b
JOIN vandelay.authority_match m ON (m.eg_record = b.id AND m.queued_record = import_id)
LIMIT 1;
SELECT q.marc INTO v_marc
FROM vandelay.queued_record q
JOIN vandelay.authority_match m ON (m.queued_record = q.id AND q.id = import_id)
LIMIT 1;
IF eg_marc IS NULL OR v_marc IS NULL THEN
-- RAISE NOTICE 'no marc for vandelay or authority record';
RETURN FALSE;
END IF;
dyn_profile := vandelay.compile_profile( v_marc );
IF merge_profile_id IS NOT NULL THEN
SELECT * INTO merge_profile FROM vandelay.merge_profile WHERE id = merge_profile_id;
IF FOUND THEN
dyn_profile.add_rule := BTRIM( dyn_profile.add_rule || ',' || COALESCE(merge_profile.add_spec,''), ',');
dyn_profile.strip_rule := BTRIM( dyn_profile.strip_rule || ',' || COALESCE(merge_profile.strip_spec,''), ',');
dyn_profile.replace_rule := BTRIM( dyn_profile.replace_rule || ',' || COALESCE(merge_profile.replace_spec,''), ',');
dyn_profile.preserve_rule := BTRIM( dyn_profile.preserve_rule || ',' || COALESCE(merge_profile.preserve_spec,''), ',');
END IF;
END IF;
IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN
-- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule;
RETURN FALSE;
END IF;
IF dyn_profile.replace_rule <> '' THEN
source_marc = v_marc;
target_marc = eg_marc;
replace_rule = dyn_profile.replace_rule;
ELSE
source_marc = eg_marc;
target_marc = v_marc;
replace_rule = dyn_profile.preserve_rule;
END IF;
UPDATE authority.record_entry
SET marc = vandelay.merge_record_xml( target_marc, source_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule )
WHERE id = eg_id;
IF FOUND THEN
UPDATE vandelay.queued_authority_record
SET imported_as = eg_id,
import_time = NOW()
WHERE id = import_id;
RETURN TRUE;
END IF;
-- RAISE NOTICE 'update of authority.record_entry failed';
RETURN FALSE;
END;
Returns: boolean
Language: PLPGSQL
DECLARE
merge_profile vandelay.merge_profile%ROWTYPE;
dyn_profile vandelay.compile_profile%ROWTYPE;
editor_string TEXT;
editor_id INT;
source_marc TEXT;
target_marc TEXT;
eg_marc TEXT;
v_marc TEXT;
replace_rule TEXT;
BEGIN
SELECT q.marc INTO v_marc
FROM vandelay.queued_record q
JOIN vandelay.bib_match m ON (m.queued_record = q.id AND q.id = import_id)
LIMIT 1;
IF v_marc IS NULL THEN
-- RAISE NOTICE 'no marc for vandelay or bib record';
RETURN FALSE;
END IF;
IF vandelay.template_overlay_bib_record( v_marc, eg_id, merge_profile_id) THEN
UPDATE vandelay.queued_bib_record
SET imported_as = eg_id,
import_time = NOW()
WHERE id = import_id;
editor_string := (oils_xpath('//*[@tag="905"]/*[@code="u"]/text()',v_marc))[1];
IF editor_string IS NOT NULL AND editor_string <> '' THEN
SELECT usr INTO editor_id FROM actor.card WHERE barcode = editor_string;
IF editor_id IS NULL THEN
SELECT id INTO editor_id FROM actor.usr WHERE usrname = editor_string;
END IF;
IF editor_id IS NOT NULL THEN
UPDATE biblio.record_entry SET editor = editor_id WHERE id = eg_id;
END IF;
END IF;
RETURN TRUE;
END IF;
-- RAISE NOTICE 'update of biblio.record_entry failed';
RETURN FALSE;
END;
Returns: text
Language: PLPGSQL
DECLARE
xml_output TEXT;
parsed_target TEXT;
curr_field TEXT;
BEGIN
parsed_target := vandelay.strip_field( target_xml, ''); -- this dance normalizes the format of the xml for the IF below
xml_output := parsed_target; -- if there are no replace rules, just return the input
FOR curr_field IN SELECT UNNEST( STRING_TO_ARRAY(field, ',') ) LOOP -- naive split, but it's the same we use in the perl
xml_output := vandelay.strip_field( parsed_target, curr_field);
IF xml_output <> parsed_target AND curr_field ~ E'~' THEN
-- we removed something, and there was a regexp restriction in the curr_field definition, so proceed
xml_output := vandelay.add_field( xml_output, source_xml, curr_field, 1 );
ELSIF curr_field !~ E'~' THEN
-- No regexp restriction, add the curr_field
xml_output := vandelay.add_field( xml_output, source_xml, curr_field, 0 );
END IF;
parsed_target := xml_output; -- in prep for any following loop iterations
END LOOP;
RETURN xml_output;
END;
Returns: text
Language: PLPERLU
use MARC::Record;
use MARC::File::XML (BinaryEncoding => 'UTF-8');
use MARC::Charset;
use strict;
MARC::Charset->assume_unicode(1);
my $xml = shift;
my $r = MARC::Record->new_from_xml( $xml );
return $xml unless ($r);
my $field_spec = shift;
my @field_list = split(',', $field_spec);
my %fields;
for my $f (@field_list) {
$f =~ s/^\s*//; $f =~ s/\s*$//;
if ($f =~ /^(.{3})(\w*)(?:\[([^]]*)\])?$/) {
my $field = $1;
$field =~ s/\s+//;
my $sf = $2;
$sf =~ s/\s+//;
my $match = $3;
$match =~ s/^\s*//; $match =~ s/\s*$//;
$fields{$field} = { sf => [ split('', $sf) ] };
if ($match) {
my ($msf,$mre) = split('~', $match);
if (length($msf) > 0 and length($mre) > 0) {
$msf =~ s/^\s*//; $msf =~ s/\s*$//;
$mre =~ s/^\s*//; $mre =~ s/\s*$//;
$fields{$field}{match} = { sf => $msf, re => qr/$mre/ };
}
}
}
}
for my $f ( keys %fields) {
for my $to_field ($r->field( $f )) {
if (exists($fields{$f}{match})) {
next unless (grep { $_ =~ $fields{$f}{match}{re} } $to_field->subfield($fields{$f}{match}{sf}));
}
if ( @{$fields{$f}{sf}} ) {
$to_field->delete_subfield(code => $fields{$f}{sf});
} else {
$r->delete_field( $to_field );
}
}
}
$xml = $r->as_xml_record;
$xml =~ s/^<\?.+?\?>$//mo;
$xml =~ s/\n//sgo;
$xml =~ s/>\s+</></sgo;
return $xml;
Returns: boolean
Language: SQL
SELECT vandelay.template_overlay_bib_record( $1, $2, NULL);
Returns: boolean
Language: PLPGSQL
DECLARE
merge_profile vandelay.merge_profile%ROWTYPE;
dyn_profile vandelay.compile_profile%ROWTYPE;
editor_string TEXT;
editor_id INT;
source_marc TEXT;
target_marc TEXT;
eg_marc TEXT;
replace_rule TEXT;
match_count INT;
BEGIN
SELECT b.marc INTO eg_marc
FROM biblio.record_entry b
WHERE b.id = eg_id
LIMIT 1;
IF eg_marc IS NULL OR v_marc IS NULL THEN
-- RAISE NOTICE 'no marc for template or bib record';
RETURN FALSE;
END IF;
dyn_profile := vandelay.compile_profile( v_marc );
IF merge_profile_id IS NOT NULL THEN
SELECT * INTO merge_profile FROM vandelay.merge_profile WHERE id = merge_profile_id;
IF FOUND THEN
dyn_profile.add_rule := BTRIM( dyn_profile.add_rule || ',' || COALESCE(merge_profile.add_spec,''), ',');
dyn_profile.strip_rule := BTRIM( dyn_profile.strip_rule || ',' || COALESCE(merge_profile.strip_spec,''), ',');
dyn_profile.replace_rule := BTRIM( dyn_profile.replace_rule || ',' || COALESCE(merge_profile.replace_spec,''), ',');
dyn_profile.preserve_rule := BTRIM( dyn_profile.preserve_rule || ',' || COALESCE(merge_profile.preserve_spec,''), ',');
END IF;
END IF;
IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN
-- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule;
RETURN FALSE;
END IF;
IF dyn_profile.replace_rule <> '' THEN
source_marc = v_marc;
target_marc = eg_marc;
replace_rule = dyn_profile.replace_rule;
ELSE
source_marc = eg_marc;
target_marc = v_marc;
replace_rule = dyn_profile.preserve_rule;
END IF;
UPDATE biblio.record_entry
SET marc = vandelay.merge_record_xml( target_marc, source_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule )
WHERE id = eg_id;
IF NOT FOUND THEN
-- RAISE NOTICE 'update of biblio.record_entry failed';
RETURN FALSE;
END IF;
RETURN TRUE;
END;
Generated by PostgreSQL Autodoc
W3C HTML 4.01 Strict