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