Moved title field to itemData table, which made the following possible:

- All remaining fields in the items table exists in all items and are non-user-editable
   - Simplified some data access code (e.g. removed Item.isEditableField())
   - 'title' is now a base field used in case (Case Name), statute (nameOfAct) and e-mail (Subject)

Reengineered parts of the data layer for better performance

   - Various recent changes, including the 'title' change above and base field mapping in Item.getField(), had a negative effect on performance. This should help. In particular, itemData values are now loaded in in bulk by Items._load() (via Items.get()) rather than on-demand, the sort process in itemTreeView caches values while sorting, and ItemFields.getFieldIDFromTypeAndBase() is faster.


Addresses #346, mapping for new item types
This commit is contained in:
Dan Stillman 2007-03-10 06:44:39 +00:00
parent 3465346694
commit 358924de47
6 changed files with 741 additions and 691 deletions

View File

@ -278,15 +278,16 @@ var ZoteroItemPane = new function()
if(_itemTypeMenu.firstChild.childNodes[i].value == _itemBeingEdited.getType()) if(_itemTypeMenu.firstChild.childNodes[i].value == _itemBeingEdited.getType())
_itemTypeMenu.selectedIndex = i; _itemTypeMenu.selectedIndex = i;
var fieldNames = new Array("title"); var fieldNames = [];
var fields = Zotero.ItemFields.getItemTypeFields(_itemBeingEdited.getField("itemTypeID")); var fields = Zotero.ItemFields.getItemTypeFields(_itemBeingEdited.getField("itemTypeID"));
for(var i = 0; i<fields.length; i++) for (var i = 0; i<fields.length; i++) {
fieldNames.push(Zotero.ItemFields.getName(fields[i])); fieldNames.push(Zotero.ItemFields.getName(fields[i]));
}
fieldNames.push("dateAdded","dateModified"); fieldNames.push("dateAdded","dateModified");
for(var i = 0; i<fieldNames.length; i++) for(var i = 0; i<fieldNames.length; i++)
{ {
var editable = (!_itemBeingEdited.isPrimaryField(fieldNames[i]) || _itemBeingEdited.isEditableField(fieldNames[i])); var editable = !_itemBeingEdited.isPrimaryField(fieldNames[i]);
var val = _itemBeingEdited.getField(fieldNames[i]); var val = _itemBeingEdited.getField(fieldNames[i]);

View File

@ -48,6 +48,7 @@ Zotero.Item.prototype._init = function(){
this._changedCreators = new Zotero.Hash(); this._changedCreators = new Zotero.Hash();
this._changedItemData = new Zotero.Hash(); this._changedItemData = new Zotero.Hash();
this._noteTitle = null;
this._noteText = null; this._noteText = null;
this._noteAccessTime = null; this._noteAccessTime = null;
@ -77,18 +78,6 @@ Zotero.Item.prototype.isPrimaryField = function(field){
return !!Zotero.Item.primaryFields[field]; return !!Zotero.Item.primaryFields[field];
} }
Zotero.Item.editableFields = {
title: true
};
/*
* Check if the specified primary field can be changed with setField()
*/
Zotero.Item.prototype.isEditableField = function(field){
return !!Zotero.Item.editableFields[field];
}
/* /*
* Build object from database * Build object from database
*/ */
@ -115,14 +104,9 @@ Zotero.Item.prototype.loadFromID = function(id){
*/ */
Zotero.Item.prototype.loadFromRow = function(row){ Zotero.Item.prototype.loadFromRow = function(row){
this._init(); this._init();
for (col in row){ for (var col in row){
// Only accept primary field data through loadFromRow() // Only accept primary field data through loadFromRow()
if (this.isPrimaryField(col)){ if (this.isPrimaryField(col)){
// Return first line of content for note items
if (col=='title' && this.isNote()){
row[col] = this._noteToTitle();
}
this._data[col] = row[col]; this._data[col] = row[col];
} }
else { else {
@ -436,30 +420,39 @@ Zotero.Item.prototype.getField = function(field, unformatted, includeBaseMapped)
if (this.isPrimaryField(field)){ if (this.isPrimaryField(field)){
return this._data[field] ? this._data[field] : ''; return this._data[field] ? this._data[field] : '';
} }
else {
if (this.getID() && !this._itemDataLoaded){
this._loadItemData();
}
if (includeBaseMapped && Zotero.ItemFields.isBaseField(field)) { if (Zotero.ItemFields.getName(field) == 'title' && this.isNote()) {
var fieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase( if (this._noteTitle !== null) {
this.getType(), field return this._noteTitle;
);
} }
else { var title = this._noteToTitle();
var fieldID = Zotero.ItemFields.getID(field); this._noteTitle = title;
} return title;
var value = this._itemData[fieldID] ? this._itemData[fieldID] : '';
if (!unformatted){
if (fieldID==Zotero.ItemFields.getID('date')){
value = Zotero.Date.multipartToStr(value);
}
}
return value;
} }
if (this.getID() && !this._itemDataLoaded){
this._loadItemData();
}
if (includeBaseMapped) {
var fieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(
this.getType(), field
);
}
if (!fieldID) {
var fieldID = Zotero.ItemFields.getID(field);
}
var value = this._itemData[fieldID] ? this._itemData[fieldID] : '';
if (!unformatted){
if (fieldID==Zotero.ItemFields.getID('date')){
value = Zotero.Date.multipartToStr(value);
}
}
return value;
} }
@ -475,71 +468,64 @@ Zotero.Item.prototype.setField = function(field, value, loadIn){
// Primary field // Primary field
if (this.isPrimaryField(field)){ if (this.isPrimaryField(field)){
if (!this.isEditableField(field)){ throw ('Primary field ' + field + ' cannot be changed through setField');
throw ('Primary field ' + field + ' cannot be changed through ' +
'setField');
}
if (this._data[field] != undefined && this._data[field]==value){
return false;
}
this._data[field] = value;
if (!loadIn){
this._changed.set(field);
}
return true;
} }
// Type-specific field // Type-specific field
else { if (!this.getType()){
if (!this.getType()){ throw ('Item type must be set before setting field data.');
throw ('Item type must be set before setting field data.');
}
// If existing item, load field data first unless we're already in
// the middle of a load
if (this.getID() && !loadIn && !this._itemDataLoaded){
this._loadItemData();
}
var fieldID = Zotero.ItemFields.getID(field);
if (!fieldID){
throw (field + ' is not a valid itemData field.');
}
if (!Zotero.ItemFields.isValidForType(fieldID, this.getType())){
throw (field + ' is not a valid field for this type.');
}
// Save date field as multipart date
if (!loadIn){
if (fieldID==Zotero.ItemFields.getID('date') &&
!Zotero.Date.isMultipart(value)){
value = Zotero.Date.strToMultipart(value);
}
if (fieldID == Zotero.ItemFields.getID('accessDate')) {
if (!Zotero.Date.isSQLDate(value) &&
!Zotero.Date.isSQLDateTime(value) &&
value != 'CURRENT_TIMESTAMP') {
Zotero.debug("Discarding invalid accessDate '" + value
+ "' in Item.setField()");
return false;
}
}
}
// If existing value, make sure it's actually changing
if ((!this._itemData[fieldID] && !value) ||
(this._itemData[fieldID] && this._itemData[fieldID]==value)){
return false;
}
this._itemData[fieldID] = value;
if (!loadIn){
this._changedItemData.set(fieldID);
}
return true;
} }
// If existing item, load field data first unless we're already in
// the middle of a load
if (this.getID() && !loadIn && !this._itemDataLoaded){
this._loadItemData();
}
var fieldID = Zotero.ItemFields.getID(field);
if (!fieldID){
throw (field + ' is not a valid itemData field.');
}
if (!Zotero.ItemFields.isValidForType(fieldID, this.getType())){
throw (field + ' is not a valid field for this type.');
}
// Save date field as multipart date
if (!loadIn){
if (fieldID==Zotero.ItemFields.getID('date') &&
!Zotero.Date.isMultipart(value)){
value = Zotero.Date.strToMultipart(value);
}
if (fieldID == Zotero.ItemFields.getID('accessDate')) {
if (!Zotero.Date.isSQLDate(value) &&
!Zotero.Date.isSQLDateTime(value) &&
value != 'CURRENT_TIMESTAMP') {
Zotero.debug("Discarding invalid accessDate '" + value
+ "' in Item.setField()");
return false;
}
}
}
// If existing value, make sure it's actually changing
if ((!this._itemData[fieldID] && !value) ||
(this._itemData[fieldID] && this._itemData[fieldID]==value)){
return false;
}
this._itemData[fieldID] = value;
if (loadIn) {
// Not ideal to do this here, but there's not a great way to set this
// private variable from Z.Items._load()
this._itemDataLoaded = true;
}
else {
this._changedItemData.set(fieldID);
}
return true;
} }
@ -596,10 +582,6 @@ Zotero.Item.prototype.save = function(){
sql += "itemTypeID=?, "; sql += "itemTypeID=?, ";
sqlValues.push({'int':this.getField('itemTypeID')}); sqlValues.push({'int':this.getField('itemTypeID')});
} }
if (this._changed.has('title')){
sql += "title=?, ";
sqlValues.push({'string':this.getField('title')});
}
// Always update modified time // Always update modified time
sql += "dateModified=CURRENT_TIMESTAMP "; sql += "dateModified=CURRENT_TIMESTAMP ";
@ -827,11 +809,6 @@ Zotero.Item.prototype.save = function(){
sqlColumns.push('itemTypeID'); sqlColumns.push('itemTypeID');
sqlValues.push({'int':this.getField('itemTypeID')}); sqlValues.push({'int':this.getField('itemTypeID')});
if (this._changed.has('title')){
sqlColumns.push('title');
sqlValues.push({'string':this.getField('title')});
}
try { try {
Zotero.DB.beginTransaction(); Zotero.DB.beginTransaction();
@ -1065,7 +1042,7 @@ Zotero.Item.prototype.updateNoteCache = function(text){
// Update cached values // Update cached values
this._noteText = text ? text : ''; this._noteText = text ? text : '';
if (this.isNote()){ if (this.isNote()){
this.setField('title', this._noteToTitle(), true); this._noteTitle = this._noteToTitle();
} }
} }
@ -1900,13 +1877,6 @@ Zotero.Item.prototype.clone = function() {
for (var i in obj) { for (var i in obj) {
switch (i) { switch (i) {
// TODO: remove when title is changed to regular field
case 'title':
if (obj.itemType != 'note') {
newItem.setField('title', obj[i]);
}
continue;
case 'creators': case 'creators':
var i = 0; var i = 0;
for each(var c in obj.creators) { for each(var c in obj.creators) {
@ -2176,8 +2146,6 @@ Zotero.Item.prototype.toArray = function(){
// Notes // Notes
if (this.isNote()) { if (this.isNote()) {
// Don't need title for notes
delete arr['title'];
arr['note'] = this.getNote(); arr['note'] = this.getNote();
if (this.getSource()){ if (this.getSource()){
arr['sourceItemID'] = this.getSource(); arr['sourceItemID'] = this.getSource();
@ -2268,24 +2236,14 @@ Zotero.Item.prototype._loadItemData = function(){
throw ('ItemID not set for object before attempting to load data'); throw ('ItemID not set for object before attempting to load data');
} }
var sql = 'SELECT ID.fieldID, value FROM itemData ID JOIN ' var sql = 'SELECT fieldID, value FROM itemData WHERE itemID=?';
+ 'itemTypeFields ITF ON (ITF.itemTypeID=(SELECT itemTypeID FROM ' var fields = Zotero.DB.query(sql, this.getID());
+ 'items WHERE itemID=?1) AND ITF.fieldID=ID.fieldID) '
+ 'WHERE itemID=?1 ORDER BY orderIndex';
var result = Zotero.DB.query(sql,[{'int':this._data['itemID']}]); for each(var field in fields) {
this.setField(field['fieldID'], field['value'], true);
}
this._itemDataLoaded = true; this._itemDataLoaded = true;
if (result){
for (var i=0,len=result.length; i<len; i++){
this.setField(result[i]['fieldID'], result[i]['value'], true);
}
return true;
}
else {
return false;
}
} }
@ -2516,22 +2474,30 @@ Zotero.Items = new function(){
if (arguments[0]){ if (arguments[0]){
sql += ' AND I.itemID IN (' + Zotero.join(arguments,',') + ')'; sql += ' AND I.itemID IN (' + Zotero.join(arguments,',') + ')';
} }
var result = Zotero.DB.query(sql); var itemsRows = Zotero.DB.query(sql);
if (result){ for each(var row in itemsRows) {
for (var i=0,len=result.length; i<len; i++){ // Item doesn't exist -- create new object and stuff in array
// Item doesn't exist -- create new object and stuff in array if (!_items[row['itemID']]){
if (!_items[result[i]['itemID']]){ var item = new Zotero.Item();
var obj = new Zotero.Item(); item.loadFromRow(row);
obj.loadFromRow(result[i]); _items[row['itemID']] = item;
_items[result[i]['itemID']] = obj; }
} // Existing item -- reload in place
// Existing item -- reload in place else {
else { _items[row['itemID']].loadFromRow(row);
_items[result[i]['itemID']].loadFromRow(result[i]);
}
} }
} }
var sql = "SELECT * FROM itemData";
if (arguments[0]) {
sql += " WHERE itemID IN (" + Zotero.join(arguments, ',') + ")";
}
var itemDataRows = Zotero.DB.query(sql);
for each(var row in itemDataRows) {
_items[row['itemID']].setField(row['fieldID'], row['value'], true);
}
return true; return true;
} }
} }
@ -3915,7 +3881,7 @@ Zotero.CharacterSets = new function(){
Zotero.ItemFields = new function(){ Zotero.ItemFields = new function(){
// Private members // Private members
var _fields = []; var _fields = {};
var _fieldsLoaded; var _fieldsLoaded;
var _fieldFormats = []; var _fieldFormats = [];
var _itemTypeFields = []; var _itemTypeFields = [];
@ -3944,7 +3910,12 @@ Zotero.ItemFields = new function(){
if (!_fieldsLoaded){ if (!_fieldsLoaded){
_loadFields(); _loadFields();
} }
return _fields['_' + field] ? _fields['_' + field]['id'] : false;
if (typeof field == 'number') {
return field;
}
return _fields[field] ? _fields[field]['id'] : false;
} }
@ -3955,7 +3926,8 @@ Zotero.ItemFields = new function(){
if (!_fieldsLoaded){ if (!_fieldsLoaded){
_loadFields(); _loadFields();
} }
return _fields['_' + field] ? _fields['_' + field]['name'] : false;
return _fields[field] ? _fields[field]['name'] : false;
} }
@ -3964,7 +3936,6 @@ Zotero.ItemFields = new function(){
// Fields in items are special cases // Fields in items are special cases
switch (field) { switch (field) {
case 'title':
case 'dateAdded': case 'dateAdded':
case 'dateModified': case 'dateModified':
fieldName = field; fieldName = field;
@ -3983,11 +3954,11 @@ Zotero.ItemFields = new function(){
_fieldCheck(fieldID, 'isValidForType'); _fieldCheck(fieldID, 'isValidForType');
if (!_fields['_' + fieldID]['itemTypes']){ if (!_fields[fieldID]['itemTypes']){
return false; return false;
} }
return !!_fields['_' + fieldID]['itemTypes'][itemTypeID]; return !!_fields[fieldID]['itemTypes'][itemTypeID];
} }
@ -3998,7 +3969,7 @@ Zotero.ItemFields = new function(){
_fieldCheck(fieldID, 'isInteger'); _fieldCheck(fieldID, 'isInteger');
var ffid = _fields['_' + fieldID]['formatID']; var ffid = _fields[fieldID]['formatID'];
return _fieldFormats[ffid] ? _fieldFormats[ffid]['isInteger'] : false; return _fieldFormats[ffid] ? _fieldFormats[ffid]['isInteger'] : false;
} }
@ -4032,7 +4003,7 @@ Zotero.ItemFields = new function(){
_fieldCheck(field, arguments.callee.name); _fieldCheck(field, arguments.callee.name);
return _fields['_' + field]['isBaseField']; return _fields[field]['isBaseField'];
} }
@ -4059,28 +4030,16 @@ Zotero.ItemFields = new function(){
} }
var itemTypeID = Zotero.ItemTypes.getID(itemType); var itemTypeID = Zotero.ItemTypes.getID(itemType);
var baseFieldID = this.getID(baseField);
if (!itemTypeID) { if (!itemTypeID) {
throw ("Invalid item type '" + itemType + "' in ItemFields.getFieldIDFromTypeAndBase()"); throw ("Invalid item type '" + itemType + "' in ItemFields.getFieldIDFromTypeAndBase()");
} }
var baseFieldID = this.getID(baseField);
if (!baseFieldID) { if (!baseFieldID) {
throw ("Invalid field '" + baseField + '" for base field in ItemFields.getFieldIDFromTypeAndBase()'); throw ("Invalid field '" + baseField + '" for base field in ItemFields.getFieldIDFromTypeAndBase()');
} }
if (!this.isBaseField(baseFieldID)) { return _baseTypeFields[itemTypeID][baseFieldID];
return false;
}
// If the base field is already valid for the type, just return that
if (this.isValidForType(baseFieldID, itemTypeID)) {
return baseFieldID;
}
return (_baseTypeFields[itemTypeID] &&
_baseTypeFields[itemTypeID][baseFieldID]) ?
_baseTypeFields[itemTypeID][baseFieldID] : false;
} }
@ -4173,16 +4132,38 @@ Zotero.ItemFields = new function(){
} }
/*
* Build a lookup table for base field mappings
*/
function _loadBaseTypeFields() { function _loadBaseTypeFields() {
var sql = "SELECT itemTypeID, baseFieldID, fieldID FROM baseFieldMappings"; // 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"
+ " ON (IT.itemTypeID=BFM.itemTypeID AND F.fieldID=BFM.baseFieldID)";
var rows = Zotero.DB.query(sql); var rows = Zotero.DB.query(sql);
var sql = "SELECT DISTINCT baseFieldID FROM baseFieldMappings";
var baseFields = Zotero.DB.columnQuery(sql);
var fields = []; var fields = [];
for each(var row in rows) { for each(var row in rows) {
if (!fields[row.itemTypeID]) { if (!fields[row.itemTypeID]) {
fields[row.itemTypeID] = []; fields[row.itemTypeID] = [];
} }
fields[row.itemTypeID][row.baseFieldID] = row.fieldID; if (row.fieldID) {
fields[row.itemTypeID][row.baseFieldID] = row.fieldID;
}
// If a base field and already valid for the type, just use that
else if (isBaseField(row.baseFieldID) &&
isValidForType(row.baseFieldID, row.itemTypeID)) {
fields[row.itemTypeID][row.baseFieldID] = row.baseFieldID;
}
// Set false for other fields so that we don't need to test for
// existence
else {
fields[row.itemTypeID][row.baseFieldID] = false;
}
} }
_baseTypeFields = fields; _baseTypeFields = fields;
@ -4193,42 +4174,37 @@ Zotero.ItemFields = new function(){
* Load all fields into an internal hash array * Load all fields into an internal hash array
*/ */
function _loadFields(){ function _loadFields(){
var i,len;
var result = Zotero.DB.query('SELECT * FROM fieldFormats'); var result = Zotero.DB.query('SELECT * FROM fieldFormats');
for (i=0; i<result.length; i++){ for (var i=0; i<result.length; i++){
_fieldFormats[result[i]['fieldFormatID']] = { _fieldFormats[result[i]['fieldFormatID']] = {
regex: result[i]['regex'], regex: result[i]['regex'],
isInteger: result[i]['isInteger'] isInteger: result[i]['isInteger']
}; };
} }
result = Zotero.DB.query('SELECT * FROM fields'); var fields = Zotero.DB.query('SELECT * FROM fields');
if (!result.length){
throw ('No fields in database!');
}
var fieldItemTypes = _getFieldItemTypes(); var fieldItemTypes = _getFieldItemTypes();
_loadBaseTypeFields();
var sql = "SELECT DISTINCT baseFieldID FROM baseFieldMappings"; var sql = "SELECT DISTINCT baseFieldID FROM baseFieldMappings";
var baseFields = Zotero.DB.columnQuery(sql); var baseFields = Zotero.DB.columnQuery(sql);
for (i=0,len=result.length; i<len; i++){ for each(var field in fields){
_fields['_' + result[i]['fieldID']] = { _fields[field['fieldID']] = {
id: result[i]['fieldID'], id: field['fieldID'],
name: result[i]['fieldName'], name: field['fieldName'],
isBaseField: (baseFields.indexOf(result[i]['fieldID']) != -1), isBaseField: (baseFields.indexOf(field['fieldID']) != -1),
formatID: result[i]['fieldFormatID'], formatID: field['fieldFormatID'],
itemTypes: fieldItemTypes[result[i]['fieldID']] itemTypes: fieldItemTypes[field['fieldID']]
}; };
// Store by name as well as id // Store by name as well as id
_fields['_' + result[i]['fieldName']] = _fields['_' + result[i]['fieldID']]; _fields[field['fieldName']] = _fields[field['fieldID']];
} }
_fieldsLoaded = true; _fieldsLoaded = true;
_loadBaseTypeFields();
} }
} }

View File

@ -587,8 +587,21 @@ Zotero.ItemTreeView.prototype.sort = function()
title: true title: true
}; };
// Cache primary values while sorting, since base-field-mapped getField()
// calls are relatively expensive
var cache = [];
function columnSort(a,b) { function columnSort(a,b) {
var cmp; var cmp, fieldA, fieldB;
var aItemID = a.ref.getID();
if (cache[aItemID]) {
fieldA = cache[aItemID];
}
var bItemID = b.ref.getID();
if (cache[bItemID]) {
fieldB = cache[bItemID];
}
switch (columnField) { switch (columnField) {
case 'type': case 'type':
@ -609,12 +622,20 @@ Zotero.ItemTreeView.prototype.sort = function()
break; break;
default: default:
var fieldA = a.getField(columnField, unformatted, true); if (fieldA == undefined) {
var fieldB = b.getField(columnField, unformatted, true); fieldA = a.getField(columnField, unformatted, true);
if (typeof fieldA == 'string') {
fieldA = fieldA.toLowerCase();
}
cache[aItemID] = fieldA;
}
if (typeof fieldA == 'string') { if (fieldB == undefined) {
fieldA = fieldA.toLowerCase(); fieldB = b.getField(columnField, unformatted, true);
fieldB = fieldB.toLowerCase(); if (typeof fieldB == 'string') {
fieldB = fieldB.toLowerCase();
}
cache[bItemID] = fieldB;
} }
// Display rows with empty values last // Display rows with empty values last
@ -650,8 +671,8 @@ Zotero.ItemTreeView.prototype.sort = function()
} }
if (columnField != 'date') { if (columnField != 'date') {
fieldA = a.getField('date', true); fieldA = a.getField('date', true, true);
fieldB = b.getField('date', true); fieldB = b.getField('date', true, true);
// Display rows with empty values last // Display rows with empty values last
cmp = (fieldA == '' && fieldB != '') ? -1 : cmp = (fieldA == '' && fieldB != '') ? -1 :

View File

@ -784,6 +784,18 @@ Zotero.Schema = new function(){
Zotero.DB.query("INSERT OR IGNORE INTO itemData SELECT itemID, 52, value FROM itemData WHERE fieldID IN (14, 52) AND itemID IN (SELECT itemID FROM items WHERE itemTypeID=19) LIMIT 1"); Zotero.DB.query("INSERT OR IGNORE INTO itemData SELECT itemID, 52, value FROM itemData WHERE fieldID IN (14, 52) AND itemID IN (SELECT itemID FROM items WHERE itemTypeID=19) LIMIT 1");
Zotero.DB.query("DELETE FROM itemData WHERE itemID IN (SELECT itemID FROM items WHERE itemTypeID=19) AND fieldID=14"); Zotero.DB.query("DELETE FROM itemData WHERE itemID IN (SELECT itemID FROM items WHERE itemTypeID=19) AND fieldID=14");
} }
if (i==21) {
Zotero.DB.query("INSERT INTO itemData SELECT itemID, 110, title FROM items WHERE title IS NOT NULL AND itemTypeID NOT IN (1,17,20,21)");
Zotero.DB.query("INSERT INTO itemData SELECT itemID, 111, title FROM items WHERE title IS NOT NULL AND itemTypeID = 17");
Zotero.DB.query("INSERT INTO itemData SELECT itemID, 112, title FROM items WHERE title IS NOT NULL AND itemTypeID = 20");
Zotero.DB.query("INSERT INTO itemData SELECT itemID, 113, title FROM items WHERE title IS NOT NULL AND itemTypeID = 21");
Zotero.DB.query("CREATE TEMPORARY TABLE itemsTemp AS SELECT itemID, itemTypeID, dateAdded, dateModified FROM items");
Zotero.DB.query("DROP TABLE items");
Zotero.DB.query("CREATE TABLE IF NOT EXISTS items (\n itemID INTEGER PRIMARY KEY,\n itemTypeID INT,\n dateAdded DATETIME DEFAULT CURRENT_TIMESTAMP,\n dateModified DATETIME DEFAULT CURRENT_TIMESTAMP\n);");
Zotero.DB.query("INSERT INTO items SELECT * FROM itemsTemp");
Zotero.DB.query("DROP TABLE itemsTemp");
}
} }
_updateSchema('userdata'); _updateSchema('userdata');

1015
system.sql

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
-- 20 -- 21
-- This file creates tables containing user-specific data -- any changes -- This file creates tables containing user-specific data -- any changes
-- to existing tables made here must be mirrored in transition steps in -- to existing tables made here must be mirrored in transition steps in
@ -57,7 +57,6 @@ CREATE TABLE IF NOT EXISTS userItemTypeFields (
CREATE TABLE IF NOT EXISTS items ( CREATE TABLE IF NOT EXISTS items (
itemID INTEGER PRIMARY KEY, itemID INTEGER PRIMARY KEY,
itemTypeID INT, itemTypeID INT,
title TEXT,
dateAdded DATETIME DEFAULT CURRENT_TIMESTAMP, dateAdded DATETIME DEFAULT CURRENT_TIMESTAMP,
dateModified DATETIME DEFAULT CURRENT_TIMESTAMP dateModified DATETIME DEFAULT CURRENT_TIMESTAMP
); );