<field reporter:label="Call number fields" name="field" reporter:datatype="text"/>
</fields>
</class>
+ <class id="acns" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::call_number_suffix" oils_persist:tablename="asset.call_number_suffix" reporter:label="Call Number/Volume Suffix">
+ <fields oils_persist:primary="id" oils_persist:sequence="asset.call_number_suffix_id_seq">
+ <field reporter:label="ID" name="id" reporter:datatype="id" />
+ <field reporter:label="Label" name="label" reporter:datatype="text"/>
+ <field reporter:label="Label Sort Key" name="label_sortkey" reporter:datatype="text"/>
+ <field reporter:label="Owning Library" name="owning_lib" reporter:datatype="org_unit"/>
+ </fields>
+ <links>
+ <link field="owning_lib" reltype="has_a" key="id" map="" class="aou"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_VOLUME_SUFFIX" context_field="owning_lib"/>
+ <retrieve/>
+ <update permission="UPDATE_VOLUME_SUFFIX" context_field="owning_lib"/>
+ <delete permission="DELETE_VOLUME_SUFFIX" context_field="owning_lib"/>
+ </actions>
+ </permacrud>
+ </class>
+ <class id="acnp" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::call_number_prefix" oils_persist:tablename="asset.call_number_prefix" reporter:label="Call Number/Volume Prefix">
+ <fields oils_persist:primary="id" oils_persist:sequence="asset.call_number_prefix_id_seq">
+ <field reporter:label="ID" name="id" reporter:datatype="id" />
+ <field reporter:label="Label" name="label" reporter:datatype="text"/>
+ <field reporter:label="Label Sort Key" name="label_sortkey" reporter:datatype="text"/>
+ <field reporter:label="Owning Library" name="owning_lib" reporter:datatype="org_unit"/>
+ </fields>
+ <links>
+ <link field="owning_lib" reltype="has_a" key="id" map="" class="aou"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_VOLUME_PREFIX" context_field="owning_lib"/>
+ <retrieve/>
+ <update permission="UPDATE_VOLUME_PREFIX" context_field="owning_lib"/>
+ <delete permission="DELETE_VOLUME_PREFIX" context_field="owning_lib"/>
+ </actions>
+ </permacrud>
+ </class>
<class id="acn" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::call_number" oils_persist:tablename="asset.call_number" reporter:label="Call Number/Volume">
<fields oils_persist:primary="id" oils_persist:sequence="asset.call_number_id_seq">
<field reporter:label="Copies" name="copies" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="URIs" name="uris" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Sort Key" name="label_sortkey" reporter:datatype="text"/>
<field reporter:label="Classification Scheme" name="label_class" reporter:datatype="link"/>
+ <field reporter:label="Prefix" name="prefix" reporter:datatype="link"/>
+ <field reporter:label="Suffix" name="suffix" reporter:datatype="link"/>
</fields>
<links>
<link field="editor" reltype="has_a" key="id" map="" class="au"/>
<link field="uris" reltype="has_many" key="call_number" map="uri" class="auricnm"/>
<link field="uri_maps" reltype="has_many" key="call_number" map="" class="auricnm"/>
<link field="label_class" reltype="has_a" key="id" map="" class="acnc"/>
+ <link field="prefix" reltype="has_a" key="id" map="" class="acnp"/>
+ <link field="suffix" reltype="has_a" key="id" map="" class="acns"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
__PACKAGE__->columns( Essential => qw/location org position/ );
#-------------------------------------------------------------------------------
+package asset::call_number_suffix;
+use base qw/asset/;
+
+__PACKAGE__->table( 'asset_call_number_suffix' );
+__PACKAGE__->columns( Primary => qw/id/ );
+__PACKAGE__->columns( Essential => qw/owning_lib label label_sortkey/ );
+
+#-------------------------------------------------------------------------------
+package asset::call_number_prefix;
+use base qw/asset/;
+
+__PACKAGE__->table( 'asset_call_number_prefix' );
+__PACKAGE__->columns( Primary => qw/id/ );
+__PACKAGE__->columns( Essential => qw/owning_lib label label_sortkey/ );
+
+#-------------------------------------------------------------------------------
package asset::call_number_class;
use base qw/asset/;
asset::call_number->sequence( 'asset.call_number_id_seq' );
#---------------------------------------------------------------------
+ package asset::call_number_suffix;
+
+ asset::call_number_suffix->table( 'asset.call_number_suffix' );
+ asset::call_number_suffix->sequence( 'asset.call_number_suffix_id_seq' );
+
+ #---------------------------------------------------------------------
+ package asset::call_number_prefix;
+
+ asset::call_number_prefix->table( 'asset.call_number_prefix' );
+ asset::call_number_prefix->sequence( 'asset.call_number_prefix_id_seq' );
+
+ #---------------------------------------------------------------------
package asset::call_number_class;
asset::call_number_class->table( 'asset.call_number_class' );
('Library of Congress (LC)', 'asset.label_normalizer_lc', '050ab,055ab')
;
+CREATE OR REPLACE FUNCTION asset.normalize_affix_sortkey () RETURNS TRIGGER AS $$
+BEGIN
+ NEW.label_sortkey := REGEXP_REPLACE(
+ lpad_number_substrings(
+ naco_normalize(NEW.label),
+ '0',
+ 10
+ ),
+ E'\\s+',
+ '',
+ 'g'
+ );
+ RETURN NEW
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE TABLE asset.call_number_preffix (
+ id SERIAL PRIMARY KEY,
+ owning_lib INT NOT NULL REFERENCES actor.org_unit (id),
+ label TEXT NOT NULL, -- i18n
+ label_sortkey TEXT
+);
+CREATE TRIGGER prefix_normalize_tgr ON asset.call_number_preffix BEFORE INSERT OR UPDATE FOR EACH ROW EXECUTE asset.normalize_affix_sortkey();
+CREATE UNIQUE INDEX asset_call_number_prefix_once_per_lib ON asset.call_number_prefix (label, owning_lib);
+CREATE INDEX asset_call_number_prefix_sortkey_idx ON asset.call_number_prefix (label_sortkey);
+INSERT INTO asset.call_number_preffix (id, owning_lib, label) VALUES (-1, 1, '');
+
+CREATE TABLE asset.call_number_sufffix (
+ id SERIAL PRIMARY KEY,
+ owning_lib INT NOT NULL REFERENCES actor.org_unit (id),
+ label TEXT NOT NULL, -- i18n
+ label_sortkey TEXT
+);
+CREATE TRIGGER suffix_normalize_tgr ON asset.call_number_sufffix BEFORE INSERT OR UPDATE FOR EACH ROW EXECUTE asset.normalize_affix_sortkey();
+CREATE UNIQUE INDEX asset_call_number_suffix_once_per_lib ON asset.call_number_suffix (label, owning_lib);
+CREATE INDEX asset_call_number_suffix_sortkey_idx ON asset.call_number_suffix (label_sortkey);
+INSERT INTO asset.call_number_sufffix (id, owning_lib, label) VALUES (-1, 1, '');
+
CREATE TABLE asset.call_number (
id bigserial PRIMARY KEY,
creator BIGINT NOT NULL,
editor BIGINT NOT NULL,
edit_date TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
record bigint NOT NULL,
- owning_lib INT NOT NULL,
+ owning_lib INT NOT NULL,
label TEXT NOT NULL,
deleted BOOL NOT NULL DEFAULT FALSE,
+ prefix INT NOT NULL DEFAULT -1 REFERENCES asset.call_number_prefix(id) DEFERRABLE INITIALLY DEFERRED,
+ suffix INT NOT NULL DEFAULT -1 REFERENCES asset.call_number_suffix(id) DEFERRABLE INITIALLY DEFERRED,
label_class BIGINT DEFAULT 1 NOT NULL
REFERENCES asset.call_number_class(id)
DEFERRABLE INITIALLY DEFERRED,
CREATE INDEX asset_call_number_dewey_idx ON asset.call_number (public.call_number_dewey(label));
CREATE INDEX asset_call_number_upper_label_id_owning_lib_idx ON asset.call_number (oils_text_as_bytea(label),id,owning_lib);
CREATE INDEX asset_call_number_label_sortkey ON asset.call_number(oils_text_as_bytea(label_sortkey));
-CREATE UNIQUE INDEX asset_call_number_label_once_per_lib ON asset.call_number (record, owning_lib, label) WHERE deleted = FALSE OR deleted IS FALSE;
+CREATE UNIQUE INDEX asset_call_number_label_once_per_lib ON asset.call_number (record, owning_lib, label, prefix, suffix) WHERE deleted = FALSE OR deleted IS FALSE;
CREATE INDEX asset_call_number_label_sortkey_browse ON asset.call_number(oils_text_as_bytea(label_sortkey), oils_text_as_bytea(label), id, owning_lib) WHERE deleted IS FALSE OR deleted = FALSE;
CREATE RULE protect_cn_delete AS ON DELETE TO asset.call_number DO INSTEAD UPDATE asset.call_number SET deleted = TRUE WHERE OLD.id = asset.call_number.id;
CREATE TRIGGER asset_label_sortkey_trigger