@devbro/neko-sql 0.1.15 → 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 +148 -70
- 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 +188 -94
- 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,159 +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) {
|
|
185
|
+
const tokenize = sqlTokenizer();
|
|
133
186
|
return {
|
|
134
187
|
sql: w.sql,
|
|
188
|
+
parts: tokenize(w.sql).filter((t) => t !== " "),
|
|
135
189
|
bindings: w.bindings
|
|
136
190
|
};
|
|
137
191
|
}
|
|
138
192
|
compileOrderBy(orderBy) {
|
|
139
193
|
let rc = "";
|
|
194
|
+
let parts = [];
|
|
140
195
|
if (orderBy.length) {
|
|
141
196
|
rc = "order by " + orderBy.join(", ");
|
|
197
|
+
parts.push("order by");
|
|
198
|
+
parts = parts.concat(orderBy);
|
|
142
199
|
}
|
|
143
|
-
return { sql: rc, bindings: [] };
|
|
200
|
+
return { sql: rc, parts, bindings: [] };
|
|
144
201
|
}
|
|
145
202
|
compileLimit(limit) {
|
|
146
203
|
let rc = "";
|
|
204
|
+
let parts = [];
|
|
147
205
|
if (limit !== null) {
|
|
148
206
|
rc = "limit " + limit;
|
|
207
|
+
parts.push("limit");
|
|
208
|
+
parts.push(limit);
|
|
149
209
|
}
|
|
150
|
-
return { sql: rc, bindings: [] };
|
|
210
|
+
return { sql: rc, parts, bindings: [] };
|
|
151
211
|
}
|
|
152
212
|
compileOffset(offset) {
|
|
153
213
|
let rc = "";
|
|
214
|
+
let parts = [];
|
|
154
215
|
if (offset !== null) {
|
|
155
216
|
rc = "offset " + offset;
|
|
217
|
+
parts.push("offset");
|
|
218
|
+
parts.push(offset);
|
|
156
219
|
}
|
|
157
|
-
return { sql: rc, bindings: [] };
|
|
220
|
+
return { sql: rc, parts, bindings: [] };
|
|
158
221
|
}
|
|
159
222
|
compileWhereNull(w) {
|
|
160
223
|
return {
|
|
161
224
|
sql: `${w.column} is null`,
|
|
225
|
+
parts: [w.column, "is", "null"],
|
|
162
226
|
bindings: []
|
|
163
227
|
};
|
|
164
228
|
}
|
|
165
229
|
compileInsert(query, data) {
|
|
166
|
-
let
|
|
230
|
+
let parts = ["insert", "into", query.parts.table, "("];
|
|
167
231
|
const columns = [];
|
|
168
232
|
const bindings = [];
|
|
169
233
|
const values = [];
|
|
170
234
|
for (const [k, v] of Object.entries(data)) {
|
|
171
|
-
|
|
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("?");
|
|
172
242
|
bindings.push(v);
|
|
173
|
-
|
|
243
|
+
parts.push(",");
|
|
174
244
|
}
|
|
175
|
-
|
|
176
|
-
|
|
245
|
+
parts.pop();
|
|
246
|
+
parts.push(")");
|
|
247
|
+
return { sql: parts.join(" "), parts, bindings };
|
|
177
248
|
}
|
|
178
249
|
compileUpdate(query, data) {
|
|
179
|
-
let sql = "update " + query.parts.table + " set ";
|
|
180
250
|
const bindings = [];
|
|
251
|
+
let parts = ["update", query.parts.table, "set"];
|
|
181
252
|
const setParts = [];
|
|
182
253
|
for (const [k, v] of Object.entries(data)) {
|
|
183
|
-
|
|
254
|
+
parts = parts.concat([k, "=", "?", ","]);
|
|
255
|
+
setParts.push(`${k} = ?`);
|
|
184
256
|
bindings.push(v);
|
|
185
257
|
}
|
|
186
|
-
|
|
258
|
+
parts.pop();
|
|
187
259
|
const where_csql = this.compileWhere(query.parts.where);
|
|
188
|
-
|
|
260
|
+
parts = parts.concat(where_csql.parts);
|
|
189
261
|
bindings.push(...where_csql.bindings);
|
|
190
|
-
return { sql, bindings };
|
|
262
|
+
return { sql: parts.join(" "), parts, bindings };
|
|
191
263
|
}
|
|
192
264
|
compileDelete(query) {
|
|
193
265
|
let sql = "delete from " + query.parts.table;
|
|
266
|
+
let parts = ["delete", "from", query.parts.table];
|
|
194
267
|
const where_csql = this.compileWhere(query.parts.where);
|
|
195
268
|
sql += " " + where_csql.sql;
|
|
196
|
-
|
|
269
|
+
parts = parts.concat(where_csql.parts);
|
|
270
|
+
return { sql, parts, bindings: where_csql.bindings };
|
|
197
271
|
}
|
|
198
272
|
compileUpsert(query, data, conflictFields, updateFields) {
|
|
199
|
-
let
|
|
200
|
-
const columns = [];
|
|
273
|
+
let parts = [];
|
|
201
274
|
const bindings = [];
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
values.push(this.getVariablePlaceholder());
|
|
207
|
-
}
|
|
208
|
-
sql += columns.join(", ") + ") values (" + values + ")";
|
|
209
|
-
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"]);
|
|
210
279
|
const setParts = [];
|
|
211
280
|
for (const f of updateFields) {
|
|
212
281
|
setParts.push(`${f} = excluded.${f}`);
|
|
282
|
+
setParts.push(`,`);
|
|
213
283
|
}
|
|
214
|
-
|
|
284
|
+
setParts.pop();
|
|
285
|
+
parts = parts.concat(setParts);
|
|
215
286
|
const where_csql = this.compileWhere(query.parts.where);
|
|
216
|
-
|
|
287
|
+
parts = parts.concat(where_csql.parts);
|
|
217
288
|
bindings.push(...where_csql.bindings);
|
|
218
|
-
return { sql, bindings };
|
|
289
|
+
return { sql: parts.join(" "), parts, bindings };
|
|
219
290
|
}
|
|
220
291
|
compileGroupBy(groupBy) {
|
|
221
292
|
let rc = "";
|
|
293
|
+
let parts = [];
|
|
222
294
|
if (groupBy.length) {
|
|
223
295
|
rc = "group by " + groupBy.join(", ");
|
|
296
|
+
parts.push("group by");
|
|
297
|
+
parts = parts.concat(groupBy);
|
|
224
298
|
}
|
|
225
|
-
return { sql: rc, bindings: [] };
|
|
299
|
+
return { sql: rc, parts, bindings: [] };
|
|
226
300
|
}
|
|
227
301
|
compileHaving(having) {
|
|
228
302
|
let sql = "";
|
|
229
303
|
let bindings = [];
|
|
304
|
+
let parts = [];
|
|
230
305
|
for (const w of having) {
|
|
231
306
|
sql += " " + w.joinCondition + " ";
|
|
307
|
+
parts.push(w.joinCondition);
|
|
232
308
|
if (w.negateCondition) {
|
|
233
309
|
sql += "not ";
|
|
310
|
+
parts.push("not");
|
|
234
311
|
}
|
|
235
312
|
const funcName = "compileHaving" + toUpperFirst(w.type);
|
|
236
313
|
const wh = this[funcName](w);
|
|
314
|
+
parts = parts.concat(wh.parts);
|
|
237
315
|
sql += wh.sql;
|
|
238
316
|
bindings = [...bindings, ...wh.bindings];
|
|
239
317
|
}
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
} else if (sql.startsWith(" or ")) {
|
|
243
|
-
sql = "having " + sql.substring(" or ".length);
|
|
318
|
+
if (parts.length > 0) {
|
|
319
|
+
parts[0] = "having";
|
|
244
320
|
}
|
|
245
|
-
return { sql, bindings };
|
|
321
|
+
return { sql: parts.join(" "), parts, bindings };
|
|
246
322
|
}
|
|
247
323
|
compileHavingOperation(w) {
|
|
248
324
|
return {
|
|
249
|
-
sql: `${w.column} ${w.operation}
|
|
325
|
+
sql: `${w.column} ${w.operation} ?`,
|
|
326
|
+
parts: [w.column, w.operation, "?"],
|
|
250
327
|
bindings: [w.value]
|
|
251
328
|
};
|
|
252
329
|
}
|
|
253
330
|
compileHavingRaw(w) {
|
|
254
331
|
return {
|
|
255
332
|
sql: w.sql,
|
|
333
|
+
parts: w.sql.split(" "),
|
|
256
334
|
bindings: w.bindings
|
|
257
335
|
};
|
|
258
336
|
}
|