@steedos/odata-v4-typeorm 2.2.50 → 2.2.51-beta.4

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@steedos/odata-v4-typeorm",
3
3
  "private": false,
4
- "version": "2.2.50",
4
+ "version": "2.2.51-beta.4",
5
5
  "description": "OData to TYPEORM query compiler",
6
6
  "main": "lib/index.js",
7
7
  "typings": "lib/index",
@@ -9,8 +9,7 @@
9
9
  "test": "test"
10
10
  },
11
11
  "scripts": {
12
- "compile": "tsc",
13
- "prepare": "tsc"
12
+ "build": "tsc"
14
13
  },
15
14
  "repository": {
16
15
  "type": "git",
@@ -36,5 +35,5 @@
36
35
  "publishConfig": {
37
36
  "access": "public"
38
37
  },
39
- "gitHead": "7859a5ac5bcc9c0089d52ce9246eee1c83022816"
38
+ "gitHead": "975061203a5c8ee2ed2ab495cfed25a100304c96"
40
39
  }
@@ -1,13 +0,0 @@
1
- import { TypeOrmVisitor as Visitor } from './visitor';
2
- import { Token } from 'odata-v4-parser/lib/lexer';
3
- import { SqlOptions } from './sqlOptions';
4
- /**
5
- * Creates an SQL WHERE clause from an OData filter expression string
6
- * @param {string} odataFilter - A filter expression in OData $filter format
7
- * @return {string} SQL WHERE clause
8
- * @example
9
- * const filter = createFilter("Size eq 4 and Age gt 18");
10
- * let sqlQuery = `SELECT * FROM table WHERE ${filter}`;
11
- */
12
- export declare function createFilter(odataFilter: string, options?: SqlOptions): Visitor;
13
- export declare function createFilter(odataFilter: Token, options?: SqlOptions): Visitor;
@@ -1,13 +0,0 @@
1
- import { TypeOrmVisitor as Visitor } from './visitor';
2
- import { Token } from 'odata-v4-parser/lib/lexer';
3
- import { SqlOptions } from './sqlOptions';
4
- /**
5
- * Creates an SQL query descriptor from an OData query string
6
- * @param {string} odataQuery - An OData query string
7
- * @return {string} SQL query descriptor
8
- * @example
9
- * const filter = createQuery("$filter=Size eq 4 and Age gt 18");
10
- * let sqlQuery = `SELECT * FROM table WHERE ${filter.where}`;
11
- */
12
- export declare function createQuery(odataQuery: string, options?: SqlOptions): Visitor;
13
- export declare function createQuery(odataQuery: Token, options?: SqlOptions): Visitor;
@@ -1,5 +0,0 @@
1
- import { SqlOptions } from './sqlOptions';
2
- declare const executeQuery: (repositoryOrQueryBuilder: any, query: any, options: SqlOptions) => Promise<any>;
3
- declare const executeCountQuery: (repositoryOrQueryBuilder: any, query: any, options: SqlOptions) => Promise<any>;
4
- declare const getExecuteQuerySQL: (repositoryOrQueryBuilder: any, query: any, options: SqlOptions) => Promise<any>;
5
- export { executeQuery, executeCountQuery, getExecuteQuerySQL };
package/lib/index.d.ts DELETED
@@ -1,6 +0,0 @@
1
- import { odataQuery } from './odataQueryMiddleware';
2
- import { executeQuery, executeCountQuery, getExecuteQuerySQL } from './executeQuery';
3
- import { SqlOptions } from './sqlOptions';
4
- import { createQuery } from './createQuery';
5
- import { createFilter } from './createFilter';
6
- export { odataQuery, executeQuery, executeCountQuery, getExecuteQuerySQL, SqlOptions, createQuery, createFilter };
@@ -1,3 +0,0 @@
1
- import { executeQuery } from './executeQuery';
2
- declare function odataQuery(repositoryOrQueryBuilder: any): (req: any, res: any, next: any) => Promise<any>;
3
- export { odataQuery, executeQuery };
@@ -1,7 +0,0 @@
1
- import { SQLLang } from 'odata-v4-sql';
2
- export interface SqlOptions {
3
- useParameters?: boolean;
4
- type?: SQLLang;
5
- alias: string;
6
- version?: string;
7
- }
package/lib/visitor.d.ts DELETED
@@ -1,20 +0,0 @@
1
- import { Token } from 'odata-v4-parser/lib/lexer';
2
- import { Visitor } from 'odata-v4-sql/lib/visitor';
3
- export declare class TypeOrmVisitor extends Visitor {
4
- includes: TypeOrmVisitor[];
5
- alias: string;
6
- constructor(options: any);
7
- from(table: string): string;
8
- asMsSql(): this;
9
- asPostgreSql(): this;
10
- asType(): this;
11
- protected VisitExpand(node: Token, context: any): void;
12
- protected VisitSelectItem(node: Token, context: any): void;
13
- protected VisitODataIdentifier(node: Token, context: any): void;
14
- private getIdentifier;
15
- protected VisitEqualsExpression(node: Token, context: any): void;
16
- protected VisitNotEqualsExpression(node: Token, context: any): void;
17
- protected VisitLiteral(node: Token, context: any): void;
18
- protected VisitNotExpression(node: Token, context: any): void;
19
- protected VisitMethodCallExpression(node: Token, context: any): void;
20
- }
@@ -1,27 +0,0 @@
1
- import {TypeOrmVisitor as Visitor} from './visitor';
2
- import {Token} from 'odata-v4-parser/lib/lexer';
3
- import {SqlOptions} from './sqlOptions';
4
- import {filter} from 'odata-v4-parser';
5
- import {SQLLang} from 'odata-v4-sql';
6
-
7
- /**
8
- * Creates an SQL WHERE clause from an OData filter expression string
9
- * @param {string} odataFilter - A filter expression in OData $filter format
10
- * @return {string} SQL WHERE clause
11
- * @example
12
- * const filter = createFilter("Size eq 4 and Age gt 18");
13
- * let sqlQuery = `SELECT * FROM table WHERE ${filter}`;
14
- */
15
- export function createFilter(odataFilter: string, options?: SqlOptions): Visitor;
16
- export function createFilter(odataFilter: Token, options?: SqlOptions): Visitor;
17
- export function createFilter(odataFilter: string | Token, options = <SqlOptions>{}): Visitor {
18
- if (!options.type){
19
- options.type = SQLLang.Oracle;
20
- }
21
- let ast: Token = <Token>(typeof odataFilter == 'string' ? filter(<string>odataFilter) : odataFilter);
22
- const visitor = new Visitor(options);
23
- const visit = visitor.Visit(ast);
24
- const type = visit.asType();
25
- return type;
26
-
27
- }
@@ -1,23 +0,0 @@
1
- import {TypeOrmVisitor as Visitor} from './visitor';
2
- import {Token} from 'odata-v4-parser/lib/lexer';
3
- import {query} from 'odata-v4-parser';
4
- import {SQLLang} from 'odata-v4-sql';
5
- import {SqlOptions} from './sqlOptions';
6
-
7
- /**
8
- * Creates an SQL query descriptor from an OData query string
9
- * @param {string} odataQuery - An OData query string
10
- * @return {string} SQL query descriptor
11
- * @example
12
- * const filter = createQuery("$filter=Size eq 4 and Age gt 18");
13
- * let sqlQuery = `SELECT * FROM table WHERE ${filter.where}`;
14
- */
15
- export function createQuery(odataQuery: string, options?: SqlOptions): Visitor;
16
- export function createQuery(odataQuery: Token, options?: SqlOptions): Visitor;
17
- export function createQuery(odataQuery: string | Token, options = <SqlOptions>{}): Visitor {
18
- if (!options.type) {
19
- options.type = SQLLang.Oracle;
20
- }
21
- let ast: Token = <Token>(typeof odataQuery == 'string' ? query(<string>odataQuery) : odataQuery);
22
- return new Visitor(options).Visit(ast).asType();
23
- }
@@ -1,292 +0,0 @@
1
- import { createQuery } from './createQuery';
2
- import { SqlOptions } from './sqlOptions';
3
- import { SQLLang } from 'odata-v4-sql';
4
- const _ = require("underscore");
5
-
6
- const mapToObject = (aMap) => {
7
- const obj = {};
8
- if (aMap) {
9
- aMap.forEach((v, k) => {
10
- obj[k] = v;
11
- });
12
- }
13
- return obj;
14
- };
15
-
16
- const queryToOdataString = (query): string => {
17
- let result = '';
18
- for (let key in query) {
19
- if (key.startsWith('$')) {
20
- if (result !== '') {
21
- result += '&';
22
- }
23
- result += `${key}=${query[key]}`;
24
- }
25
- }
26
- return result;
27
- };
28
-
29
- const processIncludes = (queryBuilder: any, odataQuery: any, alias: string) => {
30
- if (odataQuery.includes && odataQuery.includes.length > 0) {
31
- odataQuery.includes.forEach(item => {
32
- queryBuilder = queryBuilder.leftJoinAndSelect(
33
- (alias ? alias + '.' : '') + item.navigationProperty,
34
- item.navigationProperty,
35
- item.where.replace(/typeorm_query/g, item.navigationProperty),
36
- mapToObject(item.parameters)
37
- );
38
-
39
- if (item.orderby && item.orderby != '1') {
40
- const orders = item.orderby.split(',').map(i => i.trim().replace(/typeorm_query/g, item.navigationProperty));
41
- orders.forEach((itemOrd) => {
42
- queryBuilder = queryBuilder.addOrderBy(...(itemOrd.split(' ')));
43
- });
44
- }
45
-
46
- if (item.includes && item.includes.length > 0) {
47
- processIncludes(queryBuilder, { includes: item.includes }, item.navigationProperty);
48
- }
49
- });
50
- }
51
-
52
- return queryBuilder;
53
- };
54
-
55
- const executeQueryByQueryBuilder = async (inputQueryBuilder, query, options: SqlOptions, returnSql: boolean = false) => {
56
- const alias = inputQueryBuilder.expressionMap.mainAlias.name;
57
- options.alias = alias;
58
- //const filter = createFilter(query.$filter, {alias: alias});
59
- let odataQuery: any = {};
60
- if (query) {
61
- const odataString = queryToOdataString(query);
62
- if (odataString) {
63
- odataQuery = createQuery(odataString, options);
64
- }
65
- }
66
- let queryBuilder = inputQueryBuilder;
67
-
68
- if(odataQuery.where){
69
- queryBuilder = queryBuilder.andWhere(odataQuery.where)
70
- }
71
-
72
- if(odataQuery.parameters){
73
- queryBuilder = queryBuilder.setParameters(mapToObject(odataQuery.parameters));
74
- }
75
-
76
- const queryRunner = inputQueryBuilder.obtainQueryRunner();
77
- const isPaging = query.$skip !== undefined || query.$top !== undefined;
78
- if (isPaging && query.$top === undefined) {
79
- query.$top = 100;
80
- }
81
- if (queryRunner && isPaging && [SQLLang.MsSql, SQLLang.Oracle].indexOf(options.type) >= 0) {
82
- // 老版本的SqlServer/Oracle数据库不支持OFFSET FETCH 的语法来翻页,只能单独处理
83
- // SqlServer 2012版本号options.version为11.0.3128.0,这以下的版本,比如2008/2005都不支持OFFSET FETCH 的语法来翻页
84
- const oldVersionMsSql = options.type === SQLLang.MsSql && options.version && parseInt(options.version) < 11;
85
- const tooOldVersionMsSql = oldVersionMsSql && parseInt(options.version) < 9;
86
- // Oracle 12c版本号options.version为12.2...,这以下的版本,比如10.2都不支持OFFSET FETCH 的语法来翻页
87
- const oldVersionOracle = options.type === SQLLang.Oracle && options.version && parseInt(options.version) < 12;
88
- if (oldVersionMsSql || oldVersionOracle) {
89
- let selectFields = "*";
90
- if (odataQuery.select && odataQuery.select !== '*') {
91
- selectFields = odataQuery.select;
92
- }
93
- const RowNumberKey = "RowNumber";
94
- if (oldVersionMsSql) {
95
- if (tooOldVersionMsSql) {
96
- queryBuilder = queryBuilder.select(`top ${query.$top} ${selectFields}`);
97
- }
98
- else {
99
- let orderby = odataQuery.orderby;
100
- if (oldVersionMsSql && !(orderby && orderby !== '1')) {
101
- orderby = "(select null) ASC";
102
- }
103
- queryBuilder = queryBuilder.select(`${selectFields},ROW_NUMBER() OVER(ORDER BY ${orderby}) ${RowNumberKey}`);
104
- }
105
- }
106
- else if (oldVersionOracle) {
107
- queryBuilder = queryBuilder.select(`${selectFields}`);
108
- }
109
- if ((oldVersionOracle || tooOldVersionMsSql) && odataQuery.orderby && odataQuery.orderby !== '1') {
110
- const orders = odataQuery.orderby.split(',').map(i => i.trim());
111
- orders.forEach((item) => {
112
- queryBuilder = queryBuilder.addOrderBy(...(item.split(' ')));
113
- });
114
- }
115
- let qs = queryBuilder.getQueryAndParameters();
116
- if (returnSql) {
117
- return qs;
118
- }
119
- let splicedSql = "";
120
- let start = query.$skip ? query.$skip : 0;
121
- let end = 0;
122
- if (query.$top) {
123
- end = start + query.$top;
124
- }
125
- if (oldVersionMsSql) {
126
- if (tooOldVersionMsSql) {
127
- splicedSql = `SELECT * FROM (${qs[0]}) A`;
128
- }
129
- else {
130
- let betweenSql = "";
131
- if (end) {
132
- betweenSql = `BETWEEN ${start} + 1 and ${end}`;
133
- }
134
- else {
135
- betweenSql = `> ${start}`;
136
- }
137
- splicedSql = `SELECT * FROM (${qs[0]}) A WHERE ${RowNumberKey} ${betweenSql}`;
138
- }
139
- }
140
- else if (oldVersionOracle) {
141
- splicedSql = `SELECT * FROM (SELECT A.*, ROWNUM ${RowNumberKey} FROM (${qs[0]}) A ${end ? ('WHERE ROWNUM <= ' + end) : ''}) b WHERE B.${RowNumberKey} > ${start}`;
142
- }
143
- try {
144
- let getFieldMap = function(columns){
145
- let map = {};
146
- _.each(columns, function(column){
147
- if(column.givenDatabaseName && column.givenDatabaseName != column.propertyName){
148
- map[column.givenDatabaseName] = column.propertyName
149
- }
150
- })
151
- return map;
152
- }
153
- let columnsMap = getFieldMap(queryBuilder.expressionMap.mainAlias.metadata.columns)
154
- const result = await queryRunner.query(splicedSql, qs[1]);
155
- let items = result.concat();
156
- if(!_.isEmpty(columnsMap)){
157
- items.map(function(item){
158
- _.each(columnsMap, function(v, k){
159
- item[v] = item[k];
160
- delete item[k];
161
- })
162
- })
163
- }
164
- if (query.$count && query.$count !== 'false') {
165
- return {
166
- items: items,
167
- count: result.length
168
- }
169
- }
170
- else {
171
- return items;
172
- }
173
- } finally {
174
- if (queryRunner !== queryBuilder.queryRunner) {
175
- await queryRunner.release();
176
- }
177
- if (queryBuilder.connection.driver.options.type === "sqljs") {
178
- // this.connection.driver instanceof SqljsDriver
179
- // SqljsDriver is not export from typeorm,so we user driver.options.type to check the SqljsDriver instance
180
- await queryBuilder.connection.driver.autoSave();
181
- }
182
- }
183
- }
184
- }
185
-
186
- if (odataQuery.select && odataQuery.select != '*') {
187
- queryBuilder = queryBuilder.select(odataQuery.select.split(',').map(i => i.trim()));
188
- }
189
-
190
- queryBuilder = processIncludes(queryBuilder, odataQuery, alias);
191
-
192
- if (odataQuery.orderby && odataQuery.orderby !== '1') {
193
- const orders = odataQuery.orderby.split(',').map(i => i.trim());
194
- orders.forEach((item) => {
195
- queryBuilder = queryBuilder.addOrderBy(...(item.split(' ')));
196
- });
197
- }
198
- queryBuilder = queryBuilder.skip(query.$skip || 0);
199
- if (query.$top) {
200
- queryBuilder = queryBuilder.take(query.$top);
201
- }
202
- if (returnSql) {
203
- return {
204
- sql: queryBuilder.getSql(),
205
- query: queryBuilder.getQuery()
206
- };
207
- }
208
- if (query.$count && query.$count !== 'false') {
209
- const resultData = await queryBuilder.getManyAndCount();
210
- return {
211
- items: resultData[0],
212
- count: resultData[1]
213
- }
214
- }
215
-
216
- return queryBuilder.getMany();
217
- };
218
-
219
- const executeQuery = async (repositoryOrQueryBuilder: any, query, options: SqlOptions) => {
220
- // options = options || {};
221
- const alias = options.alias || '';
222
- let queryBuilder = null;
223
-
224
- // check that input object is query builder
225
- if (typeof repositoryOrQueryBuilder.expressionMap !== 'undefined') {
226
- queryBuilder = repositoryOrQueryBuilder;
227
- } else {
228
- queryBuilder = await repositoryOrQueryBuilder.createQueryBuilder(alias);
229
- }
230
- const result = await executeQueryByQueryBuilder(queryBuilder, query, options);
231
- return result;
232
- };
233
-
234
-
235
- const executeCountQueryByQueryBuilder = async (inputQueryBuilder, query, options: SqlOptions) => {
236
- const alias = inputQueryBuilder.expressionMap.mainAlias.name;
237
- options.alias = alias;
238
- //const filter = createFilter(query.$filter, {alias: alias});
239
- let odataQuery: any = {};
240
- if (query) {
241
- const odataString = queryToOdataString(query);
242
- if (odataString) {
243
- odataQuery = createQuery(odataString, options);
244
- }
245
- }
246
- const queryRunner = inputQueryBuilder.obtainQueryRunner();
247
- let queryBuilder = inputQueryBuilder;
248
-
249
- if(odataQuery.where){
250
- queryBuilder = queryBuilder.andWhere(odataQuery.where)
251
- }
252
-
253
- if(odataQuery.parameters){
254
- queryBuilder = queryBuilder.setParameters(mapToObject(odataQuery.parameters));
255
- }
256
-
257
- queryBuilder = processIncludes(queryBuilder, odataQuery, alias);
258
-
259
- return await queryBuilder.getCount();
260
- };
261
-
262
- const executeCountQuery = async (repositoryOrQueryBuilder: any, query, options: SqlOptions) => {
263
- // options = options || {};
264
- const alias = options.alias || '';
265
- let queryBuilder = null;
266
-
267
- // check that input object is query builder
268
- if (typeof repositoryOrQueryBuilder.expressionMap !== 'undefined') {
269
- queryBuilder = repositoryOrQueryBuilder;
270
- } else {
271
- queryBuilder = repositoryOrQueryBuilder.createQueryBuilder(alias);
272
- }
273
- const result = await executeCountQueryByQueryBuilder(queryBuilder, query, options);
274
- return result;
275
- };
276
-
277
- const getExecuteQuerySQL = async (repositoryOrQueryBuilder: any, query, options: SqlOptions) => {
278
- // options = options || {};
279
- const alias = options.alias || '';
280
- let queryBuilder = null;
281
-
282
- // check that input object is query builder
283
- if (typeof repositoryOrQueryBuilder.expressionMap !== 'undefined') {
284
- queryBuilder = repositoryOrQueryBuilder;
285
- } else {
286
- queryBuilder = await repositoryOrQueryBuilder.createQueryBuilder(alias);
287
- }
288
- const result = executeQueryByQueryBuilder(queryBuilder, query, options, true);
289
- return result;
290
- };
291
-
292
- export { executeQuery, executeCountQuery, getExecuteQuerySQL };
package/src/index.ts DELETED
@@ -1,7 +0,0 @@
1
- import {odataQuery} from './odataQueryMiddleware';
2
- import { executeQuery, executeCountQuery, getExecuteQuerySQL} from './executeQuery';
3
- import {SqlOptions} from './sqlOptions';
4
- import {createQuery} from './createQuery';
5
- import {createFilter} from './createFilter';
6
-
7
- export { odataQuery, executeQuery, executeCountQuery, getExecuteQuerySQL, SqlOptions, createQuery, createFilter };
@@ -1,18 +0,0 @@
1
- import {executeQuery} from './executeQuery';
2
-
3
- function odataQuery(repositoryOrQueryBuilder: any) {
4
- return async (req: any, res: any, next) => {
5
- try {
6
- const alias = '';
7
-
8
- const result = await executeQuery(repositoryOrQueryBuilder, req.query, {alias});
9
- return res.status(200).json(result);
10
- } catch (e) {
11
- console.log('ODATA ERROR',e);
12
- res.status(500).json({message: 'Internal server error.', error: {message: e.message}});
13
- }
14
- return next();
15
- }
16
- }
17
-
18
- export {odataQuery, executeQuery};
package/src/sqlOptions.ts DELETED
@@ -1,8 +0,0 @@
1
- import {SQLLang} from 'odata-v4-sql';
2
-
3
- export interface SqlOptions {
4
- useParameters?: boolean;
5
- type?: SQLLang;
6
- alias: string;
7
- version?: string;
8
- }
package/src/visitor.ts DELETED
@@ -1,301 +0,0 @@
1
- import {Token} from 'odata-v4-parser/lib/lexer';
2
- import {Literal} from 'odata-v4-literal';
3
- import {SQLLiteral, SQLLang, Visitor} from 'odata-v4-sql/lib/visitor';
4
- // import {SqlOptions} from './index';
5
-
6
- export class TypeOrmVisitor extends Visitor {
7
- //parameters:any[] = [];
8
- includes: TypeOrmVisitor[] = [];
9
- alias: string = ''// 'typeorm_query';
10
-
11
- constructor(options) {
12
- super(options);
13
- if (!options.type) {
14
- this.type = SQLLang.Oracle;
15
- }
16
- else{
17
- this.type = options.type;
18
- }
19
- this.alias = options.alias || this.alias;
20
- }
21
-
22
- from(table: string) {
23
- let sql = `SELECT ${this.select} FROM [${table}] WHERE ${this.where} ORDER BY ${this.orderby}`;
24
- switch (this.type) {
25
- case SQLLang.Oracle:
26
- if (typeof this.skip == "number") sql += ` OFFSET ${this.skip} ROWS`;
27
- if (typeof this.limit == "number") {
28
- if (typeof this.skip != "number") sql += " OFFSET 0 ROWS";
29
- sql += ` FETCH NEXT ${this.limit} ROWS ONLY`;
30
- }
31
- case SQLLang.MsSql:
32
- if (typeof this.orderby !== "string" || this.orderby === "1"){
33
- this.orderby = "(select null) ASC";
34
- }
35
- let start = this.skip ? this.skip : 0;
36
- let end = start + this.limit;
37
- sql = `SELECT * from (SELECT ${this.select}, ROW_NUMBER() OVER(ORDER BY ${this.orderby}) AS RowId
38
- FROM [${table}] WHERE ${this.where}) as a WHERE RowId BETWEEN ${start} + 1 and ${end}`;
39
- break;
40
- case SQLLang.MySql:
41
- case SQLLang.PostgreSql:
42
- default:
43
- if (typeof this.limit == "number") sql += ` LIMIT ${this.limit}`;
44
- if (typeof this.skip == "number") sql += ` OFFSET ${this.skip}`;
45
- break;
46
- }
47
- // 给sql语句中字段名称增加中括号,防止字段名称使用了数据库的关键字
48
- sql = sql.replace(/(\b\w+\b)\.(\b\w+\b)/g, '[$1].[$2]');
49
- return sql;
50
- }
51
-
52
- asMsSql() {
53
- this.type = SQLLang.MsSql;
54
- let rx = new RegExp("\\?", "g");
55
- let keys = this.parameters.keys();
56
- this.originalWhere = this.where;
57
- this.where = this.where.replace(rx, () => `:${keys.next().value}`);
58
- this.includes.forEach((item) => item.asMsSql());
59
- return this;
60
- }
61
-
62
- asPostgreSql() {
63
- this.type = SQLLang.ANSI;
64
- let rx = new RegExp("\\?", "g");
65
- let keys = this.parameters.keys();
66
- this.originalWhere = this.where;
67
- this.where = this.where.replace(rx, () => `:${keys.next().value}`);
68
- this.includes.forEach((item) => item.asPostgreSql());
69
- return this;
70
- }
71
-
72
- asType() {
73
- switch (this.type) {
74
- case SQLLang.MsSql: return this.asMsSql();
75
- case SQLLang.ANSI:
76
- case SQLLang.MySql:
77
- case SQLLang.PostgreSql: return this.asPostgreSql();
78
- case SQLLang.Oracle: return this.asOracleSql();
79
- default: return this;
80
- }
81
- }
82
-
83
- protected VisitExpand(node: Token, context: any) {
84
- node.value.items.forEach((item) => {
85
- let expandPath = item.value.path.raw;
86
- let visitor = this.includes.filter(v => v.navigationProperty == expandPath)[0];
87
- if (!visitor) {
88
- visitor = new TypeOrmVisitor(this.options);
89
- visitor.parameterSeed = this.parameterSeed;
90
- this.includes.push(visitor);
91
- }
92
- visitor.Visit(item);
93
- this.parameterSeed = visitor.parameterSeed;
94
- });
95
- }
96
-
97
- protected VisitSelectItem(node: Token, context: any) {
98
- let item = node.raw.replace(/\//g, '.');
99
- this.select += this.getIdentifier(item, context.identifier);//`${this.alias}.${item}`;
100
- }
101
-
102
- protected VisitODataIdentifier(node: Token, context: any) {
103
- if (context.identifier && context.identifier.endsWith('.')) {
104
- this[context.target] += '.';
105
- }
106
-
107
- if (node.value.name === 'NULL') {
108
- this[context.target] += node.value.name;
109
- } else {
110
- const ident = this.getIdentifier(node.value.name, context);//`${this.alias ? this.alias + '.' : ''}${node.value.name}`;
111
- this[context.target] += ident
112
- }
113
- context.identifier = /*this.getIdentifier(node.value.name, context); //*/node.value.name;
114
- }
115
-
116
- private getIdentifier(originalIdentifier: string, context: any) {
117
- let alias = '';
118
- if (!context || !context.identifier || !context.identifier.endsWith('.')) {
119
- alias = this.alias + '.';
120
- } else {
121
- this[context.target] = this[context.target].replace(new RegExp(this.alias + '.' + context.identifier, 'g'), context.identifier)
122
- }
123
- return `${alias}${originalIdentifier}`;
124
- };
125
-
126
- protected VisitEqualsExpression(node: Token, context: any) {
127
- this.Visit(node.value.left, context);
128
- this.where += ' = ';
129
- this.Visit(node.value.right, context);
130
- if (this.options.useParameters && context.literal == null) {
131
- this.where = this.where.replace(/= :p\d*$/, 'IS NULL')
132
- .replace(new RegExp(`\\:p\\d* = ${context.identifier}$`),
133
- `${context.identifier} IS NULL`);
134
- } else if (context.literal == 'NULL') {
135
- this.where = this.where.replace(/= NULL$/, 'IS NULL')
136
- .replace(new RegExp(`NULL = ${context.identifier}$`), `${context.identifier} IS NULL`);
137
- }
138
- }
139
-
140
- protected VisitNotEqualsExpression(node: Token, context: any) {
141
- this.Visit(node.value.left, context);
142
- this.where += ' <> ';
143
- this.Visit(node.value.right, context);
144
- if (this.options.useParameters && context.literal == null) {
145
- this.where = this.where.replace(/<> :p\d*$/, 'IS NOT NULL')
146
- .replace(new RegExp(`\\:p\\d* <> ${context.identifier}$`),
147
- `${context.identifier} IS NOT NULL`);
148
- } else if (context.literal == 'NULL') {
149
- this.where = this.where.replace(/<> NULL$/, 'IS NOT NULL')
150
- .replace(new RegExp(`NULL <> ${context.identifier}$`), `${context.identifier} IS NOT NULL`);
151
- }
152
- }
153
-
154
- protected VisitLiteral(node: Token, context: any) {
155
- if (this.options.useParameters) {
156
- let name = `p${this.parameterSeed++}`;
157
- let value = Literal.convert(node.value, node.raw);
158
- context.literal = value;
159
- if (context.literal != null) {
160
- this.parameters.set(name, value);
161
- }
162
- // this.where += `:${name}`;
163
- // 因为useParameters为true,所以这里不可以把where追加为:p1这种格式,因为asOracleSql、asPostgreSql等用了正则替换?占位的方式重新设置:p{index}值
164
- // 如果把where追加为:p1这种格式,已知的问题是VisitMethodCallExpression函数中的包括contains在内的所有method都只能写在过滤条件的最前面,而不可以写在后面的位置
165
- this.where += `?`;
166
- } else this.where += (context.literal = SQLLiteral.convert(node.value, node.raw));
167
- }
168
-
169
- protected VisitNotExpression(node: Token, context: any) {
170
- if (node.value && node.value.type === "MethodCallExpression" && node.value.value.method) {
171
- node.value.value.method = `not ${node.value.value.method}`;
172
- this.VisitMethodCallExpression(node.value, context);
173
- }
174
- }
175
-
176
- protected VisitMethodCallExpression(node:Token, context:any){
177
- var method = node.value.method;
178
- var params = node.value.parameters || [];
179
- switch (method){
180
- case "contains":
181
- this.Visit(params[0], context);
182
- if (this.options.useParameters){
183
- let name = `p${this.parameterSeed++}`;
184
- let value = Literal.convert(params[1].value, params[1].raw);
185
- this.parameters.set(name, `%${value}%`);
186
- this.where += " like ?";
187
- }else this.where += ` like '%${SQLLiteral.convert(params[1].value, params[1].raw).slice(1, -1)}%'`;
188
- break;
189
- case "not contains":
190
- this.Visit(params[0], context);
191
- if (this.options.useParameters) {
192
- let name = `p${this.parameterSeed++}`;
193
- let value = Literal.convert(params[1].value, params[1].raw);
194
- this.parameters.set(name, `%${value}%`);
195
- this.where += " not like ?";
196
- } else this.where += ` not like '%${SQLLiteral.convert(params[1].value, params[1].raw).slice(1, -1)}%'`;
197
- break;
198
- case "endswith":
199
- this.Visit(params[0], context);
200
- if (this.options.useParameters){
201
- let name = `p${this.parameterSeed++}`;
202
- let value = Literal.convert(params[1].value, params[1].raw);
203
- this.parameters.set(name, `%${value}`);
204
- this.where += " like ?";
205
- }else this.where += ` like '%${SQLLiteral.convert(params[1].value, params[1].raw).slice(1, -1)}'`;
206
- break;
207
- case "not endswith":
208
- this.Visit(params[0], context);
209
- if (this.options.useParameters) {
210
- let name = `p${this.parameterSeed++}`;
211
- let value = Literal.convert(params[1].value, params[1].raw);
212
- this.parameters.set(name, `%${value}`);
213
- this.where += " not like ?";
214
- } else this.where += ` not like '%${SQLLiteral.convert(params[1].value, params[1].raw).slice(1, -1)}'`;
215
- break;
216
- case "startswith":
217
- this.Visit(params[0], context);
218
- if (this.options.useParameters){
219
- let name = `p${this.parameterSeed++}`;
220
- let value = Literal.convert(params[1].value, params[1].raw);
221
- this.parameters.set(name, `${value}%`);
222
- this.where += " like ?";
223
- }else this.where += ` like '${SQLLiteral.convert(params[1].value, params[1].raw).slice(1, -1)}%'`;
224
- break;
225
- case "not startswith":
226
- this.Visit(params[0], context);
227
- if (this.options.useParameters) {
228
- let name = `p${this.parameterSeed++}`;
229
- let value = Literal.convert(params[1].value, params[1].raw);
230
- this.parameters.set(name, `${value}%`);
231
- this.where += " not like ?";
232
- } else this.where += ` not like '${SQLLiteral.convert(params[1].value, params[1].raw).slice(1, -1)}%'`;
233
- break;
234
- case "indexof":
235
- let fn = "";
236
- switch (this.type) {
237
- case SQLLang.MsSql:
238
- fn = "CHARINDEX";
239
- break;
240
- case SQLLang.ANSI:
241
- case SQLLang.MySql:
242
- case SQLLang.PostgreSql:
243
- default:
244
- fn = "INSTR";
245
- break;
246
- }
247
- if (fn === "CHARINDEX"){
248
- const tmp = params[0];
249
- params[0] = params[1];
250
- params[1] = tmp;
251
- }
252
- this.where += `${fn}(`;
253
- this.Visit(params[0], context);
254
- this.where += ', ';
255
- this.Visit(params[1], context);
256
- this.where += ") - 1";
257
- break;
258
- case "round":
259
- this.where += "ROUND(";
260
- this.Visit(params[0], context);
261
- this.where += ")";
262
- break;
263
- case "length":
264
- this.where += "LEN(";
265
- this.Visit(params[0], context);
266
- this.where += ")";
267
- break;
268
- case "tolower":
269
- this.where += "LOWER(";
270
- this.Visit(params[0], context);
271
- this.where += ")";
272
- break;
273
- case "toupper":
274
- this.where += "UPPER(";
275
- this.Visit(params[0], context);
276
- this.where += ")";
277
- break;
278
- case "floor":
279
- case "ceiling":
280
- case "year":
281
- case "month":
282
- case "day":
283
- case "hour":
284
- case "minute":
285
- case "second":
286
- this.where += `${method.toUpperCase()}(`;
287
- this.Visit(params[0], context);
288
- this.where += ")";
289
- break;
290
- case "now":
291
- this.where += "NOW()";
292
- break;
293
- case "trim":
294
- this.where += "TRIM(' ' FROM ";
295
- this.Visit(params[0], context);
296
- this.where += ")";
297
- break;
298
- }
299
- }
300
-
301
- }
package/tsconfig.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "sourceMap": true,
4
- "target": "es6",
5
- "module": "commonjs",
6
- "declaration": true,
7
- "skipLibCheck": true,
8
- "experimentalDecorators": true,
9
- "outDir": "lib"
10
- }
11
- }