]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/002.schema.config.sql
add bib-authority linking table; add stored proc to extract linking; add hook to...
[working/Evergreen.git] / Open-ILS / src / sql / Pg / 002.schema.config.sql
1 /*
2  * Copyright (C) 2004-2008  Georgia Public Library Service
3  * Copyright (C) 2008  Equinox Software, Inc.
4  * Mike Rylander <miker@esilibrary.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18
19
20 DROP SCHEMA IF EXISTS stats CASCADE;
21 DROP SCHEMA IF EXISTS config CASCADE;
22
23 BEGIN;
24 CREATE SCHEMA stats;
25
26 CREATE SCHEMA config;
27 COMMENT ON SCHEMA config IS $$
28 /*
29  * Copyright (C) 2005  Georgia Public Library Service 
30  * Mike Rylander <mrylander@gmail.com>
31  *
32  * The config schema holds static configuration data for the
33  * Open-ILS installation.
34  *
35  * ****
36  *
37  * This program is free software; you can redistribute it and/or
38  * modify it under the terms of the GNU General Public License
39  * as published by the Free Software Foundation; either version 2
40  * of the License, or (at your option) any later version.
41  *
42  * This program is distributed in the hope that it will be useful,
43  * but WITHOUT ANY WARRANTY; without even the implied warranty of
44  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45  * GNU General Public License for more details.
46  */
47 $$;
48
49 CREATE TABLE config.internal_flag (
50     name    TEXT    PRIMARY KEY,
51     value   TEXT,
52     enabled BOOL    NOT NULL DEFAULT FALSE
53 );
54 INSERT INTO config.internal_flag (name) VALUES ('ingest.metarecord_mapping.skip_on_insert');
55 INSERT INTO config.internal_flag (name) VALUES ('ingest.reingest.force_on_same_marc');
56 INSERT INTO config.internal_flag (name) VALUES ('ingest.disable_located_uri');
57 INSERT INTO config.internal_flag (name) VALUES ('ingest.disable_metabib_full_rec');
58 INSERT INTO config.internal_flag (name) VALUES ('ingest.disable_metabib_rec_descriptor');
59 INSERT INTO config.internal_flag (name) VALUES ('ingest.disable_metabib_field_entry');
60 INSERT INTO config.internal_flag (name) VALUES ('ingest.disable_authority_linking');
61
62 CREATE TABLE config.global_flag (
63     label   TEXT    NOT NULL
64 ) INHERITS (config.internal_flag);
65 ALTER TABLE config.global_flag ADD PRIMARY KEY (name);
66
67 CREATE TABLE config.upgrade_log (
68     version         TEXT    PRIMARY KEY,
69     install_date    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
70 );
71
72 INSERT INTO config.upgrade_log (version) VALUES ('0318'); -- miker
73
74 CREATE TABLE config.bib_source (
75         id              SERIAL  PRIMARY KEY,
76         quality         INT     CHECK ( quality BETWEEN 0 AND 100 ),
77         source          TEXT    NOT NULL UNIQUE,
78         transcendant    BOOL    NOT NULL DEFAULT FALSE
79 );
80 COMMENT ON TABLE config.bib_source IS $$
81 /*
82  * Copyright (C) 2005  Georgia Public Library Service 
83  * Mike Rylander <mrylander@gmail.com>
84  *
85  * Valid sources of MARC records
86  *
87  * This is table is used to set up the relative "quality" of each
88  * MARC source, such as OCLC.
89  *
90  * ****
91  *
92  * This program is free software; you can redistribute it and/or
93  * modify it under the terms of the GNU General Public License
94  * as published by the Free Software Foundation; either version 2
95  * of the License, or (at your option) any later version.
96  *
97  * This program is distributed in the hope that it will be useful,
98  * but WITHOUT ANY WARRANTY; without even the implied warranty of
99  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
100  * GNU General Public License for more details.
101  */
102 $$;
103
104 CREATE TABLE config.standing (
105         id              SERIAL  PRIMARY KEY,
106         value           TEXT    NOT NULL UNIQUE
107 );
108 COMMENT ON TABLE config.standing IS $$
109 /*
110  * Copyright (C) 2005  Georgia Public Library Service 
111  * Mike Rylander <mrylander@gmail.com>
112  *
113  * Patron Standings
114  *
115  * This table contains the values that can be applied to a patron
116  * by a staff member.  These values should not be changed, other
117  * than for translation, as the ID column is currently a "magic
118  * number" in the source. :(
119  *
120  * ****
121  *
122  * This program is free software; you can redistribute it and/or
123  * modify it under the terms of the GNU General Public License
124  * as published by the Free Software Foundation; either version 2
125  * of the License, or (at your option) any later version.
126  *
127  * This program is distributed in the hope that it will be useful,
128  * but WITHOUT ANY WARRANTY; without even the implied warranty of
129  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
130  * GNU General Public License for more details.
131  */
132 $$;
133
134 CREATE TABLE config.standing_penalty (
135         id                      SERIAL  PRIMARY KEY,
136         name            TEXT    NOT NULL UNIQUE,
137         label           TEXT    NOT NULL,
138         block_list      TEXT,
139         org_depth       INTEGER
140 );
141 INSERT INTO config.standing_penalty (id,name,label,block_list)
142         VALUES (1,'PATRON_EXCEEDS_FINES','Patron exceeds fine threshold','CIRC|HOLD|RENEW');
143 INSERT INTO config.standing_penalty (id,name,label,block_list)
144         VALUES (2,'PATRON_EXCEEDS_OVERDUE_COUNT','Patron exceeds max overdue item threshold','CIRC|HOLD|RENEW');
145 INSERT INTO config.standing_penalty (id,name,label,block_list)
146         VALUES (3,'PATRON_EXCEEDS_CHECKOUT_COUNT','Patron exceeds max checked out item threshold','CIRC');
147 INSERT INTO config.standing_penalty (id,name,label,block_list)
148         VALUES (4,'PATRON_EXCEEDS_COLLECTIONS_WARNING','Patron exceeds pre-collections warning fine threshold','CIRC|HOLD|RENEW');
149
150 INSERT INTO config.standing_penalty (id,name,label) VALUES (20,'ALERT_NOTE','Alerting Note, no blocks');
151 INSERT INTO config.standing_penalty (id,name,label) VALUES (21,'SILENT_NOTE','Note, no blocks');
152 INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (22,'STAFF_C','Alerting block on Circ','CIRC');
153 INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (23,'STAFF_CH','Alerting block on Circ and Hold','CIRC|HOLD');
154 INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (24,'STAFF_CR','Alerting block on Circ and Renew','CIRC|RENEW');
155 INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (25,'STAFF_CHR','Alerting block on Circ, Hold and Renew','CIRC|HOLD|RENEW');
156 INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (26,'STAFF_HR','Alerting block on Hold and Renew','HOLD|RENEW');
157 INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (27,'STAFF_H','Alerting block on Hold','HOLD');
158 INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (28,'STAFF_R','Alerting block on Renew','RENEW');
159 INSERT INTO config.standing_penalty (id,name,label) VALUES (29,'INVALID_PATRON_ADDRESS','Patron has an invalid address');
160 INSERT INTO config.standing_penalty (id,name,label) VALUES (30,'PATRON_IN_COLLECTIONS','Patron has been referred to a collections agency');
161
162 SELECT SETVAL('config.standing_penalty_id_seq', 100);
163
164 CREATE TABLE config.xml_transform (
165         name            TEXT    PRIMARY KEY,
166         namespace_uri   TEXT    NOT NULL,
167         prefix          TEXT    NOT NULL,
168         xslt            TEXT    NOT NULL
169 );
170
171 CREATE TABLE config.biblio_fingerprint (
172         id                      SERIAL  PRIMARY KEY,
173         name            TEXT    NOT NULL, 
174         xpath           TEXT    NOT NULL,
175     first_word  BOOL    NOT NULL DEFAULT FALSE,
176         format          TEXT    NOT NULL DEFAULT 'marcxml'
177 );
178
179 INSERT INTO config.biblio_fingerprint (name, xpath, format)
180     VALUES (
181         'Title',
182         '//marc:datafield[@tag="700"]/marc:subfield[@code="t"]|' ||
183             '//marc:datafield[@tag="240"]/marc:subfield[@code="a"]|' ||
184             '//marc:datafield[@tag="242"]/marc:subfield[@code="a"]|' ||
185             '//marc:datafield[@tag="246"]/marc:subfield[@code="a"]|' ||
186             '//marc:datafield[@tag="245"]/marc:subfield[@code="a"]',
187         'marcxml'
188     );
189
190 INSERT INTO config.biblio_fingerprint (name, xpath, format, first_word)
191     VALUES (
192         'Author',
193         '//marc:datafield[@tag="700" and ./*[@code="t"]]/marc:subfield[@code="a"]|'
194             '//marc:datafield[@tag="100"]/marc:subfield[@code="a"]|'
195             '//marc:datafield[@tag="110"]/marc:subfield[@code="a"]|'
196             '//marc:datafield[@tag="111"]/marc:subfield[@code="a"]|'
197             '//marc:datafield[@tag="260"]/marc:subfield[@code="b"]',
198         'marcxml',
199         TRUE
200     );
201
202 CREATE TABLE config.metabib_class (
203     name    TEXT    PRIMARY KEY,
204     label   TEXT    NOT NULL UNIQUE
205 );
206
207 CREATE TABLE config.metabib_field (
208         id              SERIAL  PRIMARY KEY,
209         field_class     TEXT    NOT NULL REFERENCES config.metabib_class (name),
210         name            TEXT    NOT NULL,
211         label           TEXT    NOT NULL,
212         xpath           TEXT    NOT NULL,
213         weight          INT     NOT NULL DEFAULT 1,
214         format          TEXT    NOT NULL REFERENCES config.xml_transform (name) DEFAULT 'mods33',
215         search_field    BOOL    NOT NULL DEFAULT TRUE,
216         facet_field     BOOL    NOT NULL DEFAULT FALSE,
217     facet_xpath TEXT
218 );
219 COMMENT ON TABLE config.metabib_field IS $$
220 /*
221  * Copyright (C) 2005  Georgia Public Library Service 
222  * Mike Rylander <mrylander@gmail.com>
223  *
224  * XPath used for record indexing ingest
225  *
226  * This table contains the XPath used to chop up MODS into its
227  * indexable parts.  Each XPath entry is named and assigned to
228  * a "class" of either title, subject, author, keyword or series.
229  * 
230  *
231  * ****
232  *
233  * This program is free software; you can redistribute it and/or
234  * modify it under the terms of the GNU General Public License
235  * as published by the Free Software Foundation; either version 2
236  * of the License, or (at your option) any later version.
237  *
238  * This program is distributed in the hope that it will be useful,
239  * but WITHOUT ANY WARRANTY; without even the implied warranty of
240  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
241  * GNU General Public License for more details.
242  */
243 $$;
244
245 CREATE UNIQUE INDEX config_metabib_field_class_name_idx ON config.metabib_field (field_class, name);
246
247 CREATE TABLE config.metabib_search_alias (
248     alias       TEXT    PRIMARY KEY,
249     field_class TEXT    NOT NULL REFERENCES config.metabib_class (name),
250     field       INT     REFERENCES config.metabib_field (id)
251 );
252
253 CREATE TABLE config.non_cataloged_type (
254         id              SERIAL          PRIMARY KEY,
255         owning_lib      INT             NOT NULL, -- REFERENCES actor.org_unit (id),
256         name            TEXT            NOT NULL,
257         circ_duration   INTERVAL        NOT NULL DEFAULT '14 days'::INTERVAL,
258         in_house        BOOL            NOT NULL DEFAULT FALSE,
259         CONSTRAINT noncat_once_per_lib UNIQUE (owning_lib,name)
260 );
261 COMMENT ON TABLE config.non_cataloged_type IS $$
262 /*
263  * Copyright (C) 2005  Georgia Public Library Service 
264  * Mike Rylander <mrylander@gmail.com>
265  *
266  * Types of valid non-cataloged items.
267  *
268  *
269  * ****
270  *
271  * This program is free software; you can redistribute it and/or
272  * modify it under the terms of the GNU General Public License
273  * as published by the Free Software Foundation; either version 2
274  * of the License, or (at your option) any later version.
275  *
276  * This program is distributed in the hope that it will be useful,
277  * but WITHOUT ANY WARRANTY; without even the implied warranty of
278  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
279  * GNU General Public License for more details.
280  */
281 $$;
282
283 CREATE TABLE config.identification_type (
284         id              SERIAL  PRIMARY KEY,
285         name            TEXT    NOT NULL UNIQUE
286 );
287 COMMENT ON TABLE config.identification_type IS $$
288 /*
289  * Copyright (C) 2005  Georgia Public Library Service 
290  * Mike Rylander <mrylander@gmail.com>
291  *
292  * Types of valid patron identification.
293  *
294  * Each patron must display at least one valid form of identification
295  * in order to get a library card.  This table lists those forms.
296  * 
297  *
298  * ****
299  *
300  * This program is free software; you can redistribute it and/or
301  * modify it under the terms of the GNU General Public License
302  * as published by the Free Software Foundation; either version 2
303  * of the License, or (at your option) any later version.
304  *
305  * This program is distributed in the hope that it will be useful,
306  * but WITHOUT ANY WARRANTY; without even the implied warranty of
307  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
308  * GNU General Public License for more details.
309  */
310 $$;
311
312 CREATE TABLE config.rule_circ_duration (
313         id              SERIAL          PRIMARY KEY,
314         name            TEXT            NOT NULL UNIQUE CHECK ( name ~ E'^\\w+$' ),
315         extended        INTERVAL        NOT NULL,
316         normal          INTERVAL        NOT NULL,
317         shrt            INTERVAL        NOT NULL,
318         max_renewals    INT             NOT NULL
319 );
320 COMMENT ON TABLE config.rule_circ_duration IS $$
321 /*
322  * Copyright (C) 2005  Georgia Public Library Service 
323  * Mike Rylander <mrylander@gmail.com>
324  *
325  * Circulation Duration rules
326  *
327  * Each circulation is given a duration based on one of these rules.
328  * 
329  *
330  * ****
331  *
332  * This program is free software; you can redistribute it and/or
333  * modify it under the terms of the GNU General Public License
334  * as published by the Free Software Foundation; either version 2
335  * of the License, or (at your option) any later version.
336  *
337  * This program is distributed in the hope that it will be useful,
338  * but WITHOUT ANY WARRANTY; without even the implied warranty of
339  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
340  * GNU General Public License for more details.
341  */
342 $$;
343
344 CREATE TABLE config.rule_max_fine (
345     id          SERIAL          PRIMARY KEY,
346     name        TEXT            NOT NULL UNIQUE CHECK ( name ~ E'^\\w+$' ),
347     amount      NUMERIC(6,2)    NOT NULL,
348     is_percent  BOOL            NOT NULL DEFAULT FALSE
349 );
350 COMMENT ON TABLE config.rule_max_fine IS $$
351 /*
352  * Copyright (C) 2005  Georgia Public Library Service 
353  * Mike Rylander <mrylander@gmail.com>
354  *
355  * Circulation Max Fine rules
356  *
357  * Each circulation is given a maximum fine based on one of
358  * these rules.
359  * 
360  *
361  * ****
362  *
363  * This program is free software; you can redistribute it and/or
364  * modify it under the terms of the GNU General Public License
365  * as published by the Free Software Foundation; either version 2
366  * of the License, or (at your option) any later version.
367  *
368  * This program is distributed in the hope that it will be useful,
369  * but WITHOUT ANY WARRANTY; without even the implied warranty of
370  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
371  * GNU General Public License for more details.
372  */
373 $$;
374
375 CREATE TABLE config.rule_recurring_fine (
376         id                      SERIAL          PRIMARY KEY,
377         name                    TEXT            NOT NULL UNIQUE CHECK ( name ~ E'^\\w+$' ),
378         high                    NUMERIC(6,2)    NOT NULL,
379         normal                  NUMERIC(6,2)    NOT NULL,
380         low                     NUMERIC(6,2)    NOT NULL,
381         recurrence_interval     INTERVAL        NOT NULL DEFAULT '1 day'::INTERVAL
382 );
383 COMMENT ON TABLE config.rule_recurring_fine IS $$
384 /*
385  * Copyright (C) 2005  Georgia Public Library Service 
386  * Mike Rylander <mrylander@gmail.com>
387  *
388  * Circulation Recurring Fine rules
389  *
390  * Each circulation is given a recurring fine amount based on one of
391  * these rules.  The recurrence_interval should not be any shorter
392  * than the interval between runs of the fine_processor.pl script
393  * (which is run from CRON), or you could miss fines.
394  * 
395  *
396  * ****
397  *
398  * This program is free software; you can redistribute it and/or
399  * modify it under the terms of the GNU General Public License
400  * as published by the Free Software Foundation; either version 2
401  * of the License, or (at your option) any later version.
402  *
403  * This program is distributed in the hope that it will be useful,
404  * but WITHOUT ANY WARRANTY; without even the implied warranty of
405  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
406  * GNU General Public License for more details.
407  */
408 $$;
409
410
411 CREATE TABLE config.rule_age_hold_protect (
412         id      SERIAL          PRIMARY KEY,
413         name    TEXT            NOT NULL UNIQUE CHECK ( name ~ E'^\\w+$' ),
414         age     INTERVAL        NOT NULL,
415         prox    INT             NOT NULL
416 );
417 COMMENT ON TABLE config.rule_age_hold_protect IS $$
418 /*
419  * Copyright (C) 2005  Georgia Public Library Service 
420  * Mike Rylander <mrylander@gmail.com>
421  *
422  * Hold Item Age Protection rules
423  *
424  * A hold request can only capture new(ish) items when they are
425  * within a particular proximity of the home_ou of the requesting
426  * user.  The proximity ('prox' column) is calculated by counting
427  * the number of tree edges between the user's home_ou and the owning_lib
428  * of the copy that could fulfill the hold.
429  * 
430  *
431  * ****
432  *
433  * This program is free software; you can redistribute it and/or
434  * modify it under the terms of the GNU General Public License
435  * as published by the Free Software Foundation; either version 2
436  * of the License, or (at your option) any later version.
437  *
438  * This program is distributed in the hope that it will be useful,
439  * but WITHOUT ANY WARRANTY; without even the implied warranty of
440  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
441  * GNU General Public License for more details.
442  */
443 $$;
444
445 CREATE TABLE config.copy_status (
446         id              SERIAL  PRIMARY KEY,
447         name            TEXT    NOT NULL UNIQUE,
448         holdable        BOOL    NOT NULL DEFAULT FALSE,
449         opac_visible    BOOL    NOT NULL DEFAULT FALSE
450 );
451 COMMENT ON TABLE config.copy_status IS $$
452 /*
453  * Copyright (C) 2005  Georgia Public Library Service 
454  * Mike Rylander <mrylander@gmail.com>
455  *
456  * Copy Statuses
457  *
458  * The available copy statuses, and whether a copy in that
459  * status is available for hold request capture.  0 (zero) is
460  * the only special number in this set, meaning that the item
461  * is available for immediate checkout, and is counted as available
462  * in the OPAC.
463  *
464  * Statuses with an ID below 100 are not removable, and have special
465  * meaning in the code.  Do not change them except to translate the
466  * textual name.
467  *
468  * You may add and remove statuses above 100, and these can be used
469  * to remove items from normal circulation without affecting the rest
470  * of the copy's values or its location.
471  *
472  * ****
473  *
474  * This program is free software; you can redistribute it and/or
475  * modify it under the terms of the GNU General Public License
476  * as published by the Free Software Foundation; either version 2
477  * of the License, or (at your option) any later version.
478  *
479  * This program is distributed in the hope that it will be useful,
480  * but WITHOUT ANY WARRANTY; without even the implied warranty of
481  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
482  * GNU General Public License for more details.
483  */
484 $$;
485
486 CREATE TABLE config.net_access_level (
487         id      SERIAL          PRIMARY KEY,
488         name    TEXT            NOT NULL UNIQUE
489 );
490 COMMENT ON TABLE config.net_access_level IS $$
491 /*
492  * Copyright (C) 2005  Georgia Public Library Service 
493  * Mike Rylander <mrylander@gmail.com>
494  *
495  * Patron Network Access level
496  *
497  * This will be used to inform the in-library firewall of how much
498  * internet access the using patron should be allowed.
499  *
500  * ****
501  *
502  * This program is free software; you can redistribute it and/or
503  * modify it under the terms of the GNU General Public License
504  * as published by the Free Software Foundation; either version 2
505  * of the License, or (at your option) any later version.
506  *
507  * This program is distributed in the hope that it will be useful,
508  * but WITHOUT ANY WARRANTY; without even the implied warranty of
509  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
510  * GNU General Public License for more details.
511  */
512 $$;
513
514
515 CREATE TABLE config.remote_account (
516     id          SERIAL  PRIMARY KEY,
517     label       TEXT    NOT NULL,
518     host        TEXT    NOT NULL,   -- name or IP, :port optional
519     username    TEXT,               -- optional, since we could default to $USER
520     password    TEXT,               -- optional, since we could use SSH keys, or anonymous login.
521     account     TEXT,               -- aka profile or FTP "account" command
522     path        TEXT,               -- aka directory
523     owner       INT     NOT NULL,   -- REFERENCES actor.org_unit (id) DEFERRABLE INITIALLY DEFERRED,
524     last_activity TIMESTAMP WITH TIME ZONE
525 );
526
527 CREATE TABLE config.audience_map (
528         code            TEXT    PRIMARY KEY,
529         value           TEXT    NOT NULL,
530         description     TEXT
531 );
532
533 CREATE TABLE config.lit_form_map (
534         code            TEXT    PRIMARY KEY,
535         value           TEXT    NOT NULL,
536         description     TEXT
537 );
538
539 CREATE TABLE config.language_map (
540         code    TEXT    PRIMARY KEY,
541         value   TEXT    NOT NULL
542 );
543
544 CREATE TABLE config.item_form_map (
545         code    TEXT    PRIMARY KEY,
546         value   TEXT    NOT NULL
547 );
548
549 CREATE TABLE config.item_type_map (
550         code    TEXT    PRIMARY KEY,
551         value   TEXT    NOT NULL
552 );
553
554 CREATE TABLE config.bib_level_map (
555         code    TEXT    PRIMARY KEY,
556         value   TEXT    NOT NULL
557 );
558
559 CREATE TABLE config.marc21_rec_type_map (
560     code        TEXT    PRIMARY KEY,
561     type_val    TEXT    NOT NULL,
562     blvl_val    TEXT    NOT NULL
563 );
564
565 CREATE TABLE config.marc21_ff_pos_map (
566     id          SERIAL  PRIMARY KEY,
567     fixed_field TEXT    NOT NULL,
568     tag         TEXT    NOT NULL,
569     rec_type    TEXT    NOT NULL,
570     start_pos   INT     NOT NULL,
571     length      INT     NOT NULL,
572     default_val TEXT    NOT NULL DEFAULT ' '
573 );
574
575 CREATE TABLE config.marc21_physical_characteristic_type_map (
576     ptype_key   TEXT    PRIMARY KEY,
577     label       TEXT    NOT NULL -- I18N
578 );
579
580 CREATE TABLE config.marc21_physical_characteristic_subfield_map (
581     id          SERIAL  PRIMARY KEY,
582     ptype_key   TEXT    NOT NULL REFERENCES config.marc21_physical_characteristic_type_map (ptype_key) ON DELETE CASCADE ON UPDATE CASCADE,
583     subfield    TEXT    NOT NULL,
584     start_pos   INT     NOT NULL,
585     length      INT     NOT NULL,
586     label       TEXT    NOT NULL -- I18N
587 );
588
589 CREATE TABLE config.marc21_physical_characteristic_value_map (
590     id              SERIAL  PRIMARY KEY,
591     value           TEXT    NOT NULL,
592     ptype_subfield  INT     NOT NULL REFERENCES config.marc21_physical_characteristic_subfield_map (id),
593     label           TEXT    NOT NULL -- I18N
594 );
595
596
597 CREATE TABLE config.z3950_source (
598     name                TEXT    PRIMARY KEY,
599     label               TEXT    NOT NULL UNIQUE,
600     host                TEXT    NOT NULL,
601     port                INT     NOT NULL,
602     db                  TEXT    NOT NULL,
603     record_format       TEXT    NOT NULL DEFAULT 'FI',
604     transmission_format TEXT    NOT NULL DEFAULT 'usmarc',
605     auth                BOOL    NOT NULL DEFAULT TRUE
606 );
607
608 COMMENT ON TABLE config.z3950_source IS $$
609 Z39.50 Sources
610
611 Each row in this table represents a database searchable via Z39.50.
612 $$;
613
614 COMMENT ON COLUMN config.z3950_source.record_format IS $$
615 Z39.50 element set.
616 $$;
617
618 COMMENT ON COLUMN config.z3950_source.transmission_format IS $$
619 Z39.50 preferred record syntax..
620 $$;
621
622
623 CREATE TABLE config.z3950_attr (
624     id          SERIAL  PRIMARY KEY,
625     source      TEXT    NOT NULL REFERENCES config.z3950_source (name) DEFERRABLE INITIALLY DEFERRED,
626     name        TEXT    NOT NULL,
627     label       TEXT    NOT NULL,
628     code        INT     NOT NULL,
629     format      INT     NOT NULL,
630     truncation  INT     NOT NULL DEFAULT 0,
631     CONSTRAINT z_code_format_once_per_source UNIQUE (code,format,source)
632 );
633
634 CREATE TABLE config.i18n_locale (
635     code        TEXT    PRIMARY KEY,
636     marc_code   TEXT    NOT NULL REFERENCES config.language_map (code) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
637     name        TEXT    UNIQUE NOT NULL,
638     description TEXT
639 );
640
641 CREATE TABLE config.i18n_core (
642     id              BIGSERIAL   PRIMARY KEY,
643     fq_field        TEXT        NOT NULL,
644     identity_value  TEXT        NOT NULL,
645     translation     TEXT        NOT NULL    REFERENCES config.i18n_locale (code) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
646     string          TEXT        NOT NULL
647 );
648
649 CREATE UNIQUE INDEX i18n_identity ON config.i18n_core (fq_field,identity_value,translation);
650
651 CREATE TABLE config.billing_type (
652     id              SERIAL  PRIMARY KEY,
653     name            TEXT    NOT NULL,
654     owner           INT     NOT NULL, -- REFERENCES actor.org_unit (id)
655     default_price   NUMERIC(6,2),
656     CONSTRAINT billing_type_once_per_lib UNIQUE (name, owner)
657 );
658
659 CREATE TABLE config.settings_group (
660     name    TEXT PRIMARY KEY,
661     label   TEXT UNIQUE NOT NULL -- I18N
662 );
663
664 CREATE TABLE config.org_unit_setting_type (
665     name            TEXT    PRIMARY KEY,
666     label           TEXT    UNIQUE NOT NULL,
667     grp             TEXT    REFERENCES config.settings_group (name),
668     description     TEXT,
669     datatype        TEXT    NOT NULL DEFAULT 'string',
670     fm_class        TEXT,
671     view_perm       INT,
672     update_perm     INT,
673     --
674     -- define valid datatypes
675     --
676     CONSTRAINT coust_valid_datatype CHECK ( datatype IN
677     ( 'bool', 'integer', 'float', 'currency', 'interval',
678       'date', 'string', 'object', 'array', 'link' ) ),
679     --
680     -- fm_class is meaningful only for 'link' datatype
681     --
682     CONSTRAINT coust_no_empty_link CHECK
683     ( ( datatype =  'link' AND fm_class IS NOT NULL ) OR
684       ( datatype <> 'link' AND fm_class IS NULL ) )
685 );
686
687 CREATE TABLE config.usr_setting_type (
688
689     name TEXT PRIMARY KEY,
690     opac_visible BOOL NOT NULL DEFAULT FALSE,
691     label TEXT UNIQUE NOT NULL,
692     description TEXT,
693     grp             TEXT    REFERENCES config.settings_group (name),
694     datatype TEXT NOT NULL DEFAULT 'string',
695     fm_class TEXT,
696
697     --
698     -- define valid datatypes
699     --
700     CONSTRAINT coust_valid_datatype CHECK ( datatype IN
701     ( 'bool', 'integer', 'float', 'currency', 'interval',
702         'date', 'string', 'object', 'array', 'link' ) ),
703
704     --
705     -- fm_class is meaningful only for 'link' datatype
706     --
707     CONSTRAINT coust_no_empty_link CHECK
708     ( ( datatype = 'link' AND fm_class IS NOT NULL ) OR
709         ( datatype <> 'link' AND fm_class IS NULL ) )
710
711 );
712
713 -- Some handy functions, based on existing ones, to provide optional ingest normalization
714
715 CREATE OR REPLACE FUNCTION public.left_trunc( TEXT, INT ) RETURNS TEXT AS $func$
716         SELECT SUBSTRING($1,$2);
717 $func$ LANGUAGE SQL STRICT IMMUTABLE;
718
719 CREATE OR REPLACE FUNCTION public.right_trunc( TEXT, INT ) RETURNS TEXT AS $func$
720         SELECT SUBSTRING($1,1,$2);
721 $func$ LANGUAGE SQL STRICT IMMUTABLE;
722
723 CREATE OR REPLACE FUNCTION public.split_date_range( TEXT ) RETURNS TEXT AS $func$
724         SELECT REGEXP_REPLACE( $1, E'(\\d{4})-(\\d{4})', E'\\1 \\2', 'g' );
725 $func$ LANGUAGE SQL STRICT IMMUTABLE;
726
727 CREATE OR REPLACE FUNCTION public.translate_isbn1013( TEXT ) RETURNS TEXT AS $func$
728         SELECT isbn FROM (SELECT isn_weak(true), $1 || ' ' || REPLACE( CASE WHEN length($1) = 10 THEN isbn13($1)::TEXT WHEN length($1) = 13 THEN isbn($1)::TEXT ELSE '' END, '-', '') AS isbn)x;
729 $func$ LANGUAGE SQL STRICT IMMUTABLE;
730
731 -- And ... a table in which to register them
732
733 CREATE TABLE config.index_normalizer (
734         id              SERIAL  PRIMARY KEY,
735         name            TEXT    UNIQUE NOT NULL,
736         description     TEXT,
737         func            TEXT    NOT NULL,
738         param_count     INT     NOT NULL DEFAULT 0
739 );
740
741 CREATE TABLE config.metabib_field_index_norm_map (
742         id      SERIAL  PRIMARY KEY,
743         field   INT     NOT NULL REFERENCES config.metabib_field (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
744         norm    INT     NOT NULL REFERENCES config.index_normalizer (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
745         params  TEXT,
746         pos     INT     NOT NULL DEFAULT 0
747 );
748
749 CREATE OR REPLACE FUNCTION oils_tsearch2 () RETURNS TRIGGER AS $$
750 DECLARE
751     normalizer      RECORD;
752     value           TEXT := '';
753 BEGIN
754
755     value := NEW.value;
756
757     IF TG_TABLE_NAME::TEXT ~ 'field_entry$' THEN
758         FOR normalizer IN
759             SELECT  n.func AS func,
760                     n.param_count AS param_count,
761                     m.params AS params
762               FROM  config.index_normalizer n
763                     JOIN config.metabib_field_index_norm_map m ON (m.norm = n.id)
764               WHERE field = NEW.field AND m.pos < 0
765               ORDER BY m.pos LOOP
766                 EXECUTE 'SELECT ' || normalizer.func || '(' ||
767                     quote_literal( value ) ||
768                     CASE
769                         WHEN normalizer.param_count > 0
770                             THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
771                             ELSE ''
772                         END ||
773                     ')' INTO value;
774
775         END LOOP;
776
777         NEW.value := value;
778     END IF;
779
780     IF NEW.index_vector = ''::tsvector THEN
781         RETURN NEW;
782     END IF;
783
784     IF TG_TABLE_NAME::TEXT ~ 'field_entry$' THEN
785         FOR normalizer IN
786             SELECT  n.func AS func,
787                     n.param_count AS param_count,
788                     m.params AS params
789               FROM  config.index_normalizer n
790                     JOIN config.metabib_field_index_norm_map m ON (m.norm = n.id)
791               WHERE field = NEW.field AND m.pos >= 0
792               ORDER BY m.pos LOOP
793                 EXECUTE 'SELECT ' || normalizer.func || '(' ||
794                     quote_literal( value ) ||
795                     CASE
796                         WHEN normalizer.param_count > 0
797                             THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
798                             ELSE ''
799                         END ||
800                     ')' INTO value;
801
802         END LOOP;
803     END IF;
804
805     IF REGEXP_REPLACE(VERSION(),E'^.+?(\\d+\\.\\d+).*?$',E'\\1')::FLOAT > 8.2 THEN
806         NEW.index_vector = to_tsvector((TG_ARGV[0])::regconfig, value);
807     ELSE
808         NEW.index_vector = to_tsvector(TG_ARGV[0], value);
809     END IF;
810
811     RETURN NEW;
812 END;
813 $$ LANGUAGE PLPGSQL;
814
815 COMMIT;