-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdriver.js
149 lines (127 loc) · 4.5 KB
/
driver.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
const _ = require('underscore')
const mysql = require('mysql')
/**
* Blockbase mysql driver (app.drivers.mysql)
* @memberof app.drivers
* @author Backsmith <[email protected]>
* @param {Object} app - Application namespace
*
* @returns {Object} driver object containing public methods
*/
module.exports = (app) => {
const Logger = app.drivers.logger
if (!app.config.has('mysql'))
return Logger.error('Drivers', 'Can not init mysql, no valid config')
const config = app.config.get('mysql')
config.max = config.max || 1000
const pool = new mysql.createPool(config)
/**
* Query function, executing the SQL query
* @private
* @name query
* @param {string} sql - sql query (prepared or not)
* @param {Object[]} data - array of data to pass in the prepared query
*/
async function query(sql, data) {
return new Promise((resolve, reject) => {
pool.getConnection((error, connection) => {
if (error) {
Logger.error('Drivers - mysql', error)
return reject(error)
}
connection.query(sql, data, (error, results) => {
if (error) return reject(error)
resolve(results)
})
})
})
}
return {
/**
* Execute a custom query
* @alias query
*/
execute: query,
/**
* Create an object based on a Blocbase valid model
* @param {Object} item - object compiled by the model
* @return {Promise<Object>} saved item
*/
async save(item) {
if (!item.valid()) throw Error(item.validate().error)
for (let [k, v] of Object.entries(item.data)) {
if (typeof v == 'object') {
item.data[k] = JSON.stringify(v)
}
}
try {
let q = `INSERT INTO ${item.params.table || (item.params.type + 's')} SET ? `
let result = await query(q, [item.data])
item.body({id: result.insertId})
return await item.read(item)
} catch (e) {
throw e
}
},
/**
* Read an object from the DB
* @param {Object} item - object compiled by the model (needs id)
* @return {Promise<Object>} called item
*/
async read(item) {
if (!item.data || !item.data.id)
throw Error(`Cannot read an item without an 'id'`)
let q = `SELECT * FROM ${item.params.table || (item.params.type + 's')} WHERE id=?`
try {
let rows = await query(q, [item.data.id])
if (rows.length)
item.body(rows[0])
return rows.length ? item : null
} catch (e) {
throw e
}
},
/**
* Update a valid object model
* @param {Object} item - object compiled by the model
* @return {Promise<Object>} updated item
*/
async update(item) {
if (!item.data || !item.data.id)
throw Error(`Cannot update an item without an 'id'`)
let updates = [], values = []
for ([key, value] of Object.entries(item.body())) {
updates.push(`${key}=?`)
if (typeof value == 'object')
value = JSON.stringify(value)
values.push(value)
}
values.push(item.data.id)
let q = `UPDATE ${item.params.table || (item.params.type + 's')} SET ${updates.join(' , ')} WHERE id=? `
try {
await query(q, values)
let rows = this.read(item)
item.body(rows[0])
return item
} catch (e) {
throw e
}
},
/**
* Delete a valid object model
* @param {Object} item - object compiled by the model
* @returns {Promise<boolean>} - true if deleted
*/
async delete(item) {
if (!item.data || !item.data.id)
throw Error(`Cannot delete an item without an 'id'`)
let q = `DELETE FROM ${item.params.table || (item.params.type + 's')} WHERE id=?`
try {
let result = await query(q, [item.data.id])
return result.affectedRows > 0
} catch (e) {
throw e
}
}
}
}