@zero-server/orm 0.9.1 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/index.d.ts +1 -1
- package/index.js +35 -35
- package/lib/debug.js +372 -0
- package/lib/orm/adapters/json.js +290 -0
- package/lib/orm/adapters/memory.js +764 -0
- package/lib/orm/adapters/mongo.js +764 -0
- package/lib/orm/adapters/mysql.js +933 -0
- package/lib/orm/adapters/postgres.js +1144 -0
- package/lib/orm/adapters/redis.js +1534 -0
- package/lib/orm/adapters/sql-base.js +212 -0
- package/lib/orm/adapters/sqlite.js +858 -0
- package/lib/orm/audit.js +649 -0
- package/lib/orm/cache.js +394 -0
- package/lib/orm/geo.js +387 -0
- package/lib/orm/index.js +784 -0
- package/lib/orm/migrate.js +432 -0
- package/lib/orm/model.js +1706 -0
- package/lib/orm/plugin.js +375 -0
- package/lib/orm/procedures.js +836 -0
- package/lib/orm/profiler.js +233 -0
- package/lib/orm/query.js +1772 -0
- package/lib/orm/replicas.js +241 -0
- package/lib/orm/schema.js +307 -0
- package/lib/orm/search.js +380 -0
- package/lib/orm/seed/data/commerce.js +136 -0
- package/lib/orm/seed/data/internet.js +111 -0
- package/lib/orm/seed/data/locations.js +204 -0
- package/lib/orm/seed/data/names.js +338 -0
- package/lib/orm/seed/data/person.js +128 -0
- package/lib/orm/seed/data/phone.js +211 -0
- package/lib/orm/seed/data/words.js +134 -0
- package/lib/orm/seed/factory.js +178 -0
- package/lib/orm/seed/fake.js +1186 -0
- package/lib/orm/seed/index.js +18 -0
- package/lib/orm/seed/rng.js +71 -0
- package/lib/orm/seed/seeder.js +125 -0
- package/lib/orm/seed/unique.js +68 -0
- package/lib/orm/snapshot.js +366 -0
- package/lib/orm/tenancy.js +605 -0
- package/lib/orm/views.js +350 -0
- package/package.json +12 -2
- package/types/app.d.ts +223 -0
- package/types/auth.d.ts +520 -0
- package/types/body.d.ts +14 -0
- package/types/cli.d.ts +2 -0
- package/types/cluster.d.ts +75 -0
- package/types/env.d.ts +80 -0
- package/types/errors.d.ts +316 -0
- package/types/fetch.d.ts +43 -0
- package/types/grpc.d.ts +432 -0
- package/types/index.d.ts +384 -0
- package/types/lifecycle.d.ts +60 -0
- package/types/middleware.d.ts +320 -0
- package/types/observe.d.ts +304 -0
- package/types/orm.d.ts +1887 -0
- package/types/request.d.ts +109 -0
- package/types/response.d.ts +157 -0
- package/types/router.d.ts +78 -0
- package/types/sse.d.ts +78 -0
- package/types/websocket.d.ts +126 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module orm/adapters/sql-base
|
|
3
|
+
* @description Base class for SQL adapters. Provides shared query-building
|
|
4
|
+
* utilities, parameterised queries (SQL injection safe), and
|
|
5
|
+
* type mapping helpers.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class BaseSqlAdapter
|
|
9
|
+
{
|
|
10
|
+
/**
|
|
11
|
+
* Build a WHERE clause from simple { key: value } conditions.
|
|
12
|
+
* Uses parameterised queries to prevent SQL injection.
|
|
13
|
+
*
|
|
14
|
+
* @param {object} conditions - Filter conditions.
|
|
15
|
+
* @returns {{ clause: string, values: Array }}
|
|
16
|
+
* @protected
|
|
17
|
+
*/
|
|
18
|
+
_buildWhere(conditions)
|
|
19
|
+
{
|
|
20
|
+
if (!conditions || Object.keys(conditions).length === 0)
|
|
21
|
+
{
|
|
22
|
+
return { clause: '', values: [] };
|
|
23
|
+
}
|
|
24
|
+
const parts = [];
|
|
25
|
+
const values = [];
|
|
26
|
+
for (const [k, v] of Object.entries(conditions))
|
|
27
|
+
{
|
|
28
|
+
if (v === null)
|
|
29
|
+
{
|
|
30
|
+
parts.push(`"${k}" IS NULL`);
|
|
31
|
+
}
|
|
32
|
+
else
|
|
33
|
+
{
|
|
34
|
+
parts.push(`"${k}" = ?`);
|
|
35
|
+
values.push(this._toSqlValue(v));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { clause: ' WHERE ' + parts.join(' AND '), values };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Build a WHERE clause from the Query builder's where chain.
|
|
43
|
+
* Supports operators: =, !=, >, <, >=, <=, LIKE, IN, NOT IN, BETWEEN, IS NULL, IS NOT NULL.
|
|
44
|
+
*
|
|
45
|
+
* @param {Array} where - Array of { field, op, value, logic } objects.
|
|
46
|
+
* @returns {{ clause: string, values: Array }}
|
|
47
|
+
* @protected
|
|
48
|
+
*/
|
|
49
|
+
_buildWhereFromChain(where)
|
|
50
|
+
{
|
|
51
|
+
if (!where || where.length === 0) return { clause: '', values: [] };
|
|
52
|
+
|
|
53
|
+
const parts = [];
|
|
54
|
+
const values = [];
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < where.length; i++)
|
|
57
|
+
{
|
|
58
|
+
const w = where[i];
|
|
59
|
+
|
|
60
|
+
// Handle raw WHERE clauses (from whereRaw)
|
|
61
|
+
if (w.raw)
|
|
62
|
+
{
|
|
63
|
+
const expr = w.raw;
|
|
64
|
+
if (w.params) values.push(...w.params);
|
|
65
|
+
if (i === 0) parts.push(expr);
|
|
66
|
+
else parts.push(`${w.logic} ${expr}`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const { field, op, value, logic } = w;
|
|
71
|
+
|
|
72
|
+
let expr;
|
|
73
|
+
if (op === 'IS NULL')
|
|
74
|
+
{
|
|
75
|
+
expr = `"${field}" IS NULL`;
|
|
76
|
+
}
|
|
77
|
+
else if (op === 'IS NOT NULL')
|
|
78
|
+
{
|
|
79
|
+
expr = `"${field}" IS NOT NULL`;
|
|
80
|
+
}
|
|
81
|
+
else if (op === 'IN' || op === 'NOT IN')
|
|
82
|
+
{
|
|
83
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
84
|
+
{
|
|
85
|
+
expr = op === 'IN' ? '0' : '1'; // IN () → false, NOT IN () → true
|
|
86
|
+
}
|
|
87
|
+
else
|
|
88
|
+
{
|
|
89
|
+
const placeholders = value.map(() => '?').join(', ');
|
|
90
|
+
expr = `"${field}" ${op} (${placeholders})`;
|
|
91
|
+
values.push(...value.map(v => this._toSqlValue(v)));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (op === 'BETWEEN')
|
|
95
|
+
{
|
|
96
|
+
expr = `"${field}" BETWEEN ? AND ?`;
|
|
97
|
+
values.push(this._toSqlValue(value[0]), this._toSqlValue(value[1]));
|
|
98
|
+
}
|
|
99
|
+
else
|
|
100
|
+
{
|
|
101
|
+
expr = `"${field}" ${op} ?`;
|
|
102
|
+
values.push(this._toSqlValue(value));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (i === 0) parts.push(expr);
|
|
106
|
+
else parts.push(`${logic} ${expr}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return { clause: ' WHERE ' + parts.join(' '), values };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Convert a JS value to a SQL-safe value.
|
|
114
|
+
* @param {*} value - Value to set.
|
|
115
|
+
* @returns {*} SQL-compatible representation of the input.
|
|
116
|
+
* @protected
|
|
117
|
+
*/
|
|
118
|
+
_toSqlValue(value)
|
|
119
|
+
{
|
|
120
|
+
if (value instanceof Date) return value.toISOString();
|
|
121
|
+
if (typeof value === 'boolean') return value ? 1 : 0;
|
|
122
|
+
if (typeof value === 'object' && value !== null) return JSON.stringify(value);
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Format a default value for SQL DDL.
|
|
128
|
+
* @param {*} val - Value to check.
|
|
129
|
+
* @returns {string} SQL DEFAULT literal.
|
|
130
|
+
* @protected
|
|
131
|
+
*/
|
|
132
|
+
_sqlDefault(val)
|
|
133
|
+
{
|
|
134
|
+
if (val === null) return 'NULL';
|
|
135
|
+
if (typeof val === 'number') return String(val);
|
|
136
|
+
if (typeof val === 'boolean') return val ? '1' : '0';
|
|
137
|
+
if (typeof val === 'string') return `'${val.replace(/'/g, "''")}'`;
|
|
138
|
+
return 'NULL';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Build JOIN clauses from the descriptor's joins array.
|
|
143
|
+
* @param {Array} joins - Array of { type, table, localKey, foreignKey }.
|
|
144
|
+
* @param {string} baseTable - The primary table name.
|
|
145
|
+
* @param {Function} [q] - Quote function (default: double-quote).
|
|
146
|
+
* @returns {string} SQL JOIN clause, or empty string if none.
|
|
147
|
+
* @protected
|
|
148
|
+
*/
|
|
149
|
+
_buildJoins(joins, baseTable, q)
|
|
150
|
+
{
|
|
151
|
+
if (!joins || joins.length === 0) return '';
|
|
152
|
+
const quote = q || (name => `"${name}"`);
|
|
153
|
+
return ' ' + joins.map(j =>
|
|
154
|
+
`${j.type} JOIN ${quote(j.table)} ON ${quote(baseTable)}.${quote(j.localKey)} = ${quote(j.table)}.${quote(j.foreignKey)}`
|
|
155
|
+
).join(' ');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Build GROUP BY clause.
|
|
160
|
+
* @param {Array} groupBy - Array of column names.
|
|
161
|
+
* @param {Function} [q] - Quote function.
|
|
162
|
+
* @returns {string} SQL GROUP BY clause, or empty string if none.
|
|
163
|
+
* @protected
|
|
164
|
+
*/
|
|
165
|
+
_buildGroupBy(groupBy, q)
|
|
166
|
+
{
|
|
167
|
+
if (!groupBy || groupBy.length === 0) return '';
|
|
168
|
+
const quote = q || (name => `"${name}"`);
|
|
169
|
+
return ' GROUP BY ' + groupBy.map(f => quote(f)).join(', ');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Build HAVING clause from having array.
|
|
174
|
+
* Uses ? parameter placeholders.
|
|
175
|
+
* @param {Array} having - Array of { field, op, value }.
|
|
176
|
+
* @param {Array} values - Values array to push params into.
|
|
177
|
+
* @param {Function} [q] - Quote function.
|
|
178
|
+
* @returns {string} SQL HAVING clause, or empty string if none.
|
|
179
|
+
* @protected
|
|
180
|
+
*/
|
|
181
|
+
_buildHaving(having, values, q)
|
|
182
|
+
{
|
|
183
|
+
if (!having || having.length === 0) return '';
|
|
184
|
+
const quote = q || (name => `"${name}"`);
|
|
185
|
+
const parts = having.map(h => {
|
|
186
|
+
values.push(this._toSqlValue(h.value));
|
|
187
|
+
return `${quote(h.field)} ${h.op} ?`;
|
|
188
|
+
});
|
|
189
|
+
return ' HAVING ' + parts.join(' AND ');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Build HAVING clause with PostgreSQL $N placeholders.
|
|
194
|
+
* @param {Array} having - HAVING clause.
|
|
195
|
+
* @param {Array} values - Array of values.
|
|
196
|
+
* @param {number} startIdx - Current parameter index.
|
|
197
|
+
* @returns {{ clause: string, nextIdx: number }}
|
|
198
|
+
* @protected
|
|
199
|
+
*/
|
|
200
|
+
_buildHavingPg(having, values, startIdx)
|
|
201
|
+
{
|
|
202
|
+
if (!having || having.length === 0) return { clause: '', nextIdx: startIdx };
|
|
203
|
+
let idx = startIdx;
|
|
204
|
+
const parts = having.map(h => {
|
|
205
|
+
values.push(this._toSqlValue(h.value));
|
|
206
|
+
return `"${h.field}" ${h.op} $${idx++}`;
|
|
207
|
+
});
|
|
208
|
+
return { clause: ' HAVING ' + parts.join(' AND '), nextIdx: idx };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
module.exports = BaseSqlAdapter;
|