diff chrome/content/database.js @ 0:c47ec96326ad

initial import
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Fri, 15 Aug 2008 01:57:59 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chrome/content/database.js	Fri Aug 15 01:57:59 2008 +0900
@@ -0,0 +1,207 @@
+// Database
+function Database(name, dir) {
+  name += '.sqlite';
+
+  var file = Database.getService('@mozilla.org/file/directory_service;1', 'nsIProperties')
+               .get('ProfD', Components.interfaces.nsIFile);
+
+  if (dir) {
+    file.append(dir);
+    if (!file.exists()) {
+      file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+    }
+  }
+
+  file.append(name);
+
+  this.connection = Database.getService('@mozilla.org/storage/service;1', 'mozIStorageService').openDatabase(file);
+}
+
+Database.getService = function(cls, interface) {
+  return Components.classes[cls].getService(Components.interfaces[interface]);
+}
+
+Database.bindParams = function(wrapper, params) {
+
+  if (params == null) return;
+
+  // Hash
+  if (typeof(params) == 'object' && params.length == null) {
+    var paramNames = this.getParamNames(wrapper);
+    for each(var name in paramNames) {
+      var param = params[name];
+      if (typeof(param)=='undefined') continue;
+
+      if (param instanceof Date){
+        wrapper.params[name] = param.getTime();
+        continue;
+      }
+
+      wrapper.params[name] = param;
+    }
+    return;
+  }
+
+  // Array
+  if (typeof(params) == 'string' || params.length == null) {
+    params = [].concat(params);
+  }
+
+  var statement = wrapper.statement;
+  for (var i = 0, len = statement.parameterCount; i < len; i++) {
+    statement.bindUTF8StringParameter(i, params[i]);
+  }
+}
+
+Database.getParamNames = function(wrapper) {
+  var paramNames = [];
+  var statement = wrapper.statement;
+  for (var i=0, len=statement.parameterCount ; i<len ; i++) {
+    paramNames.push(statement.getParameterName(i).substr(1));
+  }
+  return paramNames;
+}
+
+Database.getColumnNames = function(wrapper) {
+  var columnNames=[];
+  statement = wrapper.statement;
+  for ( var i = 0, len = statement.columnCount; i < len; i++) {
+    columnNames.push(statement.getColumnName(i));
+  }
+  return columnNames;
+}
+
+Database.getRow = function(row, columnNames){
+  var result = {};
+  for each(var name in columnNames) {
+    result[name] = row[name];
+  }
+  return result;
+}
+
+Database.DatabaseException = function(db, exception){
+  this.code = db.connection.lastError;
+  this.message = 'errorCode:' + this.code + '; ' + db.connection.lastErrorString;
+  this.original = exception;
+}
+
+
+Database.prototype = {
+  createStatement: function(sql) {
+
+    try {
+      var statement = this.connection.createStatement(sql);
+      var wrapper = Components.classes["@mozilla.org/storage/statement-wrapper;1"]
+                      .createInstance(Components.interfaces.mozIStorageStatementWrapper);
+
+      wrapper.initialize(statement);
+      return wrapper;
+    } catch(e) {
+      this.throwException(e);
+    }
+  },
+
+  execute: function(sql, params, handler) {
+    if (typeof(handler) == 'function') {
+      var temp = {};
+      temp.process = handler;
+      handler = temp;
+    }
+
+    var statement = sql.initialize ? sql : this.createStatement(sql);
+    try{
+      Database.bindParams(statement, params);
+
+      if (!handler) {
+        statement.execute();
+        return;
+      }
+
+      var columnNames;
+      while (statement.step()) {
+        if (!columnNames)
+          columnNames = Database.getColumnNames(statement);
+
+        handler.process(statement.row, columnNames);
+      }
+
+      return statement;
+
+    } catch(e if e==StopIteration) {
+    } catch(e) {
+      this.throwException(e);
+    } finally {
+      if (statement)
+        statement.reset();
+    }
+  },
+
+  throwException: function(exception){
+    if (this.connection.lastError != 0) {
+      throw new Database.DatabaseException(this, exception);
+    } else {
+      throw exception;
+    }
+  },
+
+  transaction: function(handler) {
+    var connection = this.connection;
+    var error = false;
+    connection.beginTransaction();
+    try {
+      handler();
+      connection.commitTransaction();
+    } catch(e) {
+      error = true;
+      this.throwException(e);
+    } finally {
+      if(error)
+        connection.rollbackTransaction();
+    }
+  }
+}
+
+// ResultArrayHandler
+function ResultArrayHandler(database, sql) {
+  this.database = database;
+  this.statement = this.database.createStatement(sql);
+}
+
+ResultArrayHandler.prototype = {
+  execute: function(params) {
+    this.result = [];
+    this.database.execute(this.statement, params, this);
+    return this.result;
+  },
+
+  createRowResult: function(row, columnNames) {
+    var result = {};
+    for (var i = 0, len = columnNames.length; i < len; i++) {
+      result[columnNames[i]] = row[columnNames[i]];
+    }
+    return result;
+  },
+
+  process: function(row, columnNames) {
+    this.result.push(Database.getRow(row, columnNames));
+  }
+}
+
+// UpdateHandler
+function UpdateHandler(database, sql) {
+  this.database = database;
+  this.statement = this.database.createStatement(sql);
+}
+
+UpdateHandler.prototype = {
+  execute: function(params) {
+    if (params && params.constructor == Array) {
+      for (var i = 0, len = params.length; i < len; i++) {
+        this.database.execute(this.statement, params[i], null);
+      }
+    } else {
+      this.database.execute(this.statement, params, null);
+    }
+  }
+}
+