]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/990.schema.unapi.sql
e7abed50b05b284084ac576af759f03e582eef53
[working/Evergreen.git] / Open-ILS / src / sql / Pg / 990.schema.unapi.sql
1 DROP SCHEMA IF EXISTS unapi CASCADE;
2
3 BEGIN;
4 CREATE SCHEMA unapi;
5
6 CREATE OR REPLACE FUNCTION array_remove_item_by_value(inp ANYARRAY, el ANYELEMENT) RETURNS anyarray AS $$ SELECT ARRAY_ACCUM(x.e) FROM UNNEST( $1 ) x(e) WHERE x.e <> $2; $$ LANGUAGE SQL;
7
8 CREATE TABLE unapi.bre_output_layout (
9     name                TEXT    PRIMARY KEY,
10     transform           TEXT    REFERENCES config.xml_transform (name) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
11     mime_type           TEXT    NOT NULL,
12     feed_top            TEXT    NOT NULL,
13     holdings_element    TEXT,
14     title_element       TEXT,
15     description_element TEXT,
16     creator_element     TEXT,
17     update_ts_element   TEXT
18 );
19
20 INSERT INTO unapi.bre_output_layout
21     (name,           transform, mime_type,              holdings_element, feed_top,         title_element, description_element, creator_element, update_ts_element)
22         VALUES
23     ('holdings_xml', NULL,      'application/xml',      NULL,             'hxml',           NULL,          NULL,                NULL,            NULL),
24     ('marcxml',      'marcxml', 'application/marc+xml', 'record',         'collection',     NULL,          NULL,                NULL,            NULL),
25     ('mods32',       'mods32',  'application/mods+xml', 'mods',           'modsCollection', NULL,          NULL,                NULL,            NULL)
26 ;
27
28 -- Dummy functions, so we can create the real ones out of order
29 CREATE OR REPLACE FUNCTION unapi.aou    ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
30 CREATE OR REPLACE FUNCTION unapi.acn    ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
31 CREATE OR REPLACE FUNCTION unapi.ssub   ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
32 CREATE OR REPLACE FUNCTION unapi.sdist  ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
33 CREATE OR REPLACE FUNCTION unapi.sstr   ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
34 CREATE OR REPLACE FUNCTION unapi.sitem  ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
35 CREATE OR REPLACE FUNCTION unapi.sunit  ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
36 CREATE OR REPLACE FUNCTION unapi.sisum  ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
37 CREATE OR REPLACE FUNCTION unapi.sbsum  ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
38 CREATE OR REPLACE FUNCTION unapi.sssum  ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
39 CREATE OR REPLACE FUNCTION unapi.siss   ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
40 CREATE OR REPLACE FUNCTION unapi.auri   ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
41 CREATE OR REPLACE FUNCTION unapi.acp    ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
42 CREATE OR REPLACE FUNCTION unapi.acpn   ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
43 CREATE OR REPLACE FUNCTION unapi.acl    ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
44 CREATE OR REPLACE FUNCTION unapi.ccs    ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
45 CREATE OR REPLACE FUNCTION unapi.ascecm ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
46 CREATE OR REPLACE FUNCTION unapi.bre    ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
47
48 CREATE OR REPLACE FUNCTION unapi.holdings_xml ( bid BIGINT, ouid INT, org TEXT, depth INT DEFAULT NULL, includes TEXT[] DEFAULT NULL::TEXT[], slimit INT DEFAULT NULL, soffset INT DEFAULT NULL) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
49 CREATE OR REPLACE FUNCTION unapi.biblio_record_entry_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL ) RETURNS XML AS $F$ SELECT NULL::XML $F$ LANGUAGE SQL;
50
51 CREATE OR REPLACE FUNCTION unapi.memoize (classname TEXT, obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
52 DECLARE
53     key     TEXT;
54     output  XML;
55 BEGIN
56     key :=
57         'id'        || COALESCE(obj_id::TEXT,'') ||
58         'format'    || COALESCE(format::TEXT,'') ||
59         'ename'     || COALESCE(ename::TEXT,'') ||
60         'includes'   || COALESCE(includes::TEXT,'{}'::TEXT[]::TEXT) ||
61         'org'       || COALESCE(org::TEXT,'') ||
62         'depth'     || COALESCE(depth::TEXT,'') ||
63         'slimit'    || COALESCE(slimit::TEXT,'') ||
64         'soffset'   || COALESCE(soffset::TEXT,'');
65     -- RAISE NOTICE 'memoize key: %', key;
66
67     key := MD5(key);
68     -- RAISE NOTICE 'memoize hash: %', key;
69
70     -- XXX cache logic ... memcached? table?
71
72     EXECUTE $$SELECT unapi.$$ || classname || $$( $1, $2, $3, $4, $5, $6, $7, $8);$$ INTO output USING obj_id, format, ename, includes, org, depth, slimit, soffset;
73     RETURN output;
74 END;
75 $F$ LANGUAGE PLPGSQL;
76
77 CREATE OR REPLACE FUNCTION unapi.biblio_record_entry_feed ( id_list BIGINT[], format TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL, title TEXT DEFAULT NULL, description TEXT DEFAULT NULL, creator TEXT DEFAULT NULL, update_ts TEXT DEFAULT NULL, unapi_url TEXT DEFAULT NULL, header_xml XML DEFAULT NULL ) RETURNS XML AS $F$
78 DECLARE
79     layout          unapi.bre_output_layout%ROWTYPE;
80     transform       config.xml_transform%ROWTYPE;
81     item_format     TEXT;
82     tmp_xml         TEXT;
83     xmlns_uri       TEXT := 'http://open-ils.org/spec/feed-xml/v1';
84     ouid            INT;
85     element_list    TEXT[];
86 BEGIN
87
88     SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
89     SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
90
91     IF layout.name IS NULL THEN
92         RETURN NULL::XML;
93     END IF;
94
95     SELECT * INTO transform FROM config.xml_transform WHERE name = layout.transform;
96     xmlns_uri := COALESCE(transform.namespace_uri,xmlns_uri);
97
98     -- Gather the bib xml
99     SELECT XMLAGG( unapi.bre(i, format, '', includes, org, depth, slimit, soffset)) INTO tmp_xml FROM UNNEST( id_list ) i;
100
101     IF layout.title_element IS NOT NULL THEN
102         EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.title_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, title;
103     END IF;
104
105     IF layout.description_element IS NOT NULL THEN
106         EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.description_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, description;
107     END IF;
108
109     IF layout.creator_element IS NOT NULL THEN
110         EXECUTE 'SELECT XMLCONCAT( XMLELEMENT( name '|| layout.creator_element ||', XMLATTRIBUTES( $1 AS xmlns), $3), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML, creator;
111     END IF;
112
113     IF layout.update_ts_element IS NOT NULL THEN
114         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;
115     END IF;
116
117     IF unapi_url IS NOT NULL THEN
118         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;
119     END IF;
120
121     IF header_xml IS NOT NULL THEN tmp_xml := XMLCONCAT(header_xml,tmp_xml::XML); END IF;
122
123     element_list := regexp_split_to_array(layout.feed_top,E'\\.');
124     FOR i IN REVERSE ARRAY_UPPER(element_list, 1) .. 1 LOOP
125         EXECUTE 'SELECT XMLELEMENT( name '|| quote_ident(element_list[i]) ||', XMLATTRIBUTES( $1 AS xmlns), $2)' INTO tmp_xml USING xmlns_uri, tmp_xml::XML;
126     END LOOP;
127
128     RETURN tmp_xml::XML;
129 END;
130 $F$ LANGUAGE PLPGSQL;
131
132 CREATE OR REPLACE FUNCTION unapi.bre ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
133 DECLARE
134     me      biblio.record_entry%ROWTYPE;
135     layout  unapi.bre_output_layout%ROWTYPE;
136     xfrm    config.xml_transform%ROWTYPE;
137     ouid    INT;
138     tmp_xml TEXT;
139     top_el  TEXT;
140     output  XML;
141     hxml    XML;
142 BEGIN
143
144     SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
145
146     IF ouid IS NULL THEN
147         RETURN NULL::XML;
148     END IF;
149
150     IF format = 'holdings_xml' THEN -- the special case
151         output := unapi.holdings_xml( obj_id, ouid, org, depth, includes, slimit, soffset);
152         RETURN output;
153     END IF;
154
155     SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
156
157     IF layout.name IS NULL THEN
158         RETURN NULL::XML;
159     END IF;
160
161     SELECT * INTO xfrm FROM config.xml_transform WHERE name = layout.transform;
162
163     SELECT * INTO me FROM biblio.record_entry WHERE id = obj_id;
164
165     -- grab hodlings if we need them
166     IF ('holdings_xml' = ANY (includes)) THEN 
167         hxml := unapi.holdings_xml(obj_id, ouid, org, depth, array_remove_item_by_value(includes,'holdings_xml'), slimit, soffset);
168     ELSE
169         hxml := NULL::XML;
170     END IF;
171
172
173     -- generate our item node
174
175
176     IF format = 'marcxml' THEN
177         tmp_xml := me.marc;
178     ELSE
179         tmp_xml := oils_xslt_process(me.marc, xfrm.xslt)::XML;
180     END IF;
181
182     top_el := REGEXP_REPLACE(tmp_xml, E'^.*?<((?:\\S+:)?' || layout.holdings_element || ').*$', E'\\1');
183
184     IF hxml IS NOT NULL THEN -- XXX how do we configure the holdings position?
185         tmp_xml := REGEXP_REPLACE(tmp_xml, '</' || top_el || '>(.*?)$', hxml || '</' || top_el || E'>\\1');
186     END IF;
187
188     IF ('bre.unapi' = ANY (includes)) THEN 
189         output := REGEXP_REPLACE(
190             tmp_xml,
191             '</' || top_el || '>(.*?)',
192             XMLELEMENT(
193                 name abbr,
194                 XMLATTRIBUTES(
195                     'http://www.w3.org/1999/xhtml' AS xmlns,
196                     'unapi-id' AS class,
197                     'tag:open-ils.org:U2@bre/' || obj_id || '/' || org AS title
198                 )
199             )::TEXT || '</' || top_el || E'>\\1'
200         );
201     ELSE
202         output := tmp_xml;
203     END IF;
204
205     RETURN output;
206 END;
207 $F$ LANGUAGE PLPGSQL;
208
209 CREATE OR REPLACE FUNCTION unapi.holdings_xml (bid BIGINT, ouid INT, org TEXT, depth INT DEFAULT NULL, includes TEXT[] DEFAULT NULL::TEXT[], slimit INT DEFAULT NULL, soffset INT DEFAULT NULL) RETURNS XML AS $F$
210      SELECT  XMLELEMENT(
211                  name holdings,
212                  XMLATTRIBUTES(
213                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
214                     CASE WHEN ('bre' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN 'tag:open-ils.org:U2@bre/' || $1 || '/' || $3 ELSE NULL END AS id
215                  ),
216                  XMLELEMENT(
217                      name counts,
218                      (SELECT  XMLAGG(XMLELEMENT::XML) FROM (
219                          SELECT  XMLELEMENT(
220                                      name count,
221                                      XMLATTRIBUTES('public' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
222                                  )::text
223                            FROM  asset.opac_ou_record_copy_count($2,  $1)
224                                      UNION
225                          SELECT  XMLELEMENT(
226                                      name count,
227                                      XMLATTRIBUTES('staff' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
228                                  )::text
229                            FROM  asset.staff_ou_record_copy_count($2, $1)
230                                      ORDER BY 1
231                      )x)
232                  ),
233                  CASE WHEN ('acn' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN 
234                      XMLELEMENT(
235                          name volumes,
236                          (SELECT XMLAGG(acn) FROM (
237                             SELECT  unapi.acn(acn.id,'xml','volume',array_remove_item_by_value(array_remove_item_by_value('{acn,auri}'::TEXT[] || $5,'holdings_xml'),'bre'), $3, $4, $6, $7)
238                               FROM  asset.call_number acn
239                               WHERE acn.record = $1
240                                     AND EXISTS (
241                                         SELECT  1
242                                           FROM  asset.copy acp
243                                                 JOIN actor.org_unit_descendants(
244                                                     $2,
245                                                     (COALESCE(
246                                                         $4,
247                                                         (SELECT aout.depth
248                                                           FROM  actor.org_unit_type aout
249                                                                 JOIN actor.org_unit aou ON (aou.ou_type = aout.id AND aou.id = $2)
250                                                         )
251                                                     ))
252                                                 ) aoud ON (acp.circ_lib = aoud.id)
253                                           LIMIT 1
254                                     )
255                               ORDER BY label_sortkey
256                               LIMIT $6
257                               OFFSET $7
258                          )x)
259                      )
260                  ELSE NULL END,
261                  CASE WHEN ('ssub' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN 
262                      XMLELEMENT(
263                          name subscriptions,
264                          (SELECT XMLAGG(ssub) FROM (
265                             SELECT  unapi.ssub(id,'xml','subscription','{}'::TEXT[], $3, $4, $6, $7)
266                               FROM  serial.subscription
267                               WHERE record_entry = $1
268                         )x)
269                      )
270                  ELSE NULL END
271              );
272 $F$ LANGUAGE SQL;
273
274 CREATE OR REPLACE FUNCTION unapi.ssub ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
275         SELECT  XMLELEMENT(
276                     name subscription,
277                     XMLATTRIBUTES(
278                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
279                         'tag:open-ils.org:U2@ssub/' || id AS id,
280                         start_date AS start, end_date AS end, expected_date_offset
281                     ),
282                     unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'ssub'), $5, $6, $7, $8),
283                     XMLELEMENT( name distributions,
284                         CASE 
285                             WHEN ('sdist' = ANY ($4)) THEN
286                                 XMLAGG((SELECT unapi.sdist( id, 'xml', 'distribution', array_remove_item_by_value($4,'ssub'), $5, $6, $7, $8) FROM serial.distribution WHERE subscription = ssub.id))
287                             ELSE NULL
288                         END
289                     )
290                 )
291           FROM  serial.subscription ssub
292           WHERE id = $1
293           GROUP BY id, start_date, end_date, expected_date_offset, owning_lib;
294 $F$ LANGUAGE SQL;
295
296 CREATE OR REPLACE FUNCTION unapi.sdist ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
297         SELECT  XMLELEMENT(
298                     name distribution,
299                     XMLATTRIBUTES(
300                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
301                         'tag:open-ils.org:U2@sdist/' || id AS id,
302                         'tag:open-ils.org:U2@acn/' || receive_call_number AS receive_call_number,
303                         'tag:open-ils.org:U2@acn/' || bind_call_number AS bind_call_number,
304                         unit_label_prefix, label, unit_label_suffix, summary_method
305                     ),
306                     unapi.aou( holding_lib, $2, 'holding_lib', array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8),
307                     CASE WHEN subscription IS NOT NULL AND ('ssub' = ANY ($4)) THEN unapi.ssub( subscription, 'xml', 'subscription', array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8) ELSE NULL END,
308                     XMLELEMENT( name streams,
309                         CASE 
310                             WHEN ('sstr' = ANY ($4)) THEN
311                                 XMLAGG((SELECT unapi.sstr( id, 'xml', 'stream', array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8) FROM serial.stream WHERE distribution = sdist.id))
312                             ELSE NULL
313                         END
314                     ),
315                     XMLELEMENT( name summaries,
316                         CASE 
317                             WHEN ('ssum' = ANY ($4)) THEN
318                                 XMLAGG((SELECT unapi.sbsum( id, 'xml', 'serial_summary', array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8) FROM serial.basic_summary WHERE distribution = sdist.id))
319                             ELSE NULL
320                         END,
321                         CASE 
322                             WHEN ('ssum' = ANY ($4)) THEN
323                                 XMLAGG((SELECT unapi.sisum( id, 'xml', 'serial_summary', array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8) FROM serial.index_summary WHERE distribution = sdist.id))
324                             ELSE NULL
325                         END,
326                         CASE 
327                             WHEN ('ssum' = ANY ($4)) THEN
328                                 XMLAGG((SELECT unapi.sssum( id, 'xml', 'serial_summary', array_remove_item_by_value($4,'sdist'), $5, $6, $7, $8) FROM serial.supplement_summary WHERE distribution = sdist.id))
329                             ELSE NULL
330                         END
331                     )
332                 )
333           FROM  serial.distribution sdist
334           WHERE id = $1
335           GROUP BY id, label, unit_label_prefix, unit_label_suffix, holding_lib, summary_method, subscription, receive_call_number, bind_call_number;
336 $F$ LANGUAGE SQL;
337
338 CREATE OR REPLACE FUNCTION unapi.sstr ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
339     SELECT  XMLELEMENT(
340                 name stream,
341                 XMLATTRIBUTES(
342                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
343                     'tag:open-ils.org:U2@sstr/' || id AS id,
344                     routing_label
345                 ),
346                 CASE WHEN distribution IS NOT NULL AND ('sdist' = ANY ($4)) THEN unapi.sssum( distribution, 'xml', 'distribtion', array_remove_item_by_value($4,'sstr'), $5, $6, $7, $8) ELSE NULL END,
347                 XMLELEMENT( name items,
348                     CASE 
349                         WHEN ('sitem' = ANY ($4)) THEN
350                             XMLAGG((SELECT unapi.sitem( id, 'xml', 'serial_item', array_remove_item_by_value($4,'sstr'), $5, $6, $7, $8) FROM serial.item WHERE stream = sstr.id))
351                         ELSE NULL
352                     END
353                 )
354             )
355       FROM  serial.stream sstr
356       WHERE id = $1
357       GROUP BY id, routing_label, distribution;
358 $F$ LANGUAGE SQL;
359
360 CREATE OR REPLACE FUNCTION unapi.siss ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
361     SELECT  XMLELEMENT(
362                 name issuance,
363                 XMLATTRIBUTES(
364                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
365                     'tag:open-ils.org:U2@siss/' || id AS id,
366                     create_date, edit_date, label, date_published,
367                     holding_code, holding_type, holding_link_id
368                 ),
369                 CASE WHEN subscription IS NOT NULL AND ('ssub' = ANY ($4)) THEN unapi.ssub( subscription, 'xml', 'subscription', array_remove_item_by_value($4,'siss'), $5, $6, $7, $8) ELSE NULL END,
370                 XMLELEMENT( name items,
371                     CASE 
372                         WHEN ('sitem' = ANY ($4)) THEN
373                             XMLAGG((SELECT unapi.sitem( id, 'xml', 'serial_item', array_remove_item_by_value($4,'siss'), $5, $6, $7, $8) FROM serial.item WHERE issuance = sstr.id))
374                         ELSE NULL
375                     END
376                 )
377             )
378       FROM  serial.issuance sstr
379       WHERE id = $1
380       GROUP BY id, create_date, edit_date, label, date_published, holding_code, holding_type, holding_link_id, subscription;
381 $F$ LANGUAGE SQL;
382
383 CREATE OR REPLACE FUNCTION unapi.sitem ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
384         SELECT  XMLELEMENT(
385                     name serial_item,
386                     XMLATTRIBUTES(
387                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
388                         'tag:open-ils.org:U2@sitem/' || id AS id,
389                         'tag:open-ils.org:U2@siss/' || issuance AS issuance,
390                         date_expected, date_received
391                     ),
392                     CASE WHEN issuance IS NOT NULL AND ('siss' = ANY ($4)) THEN unapi.siss( issuance, $2, 'issuance', array_remove_item_by_value($4,'sitem'), $5, $6, $7, $8) ELSE NULL END,
393                     CASE WHEN stream IS NOT NULL AND ('sstr' = ANY ($4)) THEN unapi.sstr( stream, $2, 'stream', array_remove_item_by_value($4,'sitem'), $5, $6, $7, $8) ELSE NULL END,
394                     CASE WHEN unit IS NOT NULL AND ('sunit' = ANY ($4)) THEN unapi.sunit( stream, $2, 'serial_unit', array_remove_item_by_value($4,'sitem'), $5, $6, $7, $8) ELSE NULL END,
395                     CASE WHEN uri IS NOT NULL AND ('auri' = ANY ($4)) THEN unapi.auri( uri, $2, 'uri', array_remove_item_by_value($4,'sitem'), $5, $6, $7, $8) ELSE NULL END
396 --                    XMLELEMENT( name notes,
397 --                        CASE 
398 --                            WHEN ('acpn' = ANY ($4)) THEN
399 --                                XMLAGG((SELECT unapi.acpn( id, 'xml', 'copy_note', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.copy_note WHERE owning_copy = cp.id AND pub))
400 --                            ELSE NULL
401 --                        END
402 --                    )
403                 )
404           FROM  serial.item sitem
405           WHERE id = $1;
406 $F$ LANGUAGE SQL;
407
408
409 CREATE OR REPLACE FUNCTION unapi.sssum ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
410     SELECT  XMLELEMENT(
411                 name serial_summary,
412                 XMLATTRIBUTES(
413                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
414                     'tag:open-ils.org:U2@sbsum/' || id AS id,
415                     'sssum' AS type, generated_coverage, textual_holdings, show_generated
416                 ),
417                 CASE WHEN ('sdist' = ANY ($4)) THEN unapi.sdist( distribution, 'xml', 'distribtion', array_remove_item_by_value($4,'ssum'), $5, $6, $7, $8) ELSE NULL END
418             )
419       FROM  serial.supplement_summary ssum
420       WHERE id = $1
421       GROUP BY id, generated_coverage, textual_holdings, distribution, show_generated;
422 $F$ LANGUAGE SQL;
423
424 CREATE OR REPLACE FUNCTION unapi.sbsum ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
425     SELECT  XMLELEMENT(
426                 name serial_summary,
427                 XMLATTRIBUTES(
428                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
429                     'tag:open-ils.org:U2@sbsum/' || id AS id,
430                     'sbsum' AS type, generated_coverage, textual_holdings, show_generated
431                 ),
432                 CASE WHEN ('sdist' = ANY ($4)) THEN unapi.sdist( distribution, 'xml', 'distribtion', array_remove_item_by_value($4,'ssum'), $5, $6, $7, $8) ELSE NULL END
433             )
434       FROM  serial.basic_summary ssum
435       WHERE id = $1
436       GROUP BY id, generated_coverage, textual_holdings, distribution, show_generated;
437 $F$ LANGUAGE SQL;
438
439 CREATE OR REPLACE FUNCTION unapi.sisum ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
440     SELECT  XMLELEMENT(
441                 name serial_summary,
442                 XMLATTRIBUTES(
443                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
444                     'tag:open-ils.org:U2@sbsum/' || id AS id,
445                     'sisum' AS type, generated_coverage, textual_holdings, show_generated
446                 ),
447                 CASE WHEN ('sdist' = ANY ($4)) THEN unapi.sdist( distribution, 'xml', 'distribtion', array_remove_item_by_value($4,'ssum'), $5, $6, $7, $8) ELSE NULL END
448             )
449       FROM  serial.index_summary ssum
450       WHERE id = $1
451       GROUP BY id, generated_coverage, textual_holdings, distribution, show_generated;
452 $F$ LANGUAGE SQL;
453
454
455 CREATE OR REPLACE FUNCTION unapi.aou ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
456 DECLARE
457     output XML;
458 BEGIN
459     IF ename = 'circlib' THEN
460         SELECT  XMLELEMENT(
461                     name circlib,
462                     XMLATTRIBUTES(
463                         'http://open-ils.org/spec/actors/v1' AS xmlns,
464                         id AS ident
465                     ),
466                     name
467                 ) INTO output
468           FROM  actor.org_unit aou
469           WHERE id = obj_id;
470     ELSE
471         EXECUTE $$SELECT  XMLELEMENT(
472                     name $$ || ename || $$,
473                     XMLATTRIBUTES(
474                         'http://open-ils.org/spec/actors/v1' AS xmlns,
475                         'tag:open-ils.org:U2@aou/' || id AS id,
476                         shortname, name, opac_visible
477                     )
478                 )
479           FROM  actor.org_unit aou
480          WHERE id = $1 $$ INTO output USING obj_id;
481     END IF;
482
483     RETURN output;
484
485 END;
486 $F$ LANGUAGE PLPGSQL;
487
488 CREATE OR REPLACE FUNCTION unapi.acl ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
489     SELECT  XMLELEMENT(
490                 name location,
491                 XMLATTRIBUTES(
492                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
493                     id AS ident
494                 ),
495                 name
496             )
497       FROM  asset.copy_location
498       WHERE id = $1;
499 $F$ LANGUAGE SQL;
500
501 CREATE OR REPLACE FUNCTION unapi.ccs ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
502     SELECT  XMLELEMENT(
503                 name status,
504                 XMLATTRIBUTES(
505                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
506                     id AS ident
507                 ),
508                 name
509             )
510       FROM  config.copy_status
511       WHERE id = $1;
512 $F$ LANGUAGE SQL;
513
514 CREATE OR REPLACE FUNCTION unapi.acpn ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
515         SELECT  XMLELEMENT(
516                     name copy_note,
517                     XMLATTRIBUTES(
518                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
519                         create_date AS date,
520                         title
521                     ),
522                     value
523                 )
524           FROM  asset.copy_note
525           WHERE id = $1;
526 $F$ LANGUAGE SQL;
527
528 CREATE OR REPLACE FUNCTION unapi.ascecm ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
529         SELECT  XMLELEMENT(
530                     name statcat,
531                     XMLATTRIBUTES(
532                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
533                         sc.name,
534                         sc.opac_visible
535                     ),
536                     asce.value
537                 )
538           FROM  asset.stat_cat_entry asce
539                 JOIN asset.stat_cat sc ON (sc.id = asce.stat_cat)
540           WHERE asce.id = $1;
541 $F$ LANGUAGE SQL;
542
543 CREATE OR REPLACE FUNCTION unapi.acp ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
544         SELECT  XMLELEMENT(
545                     name copy,
546                     XMLATTRIBUTES(
547                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
548                         'tag:open-ils.org:U2@acp/' || id AS id,
549                         create_date, edit_date, copy_number, circulate, deposit,
550                         ref, holdable, deleted, deposit_amount, price, barcode,
551                         circ_modifier, circ_as_type, opac_visible
552                     ),
553                     unapi.ccs( status, $2, 'status', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
554                     unapi.acl( location, $2, 'location', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
555                     unapi.aou( circ_lib, $2, 'circ_lib', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
556                     unapi.aou( circ_lib, $2, 'circlib', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
557                     CASE WHEN ('acn' = ANY ($4)) THEN unapi.acn( call_number, $2, 'call_number', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) ELSE NULL END,
558                     XMLELEMENT( name copy_notes,
559                         CASE 
560                             WHEN ('acpn' = ANY ($4)) THEN
561                                 XMLAGG((SELECT unapi.acpn( id, 'xml', 'copy_note', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.copy_note WHERE owning_copy = cp.id AND pub))
562                             ELSE NULL
563                         END
564                     ),
565                     XMLELEMENT( name statcats,
566                         CASE 
567                             WHEN ('ascecm' = ANY ($4)) THEN
568                                 XMLAGG((SELECT unapi.acpn( stat_cat_entry, 'xml', 'statcat', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.stat_cat_entry_copy_map WHERE owning_copy = cp.id))
569                             ELSE NULL
570                         END
571                     )
572                 )
573           FROM  asset.copy cp
574           WHERE id = $1
575           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;
576 $F$ LANGUAGE SQL;
577
578 CREATE OR REPLACE FUNCTION unapi.sunit ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
579         SELECT  XMLELEMENT(
580                     name serial_unit,
581                     XMLATTRIBUTES(
582                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
583                         'tag:open-ils.org:U2@acp/' || id AS id,
584                         create_date, edit_date, copy_number, circulate, deposit,
585                         ref, holdable, deleted, deposit_amount, price, barcode,
586                         circ_modifier, circ_as_type, opac_visible, status_changed_time,
587                         floating, mint_condition, detailed_contents, sort_key, summary_contents, cost 
588                     ),
589                     unapi.ccs( status, $2, 'status', array_remove_item_by_value(array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8),
590                     unapi.acl( location, $2, 'location', array_remove_item_by_value(array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8),
591                     unapi.aou( circ_lib, $2, 'circ_lib', array_remove_item_by_value(array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8),
592                     unapi.aou( circ_lib, $2, 'circlib', array_remove_item_by_value(array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8),
593                     CASE WHEN ('acn' = ANY ($4)) THEN unapi.acn( call_number, $2, 'call_number', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) ELSE NULL END,
594                     XMLELEMENT( name copy_notes,
595                         CASE 
596                             WHEN ('acpn' = ANY ($4)) THEN
597                                 XMLAGG((SELECT unapi.acpn( id, 'xml', 'copy_note', array_remove_item_by_value(array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8) FROM asset.copy_note WHERE owning_copy = cp.id AND pub))
598                             ELSE NULL
599                         END
600                     ),
601                     XMLELEMENT( name statcats,
602                         CASE 
603                             WHEN ('ascecm' = ANY ($4)) THEN
604                                 XMLAGG((SELECT unapi.acpn( stat_cat_entry, 'xml', 'statcat', array_remove_item_by_value(array_remove_item_by_value($4,'acp'),'sunit'), $5, $6, $7, $8) FROM asset.stat_cat_entry_copy_map WHERE owning_copy = cp.id))
605                             ELSE NULL
606                         END
607                     )
608                 )
609           FROM  serial.unit cp
610           WHERE id = $1
611           GROUP BY  id, status, location, circ_lib, call_number, create_date, edit_date, copy_number, circulate, floating, mint_condition,
612                     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;
613 $F$ LANGUAGE SQL;
614
615 CREATE OR REPLACE FUNCTION unapi.acn ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
616         SELECT  XMLELEMENT(
617                     name volume,
618                     XMLATTRIBUTES(
619                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
620                         'tag:open-ils.org:U2@acn/' || acn.id AS id,
621                         o.shortname AS lib,
622                         o.opac_visible AS opac_visible,
623                         deleted, label, label_sortkey, label_class, record
624                     ),
625                     unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8),
626                     XMLELEMENT( name copies,
627                         CASE 
628                             WHEN ('acp' = ANY ($4)) THEN
629                                 (SELECT XMLAGG(acp) FROM (
630                                     SELECT  unapi.acp( cp.id, 'xml', 'copy', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8)
631                                       FROM  asset.copy cp
632                                             JOIN actor.org_unit_descendants(
633                                                 (SELECT id FROM actor.org_unit WHERE shortname = $5),
634                                                 (COALESCE($6,(SELECT aout.depth FROM actor.org_unit_type aout JOIN actor.org_unit aou ON (aou.ou_type = aout.id AND aou.shortname = $5))))
635                                             ) aoud ON (cp.circ_lib = aoud.id)
636                                       WHERE cp.call_number = acn.id
637                                       ORDER BY COALESCE(cp.copy_number,0), cp.barcode
638                                       LIMIT $7
639                                       OFFSET $8
640                                 )x)
641                             ELSE NULL
642                         END
643                     ),
644                     XMLELEMENT(
645                         name uris,
646                         (SELECT XMLAGG(auri) FROM (SELECT unapi.auri(uri,'xml','uri', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) FROM asset.uri_call_number_map WHERE call_number = acn.id)x)
647                     ),
648                     CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( acn.record, 'marcxml', 'record', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END
649                 ) AS x
650           FROM  asset.call_number acn
651                 JOIN actor.org_unit o ON (o.id = acn.owning_lib)
652           WHERE acn.id = $1
653           GROUP BY acn.id, o.shortname, o.opac_visible, deleted, label, label_sortkey, label_class, owning_lib, record;
654 $F$ LANGUAGE SQL;
655
656 CREATE OR REPLACE FUNCTION unapi.auri ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
657         SELECT  XMLELEMENT(
658                     name volume,
659                     XMLATTRIBUTES(
660                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
661                         'tag:open-ils.org:U2@auri/' || uri.id AS id,
662                         use_restriction,
663                         href,
664                         label
665                     ),
666                     XMLELEMENT( name copies,
667                         CASE 
668                             WHEN ('acn' = ANY ($4)) THEN
669                                 (SELECT XMLAGG(acn) FROM (SELECT unapi.acn( call_number, 'xml', 'copy', array_remove_item_by_value($4,'auri'), $5, $6, $7, $8) FROM asset.uri_call_number_map WHERE uri = uri.id)x)
670                             ELSE NULL
671                         END
672                     )
673                 ) AS x
674           FROM  asset.uri uri
675           WHERE uri.id = $1
676           GROUP BY uri.id, use_restriction, href, label;
677 $F$ LANGUAGE SQL;
678
679 /*
680
681  -- Some test queries
682
683 SELECT unapi.memoize( 'bre', 1,'mods32','','{holdings_xml,acp}'::TEXT[], 'SYS1');
684 SELECT unapi.memoize( 'bre', 1,'marcxml','','{holdings_xml,acp}'::TEXT[], 'SYS1');
685 SELECT unapi.memoize( 'bre', 1,'holdings_xml','','{holdings_xml,acp}'::TEXT[], 'SYS1');
686
687 SELECT unapi.biblio_record_entry_feed('{1}'::BIGINT[],'mods32','{holdings_xml,acp}'::TEXT[],'SYS1',NULL,1,NULL, NULL,NULL,NULL,NULL,'http://c64/opac/extras/unapi', '<totalResults xmlns="http://a9.com/-/spec/opensearch/1.1/">2</totalResults><startIndex xmlns="http://a9.com/-/spec/opensearch/1.1/">1</startIndex><itemsPerPage xmlns="http://a9.com/-/spec/opensearch/1.1/">10</itemsPerPage>');
688
689 SELECT unapi.biblio_record_entry_feed('{7209,7394}'::BIGINT[],'marcxml','{}'::TEXT[],'SYS1',NULL,1,NULL, NULL,NULL,NULL,NULL,'http://fulfillment2.esilibrary.com/opac/extras/unapi', '<totalResults xmlns="http://a9.com/-/spec/opensearch/1.1/">2</totalResults><startIndex xmlns="http://a9.com/-/spec/opensearch/1.1/">1</startIndex><itemsPerPage xmlns="http://a9.com/-/spec/opensearch/1.1/">10</itemsPerPage>');
690 EXPLAIN ANALYZE SELECT unapi.biblio_record_entry_feed('{7209,7394}'::BIGINT[],'marcxml','{}'::TEXT[],'SYS1',NULL,1,NULL, NULL,NULL,NULL,NULL,'http://fulfillment2.esilibrary.com/opac/extras/unapi', '<totalResults xmlns="http://a9.com/-/spec/opensearch/1.1/">2</totalResults><startIndex xmlns="http://a9.com/-/spec/opensearch/1.1/">1</startIndex><itemsPerPage xmlns="http://a9.com/-/spec/opensearch/1.1/">10</itemsPerPage>');
691 EXPLAIN ANALYZE SELECT unapi.biblio_record_entry_feed('{7209,7394}'::BIGINT[],'marcxml','{holdings_xml}'::TEXT[],'SYS1',NULL,1,NULL, NULL,NULL,NULL,NULL,'http://fulfillment2.esilibrary.com/opac/extras/unapi', '<totalResults xmlns="http://a9.com/-/spec/opensearch/1.1/">2</totalResults><startIndex xmlns="http://a9.com/-/spec/opensearch/1.1/">1</startIndex><itemsPerPage xmlns="http://a9.com/-/spec/opensearch/1.1/">10</itemsPerPage>');
692 EXPLAIN ANALYZE SELECT unapi.biblio_record_entry_feed('{7209,7394}'::BIGINT[],'mods32','{holdings_xml}'::TEXT[],'SYS1',NULL,1,NULL, NULL,NULL,NULL,NULL,'http://fulfillment2.esilibrary.com/opac/extras/unapi', '<totalResults xmlns="http://a9.com/-/spec/opensearch/1.1/">2</totalResults><startIndex xmlns="http://a9.com/-/spec/opensearch/1.1/">1</startIndex><itemsPerPage xmlns="http://a9.com/-/spec/opensearch/1.1/">10</itemsPerPage>');
693
694 SELECT unapi.biblio_record_entry_feed('{216}'::BIGINT[],'marcxml','{}'::TEXT[], 'BR1');
695 EXPLAIN ANALYZE SELECT unapi.bre(216,'marcxml','record','{holdings_xml,bre.unapi}'::TEXT[], 'BR1');
696 EXPLAIN ANALYZE SELECT unapi.bre(216,'holdings_xml','record','{}'::TEXT[], 'BR1');
697 EXPLAIN ANALYZE SELECT unapi.holdings_xml(216,4,'BR1',2,'{bre}'::TEXT[]);
698 EXPLAIN ANALYZE SELECT unapi.bre(216,'mods32','record','{}'::TEXT[], 'BR1');
699
700 */
701
702 COMMIT;
703