1 | //- JavaScript source code
|
2 |
|
3 | //- defs-sqlite.js ~~
|
4 | //
|
5 | // NOTE: SQL is _not_ a particular strength of mine, and I appreciate input!
|
6 | //
|
7 | // ~~ (c) SRW, 25 Sep 2012
|
8 | // ~~ last updated 21 Mar 2014
|
9 |
|
10 | (function () {
|
11 | ;
|
12 |
|
13 | // Pragmas
|
14 |
|
15 | /*jshint maxparams: 2, quotmark: single, strict: true */
|
16 |
|
17 | /*jslint indent: 4, maxlen: 80, node: true */
|
18 |
|
19 | // Declarations
|
20 |
|
21 | var cluster, sqlite;
|
22 |
|
23 | // Definitions
|
24 |
|
25 | cluster = require('cluster');
|
26 |
|
27 | sqlite = require('sqlite3');
|
28 |
|
29 | // Out-of-scope definitions
|
30 |
|
31 | module.exports = function (options) {
|
32 | // This function needs documentation.
|
33 |
|
34 | var collect_garbage, db, exp_date, get_avar, get_list, set_avar;
|
35 |
|
36 | collect_garbage = function () {
|
37 | // This function needs documentation.
|
38 | var lines, values;
|
39 | lines = 'DELETE FROM avars WHERE (exp_date < $now)';
|
40 | values = {
|
41 | $now: Math.ceil(Date.now() / 1000)
|
42 | };
|
43 | db.run(lines, values, function (err) {
|
44 | // This function needs documentation.
|
45 | if (err !== null) {
|
46 | console.error('Error:', err);
|
47 | return;
|
48 | }
|
49 | console.log('Finished collecting garbage.');
|
50 | return;
|
51 | });
|
52 | return;
|
53 | };
|
54 |
|
55 | db = new sqlite.cached.Database(options.sqlite, function (err) {
|
56 | // This function needs documentation.
|
57 | if (err !== null) {
|
58 | throw err;
|
59 | }
|
60 | if (cluster.isWorker) {
|
61 | return;
|
62 | }
|
63 | var lines = [
|
64 | 'CREATE TABLE IF NOT EXISTS avars (',
|
65 | ' body TEXT NOT NULL,',
|
66 | ' box_key TEXT NOT NULL,',
|
67 | ' box_status TEXT,',
|
68 | ' exp_date INTEGER NOT NULL,',
|
69 | ' key TEXT,', //- this doesn't need to be "NOT NULL"
|
70 | ' PRIMARY KEY (box_key)',
|
71 | ')'
|
72 | ];
|
73 | db.run(lines.join('\n'), function (err) {
|
74 | // This function needs documentation.
|
75 | if (err !== null) {
|
76 | throw err;
|
77 | }
|
78 | var query;
|
79 | query = 'CREATE INDEX IF NOT EXISTS idx_avars_box_status' +
|
80 | ' ON avars (box_status)';
|
81 | db.run(query, function (err) {
|
82 | // This function needs documentation.
|
83 | if (err !== null) {
|
84 | throw err;
|
85 | }
|
86 | console.log('API: SQLite storage is ready.');
|
87 | return;
|
88 | });
|
89 | return;
|
90 | });
|
91 | return;
|
92 | });
|
93 |
|
94 | exp_date = function () {
|
95 | // This function needs documentation.
|
96 | return Math.ceil((Date.now() / 1000) + options.avar_ttl);
|
97 | };
|
98 |
|
99 | get_avar = function (params, callback) {
|
100 | // This function needs documentation.
|
101 | var box_key, sql;
|
102 | box_key = params[0] + '&' + params[1];
|
103 | sql = 'SELECT body FROM avars WHERE box_key = $box_key';
|
104 | db.get(sql, {$box_key: box_key}, function (err, row) {
|
105 | // This function needs documentation.
|
106 | if (err !== null) {
|
107 | if (err.errno === 5) {
|
108 | process.nextTick(function () {
|
109 | // This function needs documentation.
|
110 | return get_avar(params, callback);
|
111 | });
|
112 | return;
|
113 | }
|
114 | return callback(err, row);
|
115 | }
|
116 | return callback(null, (row === undefined) ? row : row.body);
|
117 | });
|
118 | return;
|
119 | };
|
120 |
|
121 | get_list = function (params, callback) {
|
122 | // This function needs documentation.
|
123 | var box_status, sql;
|
124 | box_status = params[0] + '&' + params[1];
|
125 | sql = 'SELECT key FROM avars WHERE box_status = $box_status';
|
126 | db.all(sql, {$box_status: box_status}, function (err, rows) {
|
127 | // This function needs documentation.
|
128 | if (err !== null) {
|
129 | if (err.errno === 5) {
|
130 | process.nextTick(function () {
|
131 | // This function needs documentation.
|
132 | return get_list(params, callback);
|
133 | });
|
134 | return;
|
135 | }
|
136 | return callback(err, rows);
|
137 | }
|
138 | if (rows === undefined) {
|
139 | return callback(null, rows);
|
140 | }
|
141 | return callback(null, rows.map(function (row) {
|
142 | // This function needs documentation.
|
143 | return row.key;
|
144 | }));
|
145 | });
|
146 | return;
|
147 | };
|
148 |
|
149 | set_avar = function (params, callback) {
|
150 | // This function needs documentation.
|
151 | var lines, values;
|
152 | if (params.length === 4) {
|
153 | lines = [
|
154 | 'INSERT OR REPLACE INTO avars ' +
|
155 | '(body, box_key, box_status, exp_date, key)',
|
156 | ' VALUES ($body, ' +
|
157 | ' $box_key,' +
|
158 | ' $box_status,' +
|
159 | ' $exp_date,' +
|
160 | ' $key)'
|
161 | ];
|
162 | values = {
|
163 | $body: params[3],
|
164 | $box_key: params[0] + '&' + params[1],
|
165 | $box_status: params[0] + '&' + params[2],
|
166 | $exp_date: exp_date(),
|
167 | $key: params[1]
|
168 | };
|
169 | } else {
|
170 | lines = [
|
171 | 'INSERT OR REPLACE INTO avars ' +
|
172 | '(body, box_key, exp_date)',
|
173 | ' VALUES ($body, $box_key, $exp_date)'
|
174 | ];
|
175 | values = {
|
176 | $body: params[2],
|
177 | $box_key: params[0] + '&' + params[1],
|
178 | $exp_date: exp_date()
|
179 | };
|
180 | }
|
181 | db.run(lines.join('\n'), values, function (err) {
|
182 | // This function needs documentation.
|
183 | if (err !== null) {
|
184 | if (err.errno === 5) {
|
185 | process.nextTick(function () {
|
186 | // This function needs documentation.
|
187 | return set_avar(params, callback);
|
188 | });
|
189 | return;
|
190 | }
|
191 | return callback(err);
|
192 | }
|
193 | return callback(null);
|
194 | });
|
195 | return;
|
196 | };
|
197 |
|
198 | return {
|
199 | collect_garbage: collect_garbage,
|
200 | get_avar: get_avar,
|
201 | get_list: get_list,
|
202 | set_avar: set_avar
|
203 | };
|
204 | };
|
205 |
|
206 | // That's all, folks!
|
207 |
|
208 | return;
|
209 |
|
210 | }());
|
211 |
|
212 | //- vim:set syntax=javascript:
|