Advertisement
roganhamby

Dispersal Postgres Function

Sep 17th, 2014
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. drop table rogan.dispersed_copies;
  3. drop table rogan.dispersals;
  4. */
  5.  
  6. CREATE TABLE rogan.dispersals (
  7.         id                              SERIAL                                          PRIMARY KEY,
  8.         circ_from                INT                   NOT NULL REFERENCES actor.org_unit (id) DEFERRABLE INITIALLY DEFERRED,                    
  9.         circ_to                  INT                   NOT NULL REFERENCES actor.org_unit (id) DEFERRABLE INITIALLY DEFERRED,
  10.         acl                      INT                NOT NULL REFERENCES asset.copy_location (id) DEFERRABLE INITIALLY DEFERRED,
  11.         dispersal_date  TIMESTAMP WITH TIME ZONE       NOT NULL,
  12.         num_of_copies   INT                                                     NOT NULL,
  13.         transferred             BOOLEAN                                         NOT NULL DEFAULT FALSE,
  14.         creator                 INT                                                     NOT NULL REFERENCES actor.usr (id) DEFERRABLE INITIALLY DEFERRED
  15. );
  16.  
  17. -- the transferred is a placeholder for when I add automation later to interact with buckets and have Evergreen change the
  18. -- locations for staff
  19.  
  20. CREATE TABLE rogan.dispersed_copies (
  21.         id                              SERIAL                                          PRIMARY KEY,
  22.         copy_id                 INT                                                     NOT NULL REFERENCES asset.COPY (id) DEFERRABLE INITIALLY DEFERRED,
  23.         dispersal               INT4                                            NOT NULL REFERENCES     rogan.dispersals (id) DEFERRABLE INITIALLY DEFERRED
  24. );
  25.  
  26.  
  27. CREATE TABLE rogan.org_unit_setting_type (
  28.     NAME            TEXT    PRIMARY KEY,
  29.     label           TEXT    UNIQUE NOT NULL,
  30.     grp             TEXT    REFERENCES config.settings_group (NAME),
  31.     description     TEXT,
  32.     datatype        TEXT    NOT NULL DEFAULT 'string',
  33.     fm_class        TEXT,
  34.     view_perm       INT,
  35.     update_perm     INT,
  36.     CONSTRAINT coust_valid_datatype CHECK ( datatype IN
  37.     ( 'bool', 'integer', 'float', 'currency', 'interval',
  38.       'date', 'string', 'object', 'array', 'link' ) ),
  39.     CONSTRAINT coust_no_empty_link CHECK
  40.     ( ( datatype =  'link' AND fm_class IS NOT NULL ) OR
  41.       ( datatype <> 'link' AND fm_class IS NULL ) )
  42. );
  43.  
  44.  
  45. CREATE TABLE rogan.org_unit_setting (
  46.         id              BIGSERIAL       PRIMARY KEY,
  47.         org_unit        INT             NOT NULL REFERENCES actor.org_unit ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
  48.         NAME            TEXT                    NOT NULL REFERENCES rogan.org_unit_setting_type DEFERRABLE INITIALLY DEFERRED,
  49.         VALUE           TEXT            NOT NULL,
  50.         CONSTRAINT ou_once_per_key UNIQUE (org_unit,NAME)
  51.         );
  52.  
  53. /*  seed values
  54.  
  55. insert into rogan.org_unit_setting_type (name,label,description,datatype,grp)
  56. values ('disperal_max','Dispersals before weeding.','Maximum number of items an item will disperse before being eligible for weeding.','integer','lib');
  57.  
  58. insert into rogan.org_unit_setting_type (name,label,description,datatype,grp)
  59. values ('weeding_age','Age of items before they weed.','Age an item must be older than and not have circs during to be elibible for weeding.','interval','lib');
  60.  
  61. insert into rogan.org_unit_setting_type (name,label,description,datatype,grp)
  62. values ('dispersal_age','Age before item is dispersed.','Item must be older than this and have at least this much time without circs to be dispersed.','interval','lib');
  63.  
  64. insert into rogan.org_unit_setting (org_unit,name,value)
  65. values (119,'dispersal_max',3);
  66.  
  67. insert into rogan.org_unit_setting (org_unit,name,value)
  68. values (119,'weeding_age','3 years');
  69.  
  70. insert into rogan.org_unit_setting (org_unit,name,value)
  71. values (119,'dispersal_age','6 months');
  72.  
  73. insert into rogan.org_unit_setting (org_unit,name,value)
  74. values (1,'dispersal_age','1 year');
  75.  
  76. insert into rogan.org_unit_setting (org_unit,name,value)
  77. values (1,'weeding_age','5 years');
  78.  
  79. insert into rogan.org_unit_setting (org_unit,name,value)
  80. values (1,'dispersal_max',4);
  81.  
  82. */
  83.  
  84.  
  85. /* testing time!
  86.  
  87. RH Adult Large Print 1008  
  88. YK Adult Large Print 1046
  89. My account 1599187
  90.  
  91. */
  92.  
  93.  
  94. -- -------------------------------------------------------------------------------------------------
  95. -- -------------------------------------------------------------------------------------------------
  96. -- -------------------------------------------------------------------------------------------------
  97.  
  98. -- -------------------------------------------------------------------------------------------------
  99. -- eventually I'd like to handle exceptions through an interface, gui everything and
  100. -- do something to help automate some steps through buckets or bucket like behavior
  101. -- -------------------------------------------------------------------------------------------------
  102.  
  103. /*
  104.  
  105. 2015-02-04 Correcting it for new paradign of county owned volumes and shelving locations
  106.  
  107. instead of acl to acl we need to move items at a certain shelving location from circ lib to circ lib
  108. tables are changed but code hasn't been touched yet below
  109. */
  110.  
  111. DROP FUNCTION rogan.disperse_copies(int4,int4,INT,int4);
  112.  
  113.  
  114. CREATE OR REPLACE FUNCTION rogan.disperse_copies(
  115.         from_acl                        INT4,
  116.         to_acl                          INT4,
  117.         copies_to_disperse      INT,
  118.         dispersing_staff        INT4
  119. )
  120. RETURNS INTEGER AS $$
  121.  
  122. DECLARE
  123.                 disperse_id             INT4;
  124.                 org_dispersal_age       INTERVAL;
  125.                 creator_org             INT4;
  126. BEGIN
  127.  
  128. SELECT INTO creator_org au.home_ou FROM actor.usr au WHERE au.id = dispersing_staff;
  129.  
  130. -- right now the seed values have a consortium default but I should include in here something to handle a null
  131. SELECT INTO org_dispersal_age rous.VALUE
  132. FROM rogan.org_unit_setting rous
  133. JOIN actor.org_unit_ancestors_distance(creator_org) d ON (d.id = rous.org_unit)
  134. WHERE NAME = 'dispersal_age'
  135. ORDER BY d.distance
  136. LIMIT 1
  137. ;
  138.  
  139. INSERT INTO rogan.dispersals (acl_from,acl_to,dispersal_date,num_of_copies,creator)
  140. VALUES (from_acl,to_acl,NOW(),copies_to_disperse,dispersing_staff) RETURNING id INTO disperse_id;
  141.  
  142. CREATE TEMP TABLE dest_bibs ON COMMIT DROP AS
  143.         SELECT distinct(bre.id) bre_id FROM
  144.         asset.COPY ac
  145.         JOIN asset.call_number acn ON acn.id = ac.call_number
  146.         JOIN biblio.record_entry bre ON bre.id = acn.record
  147.         WHERE ac.deleted = FALSE AND ac.LOCATION = to_acl
  148.         ;
  149.  
  150. CREATE TEMP TABLE disp_copies ON COMMIT DROP AS  
  151.         SELECT ac.id AS ids, MAX(acirc.xact_start) AS circs
  152.     FROM asset.COPY ac
  153.     JOIN asset.copy_location acl ON ac.LOCATION = acl.id
  154.     LEFT JOIN ACTION.circulation acirc ON acirc.target_copy = ac.id
  155.     JOIN asset.call_number acn ON acn.id = ac.call_number
  156.     JOIN reporter.materialized_simple_record msr ON msr.id = acn.record
  157.     WHERE acl.id = from_acl
  158.     AND acirc.xact_start IS NULL
  159.     AND date(ac.create_date) <= NOW() - org_dispersal_age
  160.     AND ac.deleted = FALSE
  161.     AND ac.status = 0
  162.     AND msr.id NOT IN (SELECT bre_id FROM dest_bibs)
  163.     GROUP BY 1
  164.         UNION ALL
  165.     SELECT ac.id, MAX(acirc.xact_start) AS circs
  166.     FROM asset.COPY ac
  167.     JOIN asset.copy_location acl ON ac.LOCATION = acl.id
  168.     LEFT JOIN ACTION.circulation acirc ON acirc.target_copy = ac.id
  169.     JOIN asset.call_number acn ON acn.id = ac.call_number
  170.     JOIN reporter.materialized_simple_record msr ON msr.id = acn.record
  171.     WHERE acl.id = from_acl
  172.     AND date(ac.create_date) <= NOW() - org_dispersal_age
  173.     AND ac.deleted = FALSE
  174.     AND ac.status = 0
  175.     AND msr.id NOT IN (SELECT bre_id FROM dest_bibs)
  176.     GROUP BY 1
  177.     HAVING MAX(acirc.xact_start) < NOW() - org_dispersal_age
  178.     ORDER BY circs DESC LIMIT copies_to_disperse;
  179.  
  180. INSERT INTO rogan.dispersed_copies (copy_id,dispersal) (
  181.         SELECT ids, disperse_id FROM disp_copies);
  182.  
  183.  
  184. RETURN disperse_id;
  185.  
  186. END
  187. $$ LANGUAGE plpgsql;
  188.  
  189.  
  190. -- -------------------------------------------------------------------------------------------------
  191. -- -------------------------------------------------------------------------------------------------
  192. -- -------------------------------------------------------------------------------------------------
  193.  
  194. -- testing
  195.  
  196.  
  197. SELECT * FROM rogan.disperse_copies(1008,1046,50,1599187);
  198.  
  199. SELECT * FROM rogan.dispersals;
  200.  
  201. SELECT * FROM rogan.dispersed_copies;
  202.  
  203. SELECT ac.barcode, rsr.author, rsr.title FROM asset.COPY ac
  204.  JOIN asset.call_number acn ON acn.id = ac.call_number
  205.  JOIN reporter.super_simple_record rsr ON rsr.id = acn.record
  206.  WHERE ac.id IN (SELECT copy_id FROM rogan.dispersed_copies WHERE dispersal = 32)
  207.  ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement