-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodel.js
More file actions
126 lines (102 loc) · 2.66 KB
/
model.js
File metadata and controls
126 lines (102 loc) · 2.66 KB
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
const { SqlQuery } = require('./query');
const { pascalToSnake } = require('./utils');
const {
FindPipeline, FindOnePipeline,
DeletePipeline, DeleteOnePipeline,
UpdatePipeline, UpdateOnePipeline
} = require('./pipelines');
/** @typedef {import('dc-api-core/db').Model} BaseModel */
/** @extends {BaseModel} */
class Model {
/**
* @param {InstanceType<import('.')>} db
* @param {string} name Model file name
* @param {any} schema
*/
constructor (db, name, schema) {
this.db = db;
this.name = name;
if (name.endsWith('s') || name.endsWith('S')) {
this.collectionName = pascalToSnake(name + 'es');
} else {
this.collectionName = pascalToSnake(name + 's');
}
if (!schema.id) {
schema = Object.assign({ id: { type: 'int', primary: true, increment: true } }, schema);
}
this.schema = schema;
}
async tableExists () {
return Boolean(
await SqlQuery
.select('information_schema.tables', 'COUNT(*)')
.where({ table_schema: this.db.config.name, table_name: this.collectionName })
.limit(1)
.takeValue(this.db)
);
}
/**
* Initialize table
* @returns `true` if table was created, `false` if already exists
*/
async init () {
if (await this.tableExists()) return false;
await SqlQuery.createTable(this.collectionName, this.schema).execute(this.db);
return true;
}
async create (values) {
this._serialize(values);
const [result] = await SqlQuery.insert(this.collectionName, values).execute(this.db);
values.id = result.insertId;
this._deserialize(values);
return values;
}
find (where) {
return new FindPipeline(this, where);
}
findOne (where) {
return new FindOnePipeline(this, where);
}
findById (id) {
return new FindOnePipeline(this, { id });
}
delete (where) {
return new DeletePipeline(this, where);
}
deleteOne (where) {
return new DeleteOnePipeline(this, where);
}
deleteById (id) {
return new DeleteOnePipeline(this, { id });
}
update (where, values) {
return new UpdatePipeline(this, where, values);
}
updateOne (where, values) {
return new UpdateOnePipeline(this, where, values);
}
updateById (id, values) {
return new UpdateOnePipeline(this, { id }, values);
}
_serialize (values) {
for (const field in values) {
const info = this.schema[field];
if (!info) continue;
if (info.type == 'json') {
if (typeof values[field] != 'string') {
values[field] = JSON.stringify(values[field]);
}
}
}
}
_deserialize (values) {
for (const field in values) {
const info = this.schema[field];
if (!info) continue;
if (info.type == 'int' || info.type == 'long') {
values[field] = parseInt(values[field]);
}
}
}
}
module.exports = { Model };