Lots of DB-related updates:

Moved schema file out of chrome and removed XML tags, since it will no longer be accessed by XMLHTTP

Changed schema updater to use XPCOM components rather than XMLHTTP

Converted DB class to a singleton named Scholar_DB

Scholar_DB.query() now returns associative array similar to mysql_fetch_assoc() for SELECT statements rather than a mozIStorageStatementWrapper -- the mozStorage executeDataSet() function doesn't work yet, so we do it this way

Added DB functions:

   - beginTransaction(), commitTransaction(), rollbackTransaction()
   - columnQuery() -- one column, multiple rows, returned as array indexed by row
   - getColumns() and getColumnHash

DB query functions can now handle bind parameters passed as an array of object literals: e.g. [{'int':2},{'string':'foobar'}]

valueQuery() now returns an int for COUNT(*) queries, so the result can be tested without a "0" being true

Changed _initializeSchema to drop existing tables before creating new ones, hacked with try/catch until DROP TABLE IF EXISTS works with the mozStorage extension (it's already in the latest SQLite release)

Added DB_REBUILD config flag to manually trigger schema regeneration

Added debug logging at level 5 for all SQL queries

Updated sample data
This commit is contained in:
Dan Stillman 2006-03-14 11:34:17 +00:00
parent 2a866fe3cd
commit 50eddb05ee
2 changed files with 308 additions and 118 deletions

View file

@ -1,9 +1,7 @@
var scholarDB = new Scholar_DB();
/* /*
* DB connection and schema management class * DB connection and schema management class
*/ */
function Scholar_DB(){ var Scholar_DB = new function(){
// Private members // Private members
var _connection; var _connection;
@ -11,9 +9,14 @@ function Scholar_DB(){
this.query = query; this.query = query;
this.valueQuery = valueQuery; this.valueQuery = valueQuery;
this.rowQuery = rowQuery; this.rowQuery = rowQuery;
this.columnQuery = columnQuery;
this.statementQuery = statementQuery; this.statementQuery = statementQuery;
this.getColumns = getColumns;
this.getColumnHash = getColumnHash;
this.updateSchema = updateSchema; this.updateSchema = updateSchema;
this.beginTransaction = beginTransaction;
this.commitTransaction = commitTransaction;
this.rollbackTransaction = rollbackTransaction;
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// //
@ -24,33 +27,56 @@ function Scholar_DB(){
/* /*
* Run an SQL query * Run an SQL query
* *
* Optional _params_ is an array of bind parameters in the form
* [{'int':2},{'string':'foobar'}]
*
* Returns: * Returns:
* - mozIStorageStatementWrapper for SELECT's * - Associative array (similar to mysql_fetch_assoc) for SELECT's
* - lastInsertId for INSERT's * - lastInsertId for INSERT's
* - TRUE for other successful queries * - TRUE for other successful queries
* - FALSE on error * - FALSE on error
*/ */
function query(sql){ function query(sql,params){
var db = _getDBConnection(); var db = _getDBConnection();
try { try {
// Parse out the SQL command being used // Parse out the SQL command being used
var op = sql.match(/^[^a-z]*[^ ]+/i).toString().toLowerCase(); var op = sql.match(/^[^a-z]*[^ ]+/i);
if (op){
op = op.toString().toLowerCase();
}
// If SELECT statement, return result // If SELECT statement, return result
if (op=='select'){ if (op=='select'){
var wrapper = // Until the native dataset methods work (or at least exist),
Components.classes['@mozilla.org/storage/statement-wrapper;1'] // we build a multi-dimensional associative array manually
.createInstance(Components.interfaces.mozIStorageStatementWrapper);
wrapper.initialize(db.createStatement(sql)); var statement = statementQuery(sql,params);
return wrapper;
var dataset = new Array();
while (statement.executeStep()){
var row = new Array();
for(var i=0; i<statement.columnCount; i++) {
row[statement.getColumnName(i)] = statement.getAsUTF8String(i);
}
dataset.push(row);
}
statement.reset();
return dataset.length ? dataset : false;
} }
else { else {
db.executeSimpleSQL(sql); if (params){
var statement = statementQuery(sql,params);
statement.execute();
}
else {
Scholar.debug(sql,5);
db.executeSimpleSQL(sql);
}
if (op=='insert'){ if (op=='insert'){
return db.lastInsertId; return db.lastInsertRowID;
} }
// DEBUG: Can't get affected rows for UPDATE or DELETE? // DEBUG: Can't get affected rows for UPDATE or DELETE?
else { else {
@ -58,9 +84,8 @@ function Scholar_DB(){
} }
} }
} }
catch(ex){ catch (e){
alert(db.lastErrorString); throw(e + ' (SQL error: ' + db.lastErrorString + ')');
return false;
} }
} }
@ -68,21 +93,26 @@ function Scholar_DB(){
/* /*
* Query a single value and return it * Query a single value and return it
*/ */
function valueQuery(sql){ function valueQuery(sql,params){
var db = _getDBConnection(); var db = _getDBConnection();
try { try {
var statement = db.createStatement(sql); var statement = statementQuery(sql,params);
} }
catch (e){ catch (e){
alert(db.lastErrorString); throw(db.lastErrorString);
return false;
} }
// No rows // No rows
if (!statement.executeStep()){ if (!statement.executeStep()){
statement.reset();
return false; return false;
} }
var value = statement.getAsUTF8String(0); if (sql.indexOf('SELECT COUNT(*)') > -1){
var value = statement.getAsInt32(0);
}
else {
var value = statement.getAsUTF8String(0);
}
statement.reset(); statement.reset();
return value; return value;
} }
@ -91,29 +121,119 @@ function Scholar_DB(){
/* /*
* Run a query and return the first row * Run a query and return the first row
*/ */
function rowQuery(sql){ function rowQuery(sql,params){
var result = query(sql); var result = query(sql,params);
if (result && result.step()){ if (result){
return result.row; return result[0];
} }
} }
/* /*
* Run a query, returning a mozIStorageStatement for direct manipulation * Run a query and return the first column as a numerically-indexed array
*/ */
function statementQuery(sql){ function columnQuery(sql,params){
var statement = statementQuery(sql,params);
if (statement){
var column = new Array();
while (statement.executeStep()){
column.push(statement.getAsUTF8String(0));
}
statement.reset();
return column.length ? column : false;
}
return false;
}
/*
* Run a query, returning a mozIStorageStatement for direct manipulation
*
* Optional _params_ is an array of bind parameters in the form
* [{'int':2},{'string':'foobar'}]
*/
function statementQuery(sql,params){
var db = _getDBConnection(); var db = _getDBConnection();
try { try {
return db.createStatement(sql); Scholar.debug(sql,5);
var statement = db.createStatement(sql);
} }
catch (e){ catch (e){
throw(db.lastErrorString);
}
if (statement && params){
for (var i=0; i<params.length; i++){
if (typeof params[i]['int'] != 'undefined'){
Scholar.debug('Binding parameter ' + (i+1) + ': ' +
params[i]['int'],5);
statement.bindInt32Parameter(i,params[i]['int']);
}
else if (typeof params[i]['string'] != 'undefined'){
Scholar.debug('Binding parameter ' + (i+1) + ': "' +
params[i]['string'] + '"',5);
statement.bindUTF8StringParameter(i,params[i]['string']);
}
}
}
return statement;
}
function beginTransaction(){
var db = _getDBConnection();
Scholar.debug('Beginning DB transaction',5);
db.beginTransaction();
}
function commitTransaction(){
var db = _getDBConnection();
Scholar.debug('Committing transaction',5);
db.commitTransaction();
}
function rollbackTransaction(){
var db = _getDBConnection();
Scholar.debug('Rolling back transaction',5);
db.rollbackTransaction();
}
function getColumns(table){
var db = _getDBConnection();
try {
var sql = "SELECT * FROM " + table + " LIMIT 1";
var statement = statementQuery(sql);
var cols = new Array();
for (var i=0,len=statement.columnCount; i<len; i++){
cols.push(statement.getColumnName(i));
}
return cols;
}
catch (e){
Scholar.debug(e,1);
return false; return false;
} }
} }
function getColumnHash(table){
var cols = getColumns(table);
var hash = new Array();
if (cols.length){
for (var i=0; i<cols.length; i++){
hash[cols[i]] = true;
}
}
return hash;
}
/* /*
* Checks if the DB schema exists and is up-to-date, updating if necessary * Checks if the DB schema exists and is up-to-date, updating if necessary
*/ */
@ -125,12 +245,17 @@ function Scholar_DB(){
} }
else if (DBVersion < SCHOLAR_CONFIG['DB_VERSION']){ else if (DBVersion < SCHOLAR_CONFIG['DB_VERSION']){
if (!DBVersion){ if (!DBVersion){
dump('Database does not exist -- creating\n'); Scholar.debug('Database does not exist -- creating\n');
return _initializeSchema(); return _initializeSchema();
} }
return _migrateSchema(DBVersion); return _migrateSchema(DBVersion);
} }
else if (SCHOLAR_CONFIG['DB_REBUILD']){
if (confirm('Erase all data and recreate database from schema?')){
return _initializeSchema();
}
}
} }
@ -180,22 +305,42 @@ function Scholar_DB(){
/* /*
* Load in SQL schema * Load in SQL schema
*
* Returns an _array_ of SQL statements for feeding into query()
*/ */
function _getSchemaSQL(){ function _getSchemaSQL(){
// We pull the schema from an external file so we only have to process // We pull the schema from an external file so we only have to process
// it when necessary // it when necessary
var req = new XMLHttpRequest(); var file = Components.classes["@mozilla.org/extensions/manager;1"]
req.open("GET", "chrome://scholar/content/schema.xml", false); .getService(Components.interfaces.nsIExtensionManager)
req.send(null); .getInstallLocation(SCHOLAR_CONFIG['GUID'])
.getItemLocation(SCHOLAR_CONFIG['GUID']);
file.append('schema.sql');
var schemaVersion = // Open an input stream from file
req.responseXML.documentElement.getAttribute('version'); var istream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
istream.init(file, 0x01, 0444, 0);
istream.QueryInterface(Components.interfaces.nsILineInputStream);
var line = {}, sql = '', hasmore;
// Fetch the schema version from the first line of the file
istream.readLine(line);
var schemaVersion = line.value.match(/-- ([0-9]+)/)[1];
do {
hasmore = istream.readLine(line);
sql += line.value + "\n";
} while(hasmore);
istream.close();
if (schemaVersion!=SCHOLAR_CONFIG['DB_VERSION']){ if (schemaVersion!=SCHOLAR_CONFIG['DB_VERSION']){
throw("Scholar config version does not match schema version"); throw("Scholar config version does not match schema version");
} }
return req.responseXML.documentElement.firstChild.data; return sql;
} }
@ -203,10 +348,26 @@ function Scholar_DB(){
* Retrieve the version attribute of the schema SQL XML * Retrieve the version attribute of the schema SQL XML
*/ */
function _getSchemaSQLVersion(){ function _getSchemaSQLVersion(){
var req = new XMLHttpRequest(); var file = Components.classes["@mozilla.org/extensions/manager;1"]
req.open("GET", "chrome://scholar/content/schema.xml", false); .getService(Components.interfaces.nsIExtensionManager)
req.send(null); .getInstallLocation(SCHOLAR_CONFIG['GUID'])
return req.responseXML.documentElement.getAttribute('version'); .getItemLocation(SCHOLAR_CONFIG['GUID']);
file.append('schema.sql');
// Open an input stream from file
var istream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
istream.init(file, 0x01, 0444, 0);
istream.QueryInterface(Components.interfaces.nsILineInputStream);
var line = {};
// Fetch the schema version from the first line of the file
istream.readLine(line);
var schemaVersion = line.value.match(/-- ([0-9]+)/)[1];
istream.close();
return schemaVersion;
} }
@ -214,8 +375,32 @@ function Scholar_DB(){
* Create new DB schema * Create new DB schema
*/ */
function _initializeSchema(){ function _initializeSchema(){
query(_getSchemaSQL()); // Until DROP TABLE IF EXISTS works with the mozStorage extension
query("INSERT INTO version VALUES (" + SCHOLAR_CONFIG['DB_VERSION'] + ")"); try { query('DROP TABLE version'); } catch(e){}
try { query('DROP TABLE objects'); } catch(e){}
try { query('DROP TABLE objectTypes'); } catch(e){}
try { query('DROP TABLE fieldFormats'); } catch(e){}
try { query('DROP TABLE fields'); } catch(e){}
try { query('DROP TABLE objectTypeFields'); } catch(e){}
try { query('DROP TABLE objectData'); } catch(e){}
try { query('DROP TABLE keywords'); } catch(e){}
try { query('DROP TABLE objectKeywords'); } catch(e){}
try { query('DROP TABLE creators'); } catch(e){}
try { query('DROP TABLE creatorTypes'); } catch(e){}
try { query('DROP TABLE objectCreators'); } catch(e){}
try { query('DROP TABLE folders'); } catch(e){}
try {
beginTransaction();
var sql = _getSchemaSQL();
query(sql);
query("INSERT INTO version VALUES (" + SCHOLAR_CONFIG['DB_VERSION'] + ")");
commitTransaction();
}
catch(e){
alert(e);
rollbackTransaction();
}
} }
@ -230,7 +415,7 @@ function Scholar_DB(){
throw("Scholar config version does not match schema version"); throw("Scholar config version does not match schema version");
} }
dump('Updating DB from version ' + fromVersion + ' to ' + toVersion + '\n'); Scholar.debug('Updating DB from version ' + fromVersion + ' to ' + toVersion + '\n');
// Step through version changes until we reach the current version // Step through version changes until we reach the current version
// //
@ -238,9 +423,14 @@ function Scholar_DB(){
// previous revision to that one. // previous revision to that one.
// //
// N.B. Be sure to call _updateDBVersion(i) at the end of each block! // N.B. Be sure to call _updateDBVersion(i) at the end of each block!
for (var i=fromVersion+1; i<=toVersion; i++){ for (var i=parseInt(fromVersion) + 1; i<=toVersion; i++){
if (i==1){ // For now, just wipe and recreate
if (i==2){
_initializeSchema();
}
if (i==3){
// do stuff // do stuff
// _updateDBVersion(i); // _updateDBVersion(i);
} }

View file

@ -1,4 +1,5 @@
<schema version="2"> -- 2
-- IF EXISTS not yet available in available mozStorage binaries, -- IF EXISTS not yet available in available mozStorage binaries,
-- so we fake it with a bunch of try/catches in the _initializeSchema() -- so we fake it with a bunch of try/catches in the _initializeSchema()
@ -11,17 +12,16 @@
CREATE TABLE objects ( CREATE TABLE objects (
objectID INTEGER PRIMARY KEY, objectID INTEGER PRIMARY KEY,
objectTypeID INT, objectTypeID INT,
objectTitle TEXT, title TEXT,
objectDate DATETIME, dateAdded DATETIME DEFAULT CURRENT_TIMESTAMP,
objectDateAdded DATETIME DEFAULT CURRENT_TIMESTAMP, dateModified DATETIME DEFAULT CURRENT_TIMESTAMP,
objectDateModified DATETIME DEFAULT CURRENT_TIMESTAMP, source TEXT,
objectSource TEXT, rights TEXT,
objectRights TEXT,
folderID INT, folderID INT,
orderIndex INT, orderIndex INT,
FOREIGN KEY (folderID) REFERENCES folders(folderID) FOREIGN KEY (folderID) REFERENCES folders(folderID)
); );
CREATE INDEX folderID ON objects (folderID); CREATE INDEX folderID ON objects(folderID);
-- DROP TABLE IF EXISTS objectTypes; -- DROP TABLE IF EXISTS objectTypes;
CREATE TABLE objectTypes ( CREATE TABLE objectTypes (
@ -82,10 +82,11 @@
-- DROP TABLE IF EXISTS creators; -- DROP TABLE IF EXISTS creators;
CREATE TABLE creators ( CREATE TABLE creators (
creatorID INTEGER PRIMARY KEY, creatorID INT,
creatorTypeID INT, creatorTypeID INT DEFAULT 1,
firstName TEXT, firstName TEXT,
lastName TEXT, lastName TEXT,
PRIMARY KEY (creatorID),
FOREIGN KEY (creatorTypeID) REFERENCES creatorTypes(creatorTypeID) FOREIGN KEY (creatorTypeID) REFERENCES creatorTypes(creatorTypeID)
); );
@ -99,7 +100,7 @@
CREATE TABLE objectCreators ( CREATE TABLE objectCreators (
objectID INT, objectID INT,
creatorID INT, creatorID INT,
orderIndex INT DEFAULT 1, orderIndex INT DEFAULT 0,
PRIMARY KEY (objectID, creatorID), PRIMARY KEY (objectID, creatorID),
FOREIGN KEY (objectID) REFERENCES objects(objectID), FOREIGN KEY (objectID) REFERENCES objects(objectID),
FOREIGN KEY (creatorID) REFERENCES creators(creatorID) FOREIGN KEY (creatorID) REFERENCES creators(creatorID)
@ -113,8 +114,8 @@
orderIndex INT, orderIndex INT,
FOREIGN KEY (parentFolderID) REFERENCES folders(folderID) FOREIGN KEY (parentFolderID) REFERENCES folders(folderID)
); );
CREATE INDEX parentFolderID ON folders(parentFolderID);
INSERT INTO folders VALUES (0, 'root', 0, 0);
-- Some sample data -- Some sample data
INSERT INTO objectTypes VALUES (1,'Book'); INSERT INTO objectTypes VALUES (1,'Book');
@ -124,16 +125,16 @@
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,'series',NULL);
INSERT INTO fields VALUES (2,'Volume',NULL); INSERT INTO fields VALUES (2,'volume',NULL);
INSERT INTO fields VALUES (3,'Number',NULL); INSERT INTO fields VALUES (3,'number',NULL);
INSERT INTO fields VALUES (4,'Edition',NULL); INSERT INTO fields VALUES (4,'edition',NULL);
INSERT INTO fields VALUES (5,'Place',NULL); INSERT INTO fields VALUES (5,'place',NULL);
INSERT INTO fields VALUES (6,'Publisher',NULL); INSERT INTO fields VALUES (6,'publisher',NULL);
INSERT INTO fields VALUES (7,'Year',NULL); INSERT INTO fields VALUES (7,'year',3);
INSERT INTO fields VALUES (8,'Pages',NULL); INSERT INTO fields VALUES (8,'pages',2);
INSERT INTO fields VALUES (9,'ISBN',NULL); INSERT INTO fields VALUES (9,'ISBN',NULL);
INSERT INTO fields VALUES (10,'Publication',NULL); INSERT INTO fields VALUES (10,'publication',NULL);
INSERT INTO fields VALUES (11,'ISSN',NULL); INSERT INTO fields VALUES (11,'ISSN',NULL);
INSERT INTO objectTypeFields VALUES (1,1,1); INSERT INTO objectTypeFields VALUES (1,1,1);
@ -150,62 +151,61 @@
INSERT INTO objectTypeFields VALUES (2,3,3); INSERT INTO objectTypeFields VALUES (2,3,3);
INSERT INTO objectTypeFields VALUES (2,8,4); INSERT INTO objectTypeFields VALUES (2,8,4);
INSERT INTO "objects" VALUES(1, 1, 'Online connections: Internet interpersonal relationships', NULL, '2006-03-12 05:24:40', '2006-03-12 05:24:40', NULL, NULL, NULL, NULL); INSERT INTO "objects" VALUES(1, 1, 'Online connections: Internet interpersonal relationships', '2006-03-12 05:24:40', '2006-03-12 05:24:40', NULL, NULL, 0, 5);
INSERT INTO "objects" VALUES(2, 1, 'Computer-Mediated Communication: Human-to-Human Communication Across the Internet', NULL, '2006-03-12 05:25:50', '2006-03-12 05:25:50', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 2);
INSERT INTO "objects" VALUES(3, 2, 'Residential propinquity as a factor in marriage selection', NULL, '2006-03-12 05:26:37', '2006-03-12 05:26:37', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 1);
INSERT INTO "objects" VALUES(4, 1, 'Connecting: how we form social bonds and communities in the Internet age', NULL, '2006-03-12 05:27:15', '2006-03-12 05:27:15', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 4);
INSERT INTO "objects" VALUES(5, 1, 'Male, Female, Email: The Struggle for Relatedness in a Paranoid Society', NULL, '2006-03-12 05:27:36', '2006-03-12 05:27:36', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 3);
INSERT INTO "objects" VALUES(6, 2, 'Social Implications of Sociology', NULL, '2006-03-12 05:27:53', '2006-03-12 05:27:53', NULL, NULL, NULL, NULL); INSERT INTO "objects" VALUES(6, 2, 'Social Implications of Sociology', '2006-03-12 05:27:53', '2006-03-12 05:27:53', NULL, NULL, 0, 7);
INSERT INTO "objects" VALUES(7, 1, 'Social Pressures in Informal Groups: A Study of Human Factors in Housing', NULL, '2006-03-12 05:28:05', '2006-03-12 05:28:05', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 6);
INSERT INTO "objects" VALUES(8, 1, 'Cybersociety 2.0: Revisiting Computer-Mediated Community and Technology', NULL, '2006-03-12 05:28:37', '2006-03-12 05:28:37', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 9);
INSERT INTO "objects" VALUES(9, 2, 'The Computer as a Communication Device', NULL, '2006-03-12 05:29:03', '2006-03-12 05:29:03', NULL, NULL, NULL, NULL); INSERT INTO "objects" VALUES(9, 2, 'The Computer as a Communication Device', '2006-03-12 05:29:03', '2006-03-12 05:29:03', NULL, NULL, 0, 8);
INSERT INTO "objects" VALUES(10, 2, 'What Does Research Say about the Nature of Computer-mediated Communication: Task-Oriented, Social-Emotion-Oriented, or Both?', NULL, '2006-03-12 05:29:12', '2006-03-12 05:29:12', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 13);
INSERT INTO "objects" VALUES(11, 1, 'The second self: computers and the human spirit', NULL, '2006-03-12 05:30:38', '2006-03-12 05:30:38', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 10);
INSERT INTO "objects" VALUES(12, 1, 'Life on the screen: identity in the age of the Internet', NULL, '2006-03-12 05:30:49', '2006-03-12 05:30:49', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 11);
INSERT INTO "objects" VALUES(13, 2, 'The computer conference: An altered state of communication', NULL, '2006-03-12 05:31:00', '2006-03-12 05:31:00', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 12);
INSERT INTO "objects" VALUES(14, 2, 'Computer Networks as Social Networks: Collaborative Work, Telework, and Community', NULL, '2006-03-12 05:31:17', '2006-03-12 05:31:17', NULL, NULL, NULL, NULL); INSERT INTO "objects" 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, 0, 14);
INSERT INTO "objects" VALUES(15, 1, 'The Internet in everyday life', NULL, '2006-03-12 05:31:41', '2006-03-12 05:31:41', NULL, NULL, NULL, NULL); INSERT INTO "objects" VALUES(15, 1, 'The Internet in everyday life', '2006-03-12 05:31:41', '2006-03-12 05:31:41', NULL, NULL, 0, 15);
INSERT INTO "objectData" VALUES(1, 7, 2001); INSERT INTO "objectData" VALUES(1, 7, 2001);
INSERT INTO "objectData" VALUES(1, 5, 'Cresskill, N.J.'); INSERT INTO "objectData" VALUES(1, 5, 'Cresskill, N.J.');
INSERT INTO "objectData" VALUES(1, 6, 'Hampton Press'); INSERT INTO "objectData" VALUES(1, 6, 'Hampton Press');
INSERT INTO "objectData" VALUES(2, 7, 2002); INSERT INTO "objectData" VALUES(2, 7, 2002);
INSERT INTO "objectData" VALUES(2, 6, 'Allyn &amp; Bacon Publishers'); INSERT INTO "objectData" VALUES(2, 6, 'Allyn & Bacon Publishers');
INSERT INTO "objectData" VALUES(2, 8, 347); INSERT INTO "objectData" VALUES(2, 8, 347);
INSERT INTO "objectData" VALUES(2, 9, '0-205-32145-3'); INSERT INTO "objectData" VALUES(2, 9, '0-205-32145-3');
INSERT INTO "creators" VALUES(1, NULL, 'Susan B.', 'Barnes'); INSERT INTO "creators" VALUES(1, 1, 'Susan B.', 'Barnes');
INSERT INTO "creators" VALUES(2, NULL, 'J.S.', 'Bassard'); INSERT INTO "creators" VALUES(2, 1, 'J.S.', 'Bassard');
INSERT INTO "creators" VALUES(3, NULL, 'Mary', 'Chayko'); INSERT INTO "creators" VALUES(3, 1, 'Mary', 'Chayko');
INSERT INTO "creators" VALUES(4, NULL, 'Michael', 'Civin'); INSERT INTO "creators" VALUES(4, 1, 'Michael', 'Civin');
INSERT INTO "creators" VALUES(5, NULL, 'Paul', 'DiMaggio'); INSERT INTO "creators" VALUES(5, 1, 'Paul', 'DiMaggio');
INSERT INTO "creators" VALUES(6, NULL, 'Leon', 'Festinger'); INSERT INTO "creators" VALUES(6, 1, 'Leon', 'Festinger');
INSERT INTO "creators" VALUES(7, NULL, 'Stanley', 'Schachter'); INSERT INTO "creators" VALUES(7, 1, 'Stanley', 'Schachter');
INSERT INTO "creators" VALUES(8, NULL, 'Kurt', 'Back'); INSERT INTO "creators" VALUES(8, 1, 'Kurt', 'Back');
INSERT INTO "creators" VALUES(9, NULL, 'Steven G.', 'Jones'); INSERT INTO "creators" VALUES(9, 1, 'Steven G.', 'Jones');
INSERT INTO "creators" VALUES(10, NULL, 'J.C.R.', 'Licklider'); INSERT INTO "creators" VALUES(10, 1, 'J.C.R.', 'Licklider');
INSERT INTO "creators" VALUES(11, NULL, 'Robert W.', 'Taylor'); INSERT INTO "creators" VALUES(11, 1, 'Robert W.', 'Taylor');
INSERT INTO "creators" VALUES(12, NULL, 'Yuliang', 'Lui'); INSERT INTO "creators" VALUES(12, 1, 'Yuliang', 'Lui');
INSERT INTO "creators" VALUES(13, NULL, 'Sherry', 'Turkle'); INSERT INTO "creators" VALUES(13, 1, 'Sherry', 'Turkle');
INSERT INTO "creators" VALUES(14, NULL, 'J.', 'Vallee'); INSERT INTO "creators" VALUES(14, 1, 'J.', 'Vallee');
INSERT INTO "creators" VALUES(15, NULL, 'Barry', 'Wellman'); INSERT INTO "creators" VALUES(15, 1, 'Barry', 'Wellman');
INSERT INTO "objectCreators" VALUES(1, 1, 1); INSERT INTO "objectCreators" VALUES(1, 1, 0);
INSERT INTO "objectCreators" VALUES(2, 1, 1); INSERT INTO "objectCreators" VALUES(2, 1, 0);
INSERT INTO "objectCreators" VALUES(3, 2, 1); INSERT INTO "objectCreators" VALUES(3, 2, 0);
INSERT INTO "objectCreators" VALUES(4, 3, 1); INSERT INTO "objectCreators" VALUES(4, 3, 0);
INSERT INTO "objectCreators" VALUES(5, 4, 1); INSERT INTO "objectCreators" VALUES(5, 4, 0);
INSERT INTO "objectCreators" VALUES(6, 5, 1); INSERT INTO "objectCreators" VALUES(6, 5, 0);
INSERT INTO "objectCreators" VALUES(7, 6, 1); INSERT INTO "objectCreators" VALUES(7, 6, 0);
INSERT INTO "objectCreators" VALUES(8, 9, 1); INSERT INTO "objectCreators" VALUES(8, 9, 0);
INSERT INTO "objectCreators" VALUES(9, 10, 1); INSERT INTO "objectCreators" VALUES(9, 10, 0);
INSERT INTO "objectCreators" VALUES(10, 12, 1); INSERT INTO "objectCreators" VALUES(10, 12, 0);
INSERT INTO "objectCreators" VALUES(11, 13, 1); INSERT INTO "objectCreators" VALUES(11, 13, 0);
INSERT INTO "objectCreators" VALUES(12, 13, 1); INSERT INTO "objectCreators" VALUES(12, 13, 0);
INSERT INTO "objectCreators" VALUES(13, 14, 1); INSERT INTO "objectCreators" VALUES(13, 14, 0);
INSERT INTO "objectCreators" VALUES(14, 15, 1); INSERT INTO "objectCreators" VALUES(14, 15, 0);
INSERT INTO "objectCreators" VALUES(15, 15, 1); INSERT INTO "objectCreators" VALUES(15, 15, 0);
INSERT INTO "objectCreators" VALUES(7, 7, 2); INSERT INTO "objectCreators" VALUES(7, 7, 1);
INSERT INTO "objectCreators" VALUES(7, 8, 3); INSERT INTO "objectCreators" VALUES(7, 8, 2);
INSERT INTO "objectCreators" VALUES(9, 11, 2); INSERT INTO "objectCreators" VALUES(9, 11, 1);
</schema>