@devbro/neko-sql 0.1.16 → 0.1.17
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/dist/{Blueprint-mmlqFfF6.d.mts → Blueprint-DiSVtLdl.d.mts} +13 -8
- package/dist/Blueprint.d.mts +1 -1
- package/dist/Connection.d.mts +1 -1
- package/dist/Expression.d.mts +1 -1
- package/dist/Expression.mjs +3 -1
- package/dist/Expression.mjs.map +1 -1
- package/dist/Migration.d.mts +1 -1
- package/dist/Query.d.mts +1 -1
- package/dist/Query.mjs +15 -2
- package/dist/Query.mjs.map +1 -1
- package/dist/QueryGrammar.d.mts +1 -1
- package/dist/QueryGrammar.mjs +149 -72
- package/dist/QueryGrammar.mjs.map +1 -1
- package/dist/Schema.d.mts +1 -1
- package/dist/Schema.mjs +2 -2
- package/dist/Schema.mjs.map +1 -1
- package/dist/SchemaGrammar.d.mts +1 -1
- package/dist/SchemaGrammar.mjs +14 -6
- package/dist/SchemaGrammar.mjs.map +1 -1
- package/dist/databases/index.d.mts +1 -1
- package/dist/databases/postgresql/PostgresqlConnection.d.mts +1 -1
- package/dist/databases/postgresql/PostgresqlConnection.mjs +6 -1
- package/dist/databases/postgresql/PostgresqlConnection.mjs.map +1 -1
- package/dist/databases/postgresql/PostgresqlQueryGrammar.d.mts +1 -3
- package/dist/databases/postgresql/PostgresqlQueryGrammar.mjs +0 -12
- package/dist/databases/postgresql/PostgresqlQueryGrammar.mjs.map +1 -1
- package/dist/databases/postgresql/PostgresqlSchemaGrammar.d.mts +1 -1
- package/dist/databases/postgresql/index.d.mts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.js +189 -96
- package/dist/index.js.map +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +5 -4
|
@@ -38,8 +38,10 @@ declare class Schema {
|
|
|
38
38
|
declare abstract class QueryGrammar {
|
|
39
39
|
sqlParts: string[];
|
|
40
40
|
toSql(query: Query): CompiledSql;
|
|
41
|
+
toSqlParts(query: Query): CompiledSql;
|
|
41
42
|
compileCount(query: Query): CompiledSql;
|
|
42
43
|
compileSelect(selects: selectType[]): CompiledSql;
|
|
44
|
+
joinArray(arr: (string | number)[]): string;
|
|
43
45
|
compileTable(tableName: string): CompiledSql;
|
|
44
46
|
compileJoin(joins: joinType[]): CompiledSql;
|
|
45
47
|
compileWhere(wheres: whereType[]): CompiledSql;
|
|
@@ -50,7 +52,6 @@ declare abstract class QueryGrammar {
|
|
|
50
52
|
compileOrderBy(orderBy: string[]): CompiledSql;
|
|
51
53
|
compileLimit(limit: number | null): CompiledSql;
|
|
52
54
|
compileOffset(offset: number | null): CompiledSql;
|
|
53
|
-
abstract getVariablePlaceholder(): string;
|
|
54
55
|
compileWhereNull(w: whereNull): CompiledSql;
|
|
55
56
|
compileInsert(query: Query, data: Record<string, Parameter>): CompiledSql;
|
|
56
57
|
abstract compileInsertGetId(query: Query, data: Record<string, Parameter>, options: {
|
|
@@ -89,6 +90,7 @@ type QueryParts = {
|
|
|
89
90
|
orderBy: string[];
|
|
90
91
|
limit: number | null;
|
|
91
92
|
offset: number | null;
|
|
93
|
+
alias: string | null;
|
|
92
94
|
};
|
|
93
95
|
declare class Query {
|
|
94
96
|
readonly connection: Connection | null;
|
|
@@ -112,6 +114,7 @@ declare class Query {
|
|
|
112
114
|
offset(offset: number): this;
|
|
113
115
|
toSql(): CompiledSql;
|
|
114
116
|
get(): Promise<any>;
|
|
117
|
+
first(): Promise<any>;
|
|
115
118
|
count(): Promise<number>;
|
|
116
119
|
getCursor(): Promise<any>;
|
|
117
120
|
getConnection(): Connection | null;
|
|
@@ -122,30 +125,31 @@ declare class Query {
|
|
|
122
125
|
update(data: Record<string, Parameter>): Promise<any>;
|
|
123
126
|
upsert(data: Record<string, Parameter>, uniqueColumns: string[], updateColumns: string[]): Promise<any>;
|
|
124
127
|
delete(): Promise<any>;
|
|
125
|
-
join(table: string, type: joinType['type'], conditions: (whereType | {
|
|
128
|
+
join(table: string | Query, type: joinType['type'], conditions: (whereType | {
|
|
126
129
|
column1: string;
|
|
127
130
|
column2: string;
|
|
128
131
|
})[]): this;
|
|
129
|
-
innerJoin(table:
|
|
132
|
+
innerJoin(table: Parameters<typeof this.join>[0], conditions: (whereType | {
|
|
130
133
|
column1: string;
|
|
131
134
|
column2: string;
|
|
132
135
|
})[]): this;
|
|
133
|
-
leftJoin(table:
|
|
136
|
+
leftJoin(table: Parameters<typeof this.join>[0], conditions: (whereType | {
|
|
134
137
|
column1: string;
|
|
135
138
|
column2: string;
|
|
136
139
|
})[]): this;
|
|
137
|
-
rightJoin(table:
|
|
140
|
+
rightJoin(table: Parameters<typeof this.join>[0], conditions: (whereType | {
|
|
138
141
|
column1: string;
|
|
139
142
|
column2: string;
|
|
140
143
|
})[]): this;
|
|
141
|
-
fullJoin(table:
|
|
144
|
+
fullJoin(table: Parameters<typeof this.join>[0], conditions: (whereType | {
|
|
142
145
|
column1: string;
|
|
143
146
|
column2: string;
|
|
144
147
|
})[]): this;
|
|
145
|
-
crossJoin(table:
|
|
148
|
+
crossJoin(table: Parameters<typeof this.join>[0], conditions: (whereType | {
|
|
146
149
|
column1: string;
|
|
147
150
|
column2: string;
|
|
148
151
|
})[]): this;
|
|
152
|
+
alias(alias: string): this;
|
|
149
153
|
}
|
|
150
154
|
|
|
151
155
|
type selectType = string;
|
|
@@ -183,12 +187,13 @@ type Parameter = string | number | Date | boolean | null | Expression | undefine
|
|
|
183
187
|
type JoinCondition = 'and' | 'or';
|
|
184
188
|
type CompiledSql = {
|
|
185
189
|
sql: string;
|
|
190
|
+
parts: (string | number)[];
|
|
186
191
|
bindings: Parameter[];
|
|
187
192
|
};
|
|
188
193
|
type havingType = whereBasic & (whereOp | whereRaw);
|
|
189
194
|
type joinType = {
|
|
190
195
|
type: 'inner' | 'left' | 'right' | 'full' | 'cross';
|
|
191
|
-
table: string;
|
|
196
|
+
table: string | Query;
|
|
192
197
|
conditions: whereType[];
|
|
193
198
|
};
|
|
194
199
|
|
package/dist/Blueprint.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { B as Blueprint, a as Column, C as ColumnPropertiesType, F as ForeignKeyConstraint, I as IndexConstraint } from './Blueprint-
|
|
1
|
+
export { B as Blueprint, a as Column, C as ColumnPropertiesType, F as ForeignKeyConstraint, I as IndexConstraint } from './Blueprint-DiSVtLdl.mjs';
|
package/dist/Connection.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { b as Connection } from './Blueprint-
|
|
1
|
+
export { b as Connection } from './Blueprint-DiSVtLdl.mjs';
|
package/dist/Expression.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { E as Expression } from './Blueprint-
|
|
1
|
+
export { E as Expression } from './Blueprint-DiSVtLdl.mjs';
|
package/dist/Expression.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { sqlTokenizer } from "sql-tokenizer";
|
|
3
4
|
class Expression {
|
|
4
5
|
constructor(sql = "", bindings = []) {
|
|
5
6
|
this.sql = sql;
|
|
@@ -9,7 +10,8 @@ class Expression {
|
|
|
9
10
|
__name(this, "Expression");
|
|
10
11
|
}
|
|
11
12
|
toCompiledSql() {
|
|
12
|
-
|
|
13
|
+
const tokenize = sqlTokenizer(this.sql);
|
|
14
|
+
return { sql: this.sql, bindings: this.bindings, parts: tokenize(this.sql) };
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
export {
|
package/dist/Expression.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Expression.mts"],"sourcesContent":["import { CompiledSql } from './types.mjs';\n\nexport class Expression {\n constructor(\n private sql = '',\n private bindings = []\n ) {}\n\n toCompiledSql(): CompiledSql {\n return { sql: this.sql, bindings: this.bindings };\n }\n}\n"],"mappings":";;
|
|
1
|
+
{"version":3,"sources":["../src/Expression.mts"],"sourcesContent":["import { CompiledSql } from './types.mjs';\n// @ts-ignore - no type definitions available for sql-tokenizer\nimport { sqlTokenizer } from 'sql-tokenizer';\n\nexport class Expression {\n constructor(\n private sql = '',\n private bindings = []\n ) {}\n\n toCompiledSql(): CompiledSql {\n const tokenize = sqlTokenizer(this.sql);\n return { sql: this.sql, bindings: this.bindings, parts: tokenize(this.sql) };\n }\n}\n"],"mappings":";;AAEA,SAAS,oBAAoB;AAEtB,MAAM,WAAW;AAAA,EACtB,YACU,MAAM,IACN,WAAW,CAAC,GACpB;AAFQ;AACA;AAAA,EACP;AAAA,EARL,OAIwB;AAAA;AAAA;AAAA,EAMtB,gBAA6B;AAC3B,UAAM,WAAW,aAAa,KAAK,GAAG;AACtC,WAAO,EAAE,KAAK,KAAK,KAAK,UAAU,KAAK,UAAU,OAAO,SAAS,KAAK,GAAG,EAAE;AAAA,EAC7E;AACF;","names":[]}
|
package/dist/Migration.d.mts
CHANGED
package/dist/Query.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { c as Query, Q as QueryParts } from './Blueprint-
|
|
1
|
+
export { c as Query, Q as QueryParts } from './Blueprint-DiSVtLdl.mjs';
|
package/dist/Query.mjs
CHANGED
|
@@ -18,7 +18,8 @@ class Query {
|
|
|
18
18
|
having: [],
|
|
19
19
|
orderBy: [],
|
|
20
20
|
limit: null,
|
|
21
|
-
offset: null
|
|
21
|
+
offset: null,
|
|
22
|
+
alias: null
|
|
22
23
|
};
|
|
23
24
|
table(tableName) {
|
|
24
25
|
this.parts.table = tableName;
|
|
@@ -108,7 +109,15 @@ class Query {
|
|
|
108
109
|
return this.grammar.toSql(this);
|
|
109
110
|
}
|
|
110
111
|
async get() {
|
|
111
|
-
|
|
112
|
+
let sql = this.toSql();
|
|
113
|
+
return await this.connection?.runQuery(sql);
|
|
114
|
+
}
|
|
115
|
+
async first() {
|
|
116
|
+
let rc = await this.connection?.runQuery(this.toSql());
|
|
117
|
+
if (rc && Array.isArray(rc) && rc.length > 0) {
|
|
118
|
+
return rc[0];
|
|
119
|
+
}
|
|
120
|
+
return void 0;
|
|
112
121
|
}
|
|
113
122
|
async count() {
|
|
114
123
|
const csql = this.grammar.compileCount(this);
|
|
@@ -174,6 +183,10 @@ class Query {
|
|
|
174
183
|
crossJoin(table, conditions) {
|
|
175
184
|
return this.join(table, "cross", conditions);
|
|
176
185
|
}
|
|
186
|
+
alias(alias) {
|
|
187
|
+
this.parts.alias = alias;
|
|
188
|
+
return this;
|
|
189
|
+
}
|
|
177
190
|
}
|
|
178
191
|
export {
|
|
179
192
|
Query
|
package/dist/Query.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Query.mts"],"sourcesContent":["import { Connection } from './Connection.mjs';\nimport { QueryGrammar } from './QueryGrammar.mjs';\nimport {\n CompiledSql,\n JoinCondition,\n Parameter,\n selectType,\n whereType,\n havingType,\n joinType,\n} from './types.mjs';\n\nexport type QueryParts = {\n select: selectType[];\n table: string;\n join: joinType[];\n where: whereType[];\n groupBy: string[];\n having: havingType[];\n orderBy: string[];\n limit: number | null;\n offset: number | null;\n};\n\nexport class Query {\n allowedOperations: string[] = ['=', '>', '<', '!=', 'like', 'ilike', 'in'];\n parts: QueryParts = {\n select: ['*'],\n table: '',\n join: [],\n where: [],\n groupBy: [],\n having: [],\n orderBy: [],\n limit: null,\n offset: null,\n };\n\n constructor(\n public readonly connection: Connection | null,\n public readonly grammar: QueryGrammar\n ) {}\n\n table(tableName: string): this {\n this.parts.table = tableName;\n return this;\n }\n\n whereNested(\n func: (q: Query) => void,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ) {\n const subQuery = new Query(this.connection, this.grammar);\n func(subQuery);\n this.parts.where.push({\n type: 'nested',\n query: subQuery,\n joinCondition,\n negateCondition,\n });\n return this;\n }\n\n whereOp(\n column: string,\n operation: (typeof this.allowedOperations)[number],\n value: Parameter,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.where.push({\n type: 'operation',\n column,\n operation,\n value,\n joinCondition,\n negateCondition,\n });\n return this;\n }\n\n whereRaw(\n sql: string,\n bindings: Parameter[],\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.where.push({ type: 'raw', sql, bindings, joinCondition, negateCondition });\n return this;\n }\n\n whereColumn(\n column1: string,\n operation: (typeof this.allowedOperations)[number],\n column2: string,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.where.push({\n type: 'operationColumn',\n column1,\n operation,\n column2,\n joinCondition,\n negateCondition,\n });\n return this;\n }\n\n whereNull(\n column: string,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.where.push({ type: 'null', column, joinCondition, negateCondition });\n return this;\n }\n\n clearWhere(): this {\n this.parts.where = [];\n return this;\n }\n\n select(selects: selectType[]): this {\n this.parts.select = [...selects];\n return this;\n }\n\n groupBy(columns: string[]): this {\n this.parts.groupBy = [...columns];\n return this;\n }\n\n havingOp(\n column: string,\n operation: (typeof this.allowedOperations)[number],\n value: Parameter,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.having.push({\n type: 'operation',\n column,\n operation,\n value,\n joinCondition,\n negateCondition,\n });\n return this;\n }\n\n havingRaw(\n sql: string,\n bindings: Parameter[],\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.having.push({ type: 'raw', sql, bindings, joinCondition, negateCondition });\n return this;\n }\n\n orderBy(column: string, direction: 'asc' | 'desc' = 'asc'): this {\n this.parts.orderBy.push(`${column} ${direction}`);\n return this;\n }\n\n limit(limit: number): this {\n this.parts.limit = limit;\n return this;\n }\n\n offset(offset: number): this {\n this.parts.offset = offset;\n return this;\n }\n\n toSql(): CompiledSql {\n return this.grammar.toSql(this);\n }\n\n async get() {\n return await this.connection?.runQuery(this.toSql());\n }\n\n async count(): Promise<number> {\n const csql: CompiledSql = this.grammar.compileCount(this);\n const result = await this.connection?.runQuery(csql);\n if (result && Array.isArray(result) && result.length > 0) {\n return parseInt(result[0]['count'], 10);\n }\n return 0;\n }\n\n async getCursor() {\n return await this.connection?.runCursor(this.toSql());\n }\n\n getConnection(): Connection | null {\n return this.connection;\n }\n\n async insert(data: Record<string, Parameter>) {\n const csql: CompiledSql = this.grammar.compileInsert(this, data);\n return await this.connection?.runQuery(csql);\n }\n\n async insertGetId(\n data: Record<string, Parameter>,\n options: { primaryKey: string[] } = { primaryKey: ['id'] }\n ) {\n const csql: CompiledSql = this.grammar.compileInsertGetId(this, data, options);\n return await this.connection?.runQuery(csql);\n }\n\n async update(data: Record<string, Parameter>) {\n const csql: CompiledSql = this.grammar.compileUpdate(this, data);\n return await this.connection?.runQuery(csql);\n }\n\n async upsert(data: Record<string, Parameter>, uniqueColumns: string[], updateColumns: string[]) {\n const csql: CompiledSql = this.grammar.compileUpsert(this, data, uniqueColumns, updateColumns);\n return await this.connection?.runQuery(csql);\n }\n\n async delete() {\n const csql: CompiledSql = this.grammar.compileDelete(this);\n return await this.connection?.runQuery(csql);\n }\n\n join(\n table: string,\n type: joinType['type'],\n conditions: (whereType | { column1: string; column2: string })[]\n ): this {\n let conditions_corrected: whereType[] = [];\n for (const cond of conditions) {\n conditions_corrected.push({\n joinCondition: 'and',\n negateCondition: false,\n type: 'operationColumn',\n // @ts-ignore\n operation: '=',\n ...cond,\n });\n }\n this.parts.join.push({ type, table, conditions: conditions_corrected });\n return this;\n }\n\n innerJoin(table: string, conditions: (whereType | { column1: string; column2: string })[]): this {\n return this.join(table, 'inner', conditions);\n }\n\n leftJoin(table: string, conditions: (whereType | { column1: string; column2: string })[]): this {\n return this.join(table, 'left', conditions);\n }\n\n rightJoin(table: string, conditions: (whereType | { column1: string; column2: string })[]): this {\n return this.join(table, 'right', conditions);\n }\n\n fullJoin(table: string, conditions: (whereType | { column1: string; column2: string })[]): this {\n return this.join(table, 'full', conditions);\n }\n\n crossJoin(table: string, conditions: (whereType | { column1: string; column2: string })[]): this {\n return this.join(table, 'cross', conditions);\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/Query.mts"],"sourcesContent":["import { Connection } from './Connection.mjs';\nimport { QueryGrammar } from './QueryGrammar.mjs';\nimport {\n CompiledSql,\n JoinCondition,\n Parameter,\n selectType,\n whereType,\n havingType,\n joinType,\n} from './types.mjs';\n\nexport type QueryParts = {\n select: selectType[];\n table: string;\n join: joinType[];\n where: whereType[];\n groupBy: string[];\n having: havingType[];\n orderBy: string[];\n limit: number | null;\n offset: number | null;\n alias: string | null;\n};\n\nexport class Query {\n allowedOperations: string[] = ['=', '>', '<', '!=', 'like', 'ilike', 'in'];\n parts: QueryParts = {\n select: ['*'],\n table: '',\n join: [],\n where: [],\n groupBy: [],\n having: [],\n orderBy: [],\n limit: null,\n offset: null,\n alias: null,\n };\n\n constructor(\n public readonly connection: Connection | null,\n public readonly grammar: QueryGrammar\n ) {}\n\n table(tableName: string): this {\n this.parts.table = tableName;\n return this;\n }\n\n whereNested(\n func: (q: Query) => void,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ) {\n const subQuery = new Query(this.connection, this.grammar);\n func(subQuery);\n this.parts.where.push({\n type: 'nested',\n query: subQuery,\n joinCondition,\n negateCondition,\n });\n return this;\n }\n\n whereOp(\n column: string,\n operation: (typeof this.allowedOperations)[number],\n value: Parameter,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.where.push({\n type: 'operation',\n column,\n operation,\n value,\n joinCondition,\n negateCondition,\n });\n return this;\n }\n\n whereRaw(\n sql: string,\n bindings: Parameter[],\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.where.push({ type: 'raw', sql, bindings, joinCondition, negateCondition });\n return this;\n }\n\n whereColumn(\n column1: string,\n operation: (typeof this.allowedOperations)[number],\n column2: string,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.where.push({\n type: 'operationColumn',\n column1,\n operation,\n column2,\n joinCondition,\n negateCondition,\n });\n return this;\n }\n\n whereNull(\n column: string,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.where.push({ type: 'null', column, joinCondition, negateCondition });\n return this;\n }\n\n clearWhere(): this {\n this.parts.where = [];\n return this;\n }\n\n select(selects: selectType[]): this {\n this.parts.select = [...selects];\n return this;\n }\n\n groupBy(columns: string[]): this {\n this.parts.groupBy = [...columns];\n return this;\n }\n\n havingOp(\n column: string,\n operation: (typeof this.allowedOperations)[number],\n value: Parameter,\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.having.push({\n type: 'operation',\n column,\n operation,\n value,\n joinCondition,\n negateCondition,\n });\n return this;\n }\n\n havingRaw(\n sql: string,\n bindings: Parameter[],\n joinCondition: JoinCondition = 'and',\n negateCondition: boolean = false\n ): this {\n this.parts.having.push({ type: 'raw', sql, bindings, joinCondition, negateCondition });\n return this;\n }\n\n orderBy(column: string, direction: 'asc' | 'desc' = 'asc'): this {\n this.parts.orderBy.push(`${column} ${direction}`);\n return this;\n }\n\n limit(limit: number): this {\n this.parts.limit = limit;\n return this;\n }\n\n offset(offset: number): this {\n this.parts.offset = offset;\n return this;\n }\n\n toSql(): CompiledSql {\n return this.grammar.toSql(this);\n }\n\n async get() {\n let sql = this.toSql();\n return await this.connection?.runQuery(sql);\n }\n\n async first() {\n let rc = await this.connection?.runQuery(this.toSql());\n if (rc && Array.isArray(rc) && rc.length > 0) {\n return rc[0];\n }\n return undefined;\n }\n\n async count(): Promise<number> {\n const csql: CompiledSql = this.grammar.compileCount(this);\n const result = await this.connection?.runQuery(csql);\n if (result && Array.isArray(result) && result.length > 0) {\n return parseInt(result[0]['count'], 10);\n }\n return 0;\n }\n\n async getCursor() {\n return await this.connection?.runCursor(this.toSql());\n }\n\n getConnection(): Connection | null {\n return this.connection;\n }\n\n async insert(data: Record<string, Parameter>) {\n const csql: CompiledSql = this.grammar.compileInsert(this, data);\n return await this.connection?.runQuery(csql);\n }\n\n async insertGetId(\n data: Record<string, Parameter>,\n options: { primaryKey: string[] } = { primaryKey: ['id'] }\n ) {\n const csql: CompiledSql = this.grammar.compileInsertGetId(this, data, options);\n return await this.connection?.runQuery(csql);\n }\n\n async update(data: Record<string, Parameter>) {\n const csql: CompiledSql = this.grammar.compileUpdate(this, data);\n return await this.connection?.runQuery(csql);\n }\n\n async upsert(data: Record<string, Parameter>, uniqueColumns: string[], updateColumns: string[]) {\n const csql: CompiledSql = this.grammar.compileUpsert(this, data, uniqueColumns, updateColumns);\n return await this.connection?.runQuery(csql);\n }\n\n async delete() {\n const csql: CompiledSql = this.grammar.compileDelete(this);\n return await this.connection?.runQuery(csql);\n }\n\n join(\n table: string | Query,\n type: joinType['type'],\n conditions: (whereType | { column1: string; column2: string })[]\n ): this {\n let conditions_corrected: whereType[] = [];\n for (const cond of conditions) {\n conditions_corrected.push({\n joinCondition: 'and',\n negateCondition: false,\n type: 'operationColumn',\n // @ts-ignore\n operation: '=',\n ...cond,\n });\n }\n this.parts.join.push({ type, table, conditions: conditions_corrected });\n return this;\n }\n\n innerJoin(\n table: Parameters<typeof this.join>[0],\n conditions: (whereType | { column1: string; column2: string })[]\n ): this {\n return this.join(table, 'inner', conditions);\n }\n\n leftJoin(\n table: Parameters<typeof this.join>[0],\n conditions: (whereType | { column1: string; column2: string })[]\n ): this {\n return this.join(table, 'left', conditions);\n }\n\n rightJoin(\n table: Parameters<typeof this.join>[0],\n conditions: (whereType | { column1: string; column2: string })[]\n ): this {\n return this.join(table, 'right', conditions);\n }\n\n fullJoin(\n table: Parameters<typeof this.join>[0],\n conditions: (whereType | { column1: string; column2: string })[]\n ): this {\n return this.join(table, 'full', conditions);\n }\n\n crossJoin(\n table: Parameters<typeof this.join>[0],\n conditions: (whereType | { column1: string; column2: string })[]\n ): this {\n return this.join(table, 'cross', conditions);\n }\n\n alias(alias: string): this {\n this.parts.alias = alias;\n return this;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/QueryGrammar.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { d as QueryGrammar } from './Blueprint-
|
|
1
|
+
export { d as QueryGrammar } from './Blueprint-DiSVtLdl.mjs';
|
package/dist/QueryGrammar.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { sqlTokenizer } from "sql-tokenizer";
|
|
3
4
|
function toUpperFirst(str) {
|
|
4
5
|
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
|
5
6
|
}
|
|
@@ -20,79 +21,118 @@ class QueryGrammar {
|
|
|
20
21
|
"offset"
|
|
21
22
|
];
|
|
22
23
|
toSql(query) {
|
|
23
|
-
let
|
|
24
|
+
let rc = this.toSqlParts(query);
|
|
25
|
+
rc.sql = this.joinArray(rc.parts);
|
|
26
|
+
return rc;
|
|
27
|
+
}
|
|
28
|
+
toSqlParts(query) {
|
|
29
|
+
let parts = [];
|
|
24
30
|
let bindings = [];
|
|
25
31
|
for (const part of this.sqlParts) {
|
|
26
32
|
const funcName = "compile" + toUpperFirst(part);
|
|
27
33
|
const r = this[funcName](query.parts[part]);
|
|
28
|
-
if (!sql) {
|
|
29
|
-
sql = r.sql;
|
|
30
|
-
} else if (r.sql) {
|
|
31
|
-
sql += " " + r.sql;
|
|
32
|
-
}
|
|
33
34
|
bindings = [...bindings, ...r.bindings];
|
|
35
|
+
parts = [...parts, ...r.parts];
|
|
34
36
|
}
|
|
35
|
-
return {
|
|
37
|
+
return {
|
|
38
|
+
sql: "",
|
|
39
|
+
bindings,
|
|
40
|
+
parts
|
|
41
|
+
};
|
|
36
42
|
}
|
|
37
43
|
compileCount(query) {
|
|
38
44
|
let sql = "";
|
|
39
45
|
let bindings = [];
|
|
46
|
+
let parts = [];
|
|
40
47
|
for (const part of this.sqlParts) {
|
|
41
|
-
let
|
|
48
|
+
let parts2 = query.parts[part];
|
|
42
49
|
if (part === "select") {
|
|
43
|
-
|
|
50
|
+
parts2 = ["count(*) as count"];
|
|
44
51
|
}
|
|
45
52
|
const funcName = "compile" + toUpperFirst(part);
|
|
46
|
-
const r = this[funcName](
|
|
47
|
-
if (!sql) {
|
|
48
|
-
sql = r.sql;
|
|
49
|
-
} else if (r.sql) {
|
|
50
|
-
sql += " " + r.sql;
|
|
51
|
-
}
|
|
53
|
+
const r = this[funcName](parts2);
|
|
52
54
|
bindings = [...bindings, ...r.bindings];
|
|
55
|
+
parts = [...parts, ...r.parts];
|
|
53
56
|
}
|
|
54
|
-
return { sql, bindings };
|
|
57
|
+
return { sql, parts, bindings };
|
|
55
58
|
}
|
|
56
59
|
compileSelect(selects) {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
const parts = ["select"];
|
|
61
|
+
selects.map((v) => {
|
|
62
|
+
parts.push(v);
|
|
63
|
+
parts.push(",");
|
|
64
|
+
});
|
|
65
|
+
parts.pop();
|
|
66
|
+
return { sql: this.joinArray(parts), parts, bindings: [] };
|
|
61
67
|
}
|
|
62
|
-
|
|
68
|
+
joinArray(arr) {
|
|
63
69
|
let rc = "";
|
|
70
|
+
let last = "";
|
|
71
|
+
for (const a of arr) {
|
|
72
|
+
if (a === ",") {
|
|
73
|
+
rc += a;
|
|
74
|
+
} else if (last === "(" || last === " " || a === ")") {
|
|
75
|
+
rc += a;
|
|
76
|
+
} else if (a === "") {
|
|
77
|
+
rc += "";
|
|
78
|
+
} else {
|
|
79
|
+
rc += " " + a;
|
|
80
|
+
}
|
|
81
|
+
last = a;
|
|
82
|
+
}
|
|
83
|
+
return rc.trim();
|
|
84
|
+
}
|
|
85
|
+
compileTable(tableName) {
|
|
86
|
+
let parts = [];
|
|
64
87
|
if (tableName.length) {
|
|
65
|
-
|
|
88
|
+
parts.push("from");
|
|
89
|
+
parts.push(tableName);
|
|
66
90
|
}
|
|
67
|
-
return { sql:
|
|
91
|
+
return { sql: parts.join(" "), parts, bindings: [] };
|
|
68
92
|
}
|
|
69
93
|
compileJoin(joins) {
|
|
70
94
|
let sql = "";
|
|
71
95
|
let bindings = [];
|
|
96
|
+
let parts = [];
|
|
72
97
|
for (const j of joins) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
98
|
+
let table = "";
|
|
99
|
+
let table_bindings = [];
|
|
100
|
+
parts.push(j.type);
|
|
101
|
+
parts.push("join");
|
|
102
|
+
if (typeof j.table === "string") {
|
|
103
|
+
parts.push(j.table);
|
|
104
|
+
} else {
|
|
105
|
+
const subQuery = j.table;
|
|
106
|
+
const { parts: parts2, bindings: bindings2 } = subQuery.toSql();
|
|
107
|
+
parts = [...parts, "(", ...parts2, ")", "as", subQuery.parts.alias || "subquery"];
|
|
108
|
+
table_bindings = bindings2;
|
|
77
109
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
110
|
+
parts.push("on");
|
|
111
|
+
const where = this.compileWhere(j.conditions);
|
|
112
|
+
const where_parts = where.parts;
|
|
113
|
+
where_parts.shift();
|
|
114
|
+
parts.push("(");
|
|
115
|
+
parts = [...parts, ...where_parts];
|
|
116
|
+
parts.push(")");
|
|
117
|
+
bindings = [...bindings, ...table_bindings, ...where.bindings];
|
|
82
118
|
}
|
|
83
|
-
return { sql, bindings };
|
|
119
|
+
return { sql, parts, bindings };
|
|
84
120
|
}
|
|
85
121
|
compileWhere(wheres) {
|
|
86
122
|
let sql = "";
|
|
87
123
|
let bindings = [];
|
|
124
|
+
let parts = [];
|
|
88
125
|
for (const w of wheres) {
|
|
89
126
|
sql += " " + w.joinCondition + " ";
|
|
127
|
+
parts.push(w.joinCondition);
|
|
90
128
|
if (w.negateCondition) {
|
|
91
129
|
sql += "not ";
|
|
130
|
+
parts.push("not");
|
|
92
131
|
}
|
|
93
132
|
const funcName = "compileWhere" + toUpperFirst(w.type);
|
|
94
133
|
const wh = this[funcName](w);
|
|
95
134
|
sql += wh.sql;
|
|
135
|
+
parts = parts.concat(wh.parts);
|
|
96
136
|
bindings = [...bindings, ...wh.bindings];
|
|
97
137
|
}
|
|
98
138
|
if (sql.startsWith(" and ")) {
|
|
@@ -100,160 +140,197 @@ class QueryGrammar {
|
|
|
100
140
|
} else if (sql.startsWith(" or ")) {
|
|
101
141
|
sql = "where " + sql.substring(" or ".length);
|
|
102
142
|
}
|
|
103
|
-
|
|
143
|
+
if (parts.length > 0) {
|
|
144
|
+
parts[0] = "where";
|
|
145
|
+
}
|
|
146
|
+
return { sql, parts, bindings };
|
|
104
147
|
}
|
|
105
148
|
compileWhereNested(w) {
|
|
106
149
|
const subQuery = w.query;
|
|
107
|
-
|
|
150
|
+
let parts = [];
|
|
151
|
+
const { sql, parts: parts2, bindings } = subQuery.grammar.compileWhere(subQuery.parts.where);
|
|
108
152
|
let sql2 = sql.replace(/^where /, "");
|
|
153
|
+
parts2.shift();
|
|
154
|
+
parts.push("(");
|
|
155
|
+
parts = parts.concat(parts2);
|
|
156
|
+
parts.push(")");
|
|
109
157
|
return {
|
|
110
158
|
sql: `(${sql2})`,
|
|
159
|
+
parts,
|
|
111
160
|
bindings
|
|
112
161
|
};
|
|
113
162
|
}
|
|
114
163
|
compileWhereOperation(w) {
|
|
115
164
|
if (w.operation.toLowerCase() === "in" && Array.isArray(w.value)) {
|
|
116
165
|
return {
|
|
117
|
-
sql: `${w.column} = ANY(
|
|
166
|
+
sql: `${w.column} = ANY( ? )`,
|
|
167
|
+
parts: [w.column, " = ANY(", "?", ")"],
|
|
118
168
|
bindings: [w.value]
|
|
119
169
|
};
|
|
120
170
|
}
|
|
121
171
|
return {
|
|
122
|
-
sql: `${w.column} ${w.operation}
|
|
172
|
+
sql: `${w.column} ${w.operation} ?`,
|
|
173
|
+
parts: [w.column, w.operation, "?"],
|
|
123
174
|
bindings: [w.value]
|
|
124
175
|
};
|
|
125
176
|
}
|
|
126
177
|
compileWhereOperationColumn(w) {
|
|
127
178
|
return {
|
|
128
179
|
sql: `${w.column1} ${w.operation} ${w.column2}`,
|
|
180
|
+
parts: [w.column1, w.operation, w.column2],
|
|
129
181
|
bindings: []
|
|
130
182
|
};
|
|
131
183
|
}
|
|
132
184
|
compileWhereRaw(w) {
|
|
133
|
-
|
|
185
|
+
const tokenize = sqlTokenizer();
|
|
134
186
|
return {
|
|
135
|
-
sql,
|
|
187
|
+
sql: w.sql,
|
|
188
|
+
parts: tokenize(w.sql).filter((t) => t !== " "),
|
|
136
189
|
bindings: w.bindings
|
|
137
190
|
};
|
|
138
191
|
}
|
|
139
192
|
compileOrderBy(orderBy) {
|
|
140
193
|
let rc = "";
|
|
194
|
+
let parts = [];
|
|
141
195
|
if (orderBy.length) {
|
|
142
196
|
rc = "order by " + orderBy.join(", ");
|
|
197
|
+
parts.push("order by");
|
|
198
|
+
parts = parts.concat(orderBy);
|
|
143
199
|
}
|
|
144
|
-
return { sql: rc, bindings: [] };
|
|
200
|
+
return { sql: rc, parts, bindings: [] };
|
|
145
201
|
}
|
|
146
202
|
compileLimit(limit) {
|
|
147
203
|
let rc = "";
|
|
204
|
+
let parts = [];
|
|
148
205
|
if (limit !== null) {
|
|
149
206
|
rc = "limit " + limit;
|
|
207
|
+
parts.push("limit");
|
|
208
|
+
parts.push(limit);
|
|
150
209
|
}
|
|
151
|
-
return { sql: rc, bindings: [] };
|
|
210
|
+
return { sql: rc, parts, bindings: [] };
|
|
152
211
|
}
|
|
153
212
|
compileOffset(offset) {
|
|
154
213
|
let rc = "";
|
|
214
|
+
let parts = [];
|
|
155
215
|
if (offset !== null) {
|
|
156
216
|
rc = "offset " + offset;
|
|
217
|
+
parts.push("offset");
|
|
218
|
+
parts.push(offset);
|
|
157
219
|
}
|
|
158
|
-
return { sql: rc, bindings: [] };
|
|
220
|
+
return { sql: rc, parts, bindings: [] };
|
|
159
221
|
}
|
|
160
222
|
compileWhereNull(w) {
|
|
161
223
|
return {
|
|
162
224
|
sql: `${w.column} is null`,
|
|
225
|
+
parts: [w.column, "is", "null"],
|
|
163
226
|
bindings: []
|
|
164
227
|
};
|
|
165
228
|
}
|
|
166
229
|
compileInsert(query, data) {
|
|
167
|
-
let
|
|
230
|
+
let parts = ["insert", "into", query.parts.table, "("];
|
|
168
231
|
const columns = [];
|
|
169
232
|
const bindings = [];
|
|
170
233
|
const values = [];
|
|
171
234
|
for (const [k, v] of Object.entries(data)) {
|
|
172
|
-
|
|
235
|
+
parts.push(k);
|
|
236
|
+
parts.push(",");
|
|
237
|
+
}
|
|
238
|
+
parts.pop();
|
|
239
|
+
parts = parts.concat([")", "values", "("]);
|
|
240
|
+
for (const [k, v] of Object.entries(data)) {
|
|
241
|
+
parts.push("?");
|
|
173
242
|
bindings.push(v);
|
|
174
|
-
|
|
243
|
+
parts.push(",");
|
|
175
244
|
}
|
|
176
|
-
|
|
177
|
-
|
|
245
|
+
parts.pop();
|
|
246
|
+
parts.push(")");
|
|
247
|
+
return { sql: parts.join(" "), parts, bindings };
|
|
178
248
|
}
|
|
179
249
|
compileUpdate(query, data) {
|
|
180
|
-
let sql = "update " + query.parts.table + " set ";
|
|
181
250
|
const bindings = [];
|
|
251
|
+
let parts = ["update", query.parts.table, "set"];
|
|
182
252
|
const setParts = [];
|
|
183
253
|
for (const [k, v] of Object.entries(data)) {
|
|
184
|
-
|
|
254
|
+
parts = parts.concat([k, "=", "?", ","]);
|
|
255
|
+
setParts.push(`${k} = ?`);
|
|
185
256
|
bindings.push(v);
|
|
186
257
|
}
|
|
187
|
-
|
|
258
|
+
parts.pop();
|
|
188
259
|
const where_csql = this.compileWhere(query.parts.where);
|
|
189
|
-
|
|
260
|
+
parts = parts.concat(where_csql.parts);
|
|
190
261
|
bindings.push(...where_csql.bindings);
|
|
191
|
-
return { sql, bindings };
|
|
262
|
+
return { sql: parts.join(" "), parts, bindings };
|
|
192
263
|
}
|
|
193
264
|
compileDelete(query) {
|
|
194
265
|
let sql = "delete from " + query.parts.table;
|
|
266
|
+
let parts = ["delete", "from", query.parts.table];
|
|
195
267
|
const where_csql = this.compileWhere(query.parts.where);
|
|
196
268
|
sql += " " + where_csql.sql;
|
|
197
|
-
|
|
269
|
+
parts = parts.concat(where_csql.parts);
|
|
270
|
+
return { sql, parts, bindings: where_csql.bindings };
|
|
198
271
|
}
|
|
199
272
|
compileUpsert(query, data, conflictFields, updateFields) {
|
|
200
|
-
let
|
|
201
|
-
const columns = [];
|
|
273
|
+
let parts = [];
|
|
202
274
|
const bindings = [];
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
values.push(this.getVariablePlaceholder());
|
|
208
|
-
}
|
|
209
|
-
sql += columns.join(", ") + ") values (" + values + ")";
|
|
210
|
-
sql += " on conflict (" + conflictFields.join(", ") + ") do update set ";
|
|
275
|
+
let isql = this.compileInsert(query, data);
|
|
276
|
+
parts = isql.parts;
|
|
277
|
+
bindings.push(...isql.bindings);
|
|
278
|
+
parts = parts.concat(["on", "conflict", "(", ...conflictFields, ")", "do", "update", "set"]);
|
|
211
279
|
const setParts = [];
|
|
212
280
|
for (const f of updateFields) {
|
|
213
281
|
setParts.push(`${f} = excluded.${f}`);
|
|
282
|
+
setParts.push(`,`);
|
|
214
283
|
}
|
|
215
|
-
|
|
284
|
+
setParts.pop();
|
|
285
|
+
parts = parts.concat(setParts);
|
|
216
286
|
const where_csql = this.compileWhere(query.parts.where);
|
|
217
|
-
|
|
287
|
+
parts = parts.concat(where_csql.parts);
|
|
218
288
|
bindings.push(...where_csql.bindings);
|
|
219
|
-
return { sql, bindings };
|
|
289
|
+
return { sql: parts.join(" "), parts, bindings };
|
|
220
290
|
}
|
|
221
291
|
compileGroupBy(groupBy) {
|
|
222
292
|
let rc = "";
|
|
293
|
+
let parts = [];
|
|
223
294
|
if (groupBy.length) {
|
|
224
295
|
rc = "group by " + groupBy.join(", ");
|
|
296
|
+
parts.push("group by");
|
|
297
|
+
parts = parts.concat(groupBy);
|
|
225
298
|
}
|
|
226
|
-
return { sql: rc, bindings: [] };
|
|
299
|
+
return { sql: rc, parts, bindings: [] };
|
|
227
300
|
}
|
|
228
301
|
compileHaving(having) {
|
|
229
302
|
let sql = "";
|
|
230
303
|
let bindings = [];
|
|
304
|
+
let parts = [];
|
|
231
305
|
for (const w of having) {
|
|
232
306
|
sql += " " + w.joinCondition + " ";
|
|
307
|
+
parts.push(w.joinCondition);
|
|
233
308
|
if (w.negateCondition) {
|
|
234
309
|
sql += "not ";
|
|
310
|
+
parts.push("not");
|
|
235
311
|
}
|
|
236
312
|
const funcName = "compileHaving" + toUpperFirst(w.type);
|
|
237
313
|
const wh = this[funcName](w);
|
|
314
|
+
parts = parts.concat(wh.parts);
|
|
238
315
|
sql += wh.sql;
|
|
239
316
|
bindings = [...bindings, ...wh.bindings];
|
|
240
317
|
}
|
|
241
|
-
if (
|
|
242
|
-
|
|
243
|
-
} else if (sql.startsWith(" or ")) {
|
|
244
|
-
sql = "having " + sql.substring(" or ".length);
|
|
318
|
+
if (parts.length > 0) {
|
|
319
|
+
parts[0] = "having";
|
|
245
320
|
}
|
|
246
|
-
return { sql, bindings };
|
|
321
|
+
return { sql: parts.join(" "), parts, bindings };
|
|
247
322
|
}
|
|
248
323
|
compileHavingOperation(w) {
|
|
249
324
|
return {
|
|
250
|
-
sql: `${w.column} ${w.operation}
|
|
325
|
+
sql: `${w.column} ${w.operation} ?`,
|
|
326
|
+
parts: [w.column, w.operation, "?"],
|
|
251
327
|
bindings: [w.value]
|
|
252
328
|
};
|
|
253
329
|
}
|
|
254
330
|
compileHavingRaw(w) {
|
|
255
331
|
return {
|
|
256
332
|
sql: w.sql,
|
|
333
|
+
parts: w.sql.split(" "),
|
|
257
334
|
bindings: w.bindings
|
|
258
335
|
};
|
|
259
336
|
}
|