zotero/chrome/chromeFiles/content/scholar/xpcom/schema.js
Dan Stillman d42258b168 Changed schema of scrapers table to use single GUID for scraperID
Assigned guids to scrapers, replaced INSERT queries with REPLACE queries, and removed table DELETE query at top -- this will allow scrapers to be updated without deleting any others that may exist (e.g. that someone is developing, third-party, etc.)
2006-06-12 15:43:24 +00:00

250 lines
6.1 KiB
JavaScript

Scholar.Schema = new function(){
var _dbVersions = [];
var _schemaVersions = [];
this.updateSchema = updateSchema;
/*
* Checks if the DB schema exists and is up-to-date, updating if necessary
*/
function updateSchema(){
var dbVersion = _getDBVersion();
var schemaVersion = _getSchemaSQLVersion();
if (dbVersion == schemaVersion){
if (SCHOLAR_CONFIG['DB_REBUILD']){
if (confirm('Erase all data and recreate database from schema?')){
_initializeSchema();
return;
}
}
_updateScrapers();
return;
}
// If DB version is less than schema file, create or update
else if (dbVersion < schemaVersion){
if (!dbVersion){
Scholar.debug('Database does not exist -- creating\n');
_initializeSchema();
return;
}
_migrateSchema(dbVersion);
_updateScrapers();
return;
}
else {
throw("Scholar DB version is newer than schema version");
}
}
/////////////////////////////////////////////////////////////////
//
// Private methods
//
/////////////////////////////////////////////////////////////////
/*
* Retrieve the DB schema version
*/
function _getDBVersion(schema){
// Default to schema.sql
if (!schema){
schema = 'schema';
}
if (_dbVersions[schema]){
return _dbVersions[schema];
}
if (Scholar.DB.tableExists('version')){
try {
var dbVersion = Scholar.DB.valueQuery("SELECT version FROM "
+ "version WHERE schema='" + schema + "'");
}
// DEBUG: this is temporary to handle version table schema change
catch(e){
if (e=='no such column: schema'){
Scholar.debug(e, 1);
return false;
}
// If some other problem, bail
throw(e);
}
_dbVersions[schema] = dbVersion;
return dbVersion;
}
return false;
}
/*
* Retrieve the version from the top line of the schema SQL file
*/
function _getSchemaSQLVersion(schema){
// Default to schema.sql
if (!schema){
schema = 'schema';
}
var schemaFile = schema + '.sql';
if (_schemaVersions[schema]){
return _schemaVersions[schema];
}
var file = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager)
.getInstallLocation(SCHOLAR_CONFIG['GUID'])
.getItemLocation(SCHOLAR_CONFIG['GUID']);
file.append(schemaFile);
// 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();
_schemaVersions[schema] = schemaVersion;
return schemaVersion;
}
/*
* Load in SQL schema
*
* Returns an _array_ of SQL statements for feeding into query()
*/
function _getSchemaSQL(schema){
// Default to schema.sql
if (!schema){
schema = 'schema';
}
var schemaFile = schema + '.sql';
// We pull the schema from an external file so we only have to process
// it when necessary
var file = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager)
.getInstallLocation(SCHOLAR_CONFIG['GUID'])
.getItemLocation(SCHOLAR_CONFIG['GUID']);
file.append(schemaFile);
// 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 = {}, sql = '', hasmore;
// Skip the first line, which contains the schema version
istream.readLine(line);
//var schemaVersion = line.value.match(/-- ([0-9]+)/)[1];
do {
hasmore = istream.readLine(line);
sql += line.value + "\n";
} while(hasmore);
istream.close();
return sql;
}
/*
* Create new DB schema
*/
function _initializeSchema(){
try {
Scholar.DB.beginTransaction();
Scholar.DB.query(_getSchemaSQL());
Scholar.DB.query("INSERT INTO version VALUES ('schema', "
+ _getSchemaSQLVersion() + ")");
Scholar.DB.query(_getSchemaSQL('scrapers'));
Scholar.DB.query("INSERT INTO version VALUES ('scrapers', "
+ _getSchemaSQLVersion('scrapers') + ")");
Scholar.DB.commitTransaction();
}
catch(e){
alert(e);
Scholar.DB.rollbackTransaction();
}
}
/*
* Update a DB schema version tag in an existing database
*/
function _updateDBVersion(schema, version){
return Scholar.DB.query("UPDATE version SET version=" + version
+ " WHERE schema='" + schema + "'");
}
/*
* Update the scrapers in the DB to the latest bundled versions
*/
function _updateScrapers(){
var dbVersion = _getDBVersion('scrapers');
var schemaVersion = _getSchemaSQLVersion('scrapers');
if (dbVersion == schemaVersion){
return;
}
else if (dbVersion < schemaVersion){
Scholar.DB.beginTransaction();
Scholar.DB.query(_getSchemaSQL('scrapers'));
_updateDBVersion('scrapers', schemaVersion);
Scholar.DB.commitTransaction();
return;
}
else {
throw("Scraper set in DB is newer than schema version");
}
}
/*
* Migrate schema from an older version, preserving data
*/
function _migrateSchema(fromVersion){
//
// Change this value to match the schema version
//
var toVersion = 18;
if (toVersion != _getSchemaSQLVersion()){
throw('Schema version does not match version in _migrateSchema()');
}
Scholar.debug('Updating DB from version ' + fromVersion + ' to ' + toVersion + '\n');
Scholar.DB.beginTransaction();
// 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.
for (var i=parseInt(fromVersion) + 1; i<=toVersion; i++){
if (i==18){
_initializeSchema();
}
}
_updateDBVersion('schema', i-1);
Scholar.DB.commitTransaction();
}
}