Updated schema for new collections ("projects"?) model and updated sample data accordingly; added a couple extra indexes; made 'rights' and 'source' regular metadata fields so that items can be used for things like notes
Overhauled data access layer to support new model: - Changed Item.getParent to Item.getCollections() to get ids of parent collections - Removed Item.setPosition() -- item positions are set internally when items are added to and deleted from collections, but the orderIndex is not currently used or manipulatable externally - Item constructor/Items.getNewItemByType()/Items.add() no longer take folderID and orderIndex as parameters - Split getTreeRows() into Scholar.getCollections(parent) and Scholar.getItems(parent), which return root collections or all library items, respectively, if no parent given - All references to folders in object/method/property names changed to collections - New methods Collection.addItem(itemID), Collection.hasItem(itemID), Collection.removeItem(itemID) - Collection.erase() takes optional deleteItems parameter to delete items from DB -- otherwise just removes association and leaves item in library (does, however, delete all descendent collections from DB regardless) * Note: This will break displaying of items until interface code is updated. *
This commit is contained in:
parent
041e607dd7
commit
03637a6c63
|
@ -6,12 +6,9 @@
|
||||||
Scholar.Item = function(){
|
Scholar.Item = function(){
|
||||||
this._init();
|
this._init();
|
||||||
|
|
||||||
// Accept itemTypeID, folderID and orderIndex in constructor
|
// Accept itemTypeIDin constructor
|
||||||
if (arguments.length){
|
if (arguments.length){
|
||||||
this.setType(arguments[0]);
|
this.setType(arguments[0]);
|
||||||
if (arguments.length>1){
|
|
||||||
this.setPosition(arguments[1], arguments[2] ? arguments[2] : false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,20 +39,17 @@ Scholar.Item.prototype._init = function(){
|
||||||
* Check if the specified field is a primary field from the items table
|
* Check if the specified field is a primary field from the items table
|
||||||
*/
|
*/
|
||||||
Scholar.Item.prototype.isPrimaryField = function(field){
|
Scholar.Item.prototype.isPrimaryField = function(field){
|
||||||
|
// Create primaryFields hash array if not yet created
|
||||||
if (!Scholar.Item.primaryFields){
|
if (!Scholar.Item.primaryFields){
|
||||||
Scholar.Item.primaryFields = Scholar.DB.getColumnHash('items');
|
Scholar.Item.primaryFields = Scholar.DB.getColumnHash('items');
|
||||||
Scholar.Item.primaryFields['firstCreator'] = true;
|
Scholar.Item.primaryFields['firstCreator'] = true;
|
||||||
Scholar.Item.primaryFields['parentFolderID'] = true;
|
|
||||||
Scholar.Item.primaryFields['orderIndex'] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!Scholar.Item.primaryFields[field];
|
return !!Scholar.Item.primaryFields[field];
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.Item.editableFields = {
|
Scholar.Item.editableFields = {
|
||||||
title: true,
|
title: true
|
||||||
source: true,
|
|
||||||
rights: true
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -70,14 +64,12 @@ Scholar.Item.prototype.isEditableField = function(field){
|
||||||
* Build object from database
|
* Build object from database
|
||||||
*/
|
*/
|
||||||
Scholar.Item.prototype.loadFromID = function(id){
|
Scholar.Item.prototype.loadFromID = function(id){
|
||||||
var sql = 'SELECT I.*, lastName AS firstCreator, TS.parentFolderID, '
|
var sql = 'SELECT I.*, lastName AS firstCreator '
|
||||||
+ 'TS.orderIndex '
|
|
||||||
+ 'FROM items I '
|
+ 'FROM items I '
|
||||||
+ 'LEFT JOIN treeStructure TS ON (I.itemID=TS.id AND isFolder=0) '
|
|
||||||
+ 'LEFT JOIN itemCreators IC ON (I.itemID=IC.itemID) '
|
+ 'LEFT JOIN itemCreators IC ON (I.itemID=IC.itemID) '
|
||||||
+ 'LEFT JOIN creators C ON (IC.creatorID=C.creatorID) '
|
+ 'LEFT JOIN creators C ON (IC.creatorID=C.creatorID) '
|
||||||
+ 'WHERE itemID=' + id
|
+ 'WHERE itemID=' + id
|
||||||
+ ' AND (IC.orderIndex=0 OR IC.orderIndex IS NULL)';
|
+ ' AND (IC.orderIndex=0 OR IC.orderIndex IS NULL)'; // first creator
|
||||||
var row = Scholar.DB.rowQuery(sql);
|
var row = Scholar.DB.rowQuery(sql);
|
||||||
this.loadFromRow(row);
|
this.loadFromRow(row);
|
||||||
}
|
}
|
||||||
|
@ -89,9 +81,13 @@ Scholar.Item.prototype.loadFromID = function(id){
|
||||||
Scholar.Item.prototype.loadFromRow = function(row){
|
Scholar.Item.prototype.loadFromRow = function(row){
|
||||||
this._init();
|
this._init();
|
||||||
for (col in row){
|
for (col in row){
|
||||||
if (this.isPrimaryField(col) || col=='firstCreator'){
|
// Only accept primary field data through loadFromRow()
|
||||||
|
if (this.isPrimaryField(col)){
|
||||||
this._data[col] = row[col];
|
this._data[col] = row[col];
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Scholar.debug(col + ' is not a valid primary field');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -116,11 +112,6 @@ Scholar.Item.prototype.getType = function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Scholar.Item.prototype.getParent = function(){
|
|
||||||
return this._data['parentFolderID'] ? this._data['parentFolderID'] : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set or change the item's type
|
* Set or change the item's type
|
||||||
*/
|
*/
|
||||||
|
@ -150,6 +141,15 @@ Scholar.Item.prototype.setType = function(itemTypeID){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of collectionIDs for all collections the item belongs to
|
||||||
|
**/
|
||||||
|
Scholar.Item.prototype.getCollections = function(){
|
||||||
|
return Scholar.DB.columnQuery("SELECT collectionID FROM collectionItems "
|
||||||
|
+ "WHERE itemID=" + this.getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the number of creators for this item
|
* Returns the number of creators for this item
|
||||||
*/
|
*/
|
||||||
|
@ -160,6 +160,7 @@ Scholar.Item.prototype.numCreators = function(){
|
||||||
return this._creators.length;
|
return this._creators.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns an array of the creator data at the given position, or false if none
|
* Returns an array of the creator data at the given position, or false if none
|
||||||
*/
|
*/
|
||||||
|
@ -313,89 +314,6 @@ Scholar.Item.prototype.setField = function(field, value, loadIn){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Move item to new position and shift surrounding items
|
|
||||||
*
|
|
||||||
* N.B. Unless isNew is set or the item doesn't yet have an id,
|
|
||||||
* this function updates the DB immediately and
|
|
||||||
* reloads all cached items -- a save() is not required
|
|
||||||
*
|
|
||||||
* If isNew is true, a transaction is not started or committed, so if
|
|
||||||
* the item has an id it should only be run from an existing transaction
|
|
||||||
* within Scholar.Item.save()
|
|
||||||
*/
|
|
||||||
Scholar.Item.prototype.setPosition = function(newFolder, newPos, isNew){
|
|
||||||
var oldFolder = this.getField('parentFolderID');
|
|
||||||
var oldPos = this.getField('orderIndex');
|
|
||||||
|
|
||||||
if (this.getID()){
|
|
||||||
if (!isNew && newFolder==oldFolder && newPos==oldPos){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNew){
|
|
||||||
Scholar.DB.beginTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!newFolder){
|
|
||||||
newFolder = 0;
|
|
||||||
}
|
|
||||||
// Do a foreign key check manually
|
|
||||||
else if (!parseInt(Scholar.DB.valueQuery('SELECT COUNT(*) FROM folders '
|
|
||||||
+ 'WHERE folderID=' + newFolder))){
|
|
||||||
throw('Attempt to add item to invalid folder');
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no position provided, drop at end of folder
|
|
||||||
if (!newPos){
|
|
||||||
newPos = Scholar.DB.valueQuery('SELECT MAX(orderIndex)+1 FROM ' +
|
|
||||||
'treeStructure WHERE parentFolderID=' + newFolder);
|
|
||||||
}
|
|
||||||
// Otherwise shift down above it in old folder and shift up at it or
|
|
||||||
// above it in new folder
|
|
||||||
else {
|
|
||||||
sql = 'UPDATE treeStructure SET orderIndex=orderIndex-1 ' +
|
|
||||||
'WHERE parentFolderID=' + oldFolder +
|
|
||||||
' AND orderIndex>' + oldPos + ";\n";
|
|
||||||
|
|
||||||
sql += 'UPDATE treeStructure SET orderIndex=orderIndex+1 ' +
|
|
||||||
'WHERE parentFolderID=' + newFolder +
|
|
||||||
' AND orderIndex>=' + newPos + ";\n";
|
|
||||||
|
|
||||||
Scholar.DB.query(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a new item, insert
|
|
||||||
if (isNew){
|
|
||||||
var sql = 'INSERT INTO treeStructure '
|
|
||||||
+ '(id, isFolder, orderIndex, parentFolderID) VALUES ('
|
|
||||||
+ this.getID() + ', 0, ' + newPos + ', ' + newFolder + ')';
|
|
||||||
}
|
|
||||||
// Otherwise update
|
|
||||||
else {
|
|
||||||
var sql = 'UPDATE treeStructure SET parentFolderID=' + newFolder +
|
|
||||||
', orderIndex=' + newPos + ' WHERE id=' + this.getID() +
|
|
||||||
" AND isFolder=0;\n";
|
|
||||||
}
|
|
||||||
Scholar.DB.query(sql);
|
|
||||||
|
|
||||||
if (!isNew){
|
|
||||||
Scholar.DB.commitTransaction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._data['parentFolderID'] = newFolder;
|
|
||||||
this._data['orderIndex'] = newPos;
|
|
||||||
|
|
||||||
if (this.getID() && !isNew){
|
|
||||||
Scholar.Items.reloadAll();
|
|
||||||
Scholar.Folders.reloadAll(); // needed to recheck isEmpty
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save changes back to database
|
* Save changes back to database
|
||||||
*/
|
*/
|
||||||
|
@ -428,12 +346,6 @@ Scholar.Item.prototype.save = function(){
|
||||||
if (this._changed.has('title')){
|
if (this._changed.has('title')){
|
||||||
sql += "title='" + this.getField('title') + "', ";
|
sql += "title='" + this.getField('title') + "', ";
|
||||||
}
|
}
|
||||||
if (this._changed.has('source')){
|
|
||||||
sql += "source='" + this.getField('source') + "', ";
|
|
||||||
}
|
|
||||||
if (this._changed.has('rights')){
|
|
||||||
sql += "rights='" + this.getField('rights') + "', ";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always update modified time
|
// Always update modified time
|
||||||
sql += "dateModified=CURRENT_TIMESTAMP ";
|
sql += "dateModified=CURRENT_TIMESTAMP ";
|
||||||
|
@ -583,14 +495,6 @@ Scholar.Item.prototype.save = function(){
|
||||||
sqlColumns.push('title');
|
sqlColumns.push('title');
|
||||||
sqlValues.push({'string':this.getField('title')});
|
sqlValues.push({'string':this.getField('title')});
|
||||||
}
|
}
|
||||||
if (this._changed.has('source')){
|
|
||||||
sqlColumns.push('source');
|
|
||||||
sqlValues.push({'string':this.getField('source')});
|
|
||||||
}
|
|
||||||
if (this._changed.has('rights')){
|
|
||||||
sqlColumns.push('rights');
|
|
||||||
sqlValues.push({'string':this.getField('rights')});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Scholar.DB.beginTransaction();
|
Scholar.DB.beginTransaction();
|
||||||
|
@ -668,20 +572,11 @@ Scholar.Item.prototype.save = function(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the position of the new item
|
|
||||||
var newFolder = this.getField('parentFolderID')
|
|
||||||
? this.getField('parentFolderID') : 0;
|
|
||||||
|
|
||||||
var newPos = this.getField('orderIndex')
|
|
||||||
? this.getField('orderIndex') : false;
|
|
||||||
|
|
||||||
this.setPosition(newFolder, newPos, true);
|
|
||||||
|
|
||||||
Scholar.DB.commitTransaction();
|
Scholar.DB.commitTransaction();
|
||||||
|
|
||||||
// Reload folders to update isEmpty,
|
// Reload collection to update isEmpty,
|
||||||
// in case this was the first item in a folder
|
// in case this was the first item in a collection
|
||||||
Scholar.Folders.reloadAll();
|
Scholar.Collections.reloadAll();
|
||||||
}
|
}
|
||||||
catch (e){
|
catch (e){
|
||||||
Scholar.DB.rollbackTransaction();
|
Scholar.DB.rollbackTransaction();
|
||||||
|
@ -707,15 +602,11 @@ Scholar.Item.prototype.erase = function(){
|
||||||
|
|
||||||
Scholar.DB.beginTransaction();
|
Scholar.DB.beginTransaction();
|
||||||
|
|
||||||
|
// Remove item from parent collections
|
||||||
var parentFolderID = this.getField('parentFolderID');
|
var parentCollectionIDs = this.getCollections();
|
||||||
var orderIndex = this.getField('orderIndex');
|
for (var i=0; i<parentCollectionIDs.length; i++){
|
||||||
|
Scholar.Collections.get(parentCollectionIDs[i]).removeItem(this.getID());
|
||||||
var sql = 'DELETE FROM treeStructure WHERE id=' + this.getID() + ";\n";
|
}
|
||||||
|
|
||||||
sql += 'UPDATE treeStructure SET orderIndex=orderIndex-1 ' +
|
|
||||||
'WHERE parentFolderID=' + parentFolderID +
|
|
||||||
' AND orderIndex>' + orderIndex + ";\n\n";
|
|
||||||
|
|
||||||
sql += 'DELETE FROM itemCreators WHERE itemID=' + this.getID() + ";\n";
|
sql += 'DELETE FROM itemCreators WHERE itemID=' + this.getID() + ";\n";
|
||||||
sql += 'DELETE FROM itemKeywords WHERE itemID=' + this.getID() + ";\n";
|
sql += 'DELETE FROM itemKeywords WHERE itemID=' + this.getID() + ";\n";
|
||||||
|
@ -744,10 +635,6 @@ Scholar.Item.prototype.toString = function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Scholar.Item.prototype.isFolder = function(){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -831,7 +718,6 @@ Scholar.Items = new function(){
|
||||||
// Privileged methods
|
// Privileged methods
|
||||||
this.get = get;
|
this.get = get;
|
||||||
this.getAll = getAll;
|
this.getAll = getAll;
|
||||||
this.getTreeRows = getTreeRows;
|
|
||||||
this.reload = reload;
|
this.reload = reload;
|
||||||
this.reloadAll = reloadAll;
|
this.reloadAll = reloadAll;
|
||||||
this.getNewItemByType = getNewItemByType;
|
this.getNewItemByType = getNewItemByType;
|
||||||
|
@ -887,79 +773,14 @@ Scholar.Items = new function(){
|
||||||
* Returns all items in the database
|
* Returns all items in the database
|
||||||
*/
|
*/
|
||||||
function getAll(){
|
function getAll(){
|
||||||
var sql = 'SELECT I.itemID FROM items I '
|
var sql = 'SELECT itemID FROM items';
|
||||||
+ 'LEFT JOIN treeStructure TS ON (I.itemID=TS.id AND isFolder=0) '
|
// DEBUG: default order?
|
||||||
+ 'ORDER BY orderIndex';
|
|
||||||
|
|
||||||
var ids = Scholar.DB.columnQuery(sql);
|
var ids = Scholar.DB.columnQuery(sql);
|
||||||
return this.get(ids);
|
return this.get(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns an array of all folders and items that are children of a folder
|
|
||||||
* as Scholar.Folder and Scholar.Item instances
|
|
||||||
*
|
|
||||||
* Takes parent folderID as optional parameter; by default, returns root items
|
|
||||||
*
|
|
||||||
* Type can tested with instanceof (e.g. if (obj instanceof Scholar.Folder)) or isFolder()
|
|
||||||
*/
|
|
||||||
function getTreeRows(parent, type){
|
|
||||||
var toReturn = new Array();
|
|
||||||
|
|
||||||
/*
|
|
||||||
// To return all items (no longer used)
|
|
||||||
var sql = 'SELECT * FROM treeStructure WHERE id>0 ORDER BY orderIndex';
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!parent){
|
|
||||||
parent = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var sql = 'SELECT * FROM treeStructure TS '
|
|
||||||
+ 'WHERE parentFolderID=' + parent;
|
|
||||||
|
|
||||||
switch (type){
|
|
||||||
case 'folders':
|
|
||||||
sql += ' AND isFolder=1';
|
|
||||||
break;
|
|
||||||
case 'items':
|
|
||||||
sql += ' AND isFolder=0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sql += ' ORDER BY orderIndex';
|
|
||||||
|
|
||||||
var tree = Scholar.DB.query(sql);
|
|
||||||
|
|
||||||
if (!tree){
|
|
||||||
Scholar.debug('No children of folder ' + parent, 5);
|
|
||||||
return toReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
_load('all');
|
|
||||||
|
|
||||||
for (var i=0, len=tree.length; i<len; i++){
|
|
||||||
if (parseInt(tree[i]['isFolder'])){
|
|
||||||
var obj = Scholar.Folders.get(tree[i]['id']);
|
|
||||||
if (!obj){
|
|
||||||
throw ('Folder ' + tree[i]['id'] + ' not found');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var obj = Scholar.Items.get(tree[i]['id']);
|
|
||||||
if (!obj){
|
|
||||||
throw ('Item ' + tree[i]['id'] + ' not found');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toReturn.push(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
return toReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reloads data for specified items into internal array
|
* Reloads data for specified items into internal array
|
||||||
*
|
*
|
||||||
|
@ -991,15 +812,15 @@ Scholar.Items = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getNewItemByType(itemTypeID, parentFolderID, orderIndex){
|
function getNewItemByType(itemTypeID){
|
||||||
return new Scholar.Item(itemTypeID, parentFolderID, orderIndex);
|
return new Scholar.Item(itemTypeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function add(data, itemTypeID, folderID, orderIndex){
|
function add(data, itemTypeID){
|
||||||
var insert = new Array();
|
var insert = new Array();
|
||||||
|
|
||||||
var obj = new Scholar.Item(itemTypeID, folderID, orderIndex);
|
var obj = new Scholar.Item(itemTypeID);
|
||||||
|
|
||||||
for (field in data){
|
for (field in data){
|
||||||
obj.setField(data[field]);
|
obj.setField(data[field]);
|
||||||
|
@ -1038,10 +859,8 @@ Scholar.Items = new function(){
|
||||||
|
|
||||||
// Should be the same as query in Scholar.Item.loadFromID, just
|
// Should be the same as query in Scholar.Item.loadFromID, just
|
||||||
// without itemID clause
|
// without itemID clause
|
||||||
var sql = 'SELECT I.*, lastName AS firstCreator, TS.parentFolderID, '
|
var sql = 'SELECT I.*, lastName AS firstCreator '
|
||||||
+ 'TS.orderIndex '
|
|
||||||
+ 'FROM items I '
|
+ 'FROM items I '
|
||||||
+ 'LEFT JOIN treeStructure TS ON (I.itemID=TS.id AND isFolder=0) '
|
|
||||||
+ 'LEFT JOIN itemCreators IC ON (I.itemID=IC.itemID) '
|
+ 'LEFT JOIN itemCreators IC ON (I.itemID=IC.itemID) '
|
||||||
+ 'LEFT JOIN creators C ON (IC.creatorID=C.creatorID) '
|
+ 'LEFT JOIN creators C ON (IC.creatorID=C.creatorID) '
|
||||||
+ 'WHERE IC.orderIndex=0 OR IC.orderIndex IS NULL';
|
+ 'WHERE IC.orderIndex=0 OR IC.orderIndex IS NULL';
|
||||||
|
@ -1068,30 +887,33 @@ Scholar.Items = new function(){
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructor for Folder object
|
* Constructor for Collection object
|
||||||
*
|
*
|
||||||
* Generally should be called from Scholar.Folders rather than directly
|
* Generally should be called from Scholar.Collection rather than directly
|
||||||
*/
|
*/
|
||||||
Scholar.Folder = function(){
|
Scholar.Collection = function(){
|
||||||
this._id;
|
this._id;
|
||||||
this._name;
|
this._name;
|
||||||
this._parent;
|
this._parent;
|
||||||
|
this._hasChildCollections;
|
||||||
|
this._hasChildItems;
|
||||||
|
this._childItems = new Scholar.Hash();
|
||||||
|
this._childItemsLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build folder from database
|
* Build collection from database
|
||||||
*/
|
*/
|
||||||
Scholar.Folder.prototype.loadFromID = function(id){
|
Scholar.Collection.prototype.loadFromID = function(id){
|
||||||
// Should be same as query in Scholar.Folders, just with folderID
|
// Should be same as query in Scholar.Collections, just with collectionID
|
||||||
var sql = "SELECT folderID, folderName, parentFolderID, "
|
var sql = "SELECT collectionID, collectionName, parentCollectionID, "
|
||||||
+ "(SELECT COUNT(*) FROM treeStructure WHERE "
|
+ "(SELECT COUNT(*) FROM collections WHERE "
|
||||||
+ "parentFolderID=TS.id AND isFolder=1)!=0 AS hasChildFolders, "
|
+ "parentCollectionID=C.collectionID)!=0 AS hasChildCollections, "
|
||||||
+ "(SELECT COUNT(*) FROM treeStructure WHERE "
|
+ "(SELECT COUNT(*) FROM collectionItems WHERE "
|
||||||
+ "parentFolderID=TS.id AND isFolder=0)!=0 AS hasChildItems "
|
+ "collectionID=C.collectionID)!=0 AS hasChildItems "
|
||||||
+ "FROM folders F "
|
+ "FROM collections C "
|
||||||
+ "JOIN treeStructure TS ON (F.folderID=TS.id AND TS.isFolder=1) "
|
+ "WHERE collectionID=" + id;
|
||||||
+ "WHERE folderID=" + id;
|
|
||||||
|
|
||||||
var row = Scholar.DB.rowQuery(sql);
|
var row = Scholar.DB.rowQuery(sql);
|
||||||
this.loadFromRow(row);
|
this.loadFromRow(row);
|
||||||
|
@ -1099,95 +921,183 @@ Scholar.Folder.prototype.loadFromID = function(id){
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Populate folder data from a database row
|
* Populate collection data from a database row
|
||||||
*/
|
*/
|
||||||
Scholar.Folder.prototype.loadFromRow = function(row){
|
Scholar.Collection.prototype.loadFromRow = function(row){
|
||||||
this._id = row['folderID'];
|
this._id = row['collectionID'];
|
||||||
this._name = row['folderName'];
|
this._name = row['collectionName'];
|
||||||
this._parent = row['parentFolderID'];
|
this._parent = row['parentCollectionID'];
|
||||||
this._hasChildFolders = row['hasChildFolders'];
|
this._hasChildCollections = row['hasChildCollections'];
|
||||||
this._hasChildItems = row['hasChildItems'];
|
this._hasChildItems = row['hasChildItems'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.Folder.prototype.getID = function(){
|
|
||||||
|
Scholar.Collection.prototype.getID = function(){
|
||||||
return this._id;
|
return this._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.Folder.prototype.getName = function(){
|
Scholar.Collection.prototype.getName = function(){
|
||||||
return this._name;
|
return this._name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.Folder.prototype.isFolder = function(){
|
Scholar.Collection.prototype.getParent = function(){
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scholar.Folder.prototype.getParent = function(){
|
|
||||||
return this._parent;
|
return this._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.Folder.prototype.isEmpty = function(){
|
|
||||||
return !(parseInt(this._hasChildFolders)) && !(parseInt(this._hasChildItems));
|
Scholar.Collection.prototype.isEmpty = function(){
|
||||||
|
return !(parseInt(this._hasChildCollections)) && !(parseInt(this._hasChildItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.Folder.prototype.hasChildFolders = function(){
|
Scholar.Collection.prototype.hasChildCollections = function(){
|
||||||
return !!(parseInt(this._hasChildFolders));
|
return !!(parseInt(this._hasChildCollections));
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.Folder.prototype.hasChildItems = function(){
|
Scholar.Collection.prototype.hasChildItems = function(){
|
||||||
return !!(parseInt(this._hasChildItems));
|
return !!(parseInt(this._hasChildItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scholar.Collection.prototype.addItem = function(itemID){
|
||||||
|
Scholar.DB.beginTransaction();
|
||||||
|
|
||||||
|
if (!Scholar.Items.get(itemID)){
|
||||||
|
Scholar.DB.rollbackTransaction();
|
||||||
|
throw(itemID + ' is not a valid item id');
|
||||||
|
}
|
||||||
|
|
||||||
|
var nextOrderIndex = Scholar.DB.valueQuery("SELECT IFNULL(MAX(orderIndex)+1, 0) "
|
||||||
|
+ "FROM collectionItems WHERE collectionID=" + this._id);
|
||||||
|
|
||||||
|
var sql = "INSERT OR IGNORE INTO collectionItems VALUES "
|
||||||
|
+ "(" + this._id + ", " + itemID + ", " + nextOrderIndex + ")";
|
||||||
|
|
||||||
|
Scholar.DB.query(sql);
|
||||||
|
Scholar.DB.commitTransaction();
|
||||||
|
|
||||||
|
this._childItems.set(itemID);
|
||||||
|
this._hasChildItems = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scholar.Collection.prototype.removeItem = function(itemID){
|
||||||
|
Scholar.DB.beginTransaction();
|
||||||
|
|
||||||
|
var sql = "SELECT orderIndex FROM collectionItems "
|
||||||
|
+ "WHERE collectionID=" + this._id + " AND itemID=" + itemID;
|
||||||
|
var orderIndex = Scholar.DB.valueQuery(sql);
|
||||||
|
|
||||||
|
if (orderIndex===false){
|
||||||
|
Scholar.debug('Item ' + itemID + ' is not a child of collection '
|
||||||
|
+ this._id);
|
||||||
|
Scholar.DB.rollbackTransaction();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sql = "DELETE FROM collectionItems WHERE collectionID=" + this._id
|
||||||
|
+ " AND itemID=" + itemID;
|
||||||
|
Scholar.DB.query(sql);
|
||||||
|
|
||||||
|
// Move down items above deleted item in collection
|
||||||
|
sql = 'UPDATE collectionItems SET orderIndex=orderIndex-1 '
|
||||||
|
+ 'WHERE collectionID=' + this._id
|
||||||
|
+ ' AND orderIndex>' + orderIndex;
|
||||||
|
Scholar.DB.query(sql);
|
||||||
|
|
||||||
|
Scholar.DB.commitTransaction();
|
||||||
|
this._childItems.remove(itemID);
|
||||||
|
|
||||||
|
// If this was the last item, set collection to empty
|
||||||
|
if (!this._childItems.length){
|
||||||
|
this._hasChildItems = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Scholar.Collection.prototype.hasItem = function(itemID){
|
||||||
|
if (!this._childItemsLoaded){
|
||||||
|
this._loadChildItems();
|
||||||
|
}
|
||||||
|
return this._childItems.has(itemID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a folder and all descendent folders and items
|
* Deletes a collection and all descendent collections and items
|
||||||
**/
|
**/
|
||||||
Scholar.Folder.prototype.erase = function(){
|
Scholar.Collection.prototype.erase = function(deleteItems){
|
||||||
Scholar.DB.beginTransaction();
|
Scholar.DB.beginTransaction();
|
||||||
|
|
||||||
var descendents = this._getDescendents();
|
var descendents = this._getDescendents();
|
||||||
var folders = new Array(this._id);
|
var collections = new Array(this._id);
|
||||||
|
|
||||||
for(var i=0, len=descendents.length; i<len; i++){
|
for(var i=0, len=descendents.length; i<len; i++){
|
||||||
if (!descendents[i]['isFolder']){
|
// Descendent collections
|
||||||
// Have items delete themselves
|
if (descendents[i]['isCollection']){
|
||||||
Scholar.Items.get(descendents[i]['id']).erase();
|
collections.push(descendents[i]['id']);
|
||||||
}
|
}
|
||||||
|
// Descendent items
|
||||||
else {
|
else {
|
||||||
folders.push(descendents[i]['id']);
|
if (deleteItems){
|
||||||
|
// Delete items from DB
|
||||||
|
Scholar.Items.get(descendents[i]['id']).erase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scholar.DB.query('DELETE FROM folders WHERE folderID IN ('
|
// Remove item associations for all descendent collections
|
||||||
+ folders.join() + ')');
|
Scholar.DB.query('DELETE FROM itemCollections WHERE collectionID IN ('
|
||||||
|
+ collections.join() + ')');
|
||||||
|
|
||||||
Scholar.DB.query('DELETE FROM treeStructure WHERE id IN ('
|
// And delete all descendent collections
|
||||||
+ folders.join() + ') AND isFolder=1');
|
Scholar.DB.query('DELETE FROM collection WHERE collectionID IN ('
|
||||||
|
+ collections.join() + ')');
|
||||||
|
|
||||||
// Clear deleted folder from internal memory
|
// Clear deleted collection from internal memory
|
||||||
Scholar.Folders.unload(folders);
|
Scholar.Collections.unload(collections);
|
||||||
|
|
||||||
Scholar.DB.commitTransaction();
|
Scholar.DB.commitTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Scholar.Collection.prototype._loadChildItems = function(){
|
||||||
|
this._childItems = new Scholar.Hash();
|
||||||
|
|
||||||
|
var sql = "SELECT itemID FROM collectionItems WHERE collectionID=" + this._id;
|
||||||
|
var itemIDs = Scholar.DB.columnQuery(sql);
|
||||||
|
|
||||||
|
if (!itemIDs){
|
||||||
|
Scholar.debug('Collection ' + this._id + ' has no child items');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i<itemIDs.length; i++){
|
||||||
|
this._childItems.set(itemIDs[i]);
|
||||||
|
}
|
||||||
|
this._childItemsLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of descendent folders and items (rows of 'id' and 'isFolder')
|
* Returns an array of descendent collections and items (rows of 'id' and 'isCollection')
|
||||||
**/
|
**/
|
||||||
Scholar.Folder.prototype._getDescendents = function(){
|
Scholar.Collection.prototype._getDescendents = function(){
|
||||||
var toReturn = new Array();
|
var toReturn = new Array();
|
||||||
|
|
||||||
var children = Scholar.DB.query('SELECT id, isFolder FROM treeStructure '
|
var children = Scholar.DB.query('SELECT collectionID AS id, '
|
||||||
+ 'WHERE parentFolderID=' + this._id);
|
+ '1 AS isCollection FROM collections '
|
||||||
|
+ 'WHERE parentCollectionID=' + this._id
|
||||||
|
+ ' UNION SELECT itemID AS id, 0 AS isCollection FROM collectionItems '
|
||||||
|
+ 'WHERE collectionID=' + this._id);
|
||||||
|
|
||||||
for(var i=0, len=children.length; i<len; i++){
|
for(var i=0, len=children.length; i<len; i++){
|
||||||
if (parseInt(children[i]['isFolder'])){
|
if (parseInt(children[i]['isCollection'])){
|
||||||
toReturn.push({
|
toReturn.push({
|
||||||
id: children[i]['id'],
|
id: children[i]['id'],
|
||||||
isFolder: 1
|
isCollection: true
|
||||||
});
|
});
|
||||||
|
|
||||||
var descendents =
|
var descendents =
|
||||||
Scholar.Folders.get(children[i]['id'])._getDescendents();
|
Scholar.Collections.get(children[i]['id'])._getDescendents();
|
||||||
|
|
||||||
for(var j=0, len=descendents.length; j<len; j++){
|
for(var j=0, len=descendents.length; j<len; j++){
|
||||||
toReturn.push(descendents[j]);
|
toReturn.push(descendents[j]);
|
||||||
|
@ -1196,7 +1106,7 @@ Scholar.Folder.prototype._getDescendents = function(){
|
||||||
else {
|
else {
|
||||||
toReturn.push({
|
toReturn.push({
|
||||||
id: children[i]['id'],
|
id: children[i]['id'],
|
||||||
isFolder: 0
|
isCollection: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1206,38 +1116,38 @@ Scholar.Folder.prototype._getDescendents = function(){
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Primary interface for accessing Scholar folders
|
* Primary interface for accessing Scholar collection
|
||||||
*/
|
*/
|
||||||
Scholar.Folders = new function(){
|
Scholar.Collections = new function(){
|
||||||
var _folders = new Array();
|
var _collections = new Array();
|
||||||
var _foldersLoaded = false;
|
var _collectionsLoaded = false;
|
||||||
|
|
||||||
this.get = get;
|
this.get = get;
|
||||||
this.reloadAll = reloadAll;
|
this.reloadAll = reloadAll;
|
||||||
this.unload = unload;
|
this.unload = unload;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a Scholar.Folder object for a folderID
|
* Returns a Scholar.Collection object for a collectionID
|
||||||
*/
|
*/
|
||||||
function get(id){
|
function get(id){
|
||||||
if (!_foldersLoaded){
|
if (!_collectionsLoaded){
|
||||||
_load();
|
_load();
|
||||||
}
|
}
|
||||||
return (typeof _folders[id]!='undefined') ? _folders[id] : false;
|
return (typeof _collections[id]!='undefined') ? _collections[id] : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears internal cache and reloads folder data from DB
|
* Clears internal cache and reloads collection data from DB
|
||||||
**/
|
**/
|
||||||
function reloadAll(){
|
function reloadAll(){
|
||||||
_folders = new Array();
|
_collections = new Array();
|
||||||
_load();
|
_load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear folder from internal cache (used by Scholar.Folder.erase())
|
* Clear collection from internal cache (used by Scholar.Collection.erase())
|
||||||
*
|
*
|
||||||
* Can be passed ids as individual parameters or as an array of ids, or both
|
* Can be passed ids as individual parameters or as an array of ids, or both
|
||||||
**/
|
**/
|
||||||
|
@ -1245,42 +1155,40 @@ Scholar.Folders = new function(){
|
||||||
var ids = Scholar.flattenArguments(arguments);
|
var ids = Scholar.flattenArguments(arguments);
|
||||||
|
|
||||||
for(var i=0; i<ids.length; i++){
|
for(var i=0; i<ids.length; i++){
|
||||||
delete _folders[ids[i]];
|
delete _collections[ids[i]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads folder data from DB and adds to internal cache
|
* Loads collection data from DB and adds to internal cache
|
||||||
**/
|
**/
|
||||||
function _load(){
|
function _load(){
|
||||||
var sql = "SELECT folderID, folderName, parentFolderID, "
|
// This should be the same as the query in Scholar.Collection.loadFromID,
|
||||||
+ "(SELECT COUNT(*) FROM treeStructure WHERE "
|
// just without a specific collectionID
|
||||||
+ "parentFolderID=TS.id AND isFolder=1)!=0 AS hasChildFolders, "
|
var sql = "SELECT collectionID, collectionName, parentCollectionID, "
|
||||||
+ "(SELECT COUNT(*) FROM treeStructure WHERE "
|
+ "(SELECT COUNT(*) FROM collections WHERE "
|
||||||
+ "parentFolderID=TS.id AND isFolder=0)!=0 AS hasChildItems "
|
+ "parentCollectionID=C.collectionID)!=0 AS hasChildCollections, "
|
||||||
+ "FROM folders F "
|
+ "(SELECT COUNT(*) FROM collectionItems WHERE "
|
||||||
+ "JOIN treeStructure TS ON (F.folderID=TS.id AND TS.isFolder=1) "
|
+ "collectionID=C.collectionID)!=0 AS hasChildItems "
|
||||||
+ "WHERE folderID>0"; // skip 'root' folder
|
+ "FROM collections C";
|
||||||
|
|
||||||
var result = Scholar.DB.query(sql);
|
var result = Scholar.DB.query(sql);
|
||||||
|
|
||||||
if (!result){
|
if (!result){
|
||||||
throw ('No folders exist');
|
throw ('No collections exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i=0; i<result.length; i++){
|
for (var i=0; i<result.length; i++){
|
||||||
var folder = new Scholar.Folder();
|
var collection = new Scholar.Collection();
|
||||||
folder.loadFromRow(result[i]);
|
collection.loadFromRow(result[i]);
|
||||||
_folders[folder.getID()] = folder;
|
_collections[collection.getID()] = collection;
|
||||||
}
|
}
|
||||||
_foldersLoaded = true;
|
_collectionsLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Scholar.Creators = new function(){
|
Scholar.Creators = new function(){
|
||||||
var _creators = new Array; // indexed by first%%%last hash
|
var _creators = new Array; // indexed by first%%%last hash
|
||||||
var _creatorsByID = new Array; // indexed by creatorID
|
var _creatorsByID = new Array; // indexed by creatorID
|
||||||
|
@ -1581,18 +1489,87 @@ Scholar.CreatorTypes = new function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
var items = Scholar.Items.getAll();
|
* Scholar.getCollections(parent)
|
||||||
|
*
|
||||||
var obj = items[9];
|
* Returns an array of all collections are children of a collection
|
||||||
for (var i=0,len=obj.numCreators(); i<len; i++){
|
* as Scholar.Collection instances
|
||||||
Scholar.debug(Scholar.varDump(obj.getCreator(i)));
|
*
|
||||||
|
* Takes parent collectionID as optional parameter;
|
||||||
|
* by default, returns root collections
|
||||||
|
*/
|
||||||
|
Scholar.getCollections = function(parent){
|
||||||
|
var toReturn = new Array();
|
||||||
|
|
||||||
|
if (!parent){
|
||||||
|
parent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sql = 'SELECT collectionID FROM collections C WHERE parentCollectionID';
|
||||||
|
sql += parent ? '=' + parent : ' IS NULL';
|
||||||
|
|
||||||
|
sql += ' ORDER BY collectionName';
|
||||||
|
|
||||||
|
var children = Scholar.DB.columnQuery(sql);
|
||||||
|
|
||||||
|
if (!children){
|
||||||
|
Scholar.debug('No child collections of collection ' + parent, 5);
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0, len=children.length; i<len; i++){
|
||||||
|
var obj = Scholar.Collections.get(children[i]);
|
||||||
|
if (!obj){
|
||||||
|
throw ('Collection ' + children[i] + ' not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
toReturn.push(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.setCreator(2,'bob','smith');
|
|
||||||
|
|
||||||
for (var i=0,len=obj.numCreators(); i<len; i++){
|
/*
|
||||||
Scholar.debug(Scholar.varDump(obj.getCreator(i)));
|
* Scholar.getItems(parent)
|
||||||
|
*
|
||||||
|
* Returns an array of all items that are children of a collection--or all
|
||||||
|
* items if no parent provided--as Scholar.Item instances
|
||||||
|
*/
|
||||||
|
Scholar.getItems = function(parent){
|
||||||
|
var toReturn = new Array();
|
||||||
|
|
||||||
|
if (!parent){
|
||||||
|
var sql = 'SELECT itemID FROM items';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var sql = 'SELECT itemID FROM collectionItems '
|
||||||
|
+ 'WHERE collectionID=' + parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
var children = Scholar.DB.columnQuery(sql);
|
||||||
|
|
||||||
|
if (!children){
|
||||||
|
if (!parent){
|
||||||
|
Scholar.debug('No items in library', 5);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Scholar.debug('No child items of collection ' + parent, 5);
|
||||||
|
}
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0, len=children.length; i<len; i++){
|
||||||
|
var obj = Scholar.Items.get(children[i]);
|
||||||
|
if (!obj){
|
||||||
|
throw ('Item ' + children[i] + ' not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
toReturn.push(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
}
|
}
|
||||||
obj.save();
|
|
||||||
*/
|
|
||||||
|
|
|
@ -449,11 +449,13 @@ Scholar.DB = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now, just wipe and recreate
|
// For now, just wipe and recreate
|
||||||
if (i==10){
|
if (i==11){
|
||||||
|
Scholar.DB.query("DROP TABLE IF EXISTS folders; "
|
||||||
|
+ "DROP TABLE IF EXISTS treeStructure;");
|
||||||
_initializeSchema();
|
_initializeSchema();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i==11){
|
if (i==12){
|
||||||
// do stuff
|
// do stuff
|
||||||
// _updateDBVersion(i);
|
// _updateDBVersion(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const SCHOLAR_CONFIG = {
|
const SCHOLAR_CONFIG = {
|
||||||
GUID: 'scholar@chnm.gmu.edu',
|
GUID: 'scholar@chnm.gmu.edu',
|
||||||
DB_FILE: 'scholar.sqlite',
|
DB_FILE: 'scholar.sqlite',
|
||||||
DB_VERSION: 10, // must match version at top of schema.sql
|
DB_VERSION: 11, // must match version at top of schema.sql
|
||||||
DB_REBUILD: false, // erase DB and recreate from schema
|
DB_REBUILD: false, // erase DB and recreate from schema
|
||||||
DEBUG_LOGGING: true,
|
DEBUG_LOGGING: true,
|
||||||
DEBUG_TO_CONSOLE: true // dump debug messages to console rather than (much slower) Debug Logger
|
DEBUG_TO_CONSOLE: true // dump debug messages to console rather than (much slower) Debug Logger
|
||||||
|
|
159
schema.sql
159
schema.sql
|
@ -1,4 +1,4 @@
|
||||||
-- 10
|
-- 11
|
||||||
|
|
||||||
DROP TABLE IF EXISTS version;
|
DROP TABLE IF EXISTS version;
|
||||||
CREATE TABLE version (
|
CREATE TABLE version (
|
||||||
|
@ -11,9 +11,7 @@
|
||||||
itemTypeID INT,
|
itemTypeID INT,
|
||||||
title TEXT,
|
title TEXT,
|
||||||
dateAdded DATETIME DEFAULT CURRENT_TIMESTAMP,
|
dateAdded DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
dateModified DATETIME DEFAULT CURRENT_TIMESTAMP,
|
dateModified DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
source TEXT,
|
|
||||||
rights TEXT
|
|
||||||
);
|
);
|
||||||
|
|
||||||
DROP TABLE IF EXISTS itemTypes;
|
DROP TABLE IF EXISTS itemTypes;
|
||||||
|
@ -57,13 +55,15 @@
|
||||||
FOREIGN KEY (fieldID) REFERENCES fields(fieldID)
|
FOREIGN KEY (fieldID) REFERENCES fields(fieldID)
|
||||||
);
|
);
|
||||||
DROP INDEX IF EXISTS value;
|
DROP INDEX IF EXISTS value;
|
||||||
CREATE INDEX value ON itemData (value);
|
CREATE INDEX value ON itemData(value);
|
||||||
|
|
||||||
DROP TABLE IF EXISTS keywords;
|
DROP TABLE IF EXISTS keywords;
|
||||||
CREATE TABLE keywords (
|
CREATE TABLE keywords (
|
||||||
keywordID INTEGER PRIMARY KEY,
|
keywordID INTEGER PRIMARY KEY,
|
||||||
keyword TEXT
|
keyword TEXT
|
||||||
);
|
);
|
||||||
|
DROP INDEX IF EXISTS keyword;
|
||||||
|
CREATE INDEX keyword ON keywords(keyword);
|
||||||
|
|
||||||
DROP TABLE IF EXISTS itemKeywords;
|
DROP TABLE IF EXISTS itemKeywords;
|
||||||
CREATE TABLE itemKeywords (
|
CREATE TABLE itemKeywords (
|
||||||
|
@ -73,6 +73,8 @@
|
||||||
FOREIGN KEY (itemID) REFERENCES items(itemID),
|
FOREIGN KEY (itemID) REFERENCES items(itemID),
|
||||||
FOREIGN KEY (keywordID) REFERENCES keywords(keywordID)
|
FOREIGN KEY (keywordID) REFERENCES keywords(keywordID)
|
||||||
);
|
);
|
||||||
|
DROP INDEX IF EXISTS keywordID;
|
||||||
|
CREATE INDEX keywordID ON itemKeywords(keywordID);
|
||||||
|
|
||||||
DROP TABLE IF EXISTS creators;
|
DROP TABLE IF EXISTS creators;
|
||||||
CREATE TABLE creators (
|
CREATE TABLE creators (
|
||||||
|
@ -100,26 +102,26 @@
|
||||||
FOREIGN KEY (creatorTypeID) REFERENCES creatorTypes(creatorTypeID)
|
FOREIGN KEY (creatorTypeID) REFERENCES creatorTypes(creatorTypeID)
|
||||||
);
|
);
|
||||||
|
|
||||||
DROP TABLE IF EXISTS folders;
|
DROP TABLE IF EXISTS collections;
|
||||||
CREATE TABLE folders (
|
CREATE TABLE collections (
|
||||||
folderID INT,
|
collectionID INT,
|
||||||
folderName TEXT,
|
collectionName TEXT,
|
||||||
PRIMARY KEY (folderID)
|
parentCollectionID INT,
|
||||||
|
PRIMARY KEY (collectionID),
|
||||||
|
FOREIGN KEY (parentCollectionID) REFERENCES collections(collectionID)
|
||||||
);
|
);
|
||||||
INSERT INTO folders VALUES (0, 'root');
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS treeStructure;
|
DROP TABLE IF EXISTS collectionItems;
|
||||||
CREATE TABLE treeStructure (
|
CREATE TABLE collectionItems (
|
||||||
id INT,
|
collectionID INT,
|
||||||
isFolder INT,
|
itemID INT,
|
||||||
orderIndex INT,
|
orderIndex INT DEFAULT 0,
|
||||||
parentFolderID INT DEFAULT 0,
|
PRIMARY KEY (collectionID, itemID),
|
||||||
PRIMARY KEY (id, isFolder),
|
FOREIGN KEY (collectionID) REFERENCES collections(collectionID),
|
||||||
FOREIGN KEY (parentFolderID) REFERENCES folders(folderID)
|
FOREIGN KEY (itemID) REFERENCES items(itemID)
|
||||||
);
|
);
|
||||||
DROP INDEX IF EXISTS parentFolderID;
|
DROP INDEX IF EXISTS itemID;
|
||||||
CREATE INDEX parentFolderID ON treeStructure(parentFolderID);
|
CREATE INDEX itemID ON collectionItems(itemID);
|
||||||
INSERT INTO treeStructure VALUES (0, 1, 0, NULL);
|
|
||||||
|
|
||||||
-- Some sample data
|
-- Some sample data
|
||||||
INSERT INTO itemTypes VALUES (1,'book');
|
INSERT INTO itemTypes VALUES (1,'book');
|
||||||
|
@ -129,17 +131,19 @@
|
||||||
INSERT INTO "fieldFormats" VALUES(2, '[0-9]*', 1);
|
INSERT INTO "fieldFormats" VALUES(2, '[0-9]*', 1);
|
||||||
INSERT INTO "fieldFormats" VALUES(3, '[0-9]{4}', 1);
|
INSERT INTO "fieldFormats" VALUES(3, '[0-9]{4}', 1);
|
||||||
|
|
||||||
INSERT INTO fields VALUES (1,'series',NULL);
|
INSERT INTO fields VALUES (1,'source',NULL);
|
||||||
INSERT INTO fields VALUES (2,'volume',NULL);
|
INSERT INTO fields VALUES (2,'rights',NULL);
|
||||||
INSERT INTO fields VALUES (3,'number',NULL);
|
INSERT INTO fields VALUES (3,'series',NULL);
|
||||||
INSERT INTO fields VALUES (4,'edition',NULL);
|
INSERT INTO fields VALUES (4,'volume',NULL);
|
||||||
INSERT INTO fields VALUES (5,'place',NULL);
|
INSERT INTO fields VALUES (5,'number',NULL);
|
||||||
INSERT INTO fields VALUES (6,'publisher',NULL);
|
INSERT INTO fields VALUES (6,'edition',NULL);
|
||||||
INSERT INTO fields VALUES (7,'year',3);
|
INSERT INTO fields VALUES (7,'place',NULL);
|
||||||
INSERT INTO fields VALUES (8,'pages',2);
|
INSERT INTO fields VALUES (8,'publisher',NULL);
|
||||||
INSERT INTO fields VALUES (9,'ISBN',NULL);
|
INSERT INTO fields VALUES (9,'year',3);
|
||||||
INSERT INTO fields VALUES (10,'publication',NULL);
|
INSERT INTO fields VALUES (10,'pages',2);
|
||||||
INSERT INTO fields VALUES (11,'ISSN',NULL);
|
INSERT INTO fields VALUES (11,'ISBN',NULL);
|
||||||
|
INSERT INTO fields VALUES (12,'publication',NULL);
|
||||||
|
INSERT INTO fields VALUES (13,'ISSN',NULL);
|
||||||
|
|
||||||
INSERT INTO itemTypeFields VALUES (1,1,1);
|
INSERT INTO itemTypeFields VALUES (1,1,1);
|
||||||
INSERT INTO itemTypeFields VALUES (1,2,2);
|
INSERT INTO itemTypeFields VALUES (1,2,2);
|
||||||
|
@ -150,34 +154,38 @@
|
||||||
INSERT INTO itemTypeFields VALUES (1,7,7);
|
INSERT INTO itemTypeFields VALUES (1,7,7);
|
||||||
INSERT INTO itemTypeFields VALUES (1,8,8);
|
INSERT INTO itemTypeFields VALUES (1,8,8);
|
||||||
INSERT INTO itemTypeFields VALUES (1,9,9);
|
INSERT INTO itemTypeFields VALUES (1,9,9);
|
||||||
INSERT INTO itemTypeFields VALUES (2,10,1);
|
INSERT INTO itemTypeFields VALUES (1,10,10);
|
||||||
|
INSERT INTO itemTypeFields VALUES (1,11,11);
|
||||||
|
INSERT INTO itemTypeFields VALUES (2,1,1);
|
||||||
INSERT INTO itemTypeFields VALUES (2,2,2);
|
INSERT INTO itemTypeFields VALUES (2,2,2);
|
||||||
INSERT INTO itemTypeFields VALUES (2,3,3);
|
INSERT INTO itemTypeFields VALUES (2,12,3);
|
||||||
INSERT INTO itemTypeFields VALUES (2,8,4);
|
INSERT INTO itemTypeFields VALUES (2,4,4);
|
||||||
|
INSERT INTO itemTypeFields VALUES (2,5,5);
|
||||||
|
INSERT INTO itemTypeFields VALUES (2,10,6);
|
||||||
|
|
||||||
INSERT INTO "items" VALUES(1, 1, 'Online connections: Internet interpersonal relationships', '2006-03-12 05:24:40', '2006-03-12 05:24:40', NULL, NULL);
|
INSERT INTO "items" VALUES(1, 1, 'Online connections: Internet interpersonal relationships', '2006-03-12 05:24:40', '2006-03-12 05:24:40');
|
||||||
INSERT INTO "items" VALUES(2, 1, 'Computer-Mediated Communication: Human-to-Human Communication Across the Internet', '2006-03-12 05:25:50', '2006-03-12 05:25:50', NULL, NULL);
|
INSERT INTO "items" VALUES(2, 1, 'Computer-Mediated Communication: Human-to-Human Communication Across the Internet', '2006-03-12 05:25:50', '2006-03-12 05:25:50');
|
||||||
INSERT INTO "items" VALUES(3, 2, 'Residential propinquity as a factor in marriage selection', '2006-03-12 05:26:37', '2006-03-12 05:26:37', NULL, NULL);
|
INSERT INTO "items" VALUES(3, 2, 'Residential propinquity as a factor in marriage selection', '2006-03-12 05:26:37', '2006-03-12 05:26:37');
|
||||||
INSERT INTO "items" VALUES(4, 1, 'Connecting: how we form social bonds and communities in the Internet age', '2006-03-12 05:27:15', '2006-03-12 05:27:15', NULL, NULL);
|
INSERT INTO "items" VALUES(4, 1, 'Connecting: how we form social bonds and communities in the Internet age', '2006-03-12 05:27:15', '2006-03-12 05:27:15');
|
||||||
INSERT INTO "items" VALUES(5, 1, 'Male, Female, Email: The Struggle for Relatedness in a Paranoid Society', '2006-03-12 05:27:36', '2006-03-12 05:27:36', NULL, NULL);
|
INSERT INTO "items" VALUES(5, 1, 'Male, Female, Email: The Struggle for Relatedness in a Paranoid Society', '2006-03-12 05:27:36', '2006-03-12 05:27:36');
|
||||||
INSERT INTO "items" VALUES(6, 2, 'Social Implications of Sociology', '2006-03-12 05:27:53', '2006-03-12 05:27:53', NULL, NULL);
|
INSERT INTO "items" VALUES(6, 2, 'Social Implications of Sociology', '2006-03-12 05:27:53', '2006-03-12 05:27:53');
|
||||||
INSERT INTO "items" VALUES(7, 1, 'Social Pressures in Informal Groups: A Study of Human Factors in Housing', '2006-03-12 05:28:05', '2006-03-12 05:28:05', NULL, NULL);
|
INSERT INTO "items" VALUES(7, 1, 'Social Pressures in Informal Groups: A Study of Human Factors in Housing', '2006-03-12 05:28:05', '2006-03-12 05:28:05');
|
||||||
INSERT INTO "items" VALUES(8, 1, 'Cybersociety 2.0: Revisiting Computer-Mediated Community and Technology', '2006-03-12 05:28:37', '2006-03-12 05:28:37', NULL, NULL);
|
INSERT INTO "items" VALUES(8, 1, 'Cybersociety 2.0: Revisiting Computer-Mediated Community and Technology', '2006-03-12 05:28:37', '2006-03-12 05:28:37');
|
||||||
INSERT INTO "items" VALUES(9, 2, 'The Computer as a Communication Device', '2006-03-12 05:29:03', '2006-03-12 05:29:03', NULL, NULL);
|
INSERT INTO "items" VALUES(9, 2, 'The Computer as a Communication Device', '2006-03-12 05:29:03', '2006-03-12 05:29:03');
|
||||||
INSERT INTO "items" VALUES(10, 2, 'What Does Research Say about the Nature of Computer-mediated Communication: Task-Oriented, Social-Emotion-Oriented, or Both?', '2006-03-12 05:29:12', '2006-03-12 05:29:12', NULL, NULL);
|
INSERT INTO "items" VALUES(10, 2, 'What Does Research Say about the Nature of Computer-mediated Communication: Task-Oriented, Social-Emotion-Oriented, or Both?', '2006-03-12 05:29:12', '2006-03-12 05:29:12');
|
||||||
INSERT INTO "items" VALUES(11, 1, 'The second self: computers and the human spirit', '2006-03-12 05:30:38', '2006-03-12 05:30:38', NULL, NULL);
|
INSERT INTO "items" VALUES(11, 1, 'The second self: computers and the human spirit', '2006-03-12 05:30:38', '2006-03-12 05:30:38');
|
||||||
INSERT INTO "items" VALUES(12, 1, 'Life on the screen: identity in the age of the Internet', '2006-03-12 05:30:49', '2006-03-12 05:30:49', NULL, NULL);
|
INSERT INTO "items" VALUES(12, 1, 'Life on the screen: identity in the age of the Internet', '2006-03-12 05:30:49', '2006-03-12 05:30:49');
|
||||||
INSERT INTO "items" VALUES(13, 2, 'The computer conference: An altered state of communication', '2006-03-12 05:31:00', '2006-03-12 05:31:00', NULL, NULL);
|
INSERT INTO "items" VALUES(13, 2, 'The computer conference: An altered state of communication', '2006-03-12 05:31:00', '2006-03-12 05:31:00');
|
||||||
INSERT INTO "items" VALUES(14, 2, 'Computer Networks as Social Networks: Collaborative Work, Telework, and Community', '2006-03-12 05:31:17', '2006-03-12 05:31:17', NULL, NULL);
|
INSERT INTO "items" VALUES(14, 2, 'Computer Networks as Social Networks: Collaborative Work, Telework, and Community', '2006-03-12 05:31:17', '2006-03-12 05:31:17');
|
||||||
INSERT INTO "items" VALUES(15, 1, 'The Internet in everyday life', '2006-03-12 05:31:41', '2006-03-12 05:31:41', NULL, NULL);
|
INSERT INTO "items" VALUES(15, 1, 'The Internet in everyday life', '2006-03-12 05:31:41', '2006-03-12 05:31:41');
|
||||||
|
|
||||||
INSERT INTO "itemData" VALUES(1, 7, 2001);
|
INSERT INTO "itemData" VALUES(1, 9, 2001);
|
||||||
INSERT INTO "itemData" VALUES(1, 5, 'Cresskill, N.J.');
|
INSERT INTO "itemData" VALUES(1, 7, 'Cresskill, N.J.');
|
||||||
INSERT INTO "itemData" VALUES(1, 6, 'Hampton Press');
|
INSERT INTO "itemData" VALUES(1, 8, 'Hampton Press');
|
||||||
INSERT INTO "itemData" VALUES(2, 7, 2002);
|
INSERT INTO "itemData" VALUES(2, 9, 2002);
|
||||||
INSERT INTO "itemData" VALUES(2, 6, 'Allyn & Bacon Publishers');
|
INSERT INTO "itemData" VALUES(2, 8, 'Allyn & Bacon Publishers');
|
||||||
INSERT INTO "itemData" VALUES(2, 8, 347);
|
INSERT INTO "itemData" VALUES(2, 10, 347);
|
||||||
INSERT INTO "itemData" VALUES(2, 9, '0-205-32145-3');
|
INSERT INTO "itemData" VALUES(2, 11, '0-205-32145-3');
|
||||||
|
|
||||||
INSERT INTO "creatorTypes" VALUES(1, "author");
|
INSERT INTO "creatorTypes" VALUES(1, "author");
|
||||||
INSERT INTO "creatorTypes" VALUES(2, "contributor");
|
INSERT INTO "creatorTypes" VALUES(2, "contributor");
|
||||||
|
@ -218,29 +226,14 @@
|
||||||
INSERT INTO "itemCreators" VALUES(7, 8, 1, 2);
|
INSERT INTO "itemCreators" VALUES(7, 8, 1, 2);
|
||||||
INSERT INTO "itemCreators" VALUES(9, 11, 1, 1);
|
INSERT INTO "itemCreators" VALUES(9, 11, 1, 1);
|
||||||
|
|
||||||
INSERT INTO folders VALUES (1241, 'Test Folder');
|
|
||||||
INSERT INTO folders VALUES (3262, 'Another Test Folder');
|
|
||||||
INSERT INTO folders VALUES (6856, 'Yet Another Folder');
|
|
||||||
INSERT INTO folders VALUES (7373, 'A Subfolder!');
|
|
||||||
INSERT INTO folders VALUES (9233, 'A Sub-subfolder!');
|
|
||||||
|
|
||||||
INSERT INTO treeStructure VALUES (1, 0, 1, 0);
|
INSERT INTO collections VALUES (1241, 'Test Project', NULL);
|
||||||
INSERT INTO treeStructure VALUES (3262, 1, 2, 0);
|
INSERT INTO collections VALUES (3262, 'Another Test Project', NULL);
|
||||||
INSERT INTO treeStructure VALUES (2, 0, 3, 0);
|
INSERT INTO collections VALUES (6856, 'Yet Another Project', NULL);
|
||||||
INSERT INTO treeStructure VALUES (3, 0, 4, 0);
|
INSERT INTO collections VALUES (7373, 'A Sub-project!', 6856);
|
||||||
INSERT INTO treeStructure VALUES (4, 0, 5, 0);
|
INSERT INTO collections VALUES (9233, 'A Sub-sub-project!', 7373);
|
||||||
INSERT INTO treeStructure VALUES (5, 0, 6, 0);
|
|
||||||
INSERT INTO treeStructure VALUES (6, 0, 7, 0);
|
INSERT INTO collectionItems VALUES (6856, 14, 0);
|
||||||
INSERT INTO treeStructure VALUES (7, 0, 8, 0);
|
INSERT INTO collectionItems VALUES (6856, 13, 1);
|
||||||
INSERT INTO treeStructure VALUES (8, 0, 9, 0);
|
INSERT INTO collectionItems VALUES (7373, 15, 0);
|
||||||
INSERT INTO treeStructure VALUES (9, 0, 10, 0);
|
INSERT INTO collectionItems VALUES (1241, 12, 0);
|
||||||
INSERT INTO treeStructure VALUES (6856, 1, 11, 0);
|
|
||||||
INSERT INTO treeStructure VALUES (14, 0, 12, 6856);
|
|
||||||
INSERT INTO treeStructure VALUES (13, 0, 13, 6856);
|
|
||||||
INSERT INTO treeStructure VALUES (7373, 1, 14, 6856);
|
|
||||||
INSERT INTO treeStructure VALUES (15, 0, 15, 7373);
|
|
||||||
INSERT INTO treeStructure VALUES (9233, 1, 16, 7373);
|
|
||||||
INSERT INTO treeStructure VALUES (11, 0, 17, 0);
|
|
||||||
INSERT INTO treeStructure VALUES (10, 0, 18, 0);
|
|
||||||
INSERT INTO treeStructure VALUES (1241, 1, 19, 0);
|
|
||||||
INSERT INTO treeStructure VALUES (12, 0, 20, 1241);
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user