0
|
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
|