15
15
* limitations under the License.
16
16
*/
17
17
18
- const async = require ( 'async ' ) ;
18
+ const util = require ( 'util ' ) ;
19
19
20
20
exports . Database = function ( settings ) {
21
21
// temp hack needs a proper fix..
@@ -50,6 +50,15 @@ exports.Database = function (settings) {
50
50
this . settings . json = true ;
51
51
} ;
52
52
53
+ exports . Database . prototype . _query = async function ( ...args ) {
54
+ return await new Promise ( ( resolve , reject ) => {
55
+ this . db . query ( ...args , ( err , ...args ) => {
56
+ if ( err != null ) return reject ( err ) ;
57
+ resolve ( args ) ;
58
+ } ) ;
59
+ } ) ;
60
+ } ;
61
+
53
62
exports . Database . prototype . clearPing = function ( ) {
54
63
if ( this . interval ) {
55
64
clearInterval ( this . interval ) ;
@@ -68,6 +77,10 @@ exports.Database.prototype.schedulePing = function () {
68
77
} ;
69
78
70
79
exports . Database . prototype . init = function ( callback ) {
80
+ return util . callbackify ( this . _init . bind ( this ) ) ( callback ) ;
81
+ } ;
82
+
83
+ exports . Database . prototype . _init = async function ( ) {
71
84
const db = this . db ;
72
85
73
86
const sqlCreate = `${ 'CREATE TABLE IF NOT EXISTS `store` ( ' +
@@ -78,105 +91,87 @@ exports.Database.prototype.init = function (callback) {
78
91
79
92
const sqlAlter = 'ALTER TABLE store MODIFY `key` VARCHAR(100) COLLATE utf8mb4_bin;' ;
80
93
81
- db . query ( {
94
+ await this . _query ( {
82
95
sql : sqlCreate ,
83
96
timeout : 60000 ,
84
- } , [ ] , ( err ) => {
85
- // call the main callback
86
- callback ( err ) ;
87
-
88
- // Checks for Database charset et al
89
- const dbCharSet =
90
- 'SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME ' +
91
- `FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${ db . database } '` ;
92
- db . query ( {
93
- sql : dbCharSet ,
94
- timeout : 60000 ,
95
- } , ( err , result ) => {
96
- result = JSON . parse ( JSON . stringify ( result ) ) ;
97
- if ( result [ 0 ] . DEFAULT_CHARACTER_SET_NAME !== db . charset ) {
98
- console . error ( `Database is not configured with charset ${ db . charset } -- ` +
99
- 'This may lead to crashes when certain characters are pasted in pads' ) ;
100
- console . log ( result [ 0 ] , db . charset ) ;
101
- }
102
-
103
- if ( result [ 0 ] . DEFAULT_COLLATION_NAME . indexOf ( db . charset ) === - 1 ) {
104
- console . error (
105
- `Database is not configured with collation name that includes ${ db . charset } -- ` +
106
- 'This may lead to crashes when certain characters are pasted in pads' ) ;
107
- console . log ( result [ 0 ] , db . charset , result [ 0 ] . DEFAULT_COLLATION_NAME ) ;
108
- }
109
- } ) ;
97
+ } , [ ] ) ;
98
+
99
+ // Checks for Database charset et al
100
+ const dbCharSet =
101
+ 'SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME ' +
102
+ `FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${ db . database } '` ;
103
+ let [ result ] = await this . _query ( {
104
+ sql : dbCharSet ,
105
+ timeout : 60000 ,
106
+ } ) ;
110
107
111
- const tableCharSet =
112
- 'SELECT CCSA.character_set_name AS character_set_name ' +
113
- 'FROM information_schema.`TABLES` ' +
114
- 'T,information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA ' +
115
- 'WHERE CCSA.collation_name = T.table_collation ' +
116
- `AND T.table_schema = '${ db . database } ' ` +
117
- "AND T.table_name = 'store'" ;
118
- db . query ( {
119
- sql : tableCharSet ,
120
- timeout : 60000 ,
121
- } , ( err , result , tf ) => {
122
- if ( ! result [ 0 ] ) {
123
- console . warn ( 'Data has no character_set_name value -- ' +
124
- 'This may lead to crashes when certain characters are pasted in pads' ) ;
125
- }
126
- if ( result [ 0 ] && ( result [ 0 ] . character_set_name !== db . charset ) ) {
127
- console . error ( `table is not configured with charset ${ db . charset } -- ` +
128
- 'This may lead to crashes when certain characters are pasted in pads' ) ;
129
- console . log ( result [ 0 ] , db . charset ) ;
130
- }
131
- } ) ;
108
+ result = JSON . parse ( JSON . stringify ( result ) ) ;
109
+ if ( result [ 0 ] . DEFAULT_CHARACTER_SET_NAME !== db . charset ) {
110
+ console . error ( `Database is not configured with charset ${ db . charset } -- ` +
111
+ 'This may lead to crashes when certain characters are pasted in pads' ) ;
112
+ console . log ( result [ 0 ] , db . charset ) ;
113
+ }
132
114
133
- // check migration level, alter if not migrated
134
- this . get ( 'MYSQL_MIGRATION_LEVEL' , ( err , level ) => {
135
- if ( err ) {
136
- throw err ;
137
- }
138
-
139
- if ( level !== '1' ) {
140
- db . query ( {
141
- sql : sqlAlter ,
142
- timeout : 60000 ,
143
- } , [ ] , ( err ) => {
144
- if ( err ) {
145
- throw err ;
146
- }
147
-
148
- this . set ( 'MYSQL_MIGRATION_LEVEL' , '1' , ( err ) => {
149
- if ( err ) {
150
- throw err ;
151
- }
152
- } ) ;
153
- } ) ;
154
- }
155
- } ) ;
115
+ if ( result [ 0 ] . DEFAULT_COLLATION_NAME . indexOf ( db . charset ) === - 1 ) {
116
+ console . error (
117
+ `Database is not configured with collation name that includes ${ db . charset } -- ` +
118
+ 'This may lead to crashes when certain characters are pasted in pads' ) ;
119
+ console . log ( result [ 0 ] , db . charset , result [ 0 ] . DEFAULT_COLLATION_NAME ) ;
120
+ }
121
+
122
+ const tableCharSet =
123
+ 'SELECT CCSA.character_set_name AS character_set_name ' +
124
+ 'FROM information_schema.`TABLES` ' +
125
+ 'T,information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA ' +
126
+ 'WHERE CCSA.collation_name = T.table_collation ' +
127
+ `AND T.table_schema = '${ db . database } ' ` +
128
+ "AND T.table_name = 'store'" ;
129
+ [ result ] = await this . _query ( {
130
+ sql : tableCharSet ,
131
+ timeout : 60000 ,
156
132
} ) ;
133
+ if ( ! result [ 0 ] ) {
134
+ console . warn ( 'Data has no character_set_name value -- ' +
135
+ 'This may lead to crashes when certain characters are pasted in pads' ) ;
136
+ }
137
+ if ( result [ 0 ] && ( result [ 0 ] . character_set_name !== db . charset ) ) {
138
+ console . error ( `table is not configured with charset ${ db . charset } -- ` +
139
+ 'This may lead to crashes when certain characters are pasted in pads' ) ;
140
+ console . log ( result [ 0 ] , db . charset ) ;
141
+ }
142
+
143
+ // check migration level, alter if not migrated
144
+ const level = await this . _get ( 'MYSQL_MIGRATION_LEVEL' ) ;
145
+
146
+ if ( level !== '1' ) {
147
+ await this . _query ( {
148
+ sql : sqlAlter ,
149
+ timeout : 60000 ,
150
+ } , [ ] ) ;
151
+ await this . _set ( 'MYSQL_MIGRATION_LEVEL' , '1' ) ;
152
+ }
157
153
158
154
this . schedulePing ( ) ;
159
155
} ;
160
156
161
157
exports . Database . prototype . get = function ( key , callback ) {
162
- this . db . query ( {
158
+ return util . callbackify ( this . _get . bind ( this ) ) ( key , callback ) ;
159
+ } ;
160
+
161
+ exports . Database . prototype . _get = async function ( key ) {
162
+ const [ results ] = await this . _query ( {
163
163
sql : 'SELECT `value` FROM `store` WHERE `key` = ? AND BINARY `key` = ?' ,
164
164
timeout : 60000 ,
165
- } , [ key , key ] ,
166
- ( err , results ) => {
167
- let value = null ;
168
-
169
- if ( ! err && results . length === 1 ) {
170
- value = results [ 0 ] . value ;
171
- }
172
-
173
- callback ( err , value ) ;
174
- } ) ;
175
-
165
+ } , [ key , key ] ) ;
176
166
this . schedulePing ( ) ;
167
+ return results . length === 1 ? results [ 0 ] . value : null ;
177
168
} ;
178
169
179
170
exports . Database . prototype . findKeys = function ( key , notKey , callback ) {
171
+ return util . callbackify ( this . _findKeys . bind ( this ) ) ( key , notKey , callback ) ;
172
+ } ;
173
+
174
+ exports . Database . prototype . _findKeys = async function ( key , notKey ) {
180
175
let query = 'SELECT `key` FROM `store` WHERE `key` LIKE ?' ;
181
176
const params = [ ] ;
182
177
@@ -190,49 +185,44 @@ exports.Database.prototype.findKeys = function (key, notKey, callback) {
190
185
query += ' AND `key` NOT LIKE ?' ;
191
186
params . push ( notKey ) ;
192
187
}
193
- this . db . query (
194
- {
195
- sql : query ,
196
- timeout : 60000 ,
197
- } , params , ( err , results ) => {
198
- const value = [ ] ;
199
-
200
- if ( ! err && results . length > 0 ) {
201
- results . forEach ( ( val ) => {
202
- value . push ( val . key ) ;
203
- } ) ;
204
- }
205
-
206
- callback ( err , value ) ;
207
- } ) ;
208
-
188
+ const [ results ] = await this . _query ( {
189
+ sql : query ,
190
+ timeout : 60000 ,
191
+ } , params ) ;
209
192
this . schedulePing ( ) ;
193
+ return results . map ( ( val ) => val . key ) ;
210
194
} ;
211
195
212
196
exports . Database . prototype . set = function ( key , value , callback ) {
213
- if ( key . length > 100 ) {
214
- callback ( 'Your Key can only be 100 chars' ) ;
215
- } else {
216
- this . db . query ( {
217
- sql : 'REPLACE INTO `store` VALUES (?,?)' ,
218
- timeout : 60000 ,
219
- } , [ key , value ] , ( err , info ) => {
220
- callback ( err ) ;
221
- } ) ;
222
- }
197
+ return util . callbackify ( this . _set . bind ( this ) ) ( key , value , callback ) ;
198
+ } ;
223
199
200
+ exports . Database . prototype . _set = async function ( key , value ) {
201
+ if ( key . length > 100 ) throw new Error ( 'Your Key can only be 100 chars' ) ;
202
+ await this . _query ( {
203
+ sql : 'REPLACE INTO `store` VALUES (?,?)' ,
204
+ timeout : 60000 ,
205
+ } , [ key , value ] ) ;
224
206
this . schedulePing ( ) ;
225
207
} ;
226
208
227
209
exports . Database . prototype . remove = function ( key , callback ) {
228
- this . db . query ( {
210
+ return util . callbackify ( this . _remove . bind ( this ) ) ( key , callback ) ;
211
+ } ;
212
+
213
+ exports . Database . prototype . _remove = async function ( key ) {
214
+ await this . _query ( {
229
215
sql : 'DELETE FROM `store` WHERE `key` = ? AND BINARY `key` = ?' ,
230
216
timeout : 60000 ,
231
- } , [ key , key ] , callback ) ;
217
+ } , [ key , key ] ) ;
232
218
this . schedulePing ( ) ;
233
219
} ;
234
220
235
221
exports . Database . prototype . doBulk = function ( bulk , callback ) {
222
+ return util . callbackify ( this . _doBulk . bind ( this ) ) ( bulk , callback ) ;
223
+ } ;
224
+
225
+ exports . Database . prototype . _doBulk = async function ( bulk ) {
236
226
let replaceSQL = 'REPLACE INTO `store` VALUES ' ;
237
227
238
228
// keysToDelete is a string of the form "(k1, k2, ..., kn)" painstakingly built by hand.
@@ -241,17 +231,17 @@ exports.Database.prototype.doBulk = function (bulk, callback) {
241
231
let firstReplace = true ;
242
232
let firstRemove = true ;
243
233
244
- for ( const i in bulk ) {
245
- if ( bulk [ i ] . type === 'set' ) {
234
+ for ( const op of bulk ) {
235
+ if ( op . type === 'set' ) {
246
236
if ( ! firstReplace ) replaceSQL += ',' ;
247
237
firstReplace = false ;
248
238
249
- replaceSQL += `(${ this . db . escape ( bulk [ i ] . key ) } , ${ this . db . escape ( bulk [ i ] . value ) } )` ;
250
- } else if ( bulk [ i ] . type === 'remove' ) {
239
+ replaceSQL += `(${ this . db . escape ( op . key ) } , ${ this . db . escape ( op . value ) } )` ;
240
+ } else if ( op . type === 'remove' ) {
251
241
if ( ! firstRemove ) keysToDelete += ',' ;
252
242
firstRemove = false ;
253
243
254
- keysToDelete += this . db . escape ( bulk [ i ] . key ) ;
244
+ keysToDelete += this . db . escape ( op . key ) ;
255
245
}
256
246
}
257
247
@@ -263,30 +253,10 @@ exports.Database.prototype.doBulk = function (bulk, callback) {
263
253
`DELETE FROM \`store\` WHERE \`key\` IN ${ keysToDelete } ` +
264
254
`AND BINARY \`key\` IN ${ keysToDelete } ;` ;
265
255
266
- async . parallel ( [
267
- ( callback ) => {
268
- if ( ! firstReplace ) {
269
- this . db . query ( {
270
- sql : replaceSQL ,
271
- timeout : 60000 ,
272
- } ,
273
- callback ) ;
274
- } else {
275
- callback ( ) ;
276
- }
277
- } ,
278
- ( callback ) => {
279
- if ( ! firstRemove ) {
280
- this . db . query ( {
281
- sql : removeSQL ,
282
- timeout : 60000 ,
283
- } ,
284
- callback ) ;
285
- } else {
286
- callback ( ) ;
287
- }
288
- } ,
289
- ] , callback ) ;
256
+ await Promise . all ( [
257
+ firstReplace ? null : this . _query ( { sql : replaceSQL , timeout : 60000 } ) ,
258
+ firstRemove ? null : this . _query ( { sql : removeSQL , timeout : 60000 } ) ,
259
+ ] ) ;
290
260
291
261
this . schedulePing ( ) ;
292
262
} ;
0 commit comments