Type/field handling overhaul
This changes the way item types, item fields, creator types, and CSL mappings are defined and handled, in preparation for updated types and fields. Instead of being predefined in SQL files or code, type/field info is read from a bundled JSON file shared with other parts of the Zotero ecosystem [1], referred to as the "global schema". Updates to the bundled schema file are automatically applied to the database at first run, allowing changes to be made consistently across apps. When syncing, invalid JSON properties are now rejected instead of being ignored and processed later, which will allow for schema changes to be made without causing problems in existing clients. We considered many alternative approaches, but this approach is by far the simplest, safest, and most transparent to the user. For now, there are no actual changes to types and fields, since we'll first need to do a sync cut-off for earlier versions that don't reject invalid properties. For third-party code, the main change is that type and field IDs should no longer be hard-coded, since they may not be consistent in new installs. For example, code should use `Zotero.ItemTypes.getID('note')` instead of hard-coding `1`. [1] https://github.com/zotero/zotero-schema
This commit is contained in:
parent
725e6e779e
commit
4b60c6ca27
42 changed files with 1470 additions and 1505 deletions
|
@ -22,34 +22,6 @@
|
|||
|
||||
-- ";---" is an ugly hack for Zotero.DB.executeSQLFile()
|
||||
|
||||
-- Triggers to validate date field
|
||||
DROP TRIGGER IF EXISTS insert_date_field;
|
||||
CREATE TRIGGER insert_date_field BEFORE INSERT ON itemData
|
||||
FOR EACH ROW WHEN NEW.fieldID IN (14, 27, 52, 96, 100)
|
||||
BEGIN
|
||||
SELECT CASE
|
||||
CAST(SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 1, 4) AS INT) BETWEEN 0 AND 9999 AND
|
||||
SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 5, 1) = '-' AND
|
||||
CAST(SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 6, 2) AS INT) BETWEEN 0 AND 12 AND
|
||||
SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 8, 1) = '-' AND
|
||||
CAST(SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 9, 2) AS INT) BETWEEN 0 AND 31
|
||||
WHEN 0 THEN RAISE (ABORT, 'Date field must begin with SQL date') END;---
|
||||
END;
|
||||
|
||||
DROP TRIGGER IF EXISTS update_date_field;
|
||||
CREATE TRIGGER update_date_field BEFORE UPDATE ON itemData
|
||||
FOR EACH ROW WHEN NEW.fieldID IN (14, 27, 52, 96, 100)
|
||||
BEGIN
|
||||
SELECT CASE
|
||||
CAST(SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 1, 4) AS INT) BETWEEN 0 AND 9999 AND
|
||||
SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 5, 1) = '-' AND
|
||||
CAST(SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 6, 2) AS INT) BETWEEN 0 AND 12 AND
|
||||
SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 8, 1) = '-' AND
|
||||
CAST(SUBSTR((SELECT value FROM itemDataValues WHERE valueID=NEW.valueID), 9, 2) AS INT) BETWEEN 0 AND 31
|
||||
WHEN 0 THEN RAISE (ABORT, 'Date field must begin with SQL date') END;---
|
||||
END;
|
||||
|
||||
|
||||
-- Don't allow empty creators
|
||||
DROP TRIGGER IF EXISTS insert_creatorData;
|
||||
CREATE TRIGGER insert_creators BEFORE INSERT ON creators
|
||||
|
@ -137,79 +109,6 @@ CREATE TRIGGER fku_itemNotes_parentItemID_collectionItems_itemID
|
|||
DELETE FROM collectionItems WHERE itemID = NEW.itemID;---
|
||||
END;
|
||||
|
||||
|
||||
-- itemAttachments
|
||||
DROP TRIGGER IF EXISTS fki_itemAttachments;
|
||||
CREATE TRIGGER fki_itemAttachments
|
||||
BEFORE INSERT ON itemAttachments
|
||||
FOR EACH ROW BEGIN
|
||||
SELECT RAISE(ABORT, 'insert on table "itemAttachments" violates foreign key constraint "fki_itemAttachments"')
|
||||
WHERE NEW.parentItemID IS NOT NULL AND
|
||||
(SELECT libraryID FROM items WHERE itemID = NEW.itemID) != (SELECT libraryID FROM items WHERE itemID = NEW.parentItemID);---
|
||||
|
||||
-- Make sure this is an attachment item
|
||||
SELECT RAISE(ABORT, 'item is not an attachment')
|
||||
WHERE (SELECT itemTypeID FROM items WHERE itemID = NEW.itemID) != 14;---
|
||||
|
||||
-- Make sure parent is a regular item
|
||||
SELECT RAISE(ABORT, 'parent is not a regular item')
|
||||
WHERE NEW.parentItemID IS NOT NULL AND (SELECT itemTypeID FROM items WHERE itemID = NEW.parentItemID) IN (1,14);---
|
||||
|
||||
-- If child, make sure attachment is not in a collection
|
||||
SELECT RAISE(ABORT, 'collection item must be top level')
|
||||
WHERE NEW.parentItemID IS NOT NULL AND (SELECT COUNT(*) FROM collectionItems WHERE itemID=NEW.itemID)>0;---
|
||||
END;
|
||||
|
||||
DROP TRIGGER IF EXISTS fku_itemAttachments;
|
||||
CREATE TRIGGER fku_itemAttachments
|
||||
BEFORE UPDATE ON itemAttachments
|
||||
FOR EACH ROW BEGIN
|
||||
SELECT RAISE(ABORT, 'update on table "itemAttachments" violates foreign key constraint "fku_itemAttachments"')
|
||||
WHERE NEW.parentItemID IS NOT NULL AND
|
||||
(SELECT libraryID FROM items WHERE itemID = NEW.itemID) != (SELECT libraryID FROM items WHERE itemID = NEW.parentItemID);---
|
||||
|
||||
-- Make sure parent is a regular item
|
||||
SELECT RAISE(ABORT, 'parent is not a regular item')
|
||||
WHERE NEW.parentItemID IS NOT NULL AND (SELECT itemTypeID FROM items WHERE itemID = NEW.parentItemID) IN (1,14);---
|
||||
END;
|
||||
|
||||
|
||||
-- itemNotes
|
||||
DROP TRIGGER IF EXISTS fki_itemNotes;
|
||||
CREATE TRIGGER fki_itemNotes
|
||||
BEFORE INSERT ON itemNotes
|
||||
FOR EACH ROW BEGIN
|
||||
SELECT RAISE(ABORT, 'insert on table "itemNotes" violates foreign key constraint "fki_itemNotes_libraryID"')
|
||||
WHERE NEW.parentItemID IS NOT NULL AND
|
||||
(SELECT libraryID FROM items WHERE itemID = NEW.itemID) != (SELECT libraryID FROM items WHERE itemID = NEW.parentItemID);---
|
||||
|
||||
-- Make sure this is a note or attachment item
|
||||
SELECT RAISE(ABORT, 'item is not a note or attachment') WHERE
|
||||
(SELECT itemTypeID FROM items WHERE itemID = NEW.itemID) NOT IN (1,14);---
|
||||
|
||||
-- Make sure parent is a regular item
|
||||
SELECT RAISE(ABORT, 'parent is not a regular item') WHERE
|
||||
NEW.parentItemID IS NOT NULL AND (SELECT itemTypeID FROM items WHERE itemID = NEW.parentItemID) IN (1,14);---
|
||||
|
||||
-- If child, make sure note is not in a collection
|
||||
SELECT RAISE(ABORT, 'collection item must be top level') WHERE
|
||||
NEW.parentItemID IS NOT NULL AND (SELECT COUNT(*) FROM collectionItems WHERE itemID=NEW.itemID)>0;---
|
||||
END;
|
||||
|
||||
DROP TRIGGER IF EXISTS fku_itemNotes;
|
||||
CREATE TRIGGER fku_itemNotes
|
||||
BEFORE UPDATE ON itemNotes
|
||||
FOR EACH ROW BEGIN
|
||||
SELECT RAISE(ABORT, 'update on table "itemNotes" violates foreign key constraint "fku_itemNotes"')
|
||||
WHERE NEW.parentItemID IS NOT NULL AND
|
||||
(SELECT libraryID FROM items WHERE itemID = NEW.itemID) != (SELECT libraryID FROM items WHERE itemID = NEW.parentItemID);---
|
||||
|
||||
-- Make sure parent is a regular item
|
||||
SELECT RAISE(ABORT, 'parent is not a regular item') WHERE
|
||||
NEW.parentItemID IS NOT NULL AND (SELECT itemTypeID FROM items WHERE itemID = NEW.parentItemID) IN (1,14);---
|
||||
END;
|
||||
|
||||
|
||||
-- Make sure tags aren't empty
|
||||
DROP TRIGGER IF EXISTS fki_tags;
|
||||
CREATE TRIGGER fki_tags
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue