rado 0.1.64 → 0.2.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 +269 -0
- package/dist/define/Column.d.ts +19 -19
- package/dist/define/Column.js +17 -5
- package/dist/define/Cursor.d.ts +48 -37
- package/dist/define/Cursor.js +109 -42
- package/dist/define/Expr.d.ts +2 -1
- package/dist/define/Expr.js +4 -3
- package/dist/define/Fields.d.ts +2 -2
- package/dist/define/Ops.js +6 -5
- package/dist/define/Query.d.ts +33 -18
- package/dist/define/Query.js +10 -5
- package/dist/define/Schema.d.ts +3 -10
- package/dist/define/Schema.js +51 -6
- package/dist/define/Selection.d.ts +3 -3
- package/dist/define/Table.d.ts +59 -51
- package/dist/define/Table.js +148 -103
- package/dist/define/Target.d.ts +4 -4
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/lib/Callable.d.ts +3 -0
- package/dist/lib/Callable.js +14 -0
- package/dist/lib/Driver.js +5 -4
- package/dist/lib/Formatter.d.ts +3 -0
- package/dist/lib/Formatter.js +58 -20
- package/package.json +1 -1
- package/dist/define/Update.d.ts +0 -4
- package/dist/define/Update.js +0 -0
package/dist/define/Table.d.ts
CHANGED
|
@@ -1,62 +1,70 @@
|
|
|
1
|
-
import { Column, PrimaryKey } from './Column';
|
|
1
|
+
import { Column, ColumnData, OptionalColumn, PrimaryColumn, PrimaryKey } from './Column';
|
|
2
2
|
import { Cursor } from './Cursor';
|
|
3
|
-
import { EV
|
|
4
|
-
import {
|
|
5
|
-
import { Index } from './Index';
|
|
6
|
-
import { Schema } from './Schema';
|
|
3
|
+
import { EV } from './Expr';
|
|
4
|
+
import { Index, IndexData } from './Index';
|
|
7
5
|
import { Selection } from './Selection';
|
|
8
|
-
|
|
9
|
-
export declare class Table<T> extends Cursor.SelectMultiple<Table.Normalize<T>> {
|
|
10
|
-
[Selection.__tableType](): Table.Normalize<T>;
|
|
11
|
-
constructor(schema: Schema);
|
|
12
|
-
fetch(id: EV<T extends {
|
|
13
|
-
id: Column.IsPrimary<infer V, any>;
|
|
14
|
-
} ? V : never>): Cursor.SelectSingle<Table.Normalize<T> | undefined>;
|
|
15
|
-
insertOne(record: Table.Insert<T>): Cursor<Table.Normalize<T>>;
|
|
16
|
-
insertAll(data: Array<Table.Insert<T>>): Cursor.InsertValues;
|
|
17
|
-
set(data: Update<Table.Normalize<T>>): Cursor.Update<Table.Normalize<T>>;
|
|
18
|
-
delete(): Cursor.Delete;
|
|
19
|
-
createTable(): Cursor.CreateTable;
|
|
20
|
-
as(alias: string): this;
|
|
21
|
-
alias(): Record<string, this>;
|
|
22
|
-
get(name: string): Expr<any>;
|
|
23
|
-
toExpr(): Expr<Table.Normalize<T>>;
|
|
24
|
-
schema(): Schema;
|
|
6
|
+
interface TableDefinition {
|
|
25
7
|
}
|
|
8
|
+
export interface TableData {
|
|
9
|
+
name: string;
|
|
10
|
+
alias?: string;
|
|
11
|
+
definition: TableDefinition;
|
|
12
|
+
columns: Record<string, ColumnData>;
|
|
13
|
+
meta(): {
|
|
14
|
+
indexes: Record<string, IndexData>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
interface TableProto<Definition> {
|
|
18
|
+
(conditions: {
|
|
19
|
+
[K in keyof Definition]?: Definition[K] extends Column<infer V> ? EV<V> : never;
|
|
20
|
+
}): Cursor.TableSelect<Definition>;
|
|
21
|
+
(...conditions: Array<EV<boolean>>): Cursor.TableSelect<Definition>;
|
|
22
|
+
}
|
|
23
|
+
declare class TableProto<Definition> {
|
|
24
|
+
[Selection.__tableType](): Table.Select<Definition>;
|
|
25
|
+
get [table.data](): TableData;
|
|
26
|
+
[table.meta](): TableMeta;
|
|
27
|
+
get name(): unknown;
|
|
28
|
+
get length(): unknown;
|
|
29
|
+
get call(): unknown;
|
|
30
|
+
get apply(): unknown;
|
|
31
|
+
get bind(): unknown;
|
|
32
|
+
get prototype(): unknown;
|
|
33
|
+
}
|
|
34
|
+
export type Table<Definition> = Definition & TableProto<Definition>;
|
|
26
35
|
export declare namespace Table {
|
|
27
|
-
type
|
|
28
|
-
[
|
|
29
|
-
}
|
|
30
|
-
type
|
|
31
|
-
[K in keyof
|
|
32
|
-
}[keyof T];
|
|
33
|
-
type RequiredKeys<T> = {
|
|
34
|
-
[K in keyof T]: null extends T[K] ? never : T[K] extends Column.IsPrimary<any, any> ? never : T[K] extends Column.IsOptional<any> ? never : K;
|
|
35
|
-
}[keyof T];
|
|
36
|
-
type Optionals<T> = {
|
|
37
|
-
[K in keyof T]?: T[K] extends Column.IsOptional<infer V> ? V : T[K] extends Column.IsPrimary<infer V, infer K> ? PrimaryKey<V, K> : T[K];
|
|
36
|
+
export type Of<Row> = Table<{
|
|
37
|
+
[K in keyof Row]: Column<Row[K]>;
|
|
38
|
+
}>;
|
|
39
|
+
export type Select<Definition> = {
|
|
40
|
+
[K in keyof Definition as Definition[K] extends Column<any> ? K : never]: Definition[K] extends PrimaryColumn<infer T, infer K> ? PrimaryKey<T, K> : Definition[K] extends Column<infer T> ? T : never;
|
|
38
41
|
};
|
|
39
|
-
export type
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
export type Update<Definition> = Partial<{
|
|
43
|
+
[K in keyof Definition as Definition[K] extends Column<any> ? K : never]: Definition[K] extends Column<infer T> ? EV<T> : never;
|
|
44
|
+
}>;
|
|
45
|
+
type IsOptional<K> = K extends PrimaryColumn<any, any> ? true : K extends OptionalColumn<any> ? true : K extends Column<infer V> ? null extends V ? true : false : never;
|
|
46
|
+
export type Insert<Definition> = {
|
|
47
|
+
[K in keyof Definition as true extends IsOptional<Definition[K]> ? K : never]?: Definition[K] extends Column<infer V> ? EV<V> : never;
|
|
48
|
+
} & {
|
|
49
|
+
[K in keyof Definition as false extends IsOptional<Definition[K]> ? K : never]: Definition[K] extends Column<infer V> ? EV<V> : never;
|
|
42
50
|
};
|
|
43
|
-
export type Infer<T> = T extends Table<infer U> ? Normalize<U> : never;
|
|
44
51
|
export {};
|
|
45
52
|
}
|
|
46
|
-
export
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
indexes?: (this: Fields<T>) => Record<string, Index>;
|
|
53
|
+
export interface TableMeta {
|
|
54
|
+
indexes?: Record<string, Index>;
|
|
55
|
+
}
|
|
56
|
+
type Definition<T> = {
|
|
57
|
+
[K in keyof T as K extends string ? K : never]: Column<any> | (() => any);
|
|
53
58
|
};
|
|
54
|
-
|
|
59
|
+
interface Define<T> {
|
|
60
|
+
new (): T;
|
|
61
|
+
}
|
|
62
|
+
type Blueprint<T> = Definition<T>;
|
|
63
|
+
export type table<T> = T extends Table<infer D> ? Table.Select<D> : never;
|
|
64
|
+
export declare function createTable<Definition>(data: TableData): Table<Definition>;
|
|
65
|
+
export declare function table<T extends Blueprint<T>>(define: Record<string, T | Define<T>>): Table<T>;
|
|
55
66
|
export declare namespace table {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
[key: string]: (this: T, ...args: any[]) => any;
|
|
59
|
-
};
|
|
60
|
-
export function extend<T extends Table<any>, E extends Extensions<T>>(target: T, extensions: E): T & E;
|
|
61
|
-
export {};
|
|
67
|
+
const data: unique symbol;
|
|
68
|
+
const meta: unique symbol;
|
|
62
69
|
}
|
|
70
|
+
export {};
|
package/dist/define/Table.js
CHANGED
|
@@ -1,130 +1,175 @@
|
|
|
1
1
|
// src/define/Table.ts
|
|
2
|
+
import {
|
|
3
|
+
Column
|
|
4
|
+
} from "./Column.js";
|
|
2
5
|
import { Cursor } from "./Cursor.js";
|
|
3
|
-
import { Expr, ExprData } from "./Expr.js";
|
|
4
|
-
import { Query } from "./Query.js";
|
|
6
|
+
import { BinOpType, Expr, ExprData } from "./Expr.js";
|
|
5
7
|
import { Selection } from "./Selection.js";
|
|
6
8
|
import { Target } from "./Target.js";
|
|
7
|
-
var
|
|
9
|
+
var {
|
|
10
|
+
keys,
|
|
11
|
+
entries,
|
|
12
|
+
fromEntries,
|
|
13
|
+
getOwnPropertyDescriptors,
|
|
14
|
+
assign,
|
|
15
|
+
getPrototypeOf,
|
|
16
|
+
setPrototypeOf,
|
|
17
|
+
getOwnPropertyDescriptor
|
|
18
|
+
} = Object;
|
|
19
|
+
var { ownKeys } = Reflect;
|
|
20
|
+
var TableProto = class {
|
|
8
21
|
[Selection.__tableType]() {
|
|
9
22
|
throw "assert";
|
|
10
23
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Query.Select({
|
|
14
|
-
from: Target.Table(schema),
|
|
15
|
-
selection: ExprData.Row(Target.Table(schema))
|
|
16
|
-
})
|
|
17
|
-
);
|
|
18
|
-
Object.defineProperty(this, "schema", {
|
|
19
|
-
enumerable: false,
|
|
20
|
-
value: () => schema
|
|
21
|
-
});
|
|
22
|
-
if (schema.columns)
|
|
23
|
-
for (const column of Object.keys(schema.columns)) {
|
|
24
|
-
Object.defineProperty(this, column, {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: () => this.get(column)
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
return new Proxy(this, {
|
|
30
|
-
get(target, key) {
|
|
31
|
-
return key in target ? target[key] : target.get(key);
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
fetch(id) {
|
|
36
|
-
return this.where(this.get("id").is(id)).first();
|
|
37
|
-
}
|
|
38
|
-
insertOne(record) {
|
|
39
|
-
return new Cursor(
|
|
40
|
-
Query.Insert({
|
|
41
|
-
into: this.schema(),
|
|
42
|
-
data: [record],
|
|
43
|
-
selection: ExprData.Row(Target.Table(this.schema())),
|
|
44
|
-
singleResult: true
|
|
45
|
-
})
|
|
46
|
-
);
|
|
24
|
+
get [table.data]() {
|
|
25
|
+
throw "assert";
|
|
47
26
|
}
|
|
48
|
-
|
|
49
|
-
|
|
27
|
+
[table.meta]() {
|
|
28
|
+
throw "assert";
|
|
50
29
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
30
|
+
// Clear the Function prototype, not sure if there's a better way
|
|
31
|
+
// as mapped types (Omit) will remove the callable signature. We define them
|
|
32
|
+
// in a class getter since it's the only way to also mark them as non-enumarable
|
|
33
|
+
// Seems open: Microsoft/TypeScript#27575
|
|
34
|
+
get name() {
|
|
35
|
+
throw "assert";
|
|
57
36
|
}
|
|
58
|
-
|
|
59
|
-
|
|
37
|
+
get length() {
|
|
38
|
+
throw "assert";
|
|
60
39
|
}
|
|
61
|
-
|
|
62
|
-
|
|
40
|
+
get call() {
|
|
41
|
+
throw "assert";
|
|
63
42
|
}
|
|
64
|
-
|
|
65
|
-
|
|
43
|
+
get apply() {
|
|
44
|
+
throw "assert";
|
|
66
45
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
{},
|
|
70
|
-
{
|
|
71
|
-
get: (_, key) => {
|
|
72
|
-
return this.as(key);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
);
|
|
46
|
+
get bind() {
|
|
47
|
+
throw "assert";
|
|
76
48
|
}
|
|
77
|
-
get(
|
|
78
|
-
|
|
49
|
+
get prototype() {
|
|
50
|
+
throw "assert";
|
|
79
51
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
52
|
+
};
|
|
53
|
+
function keysOf(input) {
|
|
54
|
+
const methods = [];
|
|
55
|
+
while (input = getPrototypeOf(input)) {
|
|
56
|
+
const keys2 = ownKeys(input);
|
|
57
|
+
for (const key of keys2)
|
|
58
|
+
if (typeof key === "string")
|
|
59
|
+
methods.push(key);
|
|
84
60
|
}
|
|
85
|
-
|
|
86
|
-
|
|
61
|
+
return methods;
|
|
62
|
+
}
|
|
63
|
+
function createTable(data) {
|
|
64
|
+
const target = Target.Table(data);
|
|
65
|
+
const call = {
|
|
66
|
+
[data.name]: function(...args) {
|
|
67
|
+
const isConditionalRecord = args.length === 1 && typeof args[0] === "object" && !(args[0] instanceof Expr);
|
|
68
|
+
const conditions = isConditionalRecord ? entries(args[0]).map(([key, value]) => {
|
|
69
|
+
const column = data.columns[key];
|
|
70
|
+
if (!column)
|
|
71
|
+
throw new Error(`Column ${key} not found`);
|
|
72
|
+
return new Expr(
|
|
73
|
+
ExprData.BinOp(
|
|
74
|
+
BinOpType.Equals,
|
|
75
|
+
ExprData.Field(ExprData.Row(target), key),
|
|
76
|
+
ExprData.create(value)
|
|
77
|
+
)
|
|
78
|
+
);
|
|
79
|
+
}) : args;
|
|
80
|
+
return new Cursor.TableSelect(data, conditions);
|
|
81
|
+
}
|
|
82
|
+
}[data.name];
|
|
83
|
+
const cols = keys(data.columns);
|
|
84
|
+
const hasKeywords = cols.concat(keysOf(data.definition)).some((name) => name in Function);
|
|
85
|
+
const expressions = fromEntries(
|
|
86
|
+
cols.map((name) => [
|
|
87
|
+
name,
|
|
88
|
+
new Expr(ExprData.Field(ExprData.Row(target), name))
|
|
89
|
+
])
|
|
90
|
+
);
|
|
91
|
+
const toExpr = () => new Expr(ExprData.Row(target));
|
|
92
|
+
const ownKeys2 = ["prototype", ...cols];
|
|
93
|
+
let res;
|
|
94
|
+
if (!hasKeywords) {
|
|
95
|
+
res = assign(call, expressions, { [table.data]: data });
|
|
96
|
+
setPrototypeOf(call, getPrototypeOf(data.definition));
|
|
97
|
+
} else {
|
|
98
|
+
let get2 = function(key) {
|
|
99
|
+
return expressions[key] || data.definition[key];
|
|
100
|
+
};
|
|
101
|
+
var get = get2;
|
|
102
|
+
res = new Proxy(call, {
|
|
103
|
+
get(target2, key) {
|
|
104
|
+
if (key === table.data)
|
|
105
|
+
return data;
|
|
106
|
+
if (key === Expr.toExpr)
|
|
107
|
+
return toExpr;
|
|
108
|
+
return get2(key);
|
|
109
|
+
},
|
|
110
|
+
ownKeys(target2) {
|
|
111
|
+
return ownKeys2;
|
|
112
|
+
},
|
|
113
|
+
getOwnPropertyDescriptor(target2, key) {
|
|
114
|
+
if (key === "prototype")
|
|
115
|
+
return getOwnPropertyDescriptor(target2, key);
|
|
116
|
+
return {
|
|
117
|
+
value: get2(key),
|
|
118
|
+
enumerable: true,
|
|
119
|
+
configurable: true
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
});
|
|
87
123
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
124
|
+
return res;
|
|
125
|
+
}
|
|
126
|
+
function table(define) {
|
|
127
|
+
const names = keys(define);
|
|
128
|
+
if (names.length !== 1)
|
|
129
|
+
throw new Error("Table must have a single name");
|
|
130
|
+
const name = names[0];
|
|
131
|
+
const target = define[name];
|
|
132
|
+
const definition = "prototype" in target ? new target() : target;
|
|
133
|
+
const columns = definition;
|
|
134
|
+
const res = createTable({
|
|
135
|
+
name,
|
|
136
|
+
definition,
|
|
137
|
+
columns: fromEntries(
|
|
138
|
+
entries(getOwnPropertyDescriptors(columns)).map(([name2, descriptor]) => {
|
|
139
|
+
const column = columns[name2];
|
|
140
|
+
if (!(column instanceof Column))
|
|
141
|
+
throw new Error(`Property ${name2} is not a column`);
|
|
94
142
|
const { data } = column;
|
|
95
|
-
return [
|
|
143
|
+
return [
|
|
144
|
+
name2,
|
|
145
|
+
{
|
|
146
|
+
...data,
|
|
147
|
+
name: data.name || name2,
|
|
148
|
+
enumerable: descriptor.enumerable
|
|
149
|
+
}
|
|
150
|
+
];
|
|
96
151
|
})
|
|
97
152
|
),
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return new Table({
|
|
111
|
-
...schema,
|
|
112
|
-
indexes
|
|
153
|
+
meta() {
|
|
154
|
+
const createMeta = res[table.meta];
|
|
155
|
+
const meta = createMeta ? createMeta.apply(res) : {};
|
|
156
|
+
return {
|
|
157
|
+
indexes: fromEntries(
|
|
158
|
+
entries(meta?.indexes || {}).map(([key, index]) => {
|
|
159
|
+
const indexName = `${name}.${key}`;
|
|
160
|
+
return [indexName, { name: indexName, ...index.data }];
|
|
161
|
+
})
|
|
162
|
+
)
|
|
163
|
+
};
|
|
164
|
+
}
|
|
113
165
|
});
|
|
166
|
+
return res;
|
|
114
167
|
}
|
|
115
168
|
((table2) => {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
get(target2, key) {
|
|
119
|
-
if (key === "as")
|
|
120
|
-
return (...args) => extend(target2.as(...args), extensions);
|
|
121
|
-
return key in extensions ? extensions[key].bind(target2) : target2[key];
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
table2.extend = extend;
|
|
169
|
+
table2.data = Symbol("data");
|
|
170
|
+
table2.meta = Symbol("meta");
|
|
126
171
|
})(table || (table = {}));
|
|
127
172
|
export {
|
|
128
|
-
|
|
173
|
+
createTable,
|
|
129
174
|
table
|
|
130
175
|
};
|
package/dist/define/Target.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ExprData } from './Expr';
|
|
2
2
|
import { Query as QueryData } from './Query';
|
|
3
|
-
import {
|
|
3
|
+
import { TableData } from './Table';
|
|
4
4
|
export declare enum TargetType {
|
|
5
5
|
Expr = "Expr",
|
|
6
6
|
Query = "Query",
|
|
@@ -23,9 +23,9 @@ export declare namespace Target {
|
|
|
23
23
|
function Query(query: QueryData, alias?: string): Query;
|
|
24
24
|
interface Table {
|
|
25
25
|
type: TargetType.Table;
|
|
26
|
-
table:
|
|
26
|
+
table: TableData;
|
|
27
27
|
}
|
|
28
|
-
function Table(table:
|
|
28
|
+
function Table(table: TableData): Table;
|
|
29
29
|
interface Join {
|
|
30
30
|
type: TargetType.Join;
|
|
31
31
|
left: Target;
|
|
@@ -34,5 +34,5 @@ export declare namespace Target {
|
|
|
34
34
|
on: ExprData;
|
|
35
35
|
}
|
|
36
36
|
function Join(left: Target, right: Target, joinType: 'left' | 'inner', on: ExprData): Join;
|
|
37
|
-
function source(from: Target):
|
|
37
|
+
function source(from: Target): TableData | undefined;
|
|
38
38
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,6 @@ export * from './define/Schema';
|
|
|
13
13
|
export * from './define/Selection';
|
|
14
14
|
export * from './define/Table';
|
|
15
15
|
export * from './define/Target';
|
|
16
|
-
export * from './define/Update';
|
|
17
16
|
export type { Driver } from './lib/Driver';
|
|
18
17
|
export type { FormatContext, Formatter } from './lib/Formatter';
|
|
19
18
|
export type { Sanitizer } from './lib/Sanitizer';
|
package/dist/index.js
CHANGED
package/dist/lib/Driver.js
CHANGED
|
@@ -4,6 +4,7 @@ import { Expr, ExprData } from "../define/Expr.js";
|
|
|
4
4
|
import { ParamData } from "../define/Param.js";
|
|
5
5
|
import { Query, QueryType } from "../define/Query.js";
|
|
6
6
|
import { Schema } from "../define/Schema.js";
|
|
7
|
+
import { table } from "../define/Table.js";
|
|
7
8
|
var Callable = class extends Function {
|
|
8
9
|
constructor(fn) {
|
|
9
10
|
super();
|
|
@@ -80,8 +81,8 @@ var SyncDriver = class extends DriverBase {
|
|
|
80
81
|
}
|
|
81
82
|
migrateSchema(...tables) {
|
|
82
83
|
const queries = [];
|
|
83
|
-
for (const
|
|
84
|
-
const schema = table.
|
|
84
|
+
for (const current of Object.values(tables)) {
|
|
85
|
+
const schema = current[table.data];
|
|
85
86
|
const localSchema = this.schemaInstructions(schema.name);
|
|
86
87
|
if (!localSchema) {
|
|
87
88
|
queries.push(...Schema.create(schema).queries);
|
|
@@ -186,8 +187,8 @@ var AsyncDriver = class extends DriverBase {
|
|
|
186
187
|
}
|
|
187
188
|
async migrateSchema(...tables) {
|
|
188
189
|
const queries = [];
|
|
189
|
-
for (const
|
|
190
|
-
const schema = table.
|
|
190
|
+
for (const current of Object.values(tables)) {
|
|
191
|
+
const schema = current[table.data];
|
|
191
192
|
const localSchema = await this.schemaInstructions(schema.name);
|
|
192
193
|
if (!localSchema) {
|
|
193
194
|
queries.push(...Schema.create(schema).queries);
|
package/dist/lib/Formatter.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface FormatContext {
|
|
|
22
22
|
formatAsInsert?: boolean;
|
|
23
23
|
formatAsIn?: boolean;
|
|
24
24
|
topLevel?: boolean;
|
|
25
|
+
selectAsColumns?: boolean;
|
|
25
26
|
}
|
|
26
27
|
type FormatSubject = (stmt: Statement, mkSubject: () => void) => void;
|
|
27
28
|
export interface CompileOptions extends Partial<FormatContext>, StatementOptions {
|
|
@@ -43,6 +44,7 @@ export declare abstract class Formatter implements Sanitizer {
|
|
|
43
44
|
formatAsInsert?: boolean | undefined;
|
|
44
45
|
formatAsIn?: boolean | undefined;
|
|
45
46
|
topLevel?: boolean | undefined;
|
|
47
|
+
selectAsColumns?: boolean | undefined;
|
|
46
48
|
skipNewlines?: boolean | undefined;
|
|
47
49
|
};
|
|
48
50
|
format<T>(ctx: FormatContext, query: Query<T>): Statement;
|
|
@@ -54,6 +56,7 @@ export declare abstract class Formatter implements Sanitizer {
|
|
|
54
56
|
formatCreateIndex(ctx: FormatContext, query: Query.CreateIndex): Statement;
|
|
55
57
|
formatDropIndex(ctx: FormatContext, query: Query.DropIndex): Statement;
|
|
56
58
|
formatAlterTable(ctx: FormatContext, query: Query.AlterTable): Statement;
|
|
59
|
+
formatDropTable(ctx: FormatContext, query: Query.DropTable): Statement;
|
|
57
60
|
formatTransaction(ctx: FormatContext, { op, id }: Query.Transaction): Statement;
|
|
58
61
|
formatBatch(ctx: FormatContext, { queries }: Query.Batch): Statement;
|
|
59
62
|
formatRaw(ctx: FormatContext, { strings, params }: Query.Raw): Statement;
|
package/dist/lib/Formatter.js
CHANGED
|
@@ -61,12 +61,14 @@ var Formatter = class {
|
|
|
61
61
|
return this.formatDelete(ctx, query);
|
|
62
62
|
case QueryType.CreateTable:
|
|
63
63
|
return this.formatCreateTable(ctx, query);
|
|
64
|
+
case QueryType.AlterTable:
|
|
65
|
+
return this.formatAlterTable(ctx, query);
|
|
66
|
+
case QueryType.DropTable:
|
|
67
|
+
return this.formatDropTable(ctx, query);
|
|
64
68
|
case QueryType.CreateIndex:
|
|
65
69
|
return this.formatCreateIndex(ctx, query);
|
|
66
70
|
case QueryType.DropIndex:
|
|
67
71
|
return this.formatDropIndex(ctx, query);
|
|
68
|
-
case QueryType.AlterTable:
|
|
69
|
-
return this.formatAlterTable(ctx, query);
|
|
70
72
|
case QueryType.Transaction:
|
|
71
73
|
return this.formatTransaction(ctx, query);
|
|
72
74
|
case QueryType.Batch:
|
|
@@ -96,18 +98,28 @@ var Formatter = class {
|
|
|
96
98
|
}
|
|
97
99
|
formatInsert(ctx, query) {
|
|
98
100
|
const { stmt } = ctx;
|
|
99
|
-
const columns = Object.values(query.into.columns);
|
|
101
|
+
const columns = Object.values(query.into.columns).map((c) => c.name);
|
|
100
102
|
stmt.add("INSERT INTO").addIdentifier(query.into.name);
|
|
101
103
|
if (query.into.alias)
|
|
102
104
|
stmt.raw("AS").addIdentifier(query.into.alias);
|
|
103
105
|
for (const column of stmt.call(columns))
|
|
104
|
-
this.formatString(ctx, column
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
stmt.add("()");
|
|
108
|
-
else
|
|
106
|
+
this.formatString(ctx, column);
|
|
107
|
+
if (query.data) {
|
|
108
|
+
stmt.add("VALUES").space();
|
|
109
109
|
for (const row of stmt.separate(query.data))
|
|
110
110
|
this.formatInsertRow(ctx, query.into.columns, row);
|
|
111
|
+
}
|
|
112
|
+
if (query.select) {
|
|
113
|
+
stmt.space();
|
|
114
|
+
this.formatSelect(
|
|
115
|
+
{
|
|
116
|
+
...ctx,
|
|
117
|
+
topLevel: false,
|
|
118
|
+
selectAsColumns: true
|
|
119
|
+
},
|
|
120
|
+
query.select
|
|
121
|
+
);
|
|
122
|
+
}
|
|
111
123
|
if (query.selection) {
|
|
112
124
|
stmt.add("RETURNING").space();
|
|
113
125
|
this.formatSelection(ctx, query.selection, formatAsResultObject);
|
|
@@ -183,17 +195,33 @@ var Formatter = class {
|
|
|
183
195
|
}
|
|
184
196
|
formatAlterTable(ctx, query) {
|
|
185
197
|
const { stmt } = ctx;
|
|
186
|
-
stmt.add("ALTER TABLE").addIdentifier(
|
|
198
|
+
stmt.add("ALTER TABLE").addIdentifier(
|
|
199
|
+
query.renameTable ? query.renameTable.from : query.table.name
|
|
200
|
+
);
|
|
187
201
|
if (query.addColumn) {
|
|
188
202
|
stmt.add("ADD COLUMN").space();
|
|
189
203
|
this.formatColumn(ctx, query.addColumn);
|
|
190
204
|
} else if (query.dropColumn) {
|
|
191
205
|
stmt.add("DROP COLUMN").addIdentifier(query.dropColumn);
|
|
206
|
+
} else if (query.renameColumn) {
|
|
207
|
+
stmt.add("RENAME COLUMN");
|
|
208
|
+
stmt.addIdentifier(query.renameColumn.from).add("TO");
|
|
209
|
+
stmt.addIdentifier(query.renameColumn.to);
|
|
210
|
+
} else if (query.renameTable) {
|
|
211
|
+
stmt.add("RENAME TO").addIdentifier(query.table.name);
|
|
192
212
|
} else if (query.alterColumn) {
|
|
193
213
|
throw new Error(`Not available in this formatter: alter column`);
|
|
194
214
|
}
|
|
195
215
|
return stmt;
|
|
196
216
|
}
|
|
217
|
+
formatDropTable(ctx, query) {
|
|
218
|
+
const { stmt } = ctx;
|
|
219
|
+
stmt.add("DROP TABLE");
|
|
220
|
+
if (query.ifExists)
|
|
221
|
+
stmt.add("IF EXISTS");
|
|
222
|
+
stmt.addIdentifier(query.table.name);
|
|
223
|
+
return stmt;
|
|
224
|
+
}
|
|
197
225
|
formatTransaction(ctx, { op, id }) {
|
|
198
226
|
const { stmt } = ctx;
|
|
199
227
|
switch (op) {
|
|
@@ -393,10 +421,10 @@ var Formatter = class {
|
|
|
393
421
|
const { stmt, forceInline } = ctx;
|
|
394
422
|
if (!limit && !offset && !singleResult)
|
|
395
423
|
return stmt;
|
|
396
|
-
stmt.newline().raw("LIMIT");
|
|
424
|
+
stmt.newline().raw("LIMIT").space();
|
|
397
425
|
this.formatValue(ctx, singleResult ? 1 : limit);
|
|
398
426
|
if (offset && offset > 0) {
|
|
399
|
-
stmt.
|
|
427
|
+
stmt.add("OFFSET").space();
|
|
400
428
|
this.formatValue(ctx, offset);
|
|
401
429
|
}
|
|
402
430
|
return stmt;
|
|
@@ -414,7 +442,8 @@ var Formatter = class {
|
|
|
414
442
|
formatSubject(stmt, mkSubject);
|
|
415
443
|
else
|
|
416
444
|
this.formatExpr(ctx, selection);
|
|
417
|
-
|
|
445
|
+
if (!ctx.selectAsColumns)
|
|
446
|
+
stmt.add("AS").addIdentifier("result");
|
|
418
447
|
return stmt;
|
|
419
448
|
}
|
|
420
449
|
formatExprJson(ctx, expr) {
|
|
@@ -579,12 +608,12 @@ var Formatter = class {
|
|
|
579
608
|
return stmt.closeParenthesis();
|
|
580
609
|
}
|
|
581
610
|
if (expr.query.singleResult) {
|
|
582
|
-
stmt.
|
|
583
|
-
this.format(ctx, expr.query);
|
|
584
|
-
return stmt.closeParenthesis().
|
|
611
|
+
stmt.openParenthesis();
|
|
612
|
+
this.format({ ...ctx, topLevel: true }, expr.query);
|
|
613
|
+
return stmt.closeParenthesis().raw(`->'$.result'`);
|
|
585
614
|
}
|
|
586
|
-
stmt.openParenthesis().raw(
|
|
587
|
-
this.format(ctx, expr.query);
|
|
615
|
+
stmt.openParenthesis().raw(`SELECT json_group_array(result->'$.result')`).newline().raw("FROM").space().openParenthesis();
|
|
616
|
+
this.format({ ...ctx, topLevel: true }, expr.query);
|
|
588
617
|
return stmt.closeParenthesis().closeParenthesis();
|
|
589
618
|
case ExprType.Row:
|
|
590
619
|
switch (expr.target.type) {
|
|
@@ -615,12 +644,21 @@ var Formatter = class {
|
|
|
615
644
|
this.formatExpr({ ...ctx, formatAsJson: true }, expr.b);
|
|
616
645
|
return stmt.closeParenthesis();
|
|
617
646
|
case ExprType.Record:
|
|
618
|
-
|
|
619
|
-
|
|
647
|
+
if (ctx.selectAsColumns) {
|
|
648
|
+
const inner = { ...ctx, selectAsColumns: false };
|
|
649
|
+
for (const [key, value] of stmt.separate(
|
|
650
|
+
Object.entries(expr.fields)
|
|
651
|
+
)) {
|
|
652
|
+
this.formatExprJson(inner, value);
|
|
653
|
+
}
|
|
654
|
+
return stmt;
|
|
655
|
+
}
|
|
656
|
+
stmt.identifier("json_object").openParenthesis();
|
|
657
|
+
for (const [key, value] of stmt.separate(Object.entries(expr.fields))) {
|
|
620
658
|
this.formatString(ctx, key).raw(", ");
|
|
621
659
|
this.formatExprJson(ctx, value);
|
|
622
660
|
}
|
|
623
|
-
return stmt;
|
|
661
|
+
return stmt.closeParenthesis();
|
|
624
662
|
case ExprType.Filter: {
|
|
625
663
|
const { target, condition } = expr;
|
|
626
664
|
switch (target.type) {
|