Support for NSF Reviewer item type (for NSF use only -- not installed by default)

Also:

- Beginnings of custom item type/field support, though not intended for external use yet
- Zotero.Date.strToDate() now parses 'yesterday'/'today'/'tomorrow' and localized equivalents, allowing those strings to be used in fields such as 'Accessed'
- Cleaner display of dates without times in 'Accessed' field
- Item type menus in metadata pane, New drop-down, and advanced search window now sort by localized string

New methods:

- Zotero.CreatorTypes.itemTypeHasCreators(itemTypeID)
- Saved searches on item type should now use 'itemType' condition rather than 'itemTypeID'
This commit is contained in:
Dan Stillman 2010-01-15 21:55:25 +00:00
parent 53d2fb6fe9
commit 8870d5e514
17 changed files with 1050 additions and 236 deletions

View file

@ -219,6 +219,11 @@
<![CDATA[
Zotero.debug('Refreshing item box');
if (!this.item) {
Zotero.debug('No item to refresh', 2);
return;
}
if (this.clickByItem) {
var itemBox = document.getAnonymousNodes(this)[0];
itemBox.setAttribute('onclick',
@ -333,21 +338,11 @@
// Item type menu
if (this.showTypeMenu) {
// Build item type menu if it hasn't been built yet
if (!this.itemTypeMenu.firstChild.hasChildNodes()) {
var itemTypes = Zotero.ItemTypes.getTypes();
for (var i=0; i<itemTypes.length; i++) {
var name = itemTypes[i].name;
if (name != 'attachment' && name != 'note') {
this.itemTypeMenu.appendItem(Zotero.getString("itemTypes." + name), itemTypes[i].id);
}
}
if (this.itemTypeMenu.itemCount == 0) {
this.buildItemTypeMenu();
}
var listitems = this.itemTypeMenu.firstChild.childNodes;
for (var i=0, len=listitems.length; i < len; i++) {
if (listitems[i].getAttribute('value') == this.item.itemTypeID) {
this.itemTypeMenu.selectedIndex = i;
}
else {
this.updateItemTypeMenuSelection();
}
this.itemTypeMenu.parentNode.hidden = false;
@ -420,9 +415,11 @@
? (i>0 ? this._tabIndexMinFields + i : 1) : 0;
this._tabIndexMaxInfoFields = Math.max(this._tabIndexMaxInfoFields, tabindex);
if (fieldIsClickable &&
!Zotero.Items.isPrimaryField(fieldName) &&
Zotero.ItemFields.isFieldOfBase(Zotero.ItemFields.getID(fieldName), 'date')) {
if (fieldIsClickable
&& !Zotero.Items.isPrimaryField(fieldName)
&& Zotero.ItemFields.isFieldOfBase(Zotero.ItemFields.getID(fieldName), 'date')
// TEMP - NSF
&& fieldName != 'dateSent') {
this.addDateRow(fieldNames[i], this.item.getField(fieldName, true), tabindex);
continue;
}
@ -448,7 +445,8 @@
Zotero.ItemFields.getLocalizedString(this.item.itemTypeID, fieldName) + ":");
}
if (fieldName == 'url' && val) {
// TEMP - NSF (homepage)
if ((fieldName == 'url' || fieldName == 'homepage') && val) {
label.setAttribute("isButton", true);
// TODO: make getFieldValue non-private and use below instead
label.setAttribute("onclick", "ZoteroPane.loadURI(this.nextSibling.firstChild ? this.nextSibling.firstChild.nodeValue : this.nextSibling.value, event)");
@ -550,7 +548,7 @@
this._addCreatorRow = false;
}
}
else if (this.editable) {
else if (this.editable && Zotero.CreatorTypes.itemTypeHasCreators(this.item.itemTypeID)) {
// Add default row
this.addCreatorRow(false, false, true, true);
}
@ -577,6 +575,58 @@
</method>
<method name="buildItemTypeMenu">
<body>
<![CDATA[
if (!this.item) {
return;
}
this.itemTypeMenu.removeAllItems();
var t = Zotero.ItemTypes.getTypes();
// Sort by localized name
var itemTypes = [];
for (var i=0; i<t.length; i++) {
itemTypes.push({
id: t[i].id,
name: t[i].name,
localized: Zotero.ItemTypes.getLocalizedString(t[i].id)
});
}
var collation = Zotero.getLocaleCollation();
itemTypes.sort(function(a, b) {
return collation.compareString(1, a.localized, b.localized);
});
for (var i=0; i<itemTypes.length; i++) {
var name = itemTypes[i].name;
if (name != 'attachment' && name != 'note') {
this.itemTypeMenu.appendItem(itemTypes[i].localized, itemTypes[i].id);
}
}
this.updateItemTypeMenuSelection();
]]>
</body>
</method>
<method name="updateItemTypeMenuSelection">
<body>
<![CDATA[
var listitems = this.itemTypeMenu.firstChild.childNodes;
for (var i=0, len=listitems.length; i < len; i++) {
if (listitems[i].getAttribute('value') == this.item.itemTypeID) {
this.itemTypeMenu.selectedIndex = i;
}
}
]]>
</body>
</method>
<method name="addDynamicRow">
<parameter name="label"/>
<parameter name="value"/>
@ -769,7 +819,7 @@
<body>
<![CDATA[
var label = document.createElement("label");
label.setAttribute("value", Zotero.getString("itemFields." + field) + ':');
label.setAttribute("value", Zotero.ItemFields.getLocalizedString(this.item.itemTypeID, field) + ':');
label.setAttribute("fieldname", field);
label.setAttribute("onclick", "this.nextSibling.firstChild.blur()");
@ -1151,10 +1201,13 @@
}
// If an abstract, check last expand state
var abstractAsVbox = (fieldName == 'abstractNote') &&
Zotero.Prefs.get('lastAbstractExpand');
var abstractAsVbox = fieldName == 'abstractNote' && Zotero.Prefs.get('lastAbstractExpand');
if (fieldName == 'extra' || abstractAsVbox) {
// Use a vbox for multiline fields (but Abstract only if it's expanded)
var useVbox = (fieldName != 'abstractNote' || abstractAsVbox)
&& Zotero.ItemFields.isMultiline(fieldName);
if (useVbox) {
var valueElement = document.createElement("vbox");
}
else {
@ -1190,13 +1243,25 @@
case 'dateAdded':
case 'dateModified':
case 'accessDate':
// TEMP - NSF
case 'dateSent':
case 'dateDue':
case 'accepted':
if (valueText) {
var date = Zotero.Date.sqlToDate(valueText, true);
valueText = date ? date.toLocaleString() : '';
// Don't show time for access date if none
if (fieldName == 'accessDate') {
valueText = valueText.replace('00:00:00 ', '');
if (date) {
// If no time, interpret as local, not UTC
if (Zotero.Date.isSQLDate(valueText)) {
date = Zotero.Date.sqlToDate(valueText);
valueText = date.toLocaleDateString();
}
else {
valueText = date.toLocaleString();
}
}
else {
valueText = '';
}
}
break;
@ -1226,7 +1291,7 @@
// To support newlines in 'extra' fields, we use multiple
// <description> elements inside a vbox
if (fieldName == 'extra' || abstractAsVbox) {
if (useVbox) {
var lines = valueText.split("\n");
for (var i = 0; i < lines.length; i++) {
var descriptionNode = document.createElement("description");
@ -1311,9 +1376,27 @@
var itemID = this.item.id;
// Access date needs to be converted from UTC
if (fieldName=='accessDate' && value!='') {
var localDate = Zotero.Date.sqlToDate(value, true);
var value = Zotero.Date.dateToSQL(localDate);
if (value != '') {
switch (fieldName) {
case 'accessDate':
// TEMP - NSF
case 'dateSent':
case 'dateDue':
case 'accepted':
// If no time, interpret as local, not UTC
if (Zotero.Date.isSQLDate(value)) {
var localDate = Zotero.Date.sqlToDate(value);
}
else {
var localDate = Zotero.Date.sqlToDate(value, true);
}
var value = Zotero.Date.dateToSQL(localDate);
// Don't show time in editor
value = value.replace(' 00:00:00', '');
break;
}
}
}
@ -1327,36 +1410,15 @@
t.setAttribute('fieldMode', elem.getAttribute('fieldMode'));
}
if (['title', 'abstractNote', 'extra'].indexOf(fieldName) != -1) {
if (Zotero.ItemFields.isMultiline(fieldName) || Zotero.ItemFields.isLong(fieldName)) {
t.setAttribute('multiline', true);
t.setAttribute('rows', 8);
}
else {
var autoCompleteFields = [
'creator',
'journalAbbreviation',
'seriesTitle',
'seriesText',
'repository',
'callNumber',
'archiveLocation',
'language',
'rights',
'tag'
];
// Add the type-specific versions of these base fields
var baseACFields = ['publisher', 'publicationTitle', 'type',
'medium', 'place'];
autoCompleteFields = autoCompleteFields.concat(baseACFields);
for (var i=0; i<baseACFields.length; i++) {
var add = Zotero.ItemFields.getTypeFieldsFromBase(baseACFields[i], true)
autoCompleteFields = autoCompleteFields.concat(add);
}
// Add auto-complete for certain fields
if (autoCompleteFields.indexOf(field) != -1) {
if (Zotero.ItemFields.isAutocompleteField(fieldName)
|| fieldName == 'creator'
|| fieldName == 'tag') {
t.setAttribute('type', 'autocomplete');
t.setAttribute('autocompletesearch', 'zotero');
var suffix = itemID ? itemID : '';
@ -1473,9 +1535,7 @@
case event.DOM_VK_RETURN:
var fieldname = target.getAttribute('fieldname');
// Use shift-enter as the save action for the larger fields
if ((fieldname == 'abstractNote' || fieldname == 'extra')
&& !event.shiftKey)
{
if (Zotero.ItemFields.isMultiline(fieldname) && !event.shiftKey) {
break;
}
@ -1711,18 +1771,45 @@
// Fields
else {
// Access date needs to be parsed and converted to UTC
if (fieldName=='accessDate' && value!='') {
if (Zotero.Date.isSQLDate(value) || Zotero.Date.isSQLDateTime(value)) {
var localDate = Zotero.Date.sqlToDate(value);
value = Zotero.Date.dateToSQL(localDate, true);
}
else {
var d = Zotero.Date.strToDate(value);
value = null;
if (d.year && d.month != undefined && d.day) {
d = new Date(d.year, d.month, d.day);
value = Zotero.Date.dateToSQL(d, true);
}
if (value != '') {
switch (fieldName) {
case 'accessDate':
// If just date, don't convert to UTC
if (Zotero.Date.isSQLDate(value)) {
var localDate = Zotero.Date.sqlToDate(value);
value = Zotero.Date.dateToSQL(localDate).replace(' 00:00:00', '');
}
else if (Zotero.Date.isSQLDateTime(value)) {
var localDate = Zotero.Date.sqlToDate(value);
value = Zotero.Date.dateToSQL(localDate, true);
}
else {
var d = Zotero.Date.strToDate(value);
value = null;
if (d.year && d.month != undefined && d.day) {
d = new Date(d.year, d.month, d.day);
value = Zotero.Date.dateToSQL(d).replace(' 00:00:00', '');
}
}
break;
// TEMP - NSF
case 'dateSent':
case 'dateDue':
case 'accepted':
if (Zotero.Date.isSQLDate(value)) {
var localDate = Zotero.Date.sqlToDate(value);
value = Zotero.Date.dateToSQL(localDate).replace(' 00:00:00', '');
}
else {
var d = Zotero.Date.strToDate(value);
value = null;
if (d.year && d.month != undefined && d.day) {
d = new Date(d.year, d.month, d.day);
value = Zotero.Date.dateToSQL(d).replace(' 00:00:00', '');
}
}
break;
}
}

View file

@ -272,7 +272,7 @@
if (!this.id(conditions[i]['name'] + '-tooltip')) {
var fieldName = null;
try {
fieldName = Zotero.getString('itemFields.' + conditions[i]['name']);
fieldName = Zotero.ItemFields.getLocalizedString(null, conditions[i].name);
}
catch (e) {}
@ -393,12 +393,26 @@
this.createValueMenu(rows);
break;
case 'itemTypeID':
var types = Zotero.ItemTypes.getTypes();
for (var i in types)
{
types[i][0] = Zotero.getString('itemTypes.' + types[i]['name']);
types[i][1] = types[i]['id'];
case 'itemType':
var t = Zotero.ItemTypes.getTypes();
// Sort by localized name
var types = [];
for (var i=0; i<t.length; i++) {
types.push({
id: t[i].id,
name: t[i].name,
localized: Zotero.ItemTypes.getLocalizedString(t[i].id)
});
}
var collation = Zotero.getLocaleCollation();
types.sort(function(a, b) {
return collation.compareString(1, a.localized, b.localized);
});
for (var i in types) {
types[i][0] = types[i].localized;
types[i][1] = types[i].name;
delete types[i]['name'];
delete types[i]['id'];
}
@ -451,7 +465,7 @@
// Drop-down menu
if (conditionsMenu.value == 'collection'
|| conditionsMenu.value == 'savedSearch'
|| conditionsMenu.value == 'itemTypeID'
|| conditionsMenu.value == 'itemType'
|| conditionsMenu.value == 'fileTypeID') {
this.id('valuefield').hidden = true;
this.id('valuemenu').hidden = false;
@ -571,12 +585,13 @@
var value = this.id('valuefield').value;
// Convert datetimes to UTC before saving
if ((this.id('conditionsmenu').value=='accessDate' ||
this.id('conditionsmenu').value=='dateAdded' ||
this.id('conditionsmenu').value=='dateModified') &&
Zotero.Date.isSQLDateTime(value)){
var value = Zotero.Date.dateToSQL(Zotero.Date.sqlToDate(value), true);
switch (this.id('conditionsmenu').value) {
case 'accessDate':
case 'dateAdded':
case 'dateModified':
if (Zotero.Date.isSQLDateTime(value)) {
var value = Zotero.Date.dateToSQL(Zotero.Date.sqlToDate(value), true);
}
}
// Append mode to condition

View file

@ -132,29 +132,7 @@ var ZoteroPane = new function()
itemsTree.controllers.appendController(new Zotero.ItemTreeCommandController(itemsTree));
itemsTree.addEventListener("click", ZoteroPane.onTreeClick, true);
// Create the New Item (+) menu with each item type
var addMenu = document.getElementById('zotero-tb-add').firstChild;
var separator = document.getElementById('zotero-tb-add').firstChild.firstChild;
var moreMenu = document.getElementById('zotero-tb-add-more');
var itemTypes = Zotero.ItemTypes.getPrimaryTypes();
for(var i = 0; i<itemTypes.length; i++)
{
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", Zotero.getString("itemTypes."+itemTypes[i]['name']));
menuitem.setAttribute("oncommand","ZoteroPane.newItem("+itemTypes[i]['id']+")");
menuitem.setAttribute("tooltiptext", "");
addMenu.insertBefore(menuitem, separator);
}
// Create submenu for secondary item types
var itemTypes = Zotero.ItemTypes.getSecondaryTypes();
for(var i = 0; i<itemTypes.length; i++)
{
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", Zotero.getString("itemTypes."+itemTypes[i]['name']));
menuitem.setAttribute("oncommand","ZoteroPane.newItem("+itemTypes[i]['id']+")");
menuitem.setAttribute("tooltiptext", "");
moreMenu.appendChild(menuitem);
}
this.buildItemTypeMenus();
var menu = document.getElementById("contentAreaContextMenu");
menu.addEventListener("popupshowing", ZoteroPane.contextPopupShowing, false);
@ -211,8 +189,8 @@ var ZoteroPane = new function()
else if (Zotero.Schema.dbInitialized && Zotero.Prefs.get('firstRun')) {
/*
setTimeout(function () {
var url = "http://www.zotero.org/support/quick_start_guide";
gBrowser.selectedTab = gBrowser.addTab(url);/
var url = "http://zotero.org/start";
gBrowser.selectedTab = gBrowser.addTab(url);
}, 400);
Zotero.Prefs.set('firstRun', false);
*/
@ -241,6 +219,77 @@ var ZoteroPane = new function()
}
this.buildItemTypeMenus = function () {
//
// Create the New Item (+) menu with each item type
//
var addMenu = document.getElementById('zotero-tb-add').firstChild;
var moreMenu = document.getElementById('zotero-tb-add-more');
// Remove all nodes, in case we're reloading
var options = addMenu.getElementsByAttribute("class", "zotero-tb-add");
while (options.length) {
var p = options[0].parentNode;
p.removeChild(options[0]);
}
var separator = addMenu.firstChild;
// Sort by localized name
var t = Zotero.ItemTypes.getPrimaryTypes();
var itemTypes = [];
for (var i=0; i<t.length; i++) {
itemTypes.push({
id: t[i].id,
name: t[i].name,
localized: Zotero.ItemTypes.getLocalizedString(t[i].id)
});
}
var collation = Zotero.getLocaleCollation();
itemTypes.sort(function(a, b) {
return collation.compareString(1, a.localized, b.localized);
});
for (var i = 0; i<itemTypes.length; i++) {
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", itemTypes[i].localized);
menuitem.setAttribute("oncommand","ZoteroPane.newItem("+itemTypes[i]['id']+")");
menuitem.setAttribute("tooltiptext", "");
menuitem.className = "zotero-tb-add";
addMenu.insertBefore(menuitem, separator);
}
//
// Create submenu for secondary item types
//
// Sort by localized name
var t = Zotero.ItemTypes.getSecondaryTypes();
var itemTypes = [];
for (var i=0; i<t.length; i++) {
itemTypes.push({
id: t[i].id,
name: t[i].name,
localized: Zotero.ItemTypes.getLocalizedString(t[i].id)
});
}
var collation = Zotero.getLocaleCollation();
itemTypes.sort(function(a, b) {
return collation.compareString(1, a.localized, b.localized);
});
for (var i = 0; i<itemTypes.length; i++) {
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", itemTypes[i].localized);
menuitem.setAttribute("oncommand","ZoteroPane.newItem("+itemTypes[i]['id']+")");
menuitem.setAttribute("tooltiptext", "");
menuitem.className = "zotero-tb-add";
moreMenu.appendChild(menuitem);
}
}
/*
* Called when the window closes
*/

View file

@ -53,6 +53,7 @@ Zotero.CachedTypes = function() {
this._nameCol = '';
this._table = '';
this._ignoreCase = false;
this._hasCustom = false;
this.getName = getName;
this.getID = getID;
@ -98,19 +99,38 @@ Zotero.CachedTypes = function() {
function getTypes(where) {
return Zotero.DB.query('SELECT ' + this._idCol + ' AS id, '
+ this._nameCol + ' AS name FROM ' + this._table
+ (where ? ' ' + where : '') + ' ORDER BY ' + this._nameCol);
+ this._nameCol + ' AS name'
+ (this._hasCustom ? ', custom' : '')
+ ' FROM ' + this._table
+ (where ? ' ' + where : ''));
}
// Currently used only for item types
this.isCustom = function (idOrName) {
if (!_typesLoaded) {
_load();
}
return _types['_' + idOrName] && _types['_' + idOrName].custom ? _types['_' + idOrName].custom : false;
}
this.reload = function () {
_typesLoaded = false;
}
function _load() {
var types = self.getTypes();
_types = [];
var types = self.getTypes();
for (var i in types) {
// Store as both id and name for access by either
var typeData = {
id: types[i]['id'],
name: types[i]['name']
name: types[i]['name'],
custom: types[i].custom ? types[i].custom : false
}
_types['_' + types[i]['id']] = typeData;
if (self._ignoreCase) {
@ -140,6 +160,7 @@ Zotero.CreatorTypes = new function() {
this._table = 'creatorTypes';
var _primaryIDCache = {};
var _hasCreatorTypeCache = {};
function getTypesForItemType(itemTypeID) {
var sql = "SELECT creatorTypeID AS id, creatorType AS name "
@ -158,6 +179,15 @@ Zotero.CreatorTypes = new function() {
}
this.itemTypeHasCreators = function (itemTypeID) {
if (typeof _hasCreatorTypeCache[itemTypeID] != 'undefined') {
return _hasCreatorTypeCache[itemTypeID];
}
_hasCreatorTypeCache[itemTypeID] = !!this.getTypesForItemType(itemTypeID).length;
return _hasCreatorTypeCache[itemTypeID];
}
function getPrimaryIDForType(itemTypeID) {
if (_primaryIDCache[itemTypeID]) {
return _primaryIDCache[itemTypeID];
@ -184,11 +214,17 @@ Zotero.ItemTypes = new function() {
this.getLocalizedString = getLocalizedString;
this.getImageSrc = getImageSrc;
this.customIDOffset = 10000;
this._typeDesc = 'item type';
this._idCol = 'itemTypeID';
this._nameCol = 'typeName';
this._table = 'itemTypes';
this._table = 'itemTypesCombined';
this._hasCustom = true;
var _customImages = {};
var _customLabels = {};
function getPrimaryTypes() {
return this.getTypes('WHERE display=2');
}
@ -201,12 +237,38 @@ Zotero.ItemTypes = new function() {
return this.getTypes('WHERE display=0');
}
function getLocalizedString(typeIDOrName) {
var typeName = this.getName(typeIDOrName);
function getLocalizedString(idOrName) {
var typeName = this.getName(idOrName);
// For custom types, use provided label
if (this.isCustom(idOrName)) {
var id = this.getID(idOrName) - this.customIDOffset;
if (_customLabels[id]) {
return _customLabels[id];
}
var sql = "SELECT label FROM customItemTypes WHERE customItemTypeID=?";
var label = Zotero.DB.valueQuery(sql, id);
_customLabels[id] = label;
return label;
}
return Zotero.getString("itemTypes." + typeName);
}
function getImageSrc(itemType) {
if (this.isCustom(itemType)) {
var id = this.getID(itemType) - this.customIDOffset;
if (_customImages[id]) {
return _customImages[id];
}
var sql = "SELECT icon FROM customItemTypes WHERE customItemTypeID=?";
var src = Zotero.DB.valueQuery(sql, id);
if (src) {
_customImages[id] = src;
return src;
}
}
// DEBUG: only have icons for some types so far
switch (itemType) {
case 'attachment-file':

View file

@ -492,6 +492,12 @@ Zotero.Item.prototype.setType = function(itemTypeID, loadIn) {
var creators = this.getCreators();
if (creators) {
for (var i in creators) {
// Remove all creators if new item type doesn't have any
if (!Zotero.CreatorTypes.itemTypeHasCreators(itemTypeID)) {
this.removeCreator(i);
continue;
}
if (!Zotero.CreatorTypes.isValidForItemType(creators[i].creatorTypeID, itemTypeID)) {
// Convert existing primary creator type to new item type's
// primary creator type, or contributor (creatorTypeID 2)
@ -853,7 +859,7 @@ Zotero.Item.prototype.getDisplayTitle = function (includeAuthorAndDate) {
strParts.push(Zotero.getString('pane.items.' + itemTypeName + '.' + str, names));
}
else {
strParts.push(Zotero.getString('itemTypes.' + itemTypeName));
strParts.push(Zotero.ItemTypes.getLocalizedString(itemTypeID));
}
if (includeAuthorAndDate) {

View file

@ -82,27 +82,38 @@ Zotero.ItemFields = new function() {
function getLocalizedString(itemType, field) {
// unused currently
//var typeName = Zotero.ItemTypes.getName(itemType);
var fieldName = this.getName(field);
var fieldName = Zotero.ItemFields.getName(field);
// Fields in the items table are special cases
switch (field) {
case 'dateAdded':
case 'dateModified':
case 'itemType':
fieldName = field;
return Zotero.getString("itemFields." + field);
}
// TODO: different labels for different item types
return Zotero.getString("itemFields." + fieldName);
try {
_fieldCheck(field, 'getLocalizedString');
}
// TEMP
catch (e) {
try {
asfasfa();
}
catch (e2) {
Zotero.debug(e2);
}
Zotero.debug(e);
throw (e);
}
return _fields[field].label ? _fields[field].label : Zotero.getString("itemFields." + fieldName);
}
function isValidForType(fieldID, itemTypeID) {
if (!_fieldsLoaded) {
_loadFields();
}
_fieldCheck(fieldID, 'isValidForType');
if (!_fields[fieldID]['itemTypes']) {
@ -114,10 +125,6 @@ Zotero.ItemFields = new function() {
function isInteger(fieldID) {
if (!_fieldsLoaded) {
_loadFields();
}
_fieldCheck(fieldID, 'isInteger');
var ffid = _fields[fieldID]['formatID'];
@ -125,10 +132,21 @@ Zotero.ItemFields = new function() {
}
this.isCustom = function (fieldID) {
_fieldCheck(fieldID, 'isCustom');
return _fields[fieldID].custom;
}
/*
* Returns an array of fieldIDs for a given item type
*/
function getItemTypeFields(itemTypeID) {
if (!_fieldsLoaded) {
_loadFields();
}
if (_itemTypeFields[itemTypeID]) {
return _itemTypeFields[itemTypeID];
}
@ -138,7 +156,7 @@ Zotero.ItemFields = new function() {
+ "' provided to getItemTypeFields()");
}
var sql = 'SELECT fieldID FROM itemTypeFields '
var sql = 'SELECT fieldID FROM itemTypeFieldsCombined '
+ 'WHERE itemTypeID=' + itemTypeID + ' ORDER BY orderIndex';
var fields = Zotero.DB.columnQuery(sql);
@ -148,10 +166,6 @@ Zotero.ItemFields = new function() {
function isBaseField(field) {
if (!_fieldsLoaded) {
_loadFields();
}
_fieldCheck(field, arguments.callee.name);
return _fields[field]['isBaseField'];
@ -176,7 +190,7 @@ Zotero.ItemFields = new function() {
function getBaseMappedFields() {
return Zotero.DB.columnQuery("SELECT DISTINCT fieldID FROM baseFieldMappings");
return Zotero.DB.columnQuery("SELECT DISTINCT fieldID FROM baseFieldMappingsCombined");
}
@ -193,10 +207,6 @@ Zotero.ItemFields = new function() {
* Accepts names or ids
*/
function getFieldIDFromTypeAndBase(itemType, baseField) {
if (!_fieldsLoaded) {
_loadFields();
}
var itemTypeID = Zotero.ItemTypes.getID(itemType);
if (!itemTypeID) {
throw ("Invalid item type '" + itemType + "' in ItemFields.getFieldIDFromTypeAndBase()");
@ -242,7 +252,7 @@ Zotero.ItemFields = new function() {
return typeFieldID;
}
return Zotero.DB.valueQuery("SELECT baseFieldID FROM baseFieldMappings "
return Zotero.DB.valueQuery("SELECT baseFieldID FROM baseFieldMappingsCombined "
+ "WHERE itemTypeID=? AND fieldID=?", [itemTypeID, typeFieldID]);
}
@ -268,6 +278,73 @@ Zotero.ItemFields = new function() {
}
this.isAutocompleteField = function (field) {
field = this.getName(field);
var autoCompleteFields = [
'journalAbbreviation',
'seriesTitle',
'seriesText',
'repository',
'callNumber',
'archiveLocation',
'language',
'rights',
// TEMP - NSF
'programDirector',
'institution',
'discipline'
];
// Add the type-specific versions of these base fields
var baseACFields = ['publisher', 'publicationTitle', 'type', 'medium', 'place'];
autoCompleteFields = autoCompleteFields.concat(baseACFields);
for (var i=0; i<baseACFields.length; i++) {
var add = Zotero.ItemFields.getTypeFieldsFromBase(baseACFields[i], true)
autoCompleteFields = autoCompleteFields.concat(add);
}
return autoCompleteFields.indexOf(field) != -1;
}
/**
* A long field expands into a multiline textbox while editing but displays
* as a single line in non-editing mode; newlines are not allowed
*/
this.isLong = function (field) {
field = this.getName(field);
var fields = [
'title'
];
return fields.indexOf(field) != -1;
}
/**
* A multiline field displays as a multiline text box in editing mode
* and non-editing mode; newlines are allowed
*/
this.isMultiline = function (field) {
field = this.getName(field);
var fields = [
'abstractNote',
'extra',
// TEMP - NSF
'address'
];
return fields.indexOf(field) != -1;
}
this.reload = function () {
_fieldsLoaded = false;
}
/**
* Check whether a field is valid, throwing an exception if not
* (since it should never actually happen)
@ -285,7 +362,7 @@ Zotero.ItemFields = new function() {
* Returns hash array of itemTypeIDs for which a given field is valid
*/
function _getFieldItemTypes() {
var sql = 'SELECT fieldID, itemTypeID FROM itemTypeFields';
var sql = 'SELECT fieldID, itemTypeID FROM itemTypeFieldsCombined';
var results = Zotero.DB.query(sql);
@ -307,14 +384,17 @@ Zotero.ItemFields = new function() {
* Build a lookup table for base field mappings
*/
function _loadBaseTypeFields() {
_typeFieldIDsByBase = {};
_typeFieldNamesByBase = {};
// Grab all fields, base field or not
var sql = "SELECT IT.itemTypeID, F.fieldID AS baseFieldID, BFM.fieldID "
+ "FROM itemTypes IT LEFT JOIN fields F "
+ "LEFT JOIN baseFieldMappings BFM"
+ "FROM itemTypesCombined IT LEFT JOIN fieldsCombined F "
+ "LEFT JOIN baseFieldMappingsCombined BFM"
+ " ON (IT.itemTypeID=BFM.itemTypeID AND F.fieldID=BFM.baseFieldID)";
var rows = Zotero.DB.query(sql);
var sql = "SELECT DISTINCT baseFieldID FROM baseFieldMappings";
var sql = "SELECT DISTINCT baseFieldID FROM baseFieldMappingsCombined";
var baseFields = Zotero.DB.columnQuery(sql);
var fields = [];
@ -341,7 +421,7 @@ Zotero.ItemFields = new function() {
var sql = "SELECT baseFieldID, fieldID, fieldName "
+ "FROM baseFieldMappings JOIN fields USING (fieldID)";
+ "FROM baseFieldMappingsCombined JOIN fieldsCombined USING (fieldID)";
var rows = Zotero.DB.query(sql);
for each(var row in rows) {
if (!_typeFieldIDsByBase[row['baseFieldID']]) {
@ -358,6 +438,10 @@ Zotero.ItemFields = new function() {
* Load all fields into an internal hash array
*/
function _loadFields() {
_fields = {};
_fieldsFormats = [];
_itemTypeFields = [];
var result = Zotero.DB.query('SELECT * FROM fieldFormats');
for (var i=0; i<result.length; i++) {
@ -367,17 +451,19 @@ Zotero.ItemFields = new function() {
};
}
var fields = Zotero.DB.query('SELECT * FROM fields');
var fields = Zotero.DB.query('SELECT * FROM fieldsCombined');
var fieldItemTypes = _getFieldItemTypes();
var sql = "SELECT DISTINCT baseFieldID FROM baseFieldMappings";
var sql = "SELECT DISTINCT baseFieldID FROM baseFieldMappingsCombined";
var baseFields = Zotero.DB.columnQuery(sql);
for each(var field in fields) {
_fields[field['fieldID']] = {
id: field['fieldID'],
name: field['fieldName'],
name: field.fieldName,
label: field.label,
custom: !!field.custom,
isBaseField: (baseFields.indexOf(field['fieldID']) != -1),
formatID: field['fieldFormatID'],
itemTypes: fieldItemTypes[field['fieldID']]

View file

@ -61,6 +61,8 @@ Zotero.ID_Tracker = function () {
case 'collections':
case 'savedSearches':
case 'tags':
case 'customItemTypes':
case 'customFields':
var id = _getNextAvailable(table);
if (!id && notNull) {
return _getNext(table);
@ -144,6 +146,8 @@ Zotero.ID_Tracker = function () {
case 'items':
case 'savedSearches':
case 'tags':
case 'customItemTypes':
case 'customFields':
return table;
default:
@ -245,6 +249,8 @@ Zotero.ID_Tracker = function () {
case 'collections':
case 'savedSearches':
case 'customItemTypes':
case 'customFields':
var maxToFind = 100;
break;

View file

@ -610,7 +610,7 @@ Zotero.ItemTreeView.prototype.getCellText = function(row, column)
}
else if(column.id == "zotero-items-column-type")
{
val = Zotero.getString('itemTypes.'+Zotero.ItemTypes.getName(obj.ref.itemTypeID));
val = Zotero.ItemTypes.getLocalizedString(obj.ref.itemTypeID);
}
// Year column is just date field truncated
else if (column.id == "zotero-items-column-year") {
@ -960,8 +960,8 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
break;
case 'type':
var typeA = Zotero.getString('itemTypes.'+Zotero.ItemTypes.getName(a.ref.itemTypeID));
var typeB = Zotero.getString('itemTypes.'+Zotero.ItemTypes.getName(b.ref.itemTypeID));
var typeA = Zotero.ItemTypes.getLocalizedString(a.ref.itemTypeID);
var typeB = Zotero.ItemTypes.getLocalizedString(b.ref.itemTypeID);
cmp = (typeA > typeB) ? -1 : (typeA < typeB) ? 1 : 0;
if (cmp) {

View file

@ -64,12 +64,13 @@ Zotero.MIMETypeHandler = new function () {
this.addHandler("ris", Zotero.Ingester.importHandler, true);
}
this.addHandler("text/x-csl", function(a1, a2) { Zotero.Styles.install(a1, a2) });
this.addHandler("application/x-zotero-schema", Zotero.Schema.importSchema);
}
/**
* Adds a handler to handle a specific MIME type
* @param {String} type MIME type to handle
* @param {Function} fn Function to call to handle type
* @param {Function} fn Function to call to handle type - fn(string, uri)
* @param {Boolean} ignoreContentDisposition If true, ignores the Content-Disposition header,
* which is often used to force a file to download rather than let it be handled by the web
* browser

View file

@ -155,7 +155,7 @@ Zotero.Report = new function() {
content += '<th>'
+ escapeXML(Zotero.getString('itemFields.itemType'))
+ '</th>\n';
content += '<td>' + escapeXML(Zotero.getString('itemTypes.' + arr['itemType'])) + '</td>\n';
content += '<td>' + escapeXML(Zotero.ItemTypes.getLocalizedString(arr.itemType)) + '</td>\n';
content += '</tr>\n';
// Creators
@ -214,7 +214,7 @@ Zotero.Report = new function() {
}
try {
var localizedFieldName = Zotero.getString('itemFields.' + i);
var localizedFieldName = Zotero.ItemFields.getLocalizedString(arr.itemType, i);
}
// Skip fields we don't have a localized string for
catch (e) {

View file

@ -107,7 +107,7 @@ Zotero.Schema = new function(){
if (!dbVersion && !_getDBVersion('schema') && !_getDBVersion('user')){
Zotero.debug('Database does not exist -- creating\n');
_initializeSchema();
return;
return true;
}
var schemaVersion = _getSchemaSQLVersion('userdata');
@ -145,6 +145,7 @@ Zotero.Schema = new function(){
Zotero.wait();
var up1 = _migrateUserDataSchema(dbVersion);
var up3 = _updateSchema('triggers');
this.updateCustomTables(up2);
Zotero.wait();
Zotero.DB.commitTransaction();
@ -198,7 +199,210 @@ Zotero.Schema = new function(){
finally {
Zotero.UnresponsiveScriptIndicator.enable();
}
return;
return up1 || up2 || up3 || up4;
}
// This is mostly temporary
// TEMP - NSF
this.importSchema = function (str, uri) {
var prompt = Components.classes["@mozilla.org/network/default-prompt;1"]
.createInstance(Components.interfaces.nsIPrompt);
if (!uri.match(/https?:\/\/([^\.]+\.)?zotero.org\//)) {
Zotero.debug("Ignoring schema file from non-zotero.org domain");
return;
}
str = Zotero.Utilities.prototype.trim(str);
Zotero.debug(str);
if (str == "%%%ZOTERO_NSF_TEMP_INSTALL%%%") {
Zotero.debug(Zotero.ItemTypes.getID("nsfReviewer"));
if (Zotero.ItemTypes.getID("nsfReviewer")) {
prompt.alert("Zotero Item Type Already Exists", "The 'NSF Reviewer' item type already exists in Zotero.");
Zotero.debug("nsfReviewer item type already exists");
return;
}
Zotero.debug("Installing nsfReviewer item type");
var itemTypeID = Zotero.ID.get('customItemTypes');
Zotero.DB.beginTransaction();
Zotero.DB.query("INSERT INTO customItemTypes VALUES (?, 'nsfReviewer', 'NSF Reviewer', 1, 'chrome://zotero/skin/report_user.png')", itemTypeID);
var fields = [
['name', 'Name'],
['institution', 'Institution'],
['address', 'Address'],
['telephone', 'Telephone'],
['email', 'Email'],
['homepage', 'Webpage'],
['discipline', 'Discipline'],
['nsfID', 'NSF ID'],
['dateSent', 'Date Sent'],
['dateDue', 'Date Due'],
['accepted', 'Accepted'],
['programDirector', 'Program Director']
];
for (var i=0; i<fields.length; i++) {
var fieldID = Zotero.ItemFields.getID(fields[i][0]);
if (!fieldID) {
var fieldID = Zotero.ID.get('customFields');
Zotero.DB.query("INSERT INTO customFields VALUES (?, ?, ?)", [fieldID, fields[i][0], fields[i][1]]);
Zotero.DB.query("INSERT INTO customItemTypeFields VALUES (?, NULL, ?, 1, ?)", [itemTypeID, fieldID, i+1]);
}
else {
Zotero.DB.query("INSERT INTO customItemTypeFields VALUES (?, ?, NULL, 1, ?)", [itemTypeID, fieldID, i+1]);
}
switch (fields[i][0]) {
case 'name':
var baseFieldID = 110; // title
break;
case 'dateSent':
var baseFieldID = 14; // date
break;
case 'homepage':
var baseFieldID = 1; // URL
break;
default:
var baseFieldID = null;
}
if (baseFieldID) {
Zotero.DB.query("INSERT INTO customBaseFieldMappings VALUES (?, ?, ?)", [itemTypeID, baseFieldID, fieldID]);
}
}
Zotero.DB.commitTransaction();
_reloadSchema();
var s = new Zotero.Search;
s.name = "Overdue NSF Reviewers";
s.addCondition('itemType', 'is', 'nsfReviewer');
s.addCondition('dateDue', 'isBefore', 'today');
s.addCondition('tag', 'isNot', 'Completed');
s.save();
prompt.alert("Zotero Item Type Added", "The 'NSF Reviewer' item type and 'Overdue NSF Reviewers' saved search have been installed.");
}
else if (str == "%%%ZOTERO_NSF_TEMP_UNINSTALL%%%") {
var itemTypeID = Zotero.ItemTypes.getID('nsfReviewer');
if (!itemTypeID) {
prompt.alert("Zotero Item Type Does Not Exist", "The 'NSF Reviewer' item type does not exist in Zotero.");
Zotero.debug("nsfReviewer item types doesn't exist", 2);
return;
}
var s = new Zotero.Search;
s.addCondition('itemType', 'is', 'nsfReviewer');
var s2 = new Zotero.Search;
s2.addCondition('itemType', 'is', 'nsfReviewer');
s2.addCondition('deleted', 'true');
if (s.search() || s2.search()) {
prompt.alert("Error", "All 'NSF Reviewer' items must be deleted before the item type can be removed from Zotero.");
return;
}
Zotero.debug("Uninstalling nsfReviewer item type");
Zotero.DB.beginTransaction();
Zotero.DB.query("DELETE FROM customItemTypes WHERE customItemTypeID=?", itemTypeID - Zotero.ItemTypes.customIDOffset);
var fields = Zotero.ItemFields.getItemTypeFields(itemTypeID);
for each(var fieldID in fields) {
if (Zotero.ItemFields.isCustom(fieldID)) {
Zotero.DB.query("DELETE FROM customFields WHERE customFieldID=?", fieldID - Zotero.ItemTypes.customIDOffset);
}
}
Zotero.DB.commitTransaction();
var searches = Zotero.Searches.getAll();
for each(var search in searches) {
if (search.name == 'Overdue NSF Reviewers') {
var id = search.id;
Zotero.Searches.erase(id);
}
}
_reloadSchema();
prompt.alert("Zotero Item Type Removed", "The 'NSF Reviewer' item type has been uninstalled.");
}
}
function _reloadSchema() {
Zotero.Schema.updateCustomTables();
Zotero.ItemTypes.reload();
Zotero.ItemFields.reload();
Zotero.SearchConditions.reload();
// Update item type menus in every open window
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var enumerator = wm.getEnumerator("navigator:browser");
while (enumerator.hasMoreElements()) {
var win = enumerator.getNext();
win.ZoteroPane.buildItemTypeMenus();
win.document.getElementById('zotero-editpane-item-box').buildItemTypeMenu();
}
}
this.updateCustomTables = function (skipDelete, skipSystem) {
Zotero.debug("Updating custom tables");
if (!skipDelete) {
Zotero.DB.query("DELETE FROM itemTypesCombined");
Zotero.DB.query("DELETE FROM fieldsCombined");
Zotero.DB.query("DELETE FROM itemTypeFieldsCombined");
Zotero.DB.query("DELETE FROM baseFieldMappingsCombined");
}
var offset = Zotero.ItemTypes.customIDOffset;
Zotero.DB.query(
"INSERT INTO itemTypesCombined "
+ (
skipSystem
? ""
: "SELECT itemTypeID, typeName, display, 0 AS custom FROM itemTypes UNION "
)
+ "SELECT customItemTypeID + " + offset + " AS itemTypeID, typeName, display, 1 AS custom FROM customItemTypes"
);
Zotero.DB.query(
"INSERT INTO fieldsCombined "
+ (
skipSystem
? ""
: "SELECT fieldID, fieldName, NULL AS label, fieldFormatID, 0 AS custom FROM fields UNION "
)
+ "SELECT customFieldID + " + offset + " AS fieldID, fieldName, label, NULL, 1 AS custom FROM customFields"
);
Zotero.DB.query(
"INSERT INTO itemTypeFieldsCombined "
+ (
skipSystem
? ""
: "SELECT itemTypeID, fieldID, hide, orderIndex FROM itemTypeFields UNION "
)
+ "SELECT customItemTypeID + " + offset + " AS itemTypeID, "
+ "COALESCE(fieldID, customFieldID + " + offset + ") AS fieldID, hide, orderIndex FROM customItemTypeFields"
);
Zotero.DB.query(
"INSERT INTO baseFieldMappingsCombined "
+ (
skipSystem
? ""
: "SELECT itemTypeID, baseFieldID, fieldID FROM baseFieldMappings UNION "
)
+ "SELECT customItemTypeID + " + offset + " AS itemTypeID, baseFieldID, "
+ "customFieldID + " + offset + " AS fieldID FROM customBaseFieldMappings"
);
}
@ -827,6 +1031,7 @@ Zotero.Schema = new function(){
Zotero.DB.query(_getSchemaSQL('system'));
Zotero.DB.query(_getSchemaSQL('userdata'));
Zotero.DB.query(_getSchemaSQL('triggers'));
Zotero.Schema.updateCustomTables(true);
_updateDBVersion('system', _getSchemaSQLVersion('system'));
_updateDBVersion('userdata', _getSchemaSQLVersion('userdata'));
@ -834,16 +1039,14 @@ Zotero.Schema = new function(){
if (!Zotero.Schema.skipDefaultData) {
/*
TODO: uncomment for release
var sql = "INSERT INTO items VALUES(1, 14, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'AJ4PT6IT')";
// Quick Start Guide web page item
var sql = "INSERT INTO items VALUES(1, 13, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, 'ABCD1234')";
Zotero.DB.query(sql);
var sql = "INSERT INTO itemAttachments VALUES (1, NULL, 3, 'text/html', 25, NULL, NULL)";
Zotero.DB.query(sql);
var sql = "INSERT INTO itemDataValues VALUES (?, ?)";
Zotero.DB.query(sql, [1, "Zotero - " + Zotero.getString('install.quickStartGuide')]);
var sql = "INSERT INTO itemDataValues VALUES (1, ?)";
Zotero.DB.query(sql, Zotero.localeJoin(["Zotero", "\u2014", Zotero.getString('install.quickStartGuide')]));
var sql = "INSERT INTO itemData VALUES (1, 110, 1)";
Zotero.DB.query(sql);
var sql = "INSERT INTO itemDataValues VALUES (2, 'http://www.zotero.org/documentation/quick_start_guide')";
var sql = "INSERT INTO itemDataValues VALUES (2, 'http://www.zotero.org/support/quick_start_guide')";
Zotero.DB.query(sql);
var sql = "INSERT INTO itemData VALUES (1, 1, 2)";
Zotero.DB.query(sql);
@ -851,11 +1054,27 @@ Zotero.Schema = new function(){
Zotero.DB.query(sql);
var sql = "INSERT INTO itemData VALUES (1, 27, 3)";
Zotero.DB.query(sql);
var sql = "INSERT INTO itemNotes (itemID, sourceItemID, note) VALUES (1, NULL, ?)";
var msg = Zotero.getString('install.quickStartGuide.message.welcome')
+ " " + Zotero.getString('install.quickStartGuide.message.clickViewPage')
+ "\n\n" + Zotero.getString('install.quickStartGuide.message.thanks');
Zotero.DB.query(sql, msg);
// CHNM as creator
var sql = "INSERT INTO creatorData VALUES (1, '', 'Center for History and New Media', '', 1, NULL)";
Zotero.DB.query(sql);
var sql = "INSERT INTO creators VALUES (1, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, 'ABCD1234')";
Zotero.DB.query(sql);
var sql = "INSERT INTO itemCreators VALUES (1, 1, 1, 0)";
Zotero.DB.query(sql);
// Welcome note
var sql = "INSERT INTO items VALUES(2, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, 'ABCD2345')";
Zotero.DB.query(sql);
var welcomeTitle = Zotero.getString('install.quickStartGuide.message.welcome');
var welcomeMsg = '<div class="zotero-note znv1"><p>' + Zotero.localeJoin([
welcomeTitle, Zotero.getString('install.quickStartGuide.message.clickViewPage')
])
+ '</p><p>'
+ Zotero.getString('install.quickStartGuide.message.thanks')
+ '</p></div>';
var sql = "INSERT INTO itemNotes VALUES (2, 1, ?, ?)";
Zotero.DB.query(sql, [welcomeMsg, welcomeTitle]);
*/
}
Zotero.DB.commitTransaction();
@ -2547,6 +2766,20 @@ Zotero.Schema = new function(){
}
}
if (i==68) {
Zotero.DB.query("DROP TRIGGER IF EXISTS fkd_itemData_fieldID_fields_fieldID");
Zotero.DB.query("DROP TRIGGER IF EXISTS fku_fields_fieldID_itemData_fieldID");
Zotero.DB.query("UPDATE savedSearchConditions SET condition='itemType', value=(SELECT typeName FROM itemTypes WHERE itemTypeID=value) WHERE condition='itemTypeID'");
Zotero.DB.query("CREATE TABLE customItemTypes (\n customItemTypeID INTEGER PRIMARY KEY,\n typeName TEXT,\n label TEXT,\n display INT DEFAULT 1,\n icon TEXT\n)");
Zotero.DB.query("CREATE TABLE customFields (\n customFieldID INTEGER PRIMARY KEY,\n fieldName TEXT,\n label TEXT\n)");
Zotero.DB.query("CREATE TABLE customItemTypeFields (\n customItemTypeID INT NOT NULL,\n fieldID INT,\n customFieldID INT,\n hide INT NOT NULL,\n orderIndex INT NOT NULL,\n PRIMARY KEY (customItemTypeID, orderIndex),\n FOREIGN KEY (customItemTypeID) REFERENCES customItemTypes(customItemTypeID),\n FOREIGN KEY (fieldID) REFERENCES fields(fieldID),\n FOREIGN KEY (customFieldID) REFERENCES customFields(customFieldID)\n)");
Zotero.DB.query("CREATE INDEX customItemTypeFields_fieldID ON customItemTypeFields(fieldID)");
Zotero.DB.query("CREATE INDEX customItemTypeFields_customFieldID ON customItemTypeFields(customFieldID)");
Zotero.DB.query("CREATE TABLE customBaseFieldMappings (\n customItemTypeID INT,\n baseFieldID INT,\n customFieldID INT,\n PRIMARY KEY (customItemTypeID, baseFieldID, customFieldID),\n FOREIGN KEY (customItemTypeID) REFERENCES customItemTypes(customItemTypeID),\n FOREIGN KEY (baseFieldID) REFERENCES fields(fieldID),\n FOREIGN KEY (customFieldID) REFERENCES fields(customFieldID)\n);\nCREATE INDEX customBaseFieldMappings_baseFieldID ON customBaseFieldMappings(baseFieldID)");
Zotero.DB.query("CREATE INDEX customBaseFieldMappings_customFieldID ON customBaseFieldMappings(customFieldID)");
}
Zotero.wait();
}

View file

@ -219,6 +219,14 @@ Zotero.Search.prototype.load = function() {
continue;
}
// Convert itemTypeID to itemType
//
// TEMP: This can be removed at some point
if (condition == 'itemTypeID') {
condition = 'itemType';
conditions[i].value = Zotero.ItemTypes.getName(conditions[i].value);
}
this._conditions[conditions[i]['searchConditionID']] = {
id: conditions[i]['searchConditionID'],
condition: condition,
@ -1202,6 +1210,11 @@ Zotero.Search.prototype._buildQuery = function(){
skipOperators = true;
break;
case 'itemType':
condSQL += "itemTypeID IN (SELECT itemTypeID FROM itemTypesCombined WHERE ";
openParens++;
break;
case 'fileTypeID':
var ftSQL = 'SELECT mimeType FROM fileTypeMimeTypes '
+ 'WHERE fileTypeID IN ('
@ -1314,35 +1327,7 @@ Zotero.Search.prototype._buildQuery = function(){
if (parseDate){
var go = false;
// Allow 'today' or localized 'today'
var lc = (condition.value + '').toLowerCase();
if (lc == 'yesterday' || lc == Zotero.getString('date.yesterday')) {
var dateparts = Zotero.Date.strToDate(
Zotero.Date.dateToSQL(
new Date(new Date().getTime() - 86400000), true
)
);
dateparts.part = null;
}
else if (lc == 'today' || lc == Zotero.getString('date.today')) {
var dateparts = Zotero.Date.strToDate(
Zotero.Date.dateToSQL(
new Date(), true
)
);
dateparts.part = null;
}
else if (lc == 'tomorrow' || lc == Zotero.getString('date.tomorrow')) {
var dateparts = Zotero.Date.strToDate(
Zotero.Date.dateToSQL(
new Date(new Date().getTime() + 86400000), true
)
);
dateparts.part = null;
}
else {
var dateparts = Zotero.Date.strToDate(condition.value);
}
var dateparts = Zotero.Date.strToDate(condition.value);
// Search on SQL date -- underscore is
// single-character wildcard
@ -1847,7 +1832,7 @@ Zotero.SearchConditions = new function(){
},
noLoad: true
},
//
// Standard conditions
@ -1900,6 +1885,7 @@ Zotero.SearchConditions = new function(){
field: 'dateModified'
},
// Deprecated
{
name: 'itemTypeID',
operators: {
@ -1907,7 +1893,18 @@ Zotero.SearchConditions = new function(){
isNot: true
},
table: 'items',
field: 'itemTypeID'
field: 'itemTypeID',
special: true
},
{
name: 'itemType',
operators: {
is: true,
isNot: true
},
table: 'items',
field: 'typeName'
},
{
@ -1998,7 +1995,7 @@ Zotero.SearchConditions = new function(){
},
table: 'itemData',
field: 'value',
aliases: Zotero.DB.columnQuery("SELECT fieldName FROM fields " +
aliases: Zotero.DB.columnQuery("SELECT fieldName FROM fieldsCombined " +
"WHERE fieldName NOT IN ('accessDate', 'date', 'pages', " +
"'section','seriesNumber','issue')"),
template: true // mark for special handling
@ -2015,7 +2012,7 @@ Zotero.SearchConditions = new function(){
},
table: 'itemData',
field: 'value',
aliases: ['accessDate', 'date'],
aliases: ['accessDate', 'date', 'dateDue', 'accepted'], // TEMP - NSF
template: true // mark for special handling
},
@ -2087,6 +2084,14 @@ Zotero.SearchConditions = new function(){
_conditions[conditions[i]['name']] = conditions[i];
if (conditions[i]['aliases']) {
for (var j in conditions[i]['aliases']) {
// TEMP - NSF
switch (conditions[i]['aliases'][j]) {
case 'dateDue':
case 'accepted':
if (!Zotero.ItemTypes.getID('nsfReviewer')) {
continue;
}
}
_conditions[conditions[i]['aliases'][j]] = conditions[i];
}
}
@ -2190,11 +2195,16 @@ Zotero.SearchConditions = new function(){
function getLocalizedName(str) {
// TEMP
if (str == 'itemType') {
str = 'itemTypeID';
}
try {
return Zotero.getString('searchConditions.' + str)
}
catch (e) {
return Zotero.getString('itemFields.' + str);
return Zotero.ItemFields.getLocalizedString(null, str);
}
}
@ -2244,4 +2254,11 @@ Zotero.SearchConditions = new function(){
return [condition, mode];
}
this.reload = function () {
_initialized = false;
_conditions = {};
_standardConditions = [];
}
}

View file

@ -358,7 +358,7 @@ var Zotero = new function(){
// If no userdata upgrade, still might need to process system/scrapers
else {
try {
Zotero.Schema.updateSchema();
var updated = Zotero.Schema.updateSchema();
}
catch (e) {
if (typeof e == 'string' && e.match('newer than SQL file')) {
@ -381,6 +381,11 @@ var Zotero = new function(){
Zotero.DB.startDummyStatement();
Zotero.Schema.updateFromRepository();
// Populate combined tables for custom types and fields -- this is likely temporary
if (!upgraded && !updated) {
Zotero.Schema.updateCustomTables();
}
// Initialize integration web server
Zotero.Integration.init();
@ -1794,6 +1799,18 @@ Zotero.Date = new function(){
var _dayRe = null;
function strToDate(string) {
// Parse 'yesterday'/'today'/'tomorrow'
var lc = (string + '').toLowerCase();
if (lc == 'yesterday' || lc == Zotero.getString('date.yesterday')) {
string = Zotero.Date.dateToSQL(new Date(new Date().getTime() - 86400000)).substr(0, 10);
}
else if (lc == 'today' || lc == Zotero.getString('date.today')) {
string = Zotero.Date.dateToSQL(new Date()).substr(0, 10);
}
else if (lc == 'tomorrow' || lc == Zotero.getString('date.tomorrow')) {
string = Zotero.Date.dateToSQL(new Date(new Date().getTime() + 86400000)).substr(0, 10);
}
var date = new Object();
// skip empty things

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 B

View file

@ -1,4 +1,4 @@
-- 25
-- 26
-- Copyright (c) 2009 Center for History and New Media
-- George Mason University, Fairfax, Virginia, USA
@ -33,6 +33,16 @@ CREATE TABLE itemTypes (
display INT DEFAULT 1 -- 0 == hide, 1 == display, 2 == primary
);
-- Populated at startup from itemTypes and customItemTypes
DROP TABLE IF EXISTS itemTypesCombined;
CREATE TABLE itemTypesCombined (
itemTypeID INT NOT NULL,
typeName TEXT NOT NULL,
display INT DEFAULT 1 NOT NULL,
custom INT NOT NULL,
PRIMARY KEY (itemTypeID)
);
-- Describes various types of fields and their format restrictions,
-- and indicates whether data should be stored as strings or integers
--
@ -53,6 +63,17 @@ CREATE TABLE fields (
FOREIGN KEY (fieldFormatID) REFERENCES fieldFormats(fieldFormatID)
);
-- Populated at startup from fields and customFields
DROP TABLE IF EXISTS fieldsCombined;
CREATE TABLE fieldsCombined (
fieldID INT NOT NULL,
fieldName TEXT NOT NULL,
label TEXT,
fieldFormatID INT,
custom INT NOT NULL,
PRIMARY KEY (fieldID)
);
-- Defines valid fields for each itemType, their display order, and their default visibility
DROP TABLE IF EXISTS itemTypeFields;
CREATE TABLE itemTypeFields (
@ -60,10 +81,24 @@ CREATE TABLE itemTypeFields (
fieldID INT,
hide INT,
orderIndex INT,
PRIMARY KEY (itemTypeID, fieldID),
PRIMARY KEY (itemTypeID, orderIndex),
UNIQUE (itemTypeID, fieldID),
FOREIGN KEY (itemTypeID) REFERENCES itemTypes(itemTypeID),
FOREIGN KEY (fieldID) REFERENCES fields(fieldID)
);
CREATE INDEX itemTypeFields_fieldID ON itemTypeFields(fieldID);
-- Populated at startup from itemTypeFields and customItemTypeFields
DROP TABLE IF EXISTS itemTypeFieldsCombined;
CREATE TABLE itemTypeFieldsCombined (
itemTypeID INT NOT NULL,
fieldID INT NOT NULL,
hide INT,
orderIndex INT NOT NULL,
PRIMARY KEY (itemTypeID, orderIndex),
UNIQUE (itemTypeID, fieldID)
);
CREATE INDEX itemTypeFieldsCombined_fieldID ON itemTypeFieldsCombined(fieldID);
-- Maps base fields to type-specific fields (e.g. publisher to label in audioRecording)
DROP TABLE IF EXISTS baseFieldMappings;
@ -72,18 +107,29 @@ CREATE TABLE baseFieldMappings (
baseFieldID INT,
fieldID INT,
PRIMARY KEY (itemTypeID, baseFieldID, fieldID),
FOREIGN KEY (itemTypeID) REFERENCES itemTypes(itemTypeID),
FOREIGN KEY (baseFieldID) REFERENCES fields(fieldID),
FOREIGN KEY (fieldID) REFERENCES fields(fieldID)
);
DROP INDEX IF EXISTS baseFieldMappings_baseFieldID;
CREATE INDEX baseFieldMappings_baseFieldID ON baseFieldMappings(baseFieldID);
CREATE INDEX baseFieldMappings_fieldID ON baseFieldMappings(fieldID);
-- Populated at startup from baseFieldMappings and customBaseFieldMappings
DROP TABLE IF EXISTS baseFieldMappingsCombined;
CREATE TABLE baseFieldMappingsCombined (
itemTypeID INT,
baseFieldID INT,
fieldID INT,
PRIMARY KEY (itemTypeID, baseFieldID, fieldID)
);
CREATE INDEX baseFieldMappingsCombined_baseFieldID ON baseFieldMappingsCombined(baseFieldID);
CREATE INDEX baseFieldMappingsCombined_fieldID ON baseFieldMappingsCombined(fieldID);
DROP TABLE IF EXISTS charsets;
CREATE TABLE charsets (
charsetID INTEGER PRIMARY KEY,
charset TEXT UNIQUE
);
DROP INDEX IF EXISTS charsets_charset;
CREATE INDEX charsets_charset ON charsets(charset);
DROP TABLE IF EXISTS fileTypes;
@ -91,7 +137,6 @@ CREATE TABLE fileTypes (
fileTypeID INTEGER PRIMARY KEY,
fileType TEXT UNIQUE
);
DROP INDEX IF EXISTS fileTypes_fileType;
CREATE INDEX fileTypes_fileType ON fileTypes(fileType);
DROP TABLE IF EXISTS fileTypeMimeTypes;
@ -101,7 +146,6 @@ CREATE TABLE fileTypeMimeTypes (
PRIMARY KEY (fileTypeID, mimeType),
FOREIGN KEY (fileTypeID) REFERENCES fileTypes(fileTypeID)
);
DROP INDEX IF EXISTS fileTypeMimeTypes_mimeType;
CREATE INDEX fileTypeMimeTypes_mimeType ON fileTypeMimeTypes(mimeType);
-- Defines the possible creator types (contributor, editor, author)
@ -120,7 +164,8 @@ CREATE TABLE itemTypeCreatorTypes (
FOREIGN KEY (itemTypeID) REFERENCES itemTypes(itemTypeID),
FOREIGN KEY (creatorTypeID) REFERENCES creatorTypes(creatorTypeID)
);
CREATE INDEX itemTypeCreatorTypes_creatorTypeID ON itemTypeCreatorTypes(creatorTypeID);
DROP TABLE IF EXISTS syncObjectTypes;
CREATE TABLE syncObjectTypes (
syncObjectTypeID INTEGER PRIMARY KEY,
@ -142,7 +187,6 @@ CREATE TABLE transactions (
context TEXT,
action TEXT
);
DROP INDEX IF EXISTS transactions_transactionSetID;
CREATE INDEX transactions_transactionSetID ON transactions(transactionSetID);
DROP TABLE IF EXISTS transactionLog;

View file

@ -1,4 +1,4 @@
-- 15
-- 16
-- Copyright (c) 2009 Center for History and New Media
-- George Mason University, Fairfax, Virginia, USA
@ -341,6 +341,171 @@ CREATE TRIGGER fku_creatorData_creatorDataID_creators_creatorDataID
WHERE (SELECT COUNT(*) FROM creators WHERE creatorDataID = OLD.creatorDataID) > 0;
END;
-- customBaseFieldMappings/customItemTypeID
DROP TRIGGER IF EXISTS fki_customBaseFieldMappings_customItemTypeID_customItemTypes_customItemTypeID;
CREATE TRIGGER fki_customBaseFieldMappings_customItemTypeID_customItemTypes_customItemTypeID
BEFORE INSERT ON customBaseFieldMappings
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'insert on table "customBaseFieldMappings" violates foreign key constraint "fki_customBaseFieldMappings_customItemTypeID_customItemTypes_customItemTypeID"')
WHERE NEW.customItemTypeID IS NOT NULL AND (SELECT COUNT(*) FROM customItemTypes WHERE customItemTypeID = NEW.customItemTypeID) = 0;
END;
DROP TRIGGER IF EXISTS fku_customBaseFieldMappings_customItemTypeID_customItemTypes_customItemTypeID;
CREATE TRIGGER fku_customBaseFieldMappings_customItemTypeID_customItemTypes_customItemTypeID
BEFORE UPDATE OF customItemTypeID ON customBaseFieldMappings
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'update on table "customBaseFieldMappings" violates foreign key constraint "fku_customBaseFieldMappings_customItemTypeID_customItemTypes_customItemTypeID"')
WHERE NEW.customItemTypeID IS NOT NULL AND (SELECT COUNT(*) FROM customItemTypes WHERE customItemTypeID = NEW.customItemTypeID) = 0;
END;
DROP TRIGGER IF EXISTS fkd_customBaseFieldMappings_customItemTypeID_customItemTypes_customItemTypeID;
CREATE TRIGGER fkd_customBaseFieldMappings_customItemTypeID_customItemTypes_customItemTypeID
BEFORE DELETE ON customItemTypes
FOR EACH ROW BEGIN
DELETE FROM customBaseFieldMappings WHERE customItemTypeID = OLD.customItemTypeID;
END;
DROP TRIGGER IF EXISTS fku_customItemTypes_customItemTypeID_customBaseFieldMappings_customItemTypeID;
CREATE TRIGGER fku_customItemTypes_customItemTypeID_customBaseFieldMappings_customItemTypeID
AFTER UPDATE OF customItemTypeID ON customItemTypes
FOR EACH ROW BEGIN
UPDATE customBaseFieldMappings SET customItemTypeID=NEW.customItemTypeID WHERE customItemTypeID=OLD.customItemTypeID;
END;
-- customBaseFieldMappings/baseFieldID
DROP TRIGGER IF EXISTS fki_customBaseFieldMappings_baseFieldID_fields_fieldID;
CREATE TRIGGER fki_customBaseFieldMappings_baseFieldID_fields_fieldID
BEFORE INSERT ON customBaseFieldMappings
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'insert on table "customBaseFieldMappings" violates foreign key constraint "fki_customBaseFieldMappings_baseFieldID_fields_fieldID"')
WHERE NEW.baseFieldID IS NOT NULL AND (SELECT COUNT(*) FROM fields WHERE fieldID = NEW.baseFieldID) = 0;
END;
DROP TRIGGER IF EXISTS fku_customBaseFieldMappings_baseFieldID_fields_fieldID;
CREATE TRIGGER fku_customBaseFieldMappings_baseFieldID_fields_fieldID
BEFORE UPDATE OF baseFieldID ON customBaseFieldMappings
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'update on table "customBaseFieldMappings" violates foreign key constraint "fku_customBaseFieldMappings_baseFieldID_fields_fieldID"')
WHERE NEW.baseFieldID IS NOT NULL AND (SELECT COUNT(*) FROM fields WHERE fieldID = NEW.baseFieldID) = 0;
END;
-- customBaseFieldMappings/customFieldID
DROP TRIGGER IF EXISTS fki_customBaseFieldMappings_customFieldID_customFields_customFieldID;
CREATE TRIGGER fki_customBaseFieldMappings_customFieldID_customFields_customFieldID
BEFORE INSERT ON customBaseFieldMappings
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'insert on table "customBaseFieldMappings" violates foreign key constraint "fki_customBaseFieldMappings_customFieldID_customFields_customFieldID"')
WHERE NEW.customFieldID IS NOT NULL AND (SELECT COUNT(*) FROM customFields WHERE customFieldID = NEW.customFieldID) = 0;
END;
DROP TRIGGER IF EXISTS fku_customBaseFieldMappings_customFieldID_customFields_customFieldID;
CREATE TRIGGER fku_customFields_customFieldID_customFields_customFieldID
BEFORE UPDATE OF customFieldID ON customBaseFieldMappings
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'update on table "customBaseFieldMappings" violates foreign key constraint "fku_customBaseFieldMappings_customFieldID_customFields_customFieldID"')
WHERE NEW.customFieldID IS NOT NULL AND (SELECT COUNT(*) FROM customFields WHERE customFieldID = NEW.customFieldID) = 0;
END;
DROP TRIGGER IF EXISTS fkd_customBaseFieldMappings_customFieldID_customFields_customFieldID;
CREATE TRIGGER fkd_customFields_customFieldID_customFields_customFieldID
BEFORE DELETE ON customFields
FOR EACH ROW BEGIN
DELETE FROM customBaseFieldMappings WHERE customFieldID = OLD.customFieldID;
END;
DROP TRIGGER IF EXISTS fku_customFields_customFieldID_customBaseFieldMappings_customFieldID;
CREATE TRIGGER fku_customFields_customFieldID_customBaseFieldMappings_customFieldID
AFTER UPDATE OF customFieldID ON customFields
FOR EACH ROW BEGIN
UPDATE customBaseFieldMappings SET customFieldID=NEW.customFieldID WHERE customFieldID=OLD.customFieldID;
END;
-- customItemTypeFields/customItemTypeID
DROP TRIGGER IF EXISTS fki_customItemTypeFields_customItemTypeID_customItemTypes_customItemTypeID;
CREATE TRIGGER fki_customItemTypeFields_customItemTypeID_customItemTypes_customItemTypeID
BEFORE INSERT ON customItemTypeFields
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'insert on table "customItemTypeFields" violates foreign key constraint "fki_customItemTypeFields_customItemTypeID_customItemTypes_customItemTypeID"')
WHERE NEW.customItemTypeID IS NOT NULL AND (SELECT COUNT(*) FROM customItemTypes WHERE customItemTypeID = NEW.customItemTypeID) = 0;
END;
DROP TRIGGER IF EXISTS fku_customItemTypeFields_customItemTypeID_customItemTypes_customItemTypeID;
CREATE TRIGGER fku_customItemTypeFields_customItemTypeID_customItemTypes_customItemTypeID
BEFORE UPDATE OF customItemTypeID ON customItemTypeFields
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'update on table "customItemTypeFields" violates foreign key constraint "fku_customItemTypeFields_customItemTypeID_customItemTypes_customItemTypeID"')
WHERE NEW.customItemTypeID IS NOT NULL AND (SELECT COUNT(*) FROM customItemTypes WHERE customItemTypeID = NEW.customItemTypeID) = 0;
END;
DROP TRIGGER IF EXISTS fkd_customItemTypeFields_customItemTypeID_customItemTypes_customItemTypeID;
CREATE TRIGGER fkd_customItemTypeFields_customItemTypeID_customItemTypes_customItemTypeID
BEFORE DELETE ON customItemTypes
FOR EACH ROW BEGIN
DELETE FROM customBaseFieldMappings WHERE customItemTypeID = OLD.customItemTypeID;
END;
DROP TRIGGER IF EXISTS fku_customItemTypes_customItemTypeID_customItemTypeFields_customItemTypeID;
CREATE TRIGGER fku_customItemTypes_customItemTypeID_customItemTypeFields_customItemTypeID
AFTER UPDATE OF customItemTypeID ON customItemTypes
FOR EACH ROW BEGIN
UPDATE customItemTypeFields SET customItemTypeID=NEW.customItemTypeID WHERE customItemTypeID=OLD.customItemTypeID;
END;
-- customItemTypeFields/fieldID
DROP TRIGGER IF EXISTS fki_customItemTypeFields_fieldID_fields_fieldID;
CREATE TRIGGER fki_customItemTypeFields_fieldID_fields_fieldID
BEFORE INSERT ON customItemTypeFields
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'insert on table "customItemTypeFields" violates foreign key constraint "fki_customItemTypeFields_fieldID_fields_fieldID"')
WHERE NEW.fieldID IS NOT NULL AND (SELECT COUNT(*) FROM fields WHERE fieldID = NEW.fieldID) = 0;
END;
DROP TRIGGER IF EXISTS fku_customItemTypeFields_fieldID_fields_fieldID;
CREATE TRIGGER fku_customItemTypeFields_fieldID_fields_fieldID
BEFORE UPDATE OF fieldID ON customItemTypeFields
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'update on table "customItemTypeFields" violates foreign key constraint "fku_customItemTypeFields_fieldID_fields_fieldID"')
WHERE NEW.fieldID IS NOT NULL AND (SELECT COUNT(*) FROM fields WHERE fieldID = NEW.fieldID) = 0;
END;
-- customItemTypeFields/customFieldID
DROP TRIGGER IF EXISTS fki_customItemTypeFields_customFieldID_customFields_customFieldID;
CREATE TRIGGER fki_customItemTypeFields_customFieldID_customFields_customFieldID
BEFORE INSERT ON customItemTypeFields
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'insert on table "customItemTypeFields" violates foreign key constraint "fki_customItemTypeFields_customFieldID_customFields_customFieldID"')
WHERE NEW.customFieldID IS NOT NULL AND (SELECT COUNT(*) FROM customFields WHERE customFieldID = NEW.customFieldID) = 0;
END;
DROP TRIGGER IF EXISTS fku_customItemTypeFields_customFieldID_customFields_customFieldID;
CREATE TRIGGER fku_customItemTypeFields_customFieldID_customFields_customFieldID
BEFORE UPDATE OF customFieldID ON customItemTypeFields
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'update on table "customItemTypeFields" violates foreign key constraint "fku_customItemTypeFields_customFieldID_customFields_customFieldID"')
WHERE NEW.customFieldID IS NOT NULL AND (SELECT COUNT(*) FROM customFields WHERE customFieldID = NEW.customFieldID) = 0;
END;
DROP TRIGGER IF EXISTS fkd_customItemTypeFields_customFieldID_customFields_customFieldID;
CREATE TRIGGER fkd_customItemTypeFields_customFieldID_customFields_customFieldID
BEFORE DELETE ON customFields
FOR EACH ROW BEGIN
DELETE FROM customItemTypeFields WHERE customFieldID = OLD.customFieldID;
END;
DROP TRIGGER IF EXISTS fku_customFields_customFieldID_customItemTypeFields_customFieldID;
CREATE TRIGGER fku_customFields_customFieldID_customItemTypeFields_customFieldID
AFTER UPDATE OF customFieldID ON customFields
FOR EACH ROW BEGIN
UPDATE customItemTypeFields SET customFieldID=NEW.customFieldID WHERE customFieldID=OLD.customFieldID;
END;
-- fulltextItems/itemID
DROP TRIGGER IF EXISTS fki_fulltextItems_itemID_items_itemID;
CREATE TRIGGER fki_fulltextItems_itemID_items_itemID
@ -859,32 +1024,16 @@ DROP TRIGGER IF EXISTS fki_itemData_fieldID_fields_fieldID;
CREATE TRIGGER fki_itemData_fieldID_fields_fieldID
BEFORE INSERT ON itemData
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'insert on table "itemData" violates foreign key constraint "fki_itemData_fieldID_fields_fieldID"')
WHERE NEW.fieldID IS NOT NULL AND (SELECT COUNT(*) FROM fields WHERE fieldID = NEW.fieldID) = 0;
SELECT RAISE(ABORT, 'insert on table "itemData" violates foreign key constraint "fki_itemData_fieldID_fieldsCombined_fieldID"')
WHERE NEW.fieldID IS NOT NULL AND (SELECT COUNT(*) FROM fieldsCombined WHERE fieldID = NEW.fieldID) = 0;
END;
DROP TRIGGER IF EXISTS fku_itemData_fieldID_fields_fieldID;
CREATE TRIGGER fku_itemData_fieldID_fields_fieldID
BEFORE UPDATE OF fieldID ON itemData
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'update on table "itemData" violates foreign key constraint "fku_itemData_fieldID_fields_fieldID"')
WHERE NEW.fieldID IS NOT NULL AND (SELECT COUNT(*) FROM fields WHERE fieldID = NEW.fieldID) = 0;
END;
DROP TRIGGER IF EXISTS fkd_itemData_fieldID_fields_fieldID;
CREATE TRIGGER fkd_itemData_fieldID_fields_fieldID
BEFORE DELETE ON FIELDS
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'delete on table "fields" violates foreign key constraint "fkd_itemData_fieldID_fields_fieldID"')
WHERE (SELECT COUNT(*) FROM itemData WHERE fieldID = OLD.fieldID) > 0;
END;
DROP TRIGGER IF EXISTS fku_fields_fieldID_itemData_fieldID;
CREATE TRIGGER fku_fields_fieldID_itemData_fieldID
BEFORE UPDATE OF fieldID ON FIELDS
FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'update on table "fields" violates foreign key constraint "fku_fields_fieldID_itemData_fieldID"')
WHERE (SELECT COUNT(*) FROM itemData WHERE fieldID = OLD.fieldID) > 0;
SELECT RAISE(ABORT, 'update on table "itemData" violates foreign key constraint "fku_itemData_fieldID_fieldsCombined_fieldID"')
WHERE NEW.fieldID IS NOT NULL AND (SELECT COUNT(*) FROM fieldsCombined WHERE fieldID = NEW.fieldID) = 0;
END;
-- itemData/valueID

View file

@ -1,4 +1,4 @@
-- 67
-- 68
-- Copyright (c) 2009 Center for History and New Media
-- George Mason University, Fairfax, Virginia, USA
@ -338,4 +338,46 @@ CREATE TABLE proxyHosts (
hostname TEXT,
FOREIGN KEY (proxyID) REFERENCES proxies(proxyID)
);
CREATE INDEX proxyHosts_proxyID ON proxyHosts(proxyID);
CREATE INDEX proxyHosts_proxyID ON proxyHosts(proxyID);
-- These shouldn't be used yet
CREATE TABLE customItemTypes (
customItemTypeID INTEGER PRIMARY KEY,
typeName TEXT,
label TEXT,
display INT DEFAULT 1, -- 0 == hide, 1 == display, 2 == primary
icon TEXT
);
CREATE TABLE customFields (
customFieldID INTEGER PRIMARY KEY,
fieldName TEXT,
label TEXT
);
CREATE TABLE customItemTypeFields (
customItemTypeID INT NOT NULL,
fieldID INT,
customFieldID INT,
hide INT NOT NULL,
orderIndex INT NOT NULL,
PRIMARY KEY (customItemTypeID, orderIndex),
FOREIGN KEY (customItemTypeID) REFERENCES customItemTypes(customItemTypeID),
FOREIGN KEY (fieldID) REFERENCES fields(fieldID),
FOREIGN KEY (customFieldID) REFERENCES customFields(customFieldID)
);
CREATE INDEX customItemTypeFields_fieldID ON customItemTypeFields(fieldID);
CREATE INDEX customItemTypeFields_customFieldID ON customItemTypeFields(customFieldID);
CREATE TABLE customBaseFieldMappings (
customItemTypeID INT,
baseFieldID INT,
customFieldID INT,
PRIMARY KEY (customItemTypeID, baseFieldID, customFieldID),
FOREIGN KEY (customItemTypeID) REFERENCES customItemTypes(customItemTypeID),
FOREIGN KEY (baseFieldID) REFERENCES fields(fieldID),
FOREIGN KEY (customFieldID) REFERENCES fields(customFieldID)
);
CREATE INDEX customBaseFieldMappings_baseFieldID ON customBaseFieldMappings(baseFieldID);
CREATE INDEX customBaseFieldMappings_customFieldID ON customBaseFieldMappings(customFieldID);