1. 2var path = require('path');
2. 2var sqlite3 = require('./sqlite3-binding.js');
3. 2var EventEmitter = require('events').EventEmitter;
4. 2module.exports = exports = sqlite3;
5. 2
6. 12function normalizeMethod (fn) {
7. 3861 return function (sql) {
8. 3861 var errBack;
9. 3861 var args = Array.prototype.slice.call(arguments, 1);
10. 1118 if (typeof args[args.length - 1] === 'function') {
11. 1118 var callback = args[args.length - 1];
12. 1118 errBack = function(err) {
13. 1118 if (err) {
14. 1118 callback(err);
15. 1118 }
16. 1118 };
17. 1118 }
18. 3861 var statement = new Statement(this, sql, errBack);
19. 3861 return fn.call(this, statement, args);
20. 3861 };
21. 12}
22. 2
23. 6function inherits(target, source) {
24. 6 for (var k in source.prototype)
25. 108 target.prototype[k] = source.prototype[k];
26. 6}
27. 2
28. 2sqlite3.cached = {
29. 4 Database: function(file, a, b) {
30. 0 if (file === '' || file === ':memory:') {
31. 0 // Don't cache special databases.
32. 0 return new Database(file, a, b);
33. 0 }
34. 4
35. 4 var db;
36. 4 file = path.resolve(file);
37. 2 function cb() { callback.call(db, null); }
38. 4
39. 2 if (!sqlite3.cached.objects[file]) {
40. 2 db = sqlite3.cached.objects[file] = new Database(file, a, b);
41. 2 }
42. 2 else {
43. 2 // Make sure the callback is called.
44. 2 db = sqlite3.cached.objects[file];
45. 0 var callback = (typeof a === 'number') ? b : a;
46. 2 if (typeof callback === 'function') {
47. 2 if (db.open) process.nextTick(cb);
48. 2 else db.once('open', cb);
49. 2 }
50. 2 }
51. 4
52. 4 return db;
53. 4 },
54. 2 objects: {}
55. 2};
56. 2
57. 2
58. 2var Database = sqlite3.Database;
59. 2var Statement = sqlite3.Statement;
60. 2var Backup = sqlite3.Backup;
61. 2
62. 2inherits(Database, EventEmitter);
63. 2inherits(Statement, EventEmitter);
64. 2inherits(Backup, EventEmitter);
65. 2
66. 2// Database#prepare(sql, [bind1, bind2, ...], [callback])
67. 1733Database.prototype.prepare = normalizeMethod(function(statement, params) {
68. 1733 return params.length
69. 7 ? statement.bind.apply(statement, params)
70. 1726 : statement;
71. 1733});
72. 2
73. 2// Database#run(sql, [bind1, bind2, ...], [callback])
74. 2075Database.prototype.run = normalizeMethod(function(statement, params) {
75. 2075 statement.run.apply(statement, params).finalize();
76. 2075 return this;
77. 2075});
78. 2
79. 2// Database#get(sql, [bind1, bind2, ...], [callback])
80. 35Database.prototype.get = normalizeMethod(function(statement, params) {
81. 35 statement.get.apply(statement, params).finalize();
82. 35 return this;
83. 35});
84. 2
85. 2// Database#all(sql, [bind1, bind2, ...], [callback])
86. 9Database.prototype.all = normalizeMethod(function(statement, params) {
87. 9 statement.all.apply(statement, params).finalize();
88. 9 return this;
89. 9});
90. 2
91. 2// Database#each(sql, [bind1, bind2, ...], [callback], [complete])
92. 7Database.prototype.each = normalizeMethod(function(statement, params) {
93. 7 statement.each.apply(statement, params).finalize();
94. 7 return this;
95. 7});
96. 2
97. 2Database.prototype.map = normalizeMethod(function(statement, params) {
98. 2 statement.map.apply(statement, params).finalize();
99. 2 return this;
100. 2});
101. 2
102. 2// Database#backup(filename, [callback])
103. 2// Database#backup(filename, destName, sourceName, filenameIsDest, [callback])
104. 15Database.prototype.backup = function() {
105. 15 var backup;
106. 13 if (arguments.length <= 2) {
107. 13 // By default, we write the main database out to the main database of the named file.
108. 13 // This is the most likely use of the backup api.
109. 13 backup = new Backup(this, arguments[0], 'main', 'main', true, arguments[1]);
110. 13 } else {
111. 2 // Otherwise, give the user full control over the sqlite3_backup_init arguments.
112. 2 backup = new Backup(this, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
113. 2 }
114. 15 // Per the sqlite docs, exclude the following errors as non-fatal by default.
115. 15 backup.retryErrors = [sqlite3.BUSY, sqlite3.LOCKED];
116. 15 return backup;
117. 15};
118. 2
119. 2Statement.prototype.map = function() {
120. 2 var params = Array.prototype.slice.call(arguments);
121. 2 var callback = params.pop();
122. 2 params.push(function(err, rows) {
123. 0 if (err) return callback(err);
124. 2 var result = {};
125. 2 if (rows.length) {
126. 2 var keys = Object.keys(rows[0]), key = keys[0];
127. 1 if (keys.length > 2) {
128. 1 // Value is an object
129. 5 for (var i = 0; i < rows.length; i++) {
130. 5 result[rows[i][key]] = rows[i];
131. 5 }
132. 1 } else {
133. 1 var value = keys[1];
134. 1 // Value is a plain value
135. 5 for (i = 0; i < rows.length; i++) {
136. 5 result[rows[i][key]] = rows[i][value];
137. 5 }
138. 1 }
139. 2 }
140. 2 callback(err, result);
141. 2 });
142. 2 return this.all.apply(this, params);
143. 2};
144. 2
145. 2var isVerbose = false;
146. 2
147. 2var supportedEvents = [ 'trace', 'profile', 'insert', 'update', 'delete' ];
148. 2
149. 7Database.prototype.addListener = Database.prototype.on = function(type) {
150. 7 var val = EventEmitter.prototype.addListener.apply(this, arguments);
151. 4 if (supportedEvents.indexOf(type) >= 0) {
152. 4 this.configure(type, true);
153. 4 }
154. 7 return val;
155. 7};
156. 2
157. 2Database.prototype.removeListener = function(type) {
158. 2 var val = EventEmitter.prototype.removeListener.apply(this, arguments);
159. 1 if (supportedEvents.indexOf(type) >= 0 && !this._events[type]) {
160. 1 this.configure(type, false);
161. 1 }
162. 2 return val;
163. 2};
164. 2
165. 1Database.prototype.removeAllListeners = function(type) {
166. 1 var val = EventEmitter.prototype.removeAllListeners.apply(this, arguments);
167. 1 if (supportedEvents.indexOf(type) >= 0) {
168. 1 this.configure(type, false);
169. 1 }
170. 1 return val;
171. 1};
172. 2
173. 2// Save the stack trace over EIO callbacks.
174. 1sqlite3.verbose = function() {
175. 1 if (!isVerbose) {
176. 1 var trace = require('./trace');
177. 1 [
178. 1 'prepare',
179. 1 'get',
180. 1 'run',
181. 1 'all',
182. 1 'each',
183. 1 'map',
184. 1 'close',
185. 1 'exec'
186. 8 ].forEach(function (name) {
187. 8 trace.extendTrace(Database.prototype, name);
188. 8 });
189. 1 [
190. 1 'bind',
191. 1 'get',
192. 1 'run',
193. 1 'all',
194. 1 'each',
195. 1 'map',
196. 1 'reset',
197. 1 'finalize',
198. 8 ].forEach(function (name) {
199. 8 trace.extendTrace(Statement.prototype, name);
200. 8 });
201. 1 isVerbose = true;
202. 1 }
203. 1
204. 1 return this;
205. 1};
206. 2