www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 9f38337ec7b92aab67db4f053c07109e3282a7b3
Author: Dan Stillman <dstillman@zotero.org>
Date:   Tue, 21 Feb 2006 17:01:06 +0000

Initial import of repository structure, basic extension layout, and functions for DB abstraction and schema maintenance


Diffstat:
Achrome.manifest | 6++++++
Achrome/chromeFiles/content/scholar/db.js | 257+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Achrome/chromeFiles/content/scholar/schema.xml | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Achrome/chromeFiles/content/scholar/scholar.js | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Achrome/chromeFiles/content/scholar/scholar.xul | 14++++++++++++++
Achrome/chromeFiles/content/scholar/test/test.js | 1+
Achrome/chromeFiles/content/scholar/test/test.xul | 18++++++++++++++++++
Achrome/chromeFiles/locale/en-US/scholar/scholar.dtd | 1+
Achrome/chromeFiles/skin/default/scholar/scholar.css | 0
Ainstall.rdf | 17+++++++++++++++++
10 files changed, 452 insertions(+), 0 deletions(-)

diff --git a/chrome.manifest b/chrome.manifest @@ -0,0 +1,6 @@ +content scholar chrome/chromeFiles/content/scholar/ +locale scholar en-US chrome/chromeFiles/locale/en-US/scholar/ +skin scholar default chrome/chromeFiles/skin/default/scholar/ + +overlay chrome://browser/content/browser.xul chrome://scholar/content/scholar.xul +style chrome://browser/content/browser.xul chrome://scholar/skin/scholar.css diff --git a/chrome/chromeFiles/content/scholar/db.js b/chrome/chromeFiles/content/scholar/db.js @@ -0,0 +1,257 @@ +var scholarDB = new Scholar_DB(); + +/* + * DB connection and schema management class + */ +function Scholar_DB(){ + // Private members + var _connection; + + // Privileged methods + this.query = query; + this.valueQuery = valueQuery; + this.rowQuery = rowQuery; + this.statementQuery = statementQuery; + this.updateSchema = updateSchema; + + + ///////////////////////////////////////////////////////////////// + // + // Privileged methods + // + ///////////////////////////////////////////////////////////////// + + /* + * Run an SQL query + * + * Returns: + * - mozIStorageStatementWrapper for SELECT's + * - lastInsertId for INSERT's + * - TRUE for other successful queries + * - FALSE on error + */ + function query(sql){ + var db = _getDBConnection(); + + try { + // Parse out the SQL command being used + var op = sql.match(/^[^a-z]*[^ ]+/i).toString().toLowerCase(); + + // If SELECT statement, return result + if (op=='select'){ + var wrapper = + Components.classes['@mozilla.org/storage/statement-wrapper;1'] + .createInstance(Components.interfaces.mozIStorageStatementWrapper); + + wrapper.initialize(db.createStatement(sql)); + return wrapper; + } + else { + db.executeSimpleSQL(sql); + + if (op=='insert'){ + return db.lastInsertId; + } + // DEBUG: Can't get affected rows for UPDATE or DELETE? + else { + return true; + } + } + } + catch(ex){ + alert(db.lastErrorString); + return false; + } + } + + + /* + * Query a single value and return it + */ + function valueQuery(sql){ + var db = _getDBConnection(); + try { + var statement = db.createStatement(sql); + } + catch (e){ + alert(db.lastErrorString); + return false; + } + + // No rows + if (!statement.executeStep()){ + return false; + } + var value = statement.getAsUTF8String(0); + statement.reset(); + return value; + } + + + /* + * Run a query and return the first row + */ + function rowQuery(sql){ + var result = query(sql); + if (result && result.step()){ + return result.row; + } + } + + + /* + * Run a query, returning a mozIStorageStatement for direct manipulation + */ + function statementQuery(sql){ + var db = _getDBConnection(); + + try { + return db.createStatement(sql); + } + catch (e){ + return false; + } + } + + + /* + * Checks if the DB schema exists and is up-to-date, updating if necessary + */ + function updateSchema(){ + var DBVersion = _getDBVersion(); + + if (DBVersion > SCHOLAR_CONFIG['DB_VERSION']){ + throw("Scholar DB version is newer than config version"); + } + else if (DBVersion < SCHOLAR_CONFIG['DB_VERSION']){ + if (!DBVersion){ + dump('Database does not exist -- creating\n'); + return _initializeSchema(); + } + + return _migrateSchema(DBVersion); + } + } + + + + ///////////////////////////////////////////////////////////////// + // + // Private methods + // + ///////////////////////////////////////////////////////////////// + + /* + * Retrieve a link to the data store + */ + function _getDBConnection(){ + if (_connection){ + return _connection; + } + + // Get the storage service + var store = Components.classes["@mozilla.org/storage/service;1"]. + getService(Components.interfaces.mozIStorageService); + + // Get the profile directory + var file = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("ProfD", Components.interfaces.nsILocalFile); + + // This makes file point to PROFILE_DIR/<scholar database file> + file.append(SCHOLAR_CONFIG['DB_FILE']); + + _connection = store.openDatabase(file); + + return _connection; + } + + + /* + * Retrieve the DB schema version + */ + function _getDBVersion(){ + if (_getDBConnection().tableExists('version')){ + return valueQuery("SELECT version FROM version;"); + } + return false; + } + + + /* + * Load in SQL schema + */ + function _getSchemaSQL(){ + // We pull the schema from an external file so we only have to process + // it when necessary + var req = new XMLHttpRequest(); + req.open("GET", "chrome://scholar/content/schema.xml", false); + req.send(null); + + var schemaVersion = + req.responseXML.documentElement.getAttribute('version'); + + if (schemaVersion!=SCHOLAR_CONFIG['DB_VERSION']){ + throw("Scholar config version does not match schema version"); + } + + return req.responseXML.documentElement.firstChild.data; + } + + + /* + * Retrieve the version attribute of the schema SQL XML + */ + function _getSchemaSQLVersion(){ + var req = new XMLHttpRequest(); + req.open("GET", "chrome://scholar/content/schema.xml", false); + req.send(null); + return req.responseXML.documentElement.getAttribute('version'); + } + + + /* + * Create new DB schema + */ + function _initializeSchema(){ + query(_getSchemaSQL()); + query("INSERT INTO version VALUES (" + SCHOLAR_CONFIG['DB_VERSION'] + ")"); + } + + + /* + * Migrate schema from an older version, preserving data + */ + function _migrateSchema(fromVersion){ + var toVersion = SCHOLAR_CONFIG['DB_VERSION']; + var schemaVersion = _getSchemaSQLVersion(); + + if (toVersion!=schemaVersion){ + throw("Scholar config version does not match schema version"); + } + + dump('Updating DB from version ' + fromVersion + ' to ' + toVersion + '\n'); + + // Step through version changes until we reach the current version + // + // Each block performs the changes necessary to move from the + // previous revision to that one. + // + // N.B. Be sure to call _updateDBVersion(i) at the end of each block! + for (var i=fromVersion+1; i<=toVersion; i++){ + + if (i==1){ + // do stuff + // _updateDBVersion(i); + } + } + } + + + /* + * Update the DB schema version tag of an existing database + */ + function _updateDBVersion(version){ + return query("UPDATE version SET version=" + version); + } +} diff --git a/chrome/chromeFiles/content/scholar/schema.xml b/chrome/chromeFiles/content/scholar/schema.xml @@ -0,0 +1,85 @@ +<schema version="1"> +BEGIN; + CREATE TABLE version ( + version INT PRIMARY KEY + ); + + CREATE TABLE objects ( + objectID INT PRIMARY KEY, + objectTypeID INT, + objectTitle TEXT, + objectDate DATETIME, + objectDateAdded DATETIME DEFAULT CURRENT_TIMESTAMP, + objectDateModified DATETIME DEFAULT CURRENT_TIMESTAMP, + objectSource TEXT, + objectRights TEXT, + parentID INT, + orderIndex INT + ); + CREATE INDEX parentID ON objects (parentID); + + CREATE TABLE objectTypes ( + objectTypeID INT PRIMARY KEY, + typeName TEXT + ); + + CREATE TABLE fields ( + fieldID INT PRIMARY KEY, + fieldName TEXT, + regex TEXT + ); + + CREATE TABLE objectTypeFields ( + objectTypeID, + fieldID INT, + orderIndex INT, + PRIMARY KEY (objectTypeID, fieldID), + FOREIGN KEY (objectTypeID) REFERENCES objectTypes(objectTypeID), + FOREIGN KEY (fieldID) REFERENCES objectTypes(objectTypeID) + ); + + CREATE TABLE objectData ( + objectID INT, + fieldID INT, + value NONE, + PRIMARY KEY (objectID, fieldID), + FOREIGN KEY (objectID) REFERENCES objects(objectID), + FOREIGN KEY (fieldID) REFERENCES fields(fieldID) + ); + CREATE INDEX value ON objectData (value); + + CREATE TABLE keywords ( + keywordID INT PRIMARY KEY, + keyword TEXT + ); + + CREATE TABLE objectKeywords ( + objectID INT, + keywordID INT, + PRIMARY KEY (objectID, keywordID), + FOREIGN KEY (objectID) REFERENCES objects(objectID), + FOREIGN KEY (keywordID) REFERENCES keywords(keywordID) + ); + + CREATE TABLE creators ( + creatorID INT PRIMARY KEY, + firstName TEXT, + lastName TEXT + ); + + CREATE TABLE creatorTypes ( + creatorTypeID INT PRIMARY KEY, + creatorType TEXT + ); + + CREATE TABLE objectCreators ( + objectID INT, + creatorID INT, + creatorTypeID INT, + orderIndex INT, + PRIMARY KEY (objectID, creatorID), + FOREIGN KEY (objectID) REFERENCES objects(objectID), + FOREIGN KEY (creatorID) REFERENCES creators(creatorID) + ); +COMMIT; +</schema> diff --git a/chrome/chromeFiles/content/scholar/scholar.js b/chrome/chromeFiles/content/scholar/scholar.js @@ -0,0 +1,53 @@ +const SCHOLAR_CONFIG = { + DB_FILE : 'scholar.sdb', + DB_VERSION : 1, + DEBUG_LOGGING : true +}; + +/* + * Core functions + */ +var Scholar = { + /* + * Initialize the extension + */ + init: function() { + scholarDB.updateSchema(); + }, + + /* + * Debug logging function + * + * Uses DebugLogger extension available from http://mozmonkey.com/debuglogger/ + * if available, otherwise the console + * + * Defaults to log level 3 if level not provided + */ + debug: function(message, level) { + if (!SCHOLAR_CONFIG['DEBUG_LOGGING']){ + return false; + } + + if (!level){ + level = 3; + } + + try { + var logManager = + Components.classes["@mozmonkey.com/debuglogger/manager;1"] + .getService(Components.interfaces.nsIDebugLoggerManager); + var logger = logManager.registerLogger("Firefox Scholar"); + } + catch (e){} + + if (logger){ + logger.log(level, message); + } + else { + dump('scholar(' + level + '): ' + message); + } + return true; + } +} + +window.addEventListener("load", function(e) { Scholar.init(e); }, false); diff --git a/chrome/chromeFiles/content/scholar/scholar.xul b/chrome/chromeFiles/content/scholar/scholar.xul @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://scholar/skin/scholar.css" type="text/css"?> +<!DOCTYPE window SYSTEM "chrome://scholar/locale/scholar.dtd"> + +<overlay id="scholar" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="scholar.js"/> + <script src="db.js"/> + + <statusbar id="status-bar"> + <statusbarpanel id="my-panel" label="&statusbarpanel.helloworld;"/> + </statusbar> +</overlay> diff --git a/chrome/chromeFiles/content/scholar/test/test.js b/chrome/chromeFiles/content/scholar/test/test.js @@ -0,0 +1 @@ +alert("Hello, world!"); diff --git a/chrome/chromeFiles/content/scholar/test/test.xul b/chrome/chromeFiles/content/scholar/test/test.xul @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://scholar/skin/scholar.css" type="text/css"?> +<!DOCTYPE window SYSTEM "chrome://scholar/locale/scholar.dtd"> + +<window + id="test-window" + title="Test" + orient="horizontal" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + style="padding:2em"> + + <script src="../scholar.js"/> + <script src="../db.js"/> + + <script src="test.js"/> + + <label>I am a test page.</label> +</window> diff --git a/chrome/chromeFiles/locale/en-US/scholar/scholar.dtd b/chrome/chromeFiles/locale/en-US/scholar/scholar.dtd @@ -0,0 +1 @@ +<!ENTITY statusbarpanel.helloworld "Hello, World"> diff --git a/chrome/chromeFiles/skin/default/scholar/scholar.css b/chrome/chromeFiles/skin/default/scholar/scholar.css diff --git a/install.rdf b/install.rdf @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#" + xmlns:NC="http://home.netscape.com/NC-rdf#" + xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <RDF:Description RDF:about="rdf:#$V4RG2" + em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}" + em:minVersion="1.0+" + em:maxVersion="1.5.0.*" /> + <RDF:Description RDF:about="urn:mozilla:install-manifest" + em:id="scholar@chnm" + em:name="Firefox Scholar" + em:version="1.0" + em:creator="Center for History and New Media, George Mason University" + em:homepageURL="http://chnm.gmu.edu"> + <em:targetApplication RDF:resource="rdf:#$V4RG2"/> + </RDF:Description> +</RDF:RDF>