rado 1.2.1 → 1.3.0-preview.1
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/README.md +163 -257
- package/dist/compat.d.ts +3 -0
- package/dist/core/Builder.d.ts +16 -9
- package/dist/core/Builder.js +52 -4
- package/dist/core/Column.d.ts +25 -21
- package/dist/core/Column.js +39 -23
- package/dist/core/Constraint.d.ts +2 -1
- package/dist/core/Constraint.js +2 -1
- package/dist/core/Database.d.ts +5 -4
- package/dist/core/Database.js +14 -13
- package/dist/core/Emitter.d.ts +2 -2
- package/dist/core/Index.d.ts +1 -1
- package/dist/core/Internal.d.ts +19 -2
- package/dist/core/Internal.js +29 -11
- package/dist/core/Param.js +2 -0
- package/dist/core/Queries.d.ts +1 -0
- package/dist/core/Queries.js +11 -1
- package/dist/core/Resolver.js +2 -2
- package/dist/core/Schema.d.ts +1 -3
- package/dist/core/Selection.d.ts +9 -4
- package/dist/core/Selection.js +94 -5
- package/dist/core/Sql.d.ts +4 -3
- package/dist/core/Sql.js +8 -2
- package/dist/core/Table.d.ts +18 -11
- package/dist/core/Table.js +45 -25
- package/dist/core/View.d.ts +34 -0
- package/dist/core/View.js +153 -0
- package/dist/core/Virtual.d.ts +7 -2
- package/dist/core/Virtual.js +14 -10
- package/dist/core/expr/Conditions.d.ts +7 -7
- package/dist/core/expr/Include.d.ts +4 -4
- package/dist/core/expr/Include.js +2 -2
- package/dist/core/expr/Input.d.ts +1 -1
- package/dist/core/expr/Input.js +5 -1
- package/dist/core/query/CTE.d.ts +3 -5
- package/dist/core/query/CTE.js +1 -13
- package/dist/core/query/Delete.d.ts +10 -10
- package/dist/core/query/Delete.js +2 -2
- package/dist/core/query/Insert.d.ts +6 -5
- package/dist/core/query/Insert.js +22 -9
- package/dist/core/query/Query.d.ts +26 -11
- package/dist/core/query/Select.d.ts +41 -8
- package/dist/core/query/Select.js +235 -25
- package/dist/core/query/Shared.d.ts +2 -1
- package/dist/core/query/Shared.js +8 -5
- package/dist/core/query/Update.d.ts +9 -9
- package/dist/core/query/Update.js +24 -12
- package/dist/driver/better-sqlite3.js +4 -0
- package/dist/driver/bun-sqlite.js +3 -0
- package/dist/driver/d1.js +3 -0
- package/dist/driver/libsql.js +4 -0
- package/dist/driver/mysql2.js +5 -0
- package/dist/driver/pg.d.ts +17 -1
- package/dist/driver/pg.js +10 -1
- package/dist/driver/pglite.js +21 -6
- package/dist/driver/sql.js.js +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mysql/columns.d.ts +30 -30
- package/dist/mysql/columns.js +25 -24
- package/dist/mysql/dialect.js +6 -2
- package/dist/mysql/diff.js +1 -1
- package/dist/mysql.d.ts +1 -0
- package/dist/mysql.js +2 -0
- package/dist/postgres/columns.d.ts +103 -33
- package/dist/postgres/columns.js +317 -35
- package/dist/postgres/diff.js +3 -3
- package/dist/postgres/enum.d.ts +17 -0
- package/dist/postgres/enum.js +64 -0
- package/dist/postgres/schema.d.ts +19 -0
- package/dist/postgres/schema.js +47 -0
- package/dist/postgres.d.ts +3 -1
- package/dist/postgres.js +9 -2
- package/dist/sqlite/columns.d.ts +29 -14
- package/dist/sqlite/columns.js +41 -9
- package/dist/sqlite/dialect.js +3 -1
- package/dist/sqlite/diff.js +1 -1
- package/dist/sqlite/functions.d.ts +1 -1
- package/dist/sqlite/functions.js +1 -1
- package/dist/sqlite.d.ts +1 -0
- package/dist/sqlite.js +3 -6
- package/dist/universal/columns.d.ts +8 -8
- package/dist/universal/columns.js +10 -9
- package/dist/universal/functions.d.ts +1 -1
- package/dist/universal/functions.js +1 -1
- package/package.json +57 -38
package/dist/postgres/columns.js
CHANGED
|
@@ -1,38 +1,233 @@
|
|
|
1
1
|
// src/postgres/columns.ts
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
Column,
|
|
4
|
+
ColumnType,
|
|
4
5
|
column,
|
|
5
6
|
columnConfig
|
|
6
7
|
} from "../core/Column.js";
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
import { getData } from "../core/Internal.js";
|
|
9
|
+
import { sql } from "../core/Sql.js";
|
|
10
|
+
var GEOMETRY_TYPE = /^(geometry|point|line|linestring|polygon|multipoint|multilinestring|multipolygon|geometrycollection|circularstring|compoundcurve|curvepolygon|multicurve|multisurface|polyhedralsurface|triangle|tin)(z|m|zm)?$/;
|
|
11
|
+
function parsePoint(value) {
|
|
12
|
+
const cleaned = value.trim().replace(/^\(/, "").replace(/\)$/, "");
|
|
13
|
+
const [x, y] = cleaned.split(",").map((v) => Number.parseFloat(v));
|
|
14
|
+
return [x, y];
|
|
15
|
+
}
|
|
16
|
+
function formatPoint(value) {
|
|
17
|
+
if (typeof value === "string") return value;
|
|
18
|
+
if (Array.isArray(value)) return `(${value[0]},${value[1]})`;
|
|
19
|
+
return `(${value.x},${value.y})`;
|
|
20
|
+
}
|
|
21
|
+
function parseLine(value) {
|
|
22
|
+
const cleaned = value.trim().replace(/^[({[]/, "").replace(/[)}\]]$/, "");
|
|
23
|
+
const [a, b, c] = cleaned.split(",").map((v) => Number.parseFloat(v));
|
|
24
|
+
return [a, b, c];
|
|
25
|
+
}
|
|
26
|
+
function formatLine(value) {
|
|
27
|
+
if (typeof value === "string") return value;
|
|
28
|
+
if (Array.isArray(value)) return `{${value[0]},${value[1]},${value[2]}}`;
|
|
29
|
+
return `{${value.a},${value.b},${value.c}}`;
|
|
30
|
+
}
|
|
31
|
+
function pad2(value) {
|
|
32
|
+
return String(value).padStart(2, "0");
|
|
33
|
+
}
|
|
34
|
+
function pad3(value) {
|
|
35
|
+
return String(value).padStart(3, "0");
|
|
36
|
+
}
|
|
37
|
+
function formatDateString(value) {
|
|
38
|
+
return `${value.getUTCFullYear()}-${pad2(value.getUTCMonth() + 1)}-${pad2(
|
|
39
|
+
value.getUTCDate()
|
|
40
|
+
)}`;
|
|
41
|
+
}
|
|
42
|
+
function formatTimestampString(value, withTimeZone) {
|
|
43
|
+
const date2 = formatDateString(value);
|
|
44
|
+
const time2 = `${pad2(value.getUTCHours())}:${pad2(
|
|
45
|
+
value.getUTCMinutes()
|
|
46
|
+
)}:${pad2(value.getUTCSeconds())}.${pad3(value.getUTCMilliseconds())}`;
|
|
47
|
+
return withTimeZone ? `${date2} ${time2}+00` : `${date2} ${time2}`;
|
|
48
|
+
}
|
|
49
|
+
function parsePgArrayValue(input) {
|
|
50
|
+
if (!input.startsWith("{") || !input.endsWith("}")) return [input];
|
|
51
|
+
const source = input.slice(1, -1);
|
|
52
|
+
const parts = [];
|
|
53
|
+
let token = "";
|
|
54
|
+
let depth = 0;
|
|
55
|
+
let inQuotes = false;
|
|
56
|
+
let wasQuoted = false;
|
|
57
|
+
const pushToken = () => {
|
|
58
|
+
if (!wasQuoted && token === "NULL") parts.push("\0NULL");
|
|
59
|
+
else parts.push(token);
|
|
60
|
+
token = "";
|
|
61
|
+
wasQuoted = false;
|
|
62
|
+
};
|
|
63
|
+
for (let i = 0; i < source.length; i++) {
|
|
64
|
+
const char2 = source[i];
|
|
65
|
+
if (inQuotes) {
|
|
66
|
+
if (char2 === "\\") {
|
|
67
|
+
const next = source[++i];
|
|
68
|
+
if (next !== void 0) token += next;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (char2 === '"') {
|
|
72
|
+
inQuotes = false;
|
|
73
|
+
wasQuoted = true;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
token += char2;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (char2 === '"') {
|
|
80
|
+
inQuotes = true;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (char2 === "{") {
|
|
84
|
+
depth++;
|
|
85
|
+
token += char2;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (char2 === "}") {
|
|
89
|
+
depth--;
|
|
90
|
+
token += char2;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (char2 === "," && depth === 0) {
|
|
94
|
+
pushToken();
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
token += char2;
|
|
98
|
+
}
|
|
99
|
+
pushToken();
|
|
100
|
+
return parts.map((part) => {
|
|
101
|
+
if (part === "\0NULL") return null;
|
|
102
|
+
if (part.startsWith("{") && part.endsWith("}"))
|
|
103
|
+
return parsePgArrayValue(part);
|
|
104
|
+
return part;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function serializePgArrayValue(value) {
|
|
108
|
+
return `{${value.map(serializePgArrayItem).join(",")}}`;
|
|
109
|
+
}
|
|
110
|
+
function serializePgArrayItem(value) {
|
|
111
|
+
if (Array.isArray(value)) return serializePgArrayValue(value);
|
|
112
|
+
if (value === null || value === void 0) return "NULL";
|
|
113
|
+
let normalized;
|
|
114
|
+
if (value instanceof Date) normalized = value.toISOString();
|
|
115
|
+
else if (typeof value === "string") normalized = value;
|
|
116
|
+
else if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint")
|
|
117
|
+
normalized = String(value);
|
|
118
|
+
else normalized = JSON.stringify(value);
|
|
119
|
+
const escaped = normalized.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
120
|
+
return `"${escaped}"`;
|
|
121
|
+
}
|
|
122
|
+
function mapArrayItems(value, mapper) {
|
|
123
|
+
if (!Array.isArray(value)) return value;
|
|
124
|
+
return value.map((item) => mapper(item));
|
|
125
|
+
}
|
|
126
|
+
var PgColumn = class _PgColumn extends Column {
|
|
127
|
+
notNull() {
|
|
128
|
+
return new _PgColumn({
|
|
129
|
+
...getData(this),
|
|
130
|
+
notNull: true
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
unique(name, config) {
|
|
134
|
+
return new _PgColumn({
|
|
135
|
+
...getData(this),
|
|
136
|
+
isUnique: true,
|
|
137
|
+
nullsNotDistinct: config?.nulls === "not distinct",
|
|
138
|
+
name
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
array(size) {
|
|
142
|
+
const data = getData(this);
|
|
143
|
+
const mapTo = data.mapToDriverValue;
|
|
144
|
+
const mapFrom = data.mapFromDriverValue;
|
|
145
|
+
return new _PgColumn({
|
|
146
|
+
...data,
|
|
147
|
+
type: new ColumnType("array", [data.type], sql`${data.type}[${size}]`),
|
|
148
|
+
mapToDriverValue(value) {
|
|
149
|
+
if (!Array.isArray(value)) return value;
|
|
150
|
+
const mapped = mapArrayItems(
|
|
151
|
+
value,
|
|
152
|
+
(item) => item !== null && item !== void 0 && mapTo ? mapTo(item) : item
|
|
153
|
+
);
|
|
154
|
+
return serializePgArrayValue(mapped);
|
|
155
|
+
},
|
|
156
|
+
mapFromDriverValue(value, specs) {
|
|
157
|
+
const parsed = typeof value === "string" ? parsePgArrayValue(value) : value;
|
|
158
|
+
if (!Array.isArray(parsed)) return parsed;
|
|
159
|
+
return mapArrayItems(
|
|
160
|
+
parsed,
|
|
161
|
+
(item) => item !== null && item !== void 0 && mapFrom ? mapFrom(item, specs) : item
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
generatedAlwaysAsIdentity() {
|
|
167
|
+
const data = getData(this);
|
|
168
|
+
return new _PgColumn({
|
|
169
|
+
...data,
|
|
170
|
+
type: new ColumnType(
|
|
171
|
+
data.type.kind,
|
|
172
|
+
data.type.args,
|
|
173
|
+
sql`${data.type} generated always as identity`
|
|
174
|
+
)
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
generatedByDefaultAsIdentity() {
|
|
178
|
+
const data = getData(this);
|
|
179
|
+
return new _PgColumn({
|
|
180
|
+
...data,
|
|
181
|
+
type: new ColumnType(
|
|
182
|
+
data.type.kind,
|
|
183
|
+
data.type.args,
|
|
184
|
+
sql`${data.type} generated by default as identity`
|
|
185
|
+
)
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
function bigint(...args) {
|
|
190
|
+
const { name, options } = columnConfig(args);
|
|
191
|
+
return new PgColumn({
|
|
9
192
|
name,
|
|
10
193
|
type: column.bigint(),
|
|
11
194
|
mapFromDriverValue: options?.mode === "number" ? Number : BigInt
|
|
12
195
|
});
|
|
13
196
|
}
|
|
14
|
-
function bigserial(
|
|
15
|
-
|
|
197
|
+
function bigserial(...args) {
|
|
198
|
+
const { name, options } = columnConfig(args);
|
|
199
|
+
return new PgColumn({
|
|
16
200
|
name,
|
|
17
201
|
type: column.bigserial(),
|
|
18
202
|
mapFromDriverValue: options?.mode === "number" ? Number : BigInt
|
|
19
203
|
});
|
|
20
204
|
}
|
|
21
205
|
function char(name, options) {
|
|
22
|
-
return
|
|
206
|
+
return new PgColumn({
|
|
23
207
|
name,
|
|
24
208
|
type: column.character(options?.length ?? 1)
|
|
25
209
|
});
|
|
26
210
|
}
|
|
211
|
+
function bit(...args) {
|
|
212
|
+
const { name, options } = columnConfig(args);
|
|
213
|
+
return new PgColumn({ name, type: column.bit(options?.dimensions) });
|
|
214
|
+
}
|
|
215
|
+
function varbit(...args) {
|
|
216
|
+
const { name, options } = columnConfig(args);
|
|
217
|
+
return new PgColumn({ name, type: column.varbit(options?.dimensions) });
|
|
218
|
+
}
|
|
27
219
|
function cidr(name) {
|
|
28
|
-
return
|
|
220
|
+
return new PgColumn({ name, type: column.cidr() });
|
|
29
221
|
}
|
|
30
222
|
function date(name, options) {
|
|
31
|
-
|
|
223
|
+
const mode = options?.mode ?? "date";
|
|
224
|
+
return new PgColumn({
|
|
32
225
|
name,
|
|
33
226
|
type: column.date(),
|
|
34
227
|
mapFromDriverValue(value) {
|
|
35
|
-
|
|
228
|
+
if (mode === "date")
|
|
229
|
+
return value instanceof Date ? value : new Date(value);
|
|
230
|
+
return value instanceof Date ? formatDateString(value) : value;
|
|
36
231
|
},
|
|
37
232
|
mapToDriverValue(value) {
|
|
38
233
|
return value instanceof Date ? value.toISOString() : value;
|
|
@@ -40,7 +235,7 @@ function date(name, options) {
|
|
|
40
235
|
});
|
|
41
236
|
}
|
|
42
237
|
function doublePrecision(name) {
|
|
43
|
-
return
|
|
238
|
+
return new PgColumn({
|
|
44
239
|
name,
|
|
45
240
|
type: column["double precision"](),
|
|
46
241
|
mapFromDriverValue(value) {
|
|
@@ -49,18 +244,48 @@ function doublePrecision(name) {
|
|
|
49
244
|
});
|
|
50
245
|
}
|
|
51
246
|
function inet(name) {
|
|
52
|
-
return
|
|
247
|
+
return new PgColumn({ name, type: column.inet() });
|
|
53
248
|
}
|
|
54
249
|
function integer(name) {
|
|
55
|
-
return
|
|
250
|
+
return new PgColumn({ name, type: column.integer() });
|
|
56
251
|
}
|
|
57
252
|
var int = integer;
|
|
58
253
|
function oid(name) {
|
|
59
|
-
return
|
|
254
|
+
return new PgColumn({ name, type: column.oid() });
|
|
255
|
+
}
|
|
256
|
+
function point(...args) {
|
|
257
|
+
const { name, options } = columnConfig(args);
|
|
258
|
+
const mode = options?.mode ?? "tuple";
|
|
259
|
+
return new PgColumn({
|
|
260
|
+
name,
|
|
261
|
+
type: column.point(),
|
|
262
|
+
mapFromDriverValue(value) {
|
|
263
|
+
const [x, y] = parsePoint(value);
|
|
264
|
+
return mode === "xy" ? { x, y } : [x, y];
|
|
265
|
+
},
|
|
266
|
+
mapToDriverValue(value) {
|
|
267
|
+
return formatPoint(value);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
function line(...args) {
|
|
272
|
+
const { name, options } = columnConfig(args);
|
|
273
|
+
const mode = options?.mode ?? "tuple";
|
|
274
|
+
return new PgColumn({
|
|
275
|
+
name,
|
|
276
|
+
type: column.line(),
|
|
277
|
+
mapFromDriverValue(value) {
|
|
278
|
+
const [a, b, c] = parseLine(value);
|
|
279
|
+
return mode === "abc" ? { a, b, c } : [a, b, c];
|
|
280
|
+
},
|
|
281
|
+
mapToDriverValue(value) {
|
|
282
|
+
return formatLine(value);
|
|
283
|
+
}
|
|
284
|
+
});
|
|
60
285
|
}
|
|
61
286
|
function interval(...args) {
|
|
62
287
|
const { name, options } = columnConfig(args);
|
|
63
|
-
return
|
|
288
|
+
return new PgColumn({
|
|
64
289
|
name,
|
|
65
290
|
type: column[options?.fields ? `interval ${options.fields}` : "interval"](
|
|
66
291
|
options?.precision
|
|
@@ -68,19 +293,19 @@ function interval(...args) {
|
|
|
68
293
|
});
|
|
69
294
|
}
|
|
70
295
|
function serial(name) {
|
|
71
|
-
return
|
|
296
|
+
return new PgColumn({ name, type: column.serial() });
|
|
72
297
|
}
|
|
73
298
|
function boolean(name) {
|
|
74
|
-
return
|
|
299
|
+
return new PgColumn({ name, type: column.boolean() });
|
|
75
300
|
}
|
|
76
301
|
function bytea(name) {
|
|
77
|
-
return
|
|
302
|
+
return new PgColumn({ name, type: column.bytea() });
|
|
78
303
|
}
|
|
79
304
|
function text(name) {
|
|
80
|
-
return
|
|
305
|
+
return new PgColumn({ name, type: column.text() });
|
|
81
306
|
}
|
|
82
307
|
function json(name) {
|
|
83
|
-
return new
|
|
308
|
+
return new PgColumn({
|
|
84
309
|
name,
|
|
85
310
|
type: column.json(),
|
|
86
311
|
mapToDriverValue(value) {
|
|
@@ -88,11 +313,12 @@ function json(name) {
|
|
|
88
313
|
},
|
|
89
314
|
mapFromDriverValue(value, { parsesJson }) {
|
|
90
315
|
return parsesJson ? value : JSON.parse(value);
|
|
91
|
-
}
|
|
316
|
+
},
|
|
317
|
+
json: true
|
|
92
318
|
});
|
|
93
319
|
}
|
|
94
320
|
function jsonb(name) {
|
|
95
|
-
return new
|
|
321
|
+
return new PgColumn({
|
|
96
322
|
name,
|
|
97
323
|
type: column.jsonb(),
|
|
98
324
|
mapToDriverValue(value) {
|
|
@@ -100,24 +326,64 @@ function jsonb(name) {
|
|
|
100
326
|
},
|
|
101
327
|
mapFromDriverValue(value, { parsesJson }) {
|
|
102
328
|
return parsesJson ? value : JSON.parse(value);
|
|
329
|
+
},
|
|
330
|
+
json: true
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function geometry(...args) {
|
|
334
|
+
const { name, options } = columnConfig(args);
|
|
335
|
+
const geometryTypeName = options?.type?.toLowerCase();
|
|
336
|
+
if (geometryTypeName && !GEOMETRY_TYPE.test(geometryTypeName)) {
|
|
337
|
+
throw new Error(`Invalid geometry type: ${options?.type}`);
|
|
338
|
+
}
|
|
339
|
+
const typeArg = geometryTypeName ? sql.unsafe(geometryTypeName) : void 0;
|
|
340
|
+
const geometryType = options?.type ? new ColumnType("geometry", [], sql`geometry(${typeArg})`) : column.geometry();
|
|
341
|
+
const mode = options?.mode ?? "tuple";
|
|
342
|
+
const mapsPoint = geometryTypeName === "point";
|
|
343
|
+
return new PgColumn({
|
|
344
|
+
name,
|
|
345
|
+
type: geometryType,
|
|
346
|
+
mapFromDriverValue(value) {
|
|
347
|
+
if (!mapsPoint) return value;
|
|
348
|
+
const [x, y] = parsePoint(value);
|
|
349
|
+
return mode === "xy" ? { x, y } : [x, y];
|
|
350
|
+
},
|
|
351
|
+
mapToDriverValue(value) {
|
|
352
|
+
if (!mapsPoint) return value;
|
|
353
|
+
return formatPoint(value);
|
|
103
354
|
}
|
|
104
355
|
});
|
|
105
356
|
}
|
|
357
|
+
function vector(...args) {
|
|
358
|
+
const { name, options } = columnConfig(args);
|
|
359
|
+
return new PgColumn({ name, type: column.vector(options?.dimensions) });
|
|
360
|
+
}
|
|
361
|
+
function halfvec(...args) {
|
|
362
|
+
const { name, options } = columnConfig(args);
|
|
363
|
+
return new PgColumn({ name, type: column.halfvec(options?.dimensions) });
|
|
364
|
+
}
|
|
365
|
+
function sparsevec(...args) {
|
|
366
|
+
const { name, options } = columnConfig(args);
|
|
367
|
+
return new PgColumn({ name, type: column.sparsevec(options?.dimensions) });
|
|
368
|
+
}
|
|
106
369
|
function macaddr(name) {
|
|
107
|
-
return
|
|
370
|
+
return new PgColumn({ name, type: column.macaddr() });
|
|
108
371
|
}
|
|
109
372
|
function macaddr8(name) {
|
|
110
|
-
return
|
|
373
|
+
return new PgColumn({ name, type: column.macaddr8() });
|
|
111
374
|
}
|
|
112
375
|
function numeric(...args) {
|
|
113
376
|
const { name, options } = columnConfig(args);
|
|
114
|
-
|
|
377
|
+
const mode = options?.mode;
|
|
378
|
+
const mapFromDriverValue = mode && (mode === "bigint" ? BigInt : Number);
|
|
379
|
+
return new PgColumn({
|
|
115
380
|
name,
|
|
116
|
-
type: column.numeric(options?.precision, options?.scale)
|
|
381
|
+
type: column.numeric(options?.precision, options?.scale),
|
|
382
|
+
mapFromDriverValue
|
|
117
383
|
});
|
|
118
384
|
}
|
|
119
385
|
function real(name) {
|
|
120
|
-
return
|
|
386
|
+
return new PgColumn({
|
|
121
387
|
name,
|
|
122
388
|
type: column.real(),
|
|
123
389
|
mapFromDriverValue(value) {
|
|
@@ -126,14 +392,14 @@ function real(name) {
|
|
|
126
392
|
});
|
|
127
393
|
}
|
|
128
394
|
function smallint(name) {
|
|
129
|
-
return
|
|
395
|
+
return new PgColumn({ name, type: column.smallint() });
|
|
130
396
|
}
|
|
131
397
|
function smallserial(name) {
|
|
132
|
-
return
|
|
398
|
+
return new PgColumn({ name, type: column.smallserial() });
|
|
133
399
|
}
|
|
134
400
|
function time(...args) {
|
|
135
401
|
const { name, options } = columnConfig(args);
|
|
136
|
-
return
|
|
402
|
+
return new PgColumn({
|
|
137
403
|
name,
|
|
138
404
|
type: column[options?.withTimeZone ? "time with time zone" : "time"](
|
|
139
405
|
options?.precision
|
|
@@ -142,11 +408,18 @@ function time(...args) {
|
|
|
142
408
|
}
|
|
143
409
|
function timestamp(...args) {
|
|
144
410
|
const { name, options } = columnConfig(args);
|
|
145
|
-
|
|
411
|
+
const withTimeZone = options?.withTimeZone ?? options?.withTimezone;
|
|
412
|
+
const mode = options?.mode ?? "date";
|
|
413
|
+
return new PgColumn({
|
|
146
414
|
name,
|
|
147
|
-
type: column[
|
|
415
|
+
type: column[withTimeZone ? "timestamp with time zone" : "timestamp"](
|
|
416
|
+
options?.precision
|
|
417
|
+
),
|
|
148
418
|
mapFromDriverValue(value) {
|
|
149
|
-
|
|
419
|
+
if (mode === "string") {
|
|
420
|
+
return value instanceof Date ? formatTimestampString(value, !!withTimeZone) : value;
|
|
421
|
+
}
|
|
422
|
+
return value instanceof Date ? value : new Date(value);
|
|
150
423
|
},
|
|
151
424
|
mapToDriverValue(value) {
|
|
152
425
|
return value instanceof Date ? value.toISOString() : value;
|
|
@@ -154,41 +427,50 @@ function timestamp(...args) {
|
|
|
154
427
|
});
|
|
155
428
|
}
|
|
156
429
|
function uuid(name) {
|
|
157
|
-
return
|
|
430
|
+
return new PgColumn({ name, type: column.uuid() });
|
|
158
431
|
}
|
|
159
432
|
function varchar(...args) {
|
|
160
433
|
const { name, options } = columnConfig(args);
|
|
161
|
-
return
|
|
434
|
+
return new PgColumn({
|
|
162
435
|
name,
|
|
163
436
|
type: column.varchar(options?.length)
|
|
164
437
|
});
|
|
165
438
|
}
|
|
166
439
|
export {
|
|
440
|
+
PgColumn,
|
|
167
441
|
bigint,
|
|
168
442
|
bigserial,
|
|
443
|
+
bit,
|
|
169
444
|
boolean,
|
|
170
445
|
bytea,
|
|
171
446
|
char,
|
|
172
447
|
cidr,
|
|
173
448
|
date,
|
|
174
449
|
doublePrecision,
|
|
450
|
+
geometry,
|
|
451
|
+
halfvec,
|
|
175
452
|
inet,
|
|
176
453
|
int,
|
|
177
454
|
integer,
|
|
178
455
|
interval,
|
|
179
456
|
json,
|
|
180
457
|
jsonb,
|
|
458
|
+
line,
|
|
181
459
|
macaddr,
|
|
182
460
|
macaddr8,
|
|
183
461
|
numeric,
|
|
184
462
|
oid,
|
|
463
|
+
point,
|
|
185
464
|
real,
|
|
186
465
|
serial,
|
|
187
466
|
smallint,
|
|
188
467
|
smallserial,
|
|
468
|
+
sparsevec,
|
|
189
469
|
text,
|
|
190
470
|
time,
|
|
191
471
|
timestamp,
|
|
192
472
|
uuid,
|
|
193
|
-
|
|
473
|
+
varbit,
|
|
474
|
+
varchar,
|
|
475
|
+
vector
|
|
194
476
|
};
|
package/dist/postgres/diff.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
// src/postgres/diff.ts
|
|
2
2
|
import { formatColumn } from "../core/Column.js";
|
|
3
|
-
import { getData, getTable } from "../core/Internal.js";
|
|
4
|
-
import { sql } from "../core/Sql.js";
|
|
5
|
-
import { table } from "../core/Table.js";
|
|
6
3
|
import {
|
|
7
4
|
and,
|
|
8
5
|
asc,
|
|
@@ -15,6 +12,9 @@ import {
|
|
|
15
12
|
or,
|
|
16
13
|
when
|
|
17
14
|
} from "../core/expr/Conditions.js";
|
|
15
|
+
import { getData, getTable } from "../core/Internal.js";
|
|
16
|
+
import { sql } from "../core/Sql.js";
|
|
17
|
+
import { table } from "../core/Table.js";
|
|
18
18
|
import { concat, txGenerator } from "../universal.js";
|
|
19
19
|
import * as column from "./columns.js";
|
|
20
20
|
import { postgresDialect } from "./dialect.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type HasCreate, type HasDrop } from '../core/Internal.js';
|
|
2
|
+
import type { Sql } from '../core/Sql.js';
|
|
3
|
+
import type { TableApi } from '../core/Table.js';
|
|
4
|
+
import { PgColumn } from './columns.js';
|
|
5
|
+
export interface PgEnum<Values extends EnumInput> extends HasCreate, HasDrop {
|
|
6
|
+
(name?: string): PgColumn<Values[keyof Values] | null>;
|
|
7
|
+
}
|
|
8
|
+
export interface PgEnumInfo {
|
|
9
|
+
name: string;
|
|
10
|
+
schema?: string;
|
|
11
|
+
values: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
type EnumInput = readonly [string, ...string[]] | Record<string, string>;
|
|
14
|
+
export declare function pgEnum<const Name extends string, const Values extends EnumInput>(name: Name, values: Values, schemaName?: string): PgEnum<Values>;
|
|
15
|
+
export declare function enumQuery(enumInfo: PgEnumInfo): Sql;
|
|
16
|
+
export declare function collectEnumQuery(table: TableApi): Array<Sql>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// src/postgres/enum.ts
|
|
2
|
+
import { ColumnType } from "../core/Column.js";
|
|
3
|
+
import {
|
|
4
|
+
getData,
|
|
5
|
+
getEnum,
|
|
6
|
+
hasEnum,
|
|
7
|
+
internalCreate,
|
|
8
|
+
internalDrop,
|
|
9
|
+
internalEnum
|
|
10
|
+
} from "../core/Internal.js";
|
|
11
|
+
import { sql } from "../core/Sql.js";
|
|
12
|
+
import { PgColumn } from "./columns.js";
|
|
13
|
+
function pgEnum(name, values, schemaName) {
|
|
14
|
+
const enumIdentifier = schemaName ? sql.join([sql.identifier(schemaName), sql.identifier(name)], sql`.`) : sql.identifier(name);
|
|
15
|
+
const enumType = new ColumnType(name, [], enumIdentifier);
|
|
16
|
+
const v = Array.isArray(values) ? values : Object.values(values);
|
|
17
|
+
const info = { name, schema: schemaName, values: v };
|
|
18
|
+
return Object.assign(
|
|
19
|
+
(columnName) => {
|
|
20
|
+
return new PgColumn({
|
|
21
|
+
name: columnName,
|
|
22
|
+
type: enumType,
|
|
23
|
+
[internalEnum]: info
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
get [internalCreate]() {
|
|
28
|
+
return [enumQuery(info)];
|
|
29
|
+
},
|
|
30
|
+
get [internalDrop]() {
|
|
31
|
+
return [sql`drop type if exists ${enumIdentifier}`];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function enumQuery(enumInfo) {
|
|
37
|
+
const enumIdentifier = enumInfo.schema ? sql.join(
|
|
38
|
+
[sql.identifier(enumInfo.schema), sql.identifier(enumInfo.name)],
|
|
39
|
+
sql`.`
|
|
40
|
+
) : sql.identifier(enumInfo.name);
|
|
41
|
+
return sql`do $$ begin create type ${enumIdentifier} as enum (${sql.join(
|
|
42
|
+
enumInfo.values.map(sql.inline),
|
|
43
|
+
sql`, `
|
|
44
|
+
)}); exception when duplicate_object then null; end $$`;
|
|
45
|
+
}
|
|
46
|
+
function collectEnumQuery(table) {
|
|
47
|
+
const enums = [];
|
|
48
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49
|
+
for (const column of Object.values(table.columns)) {
|
|
50
|
+
const data = getData(column);
|
|
51
|
+
if (!hasEnum(data)) continue;
|
|
52
|
+
const info = getEnum(data);
|
|
53
|
+
const enumKey = info.schema ? `${info.schema}.${info.name}` : info.name;
|
|
54
|
+
if (seen.has(enumKey)) continue;
|
|
55
|
+
seen.add(enumKey);
|
|
56
|
+
enums.push(enumQuery(info));
|
|
57
|
+
}
|
|
58
|
+
return enums;
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
collectEnumQuery,
|
|
62
|
+
enumQuery,
|
|
63
|
+
pgEnum
|
|
64
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type HasCreate, type HasDrop, internalCreate, internalDrop, internalTarget } from '../core/Internal.js';
|
|
2
|
+
import { type Sql } from '../core/Sql.js';
|
|
3
|
+
import type { Table, TableConfig, TableDefinition } from '../core/Table.js';
|
|
4
|
+
import { type DefinedView, type QueryView } from '../core/View.js';
|
|
5
|
+
import { type PgEnum } from './enum.js';
|
|
6
|
+
export declare class PgSchema<SchemaName extends string> implements HasCreate, HasDrop {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(schemaName: SchemaName);
|
|
9
|
+
get [internalTarget](): Sql;
|
|
10
|
+
get [internalCreate](): Array<Sql>;
|
|
11
|
+
get [internalDrop](): Array<Sql>;
|
|
12
|
+
table<Definition extends TableDefinition, TableName extends string>(tableName: TableName, columns: Definition, config?: (self: Table<Definition>) => TableConfig<TableName>): Table<Definition, TableName>;
|
|
13
|
+
enum<const Name extends string, const Values extends readonly [string, ...string[]]>(name: Name, values: Values): PgEnum<Values>;
|
|
14
|
+
view(name: string): QueryView;
|
|
15
|
+
view<Definition extends TableDefinition>(name: string, fields: Definition): DefinedView<Definition>;
|
|
16
|
+
materializedView(name: string): QueryView;
|
|
17
|
+
materializedView<Definition extends TableDefinition>(name: string, fields: Definition): DefinedView<Definition>;
|
|
18
|
+
}
|
|
19
|
+
export declare function pgSchema<SchemaName extends string>(schemaName: SchemaName): PgSchema<SchemaName>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// src/postgres/schema.ts
|
|
2
|
+
import {
|
|
3
|
+
internalCreate,
|
|
4
|
+
internalDrop,
|
|
5
|
+
internalTarget
|
|
6
|
+
} from "../core/Internal.js";
|
|
7
|
+
import { sql } from "../core/Sql.js";
|
|
8
|
+
import { table } from "../core/Table.js";
|
|
9
|
+
import {
|
|
10
|
+
materializedView,
|
|
11
|
+
view
|
|
12
|
+
} from "../core/View.js";
|
|
13
|
+
import { pgEnum } from "./enum.js";
|
|
14
|
+
var PgSchema = class {
|
|
15
|
+
#schemaName;
|
|
16
|
+
constructor(schemaName) {
|
|
17
|
+
this.#schemaName = schemaName;
|
|
18
|
+
}
|
|
19
|
+
get [internalTarget]() {
|
|
20
|
+
return sql.identifier(this.#schemaName);
|
|
21
|
+
}
|
|
22
|
+
get [internalCreate]() {
|
|
23
|
+
return [sql`create schema if not exists ${this}`];
|
|
24
|
+
}
|
|
25
|
+
get [internalDrop]() {
|
|
26
|
+
return [sql`drop schema if exists ${this} cascade`];
|
|
27
|
+
}
|
|
28
|
+
table(tableName, columns, config) {
|
|
29
|
+
return table(tableName, columns, config, this.#schemaName);
|
|
30
|
+
}
|
|
31
|
+
enum(name, values) {
|
|
32
|
+
return pgEnum(name, values, this.#schemaName);
|
|
33
|
+
}
|
|
34
|
+
view(name, fields) {
|
|
35
|
+
return view(name, fields, this.#schemaName);
|
|
36
|
+
}
|
|
37
|
+
materializedView(name, fields) {
|
|
38
|
+
return materializedView(name, fields, this.#schemaName);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
function pgSchema(schemaName) {
|
|
42
|
+
return new PgSchema(schemaName);
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
PgSchema,
|
|
46
|
+
pgSchema
|
|
47
|
+
};
|
package/dist/postgres.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export { foreignKey, primaryKey, unique } from './core/Constraint.js';
|
|
2
2
|
export { index, uniqueIndex } from './core/Index.js';
|
|
3
3
|
export { except, exceptAll, intersect, intersectAll, union, unionAll } from './core/query/Select.js';
|
|
4
|
-
export { schema as pgSchema } from './core/Schema.js';
|
|
5
4
|
export { alias, table as pgTable, tableCreator as pgTableCreator } from './core/Table.js';
|
|
5
|
+
export { materializedView as pgMaterializedView, view as pgView } from './core/View.js';
|
|
6
6
|
export * from './postgres/builder.js';
|
|
7
7
|
export * from './postgres/columns.js';
|
|
8
8
|
export * from './postgres/dialect.js';
|
|
9
|
+
export * from './postgres/enum.js';
|
|
10
|
+
export { pgSchema } from './postgres/schema.js';
|