comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:c47ec96326ad
1 // Database
2 function Database(name, dir) {
3 name += '.sqlite';
4
5 var file = Database.getService('@mozilla.org/file/directory_service;1', 'nsIProperties')
6 .get('ProfD', Components.interfaces.nsIFile);
7
8 if (dir) {
9 file.append(dir);
10 if (!file.exists()) {
11 file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
12 }
13 }
14
15 file.append(name);
16
17 this.connection = Database.getService('@mozilla.org/storage/service;1', 'mozIStorageService').openDatabase(file);
18 }
19
20 Database.getService = function(cls, interface) {
21 return Components.classes[cls].getService(Components.interfaces[interface]);
22 }
23
24 Database.bindParams = function(wrapper, params) {
25
26 if (params == null) return;
27
28 // Hash
29 if (typeof(params) == 'object' && params.length == null) {
30 var paramNames = this.getParamNames(wrapper);
31 for each(var name in paramNames) {
32 var param = params[name];
33 if (typeof(param)=='undefined') continue;
34
35 if (param instanceof Date){
36 wrapper.params[name] = param.getTime();
37 continue;
38 }
39
40 wrapper.params[name] = param;
41 }
42 return;
43 }
44
45 // Array
46 if (typeof(params) == 'string' || params.length == null) {
47 params = [].concat(params);
48 }
49
50 var statement = wrapper.statement;
51 for (var i = 0, len = statement.parameterCount; i < len; i++) {
52 statement.bindUTF8StringParameter(i, params[i]);
53 }
54 }
55
56 Database.getParamNames = function(wrapper) {
57 var paramNames = [];
58 var statement = wrapper.statement;
59 for (var i=0, len=statement.parameterCount ; i<len ; i++) {
60 paramNames.push(statement.getParameterName(i).substr(1));
61 }
62 return paramNames;
63 }
64
65 Database.getColumnNames = function(wrapper) {
66 var columnNames=[];
67 statement = wrapper.statement;
68 for ( var i = 0, len = statement.columnCount; i < len; i++) {
69 columnNames.push(statement.getColumnName(i));
70 }
71 return columnNames;
72 }
73
74 Database.getRow = function(row, columnNames){
75 var result = {};
76 for each(var name in columnNames) {
77 result[name] = row[name];
78 }
79 return result;
80 }
81
82 Database.DatabaseException = function(db, exception){
83 this.code = db.connection.lastError;
84 this.message = 'errorCode:' + this.code + '; ' + db.connection.lastErrorString;
85 this.original = exception;
86 }
87
88
89 Database.prototype = {
90 createStatement: function(sql) {
91
92 try {
93 var statement = this.connection.createStatement(sql);
94 var wrapper = Components.classes["@mozilla.org/storage/statement-wrapper;1"]
95 .createInstance(Components.interfaces.mozIStorageStatementWrapper);
96
97 wrapper.initialize(statement);
98 return wrapper;
99 } catch(e) {
100 this.throwException(e);
101 }
102 },
103
104 execute: function(sql, params, handler) {
105 if (typeof(handler) == 'function') {
106 var temp = {};
107 temp.process = handler;
108 handler = temp;
109 }
110
111 var statement = sql.initialize ? sql : this.createStatement(sql);
112 try{
113 Database.bindParams(statement, params);
114
115 if (!handler) {
116 statement.execute();
117 return;
118 }
119
120 var columnNames;
121 while (statement.step()) {
122 if (!columnNames)
123 columnNames = Database.getColumnNames(statement);
124
125 handler.process(statement.row, columnNames);
126 }
127
128 return statement;
129
130 } catch(e if e==StopIteration) {
131 } catch(e) {
132 this.throwException(e);
133 } finally {
134 if (statement)
135 statement.reset();
136 }
137 },
138
139 throwException: function(exception){
140 if (this.connection.lastError != 0) {
141 throw new Database.DatabaseException(this, exception);
142 } else {
143 throw exception;
144 }
145 },
146
147 transaction: function(handler) {
148 var connection = this.connection;
149 var error = false;
150 connection.beginTransaction();
151 try {
152 handler();
153 connection.commitTransaction();
154 } catch(e) {
155 error = true;
156 this.throwException(e);
157 } finally {
158 if(error)
159 connection.rollbackTransaction();
160 }
161 }
162 }
163
164 // ResultArrayHandler
165 function ResultArrayHandler(database, sql) {
166 this.database = database;
167 this.statement = this.database.createStatement(sql);
168 }
169
170 ResultArrayHandler.prototype = {
171 execute: function(params) {
172 this.result = [];
173 this.database.execute(this.statement, params, this);
174 return this.result;
175 },
176
177 createRowResult: function(row, columnNames) {
178 var result = {};
179 for (var i = 0, len = columnNames.length; i < len; i++) {
180 result[columnNames[i]] = row[columnNames[i]];
181 }
182 return result;
183 },
184
185 process: function(row, columnNames) {
186 this.result.push(Database.getRow(row, columnNames));
187 }
188 }
189
190 // UpdateHandler
191 function UpdateHandler(database, sql) {
192 this.database = database;
193 this.statement = this.database.createStatement(sql);
194 }
195
196 UpdateHandler.prototype = {
197 execute: function(params) {
198 if (params && params.constructor == Array) {
199 for (var i = 0, len = params.length; i < len; i++) {
200 this.database.execute(this.statement, params[i], null);
201 }
202 } else {
203 this.database.execute(this.statement, params, null);
204 }
205 }
206 }
207