query-core 0.1.8 → 0.1.9
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/lib/SearchBuilder.js +16 -8
- package/lib/batch.js +1 -1
- package/lib/build.js +202 -100
- package/lib/client.js +180 -0
- package/lib/index.js +9 -70
- package/lib/map.js +75 -0
- package/lib/query.js +7 -3
- package/lib/search.js +4 -1
- package/lib/services.js +13 -4
- package/package.json +1 -1
- package/src/SearchBuilder.ts +23 -14
- package/src/batch.ts +2 -2
- package/src/build.ts +177 -86
- package/src/client.ts +202 -0
- package/src/index.ts +23 -63
- package/src/map.ts +67 -0
- package/src/query.ts +14 -10
- package/src/search.ts +11 -8
- package/src/services.ts +20 -10
- package/tsconfig.json +1 -0
package/src/client.ts
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import {buildToInsert, buildToInsertBatch, buildToUpdate, buildToUpdateBatch} from './build';
|
|
2
|
+
import {handleResults} from './map';
|
|
3
|
+
import {Attribute, Attributes, Statement, StringMap} from './metadata';
|
|
4
|
+
|
|
5
|
+
export interface JStatement {
|
|
6
|
+
query: string;
|
|
7
|
+
params?: any[];
|
|
8
|
+
dates?: number[];
|
|
9
|
+
}
|
|
10
|
+
export interface Headers {
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}
|
|
13
|
+
export interface HttpOptionsService {
|
|
14
|
+
getHttpOptions(): { headers?: Headers };
|
|
15
|
+
}
|
|
16
|
+
export interface HttpRequest {
|
|
17
|
+
post<T>(url: string, obj: any, options?: {headers?: Headers}): Promise<T>;
|
|
18
|
+
}
|
|
19
|
+
export interface Proxy {
|
|
20
|
+
query<T>(sql: string, args?: any[], m?: StringMap, bools?: Attribute[]): Promise<T[]>;
|
|
21
|
+
exec(sql: string, args?: any[]): Promise<number>;
|
|
22
|
+
execBatch(stmts: Statement[]): Promise<number>;
|
|
23
|
+
beginTransaction?(timeout?: number): Promise<string>;
|
|
24
|
+
commitTransaction?(tx: string): Promise<boolean>;
|
|
25
|
+
rollbackTransaction?(tx: string): Promise<boolean>;
|
|
26
|
+
queryWithTx?<T>(tx: string, commit: boolean, sql: string, args?: any[], m?: StringMap, bools?: Attribute[]): Promise<T[]>;
|
|
27
|
+
execWithTx?(tx: string, commit: boolean, sql: string, args?: any[]): Promise<number>;
|
|
28
|
+
execBatchWithTx?(tx: string, commit: boolean, stmts: Statement[]): Promise<number>;
|
|
29
|
+
insert?<T>(table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number>;
|
|
30
|
+
update?<T>(table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number>;
|
|
31
|
+
insertBatch?<T>(table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, driver?: string): Promise<number>;
|
|
32
|
+
updateBatch?<T>(table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, notSkipInvalid?: boolean): Promise<number>;
|
|
33
|
+
insertWithTx?<T>(tx: string, commit: boolean, table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number>;
|
|
34
|
+
updateWithTx?<T>(tx: string, commit: boolean, table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number>;
|
|
35
|
+
insertBatchWithTx?<T>(tx: string, commit: boolean, table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, driver?: string): Promise<number>;
|
|
36
|
+
updateBatchWithTx?<T>(tx: string, commit: boolean, table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, notSkipInvalid?: boolean): Promise<number>;
|
|
37
|
+
save?<T>(table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number>;
|
|
38
|
+
saveBatch?<T>(table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, ver?: string): Promise<number>;
|
|
39
|
+
}
|
|
40
|
+
export function buildStatements(s: Statement[]): JStatement[] {
|
|
41
|
+
const d: JStatement[] = [];
|
|
42
|
+
if (!s || s.length === 0) {
|
|
43
|
+
return d;
|
|
44
|
+
}
|
|
45
|
+
for (const t of s) {
|
|
46
|
+
const dates = toDates(t.params);
|
|
47
|
+
const j: JStatement = {query: t.query, params: t.params, dates};
|
|
48
|
+
d.push(j);
|
|
49
|
+
}
|
|
50
|
+
return d;
|
|
51
|
+
}
|
|
52
|
+
export function toDates(args?: any[]): number[] {
|
|
53
|
+
const d: number[] = [];
|
|
54
|
+
if (!args || args.length === 0) {
|
|
55
|
+
return d;
|
|
56
|
+
}
|
|
57
|
+
const l = args.length;
|
|
58
|
+
for (let i = 0; i < l; i++) {
|
|
59
|
+
if (args[i] && args[i] instanceof Date) {
|
|
60
|
+
d.push(i);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return d;
|
|
64
|
+
}
|
|
65
|
+
export class ProxyClient {
|
|
66
|
+
constructor(protected httpRequest: HttpRequest, protected url: string) {
|
|
67
|
+
this.query = this.query.bind(this);
|
|
68
|
+
this.exec = this.exec.bind(this);
|
|
69
|
+
this.execBatch = this.execBatch.bind(this);
|
|
70
|
+
|
|
71
|
+
this.insert = this.insert.bind(this);
|
|
72
|
+
this.update = this.update.bind(this);
|
|
73
|
+
this.insertBatch = this.insertBatch.bind(this);
|
|
74
|
+
this.updateBatch = this.updateBatch.bind(this);
|
|
75
|
+
this.insertWithTx = this.insertWithTx.bind(this);
|
|
76
|
+
this.updateWithTx = this.updateWithTx.bind(this);
|
|
77
|
+
this.insertBatchWithTx = this.insertBatchWithTx.bind(this);
|
|
78
|
+
this.updateBatchWithTx = this.updateBatchWithTx.bind(this);
|
|
79
|
+
|
|
80
|
+
this.beginTransaction = this.beginTransaction.bind(this);
|
|
81
|
+
this.commitTransaction = this.commitTransaction.bind(this);
|
|
82
|
+
this.rollbackTransaction = this.rollbackTransaction.bind(this);
|
|
83
|
+
this.queryWithTx = this.queryWithTx.bind(this);
|
|
84
|
+
this.execWithTx = this.execWithTx.bind(this);
|
|
85
|
+
this.execBatchWithTx = this.execBatchWithTx.bind(this);
|
|
86
|
+
}
|
|
87
|
+
query<T>(sql: string, args?: any[], m?: StringMap, bools?: Attribute[]): Promise<T[]> {
|
|
88
|
+
const dates = toDates(args);
|
|
89
|
+
const j: JStatement = {query: sql, params: args, dates};
|
|
90
|
+
if (m || bools) {
|
|
91
|
+
return this.httpRequest.post<T[]>(this.url + '/query', j).then(r => handleResults(r, m, bools));
|
|
92
|
+
} else {
|
|
93
|
+
return this.httpRequest.post<T[]>(this.url + '/query', j);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exec(sql: string, args?: any[]): Promise<number> {
|
|
97
|
+
const dates = toDates(args);
|
|
98
|
+
const j: JStatement = {query: sql, params: args, dates};
|
|
99
|
+
return this.httpRequest.post<number>(this.url + '/exec', j);
|
|
100
|
+
}
|
|
101
|
+
execBatch(stmts: Statement[]): Promise<number> {
|
|
102
|
+
const d = buildStatements(stmts);
|
|
103
|
+
return this.httpRequest.post<number>(this.url + '/exec-batch', d);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
beginTransaction(timeout?: number): Promise<string> {
|
|
107
|
+
const st = (timeout && timeout > 0 ? '?timeout=' + timeout : '');
|
|
108
|
+
return this.httpRequest.post<string>(this.url + '/begin' + st, '');
|
|
109
|
+
}
|
|
110
|
+
commitTransaction(tx: string): Promise<boolean> {
|
|
111
|
+
return this.httpRequest.post<boolean>(this.url + '/end?tx=' + tx, '');
|
|
112
|
+
}
|
|
113
|
+
rollbackTransaction(tx: string): Promise<boolean> {
|
|
114
|
+
return this.httpRequest.post<boolean>(this.url + '/end?roleback=true&tx=' + tx, '');
|
|
115
|
+
}
|
|
116
|
+
queryWithTx<T>(tx: string, commit: boolean, sql: string, args?: any[], m?: StringMap, bools?: Attribute[]): Promise<T[]> {
|
|
117
|
+
const dates = toDates(args);
|
|
118
|
+
const j: JStatement = {query: sql, params: args, dates};
|
|
119
|
+
const sc = (commit ? '&commit=true' : '');
|
|
120
|
+
if (m || bools) {
|
|
121
|
+
return this.httpRequest.post<T[]>(this.url + '/query?tx=' + tx + sc, j).then(r => handleResults(r, m, bools));
|
|
122
|
+
} else {
|
|
123
|
+
return this.httpRequest.post<T[]>(this.url + '/query?tx=' + tx + sc, j);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
execWithTx(tx: string, commit: boolean, sql: string, args?: any[]): Promise<number> {
|
|
127
|
+
const dates = toDates(args);
|
|
128
|
+
const j: JStatement = {query: sql, params: args, dates};
|
|
129
|
+
const sc = (commit ? '&commit=true' : '');
|
|
130
|
+
return this.httpRequest.post<number>(this.url + '/exec?tx=' + tx + sc, j);
|
|
131
|
+
}
|
|
132
|
+
execBatchWithTx(tx: string, commit: boolean, stmts: Statement[]): Promise<number> {
|
|
133
|
+
const d = buildStatements(stmts);
|
|
134
|
+
const sc = (commit ? '&commit=true' : '');
|
|
135
|
+
return this.httpRequest.post<number>(this.url + '/exec-batch?tx=' + tx + sc, d);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
insert<T>(table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number> {
|
|
139
|
+
const s = buildToInsert(obj, table, attrs, buildParam, ver);
|
|
140
|
+
if (s) {
|
|
141
|
+
return this.exec(s.query, s.params);
|
|
142
|
+
} else {
|
|
143
|
+
return Promise.resolve(-1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
update<T>(table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number> {
|
|
147
|
+
const s = buildToUpdate(obj, table, attrs, buildParam, ver);
|
|
148
|
+
if (s) {
|
|
149
|
+
return this.exec(s.query, s.params);
|
|
150
|
+
} else {
|
|
151
|
+
return Promise.resolve(-1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
insertBatch<T>(table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, driver?: string): Promise<number> {
|
|
155
|
+
const s = buildToInsertBatch(objs, table, attrs, buildParam);
|
|
156
|
+
if (s) {
|
|
157
|
+
return this.exec(s.query, s.params);
|
|
158
|
+
} else {
|
|
159
|
+
return Promise.resolve(-1);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
updateBatch<T>(table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, notSkipInvalid?: boolean): Promise<number> {
|
|
163
|
+
const s = buildToUpdateBatch(objs, table, attrs, buildParam, notSkipInvalid);
|
|
164
|
+
if (s && s.length > 0) {
|
|
165
|
+
return this.execBatch(s);
|
|
166
|
+
} else {
|
|
167
|
+
return Promise.resolve(-1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
insertWithTx<T>(tx: string, commit: boolean, table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number> {
|
|
171
|
+
const s = buildToInsert(obj, table, attrs, buildParam, ver);
|
|
172
|
+
if (s) {
|
|
173
|
+
return this.execWithTx(tx, commit, s.query, s.params);
|
|
174
|
+
} else {
|
|
175
|
+
return Promise.resolve(-1);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
updateWithTx<T>(tx: string, commit: boolean, table: string, attrs: Attributes, obj: T, buildParam: (i: number) => string, ver?: string): Promise<number> {
|
|
179
|
+
const s = buildToUpdate(obj, table, attrs, buildParam, ver);
|
|
180
|
+
if (s) {
|
|
181
|
+
return this.execWithTx(tx, commit, s.query, s.params);
|
|
182
|
+
} else {
|
|
183
|
+
return Promise.resolve(-1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
insertBatchWithTx<T>(tx: string, commit: boolean, table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, driver?: string): Promise<number> {
|
|
187
|
+
const s = buildToInsertBatch(objs, table, attrs, buildParam);
|
|
188
|
+
if (s) {
|
|
189
|
+
return this.execWithTx(tx, commit, s.query, s.params);
|
|
190
|
+
} else {
|
|
191
|
+
return Promise.resolve(-1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
updateBatchWithTx<T>(tx: string, commit: boolean, table: string, attrs: Attributes, objs: T[], buildParam: (i: number) => string, notSkipInvalid?: boolean): Promise<number> {
|
|
195
|
+
const s = buildToUpdateBatch(objs, table, attrs, buildParam, notSkipInvalid);
|
|
196
|
+
if (s && s.length > 0) {
|
|
197
|
+
return this.execBatchWithTx(tx, commit, s);
|
|
198
|
+
} else {
|
|
199
|
+
return Promise.resolve(-1);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -6,12 +6,20 @@ export {SqlLoader as SqlLoadService};
|
|
|
6
6
|
export {SqlWriter as SqlGenericService};
|
|
7
7
|
export {SqlSearchLoader as ViewSearchRepository};
|
|
8
8
|
export {SqlSearchLoader as ViewSearchService};
|
|
9
|
+
export {SqlSearchLoader as SearchRepository};
|
|
10
|
+
export {SqlSearchLoader as SearchService};
|
|
9
11
|
export {SqlSearchWriter as GenericSearchRepository};
|
|
10
12
|
export {SqlSearchWriter as GenericSearchService};
|
|
13
|
+
export {SqlSearchWriter as SqlRepository};
|
|
14
|
+
export {SqlSearchWriter as SqlService};
|
|
15
|
+
export {SqlSearchWriter as Repository};
|
|
16
|
+
export {SqlSearchWriter as Service};
|
|
11
17
|
export {createSqlWriter as createGenericRepository};
|
|
12
18
|
export {createSqlWriter as createGenericService};
|
|
13
19
|
export {createSqlSearchWriter as createGenericSearchRepository};
|
|
14
20
|
export {createSqlSearchWriter as createGenericSearchService};
|
|
21
|
+
export {createSqlSearchWriter as createRepository};
|
|
22
|
+
export {createSqlSearchWriter as createService};
|
|
15
23
|
|
|
16
24
|
export * from './metadata';
|
|
17
25
|
export * from './build';
|
|
@@ -20,7 +28,21 @@ export * from './batch';
|
|
|
20
28
|
export * from './query';
|
|
21
29
|
export * from './search';
|
|
22
30
|
export * from './SearchBuilder';
|
|
31
|
+
export * from './client';
|
|
23
32
|
|
|
33
|
+
export interface Config {
|
|
34
|
+
connectString?: string | undefined;
|
|
35
|
+
host?: string | undefined;
|
|
36
|
+
port?: number;
|
|
37
|
+
server?: string | undefined;
|
|
38
|
+
database?: string | undefined;
|
|
39
|
+
user?: string | undefined;
|
|
40
|
+
password?: string | undefined;
|
|
41
|
+
multipleStatements?: boolean | undefined;
|
|
42
|
+
max?: number | undefined;
|
|
43
|
+
min?: number | undefined;
|
|
44
|
+
idleTimeoutMillis?: number | undefined;
|
|
45
|
+
}
|
|
24
46
|
// tslint:disable-next-line:class-name
|
|
25
47
|
export class resource {
|
|
26
48
|
static string?: boolean;
|
|
@@ -63,43 +85,6 @@ export function toArray(arr: any[]): any[] {
|
|
|
63
85
|
}
|
|
64
86
|
return p;
|
|
65
87
|
}
|
|
66
|
-
export function handleResults<T>(r: T[], m?: StringMap, bools?: Attribute[]): T[] {
|
|
67
|
-
if (m) {
|
|
68
|
-
const res = mapArray(r, m);
|
|
69
|
-
if (bools && bools.length > 0) {
|
|
70
|
-
return handleBool(res, bools);
|
|
71
|
-
} else {
|
|
72
|
-
return res;
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
if (bools && bools.length > 0) {
|
|
76
|
-
return handleBool(r, bools);
|
|
77
|
-
} else {
|
|
78
|
-
return r;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
export function handleBool<T>(objs: T[], bools: Attribute[]): T[] {
|
|
83
|
-
if (!bools || bools.length === 0 || !objs) {
|
|
84
|
-
return objs;
|
|
85
|
-
}
|
|
86
|
-
for (const obj of objs) {
|
|
87
|
-
for (const field of bools) {
|
|
88
|
-
const value = obj[field.name];
|
|
89
|
-
if (value != null && value !== undefined) {
|
|
90
|
-
const b = field.true;
|
|
91
|
-
if (b == null || b === undefined) {
|
|
92
|
-
// tslint:disable-next-line:triple-equals
|
|
93
|
-
obj[field.name] = ('1' == value || 'T' == value || 'Y' == value);
|
|
94
|
-
} else {
|
|
95
|
-
// tslint:disable-next-line:triple-equals
|
|
96
|
-
obj[field.name] = (value == b ? true : false);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return objs;
|
|
102
|
-
}
|
|
103
88
|
export function map<T>(obj: T, m?: StringMap): any {
|
|
104
89
|
if (!m) {
|
|
105
90
|
return obj;
|
|
@@ -115,32 +100,7 @@ export function map<T>(obj: T, m?: StringMap): any {
|
|
|
115
100
|
if (!k0) {
|
|
116
101
|
k0 = key;
|
|
117
102
|
}
|
|
118
|
-
obj2[k0] = obj[key];
|
|
103
|
+
obj2[k0] = (obj as any)[key];
|
|
119
104
|
}
|
|
120
105
|
return obj2;
|
|
121
106
|
}
|
|
122
|
-
export function mapArray<T>(results: T[], m?: StringMap): T[] {
|
|
123
|
-
if (!m) {
|
|
124
|
-
return results;
|
|
125
|
-
}
|
|
126
|
-
const mkeys = Object.keys(m);
|
|
127
|
-
if (mkeys.length === 0) {
|
|
128
|
-
return results;
|
|
129
|
-
}
|
|
130
|
-
const objs = [];
|
|
131
|
-
const length = results.length;
|
|
132
|
-
for (let i = 0; i < length; i++) {
|
|
133
|
-
const obj = results[i];
|
|
134
|
-
const obj2: any = {};
|
|
135
|
-
const keys = Object.keys(obj);
|
|
136
|
-
for (const key of keys) {
|
|
137
|
-
let k0 = m[key];
|
|
138
|
-
if (!k0) {
|
|
139
|
-
k0 = key;
|
|
140
|
-
}
|
|
141
|
-
obj2[k0] = (obj as any)[key];
|
|
142
|
-
}
|
|
143
|
-
objs.push(obj2);
|
|
144
|
-
}
|
|
145
|
-
return objs;
|
|
146
|
-
}
|
package/src/map.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {Attribute, StringMap} from './metadata';
|
|
2
|
+
|
|
3
|
+
export function mapArray<T>(results: T[], m?: StringMap): T[] {
|
|
4
|
+
if (!m) {
|
|
5
|
+
return results;
|
|
6
|
+
}
|
|
7
|
+
const mkeys = Object.keys(m);
|
|
8
|
+
if (mkeys.length === 0) {
|
|
9
|
+
return results;
|
|
10
|
+
}
|
|
11
|
+
const objs = [];
|
|
12
|
+
const length = results.length;
|
|
13
|
+
for (let i = 0; i < length; i++) {
|
|
14
|
+
const obj = results[i];
|
|
15
|
+
const obj2: any = {};
|
|
16
|
+
const keys = Object.keys(obj);
|
|
17
|
+
for (const key of keys) {
|
|
18
|
+
let k0 = m[key];
|
|
19
|
+
if (!k0) {
|
|
20
|
+
k0 = key;
|
|
21
|
+
}
|
|
22
|
+
obj2[k0] = (obj as any)[key];
|
|
23
|
+
}
|
|
24
|
+
objs.push(obj2);
|
|
25
|
+
}
|
|
26
|
+
return objs;
|
|
27
|
+
}
|
|
28
|
+
export function handleResults<T>(r: T[], m?: StringMap, bools?: Attribute[]): T[] {
|
|
29
|
+
if (m) {
|
|
30
|
+
const res = mapArray(r, m);
|
|
31
|
+
if (bools && bools.length > 0) {
|
|
32
|
+
return handleBool(res, bools);
|
|
33
|
+
} else {
|
|
34
|
+
return res;
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
if (bools && bools.length > 0) {
|
|
38
|
+
return handleBool(r, bools);
|
|
39
|
+
} else {
|
|
40
|
+
return r;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function handleBool<T>(objs: T[], bools: Attribute[]): T[] {
|
|
45
|
+
if (!bools || bools.length === 0 || !objs) {
|
|
46
|
+
return objs;
|
|
47
|
+
}
|
|
48
|
+
for (const obj of objs) {
|
|
49
|
+
const o: any = obj;
|
|
50
|
+
for (const field of bools) {
|
|
51
|
+
if (field.name) {
|
|
52
|
+
const v = o[field.name];
|
|
53
|
+
if (typeof v !== 'boolean' && v != null && v !== undefined) {
|
|
54
|
+
const b = field.true;
|
|
55
|
+
if (b == null || b === undefined) {
|
|
56
|
+
// tslint:disable-next-line:triple-equals
|
|
57
|
+
o[field.name] = ('true' == v || '1' == v || 't' == v || 'y' == v || 'on' == v);
|
|
58
|
+
} else {
|
|
59
|
+
// tslint:disable-next-line:triple-equals
|
|
60
|
+
o[field.name] = (v == b ? true : false);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return objs;
|
|
67
|
+
}
|
package/src/query.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {Attribute, Attributes, Statement, StringMap} from './metadata';
|
|
|
3
3
|
|
|
4
4
|
export type LikeType = 'like' | 'ilike';
|
|
5
5
|
|
|
6
|
-
export function buildSort(sort
|
|
6
|
+
export function buildSort(sort?: string, map?: Attributes|StringMap): string {
|
|
7
7
|
if (!sort || sort.length === 0) {
|
|
8
8
|
return '';
|
|
9
9
|
}
|
|
@@ -52,7 +52,11 @@ export function buildOracleParam(i: number): string {
|
|
|
52
52
|
export function buildDollarParam(i: number): string {
|
|
53
53
|
return '$' + i;
|
|
54
54
|
}
|
|
55
|
-
export function buildQuery<S>(
|
|
55
|
+
export function buildQuery<S>(filter: S, bparam: LikeType|((i: number ) => string), table?: string, attrs?: Attributes, sort?: string, fields?: string[], sq?: string, strExcluding?: string, buildSort3?: (sort?: string, map?: Attributes|StringMap) => string): Statement|undefined {
|
|
56
|
+
if (!table || !attrs) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
const s: any = filter;
|
|
56
60
|
let like = 'like';
|
|
57
61
|
let param: (i: number ) => string;
|
|
58
62
|
if (typeof bparam === 'string') {
|
|
@@ -67,8 +71,8 @@ export function buildQuery<S>(s: S, bparam: LikeType|((i: number ) => string), t
|
|
|
67
71
|
like = 'like';
|
|
68
72
|
}
|
|
69
73
|
const filters: string[] = [];
|
|
70
|
-
let q: string;
|
|
71
|
-
let excluding: string[]|number[];
|
|
74
|
+
let q: string|undefined;
|
|
75
|
+
let excluding: string[]|number[]|undefined;
|
|
72
76
|
const args: any[] = [];
|
|
73
77
|
if (sq && sq.length > 0) {
|
|
74
78
|
q = s[sq];
|
|
@@ -220,7 +224,7 @@ export function buildQuery<S>(s: S, bparam: LikeType|((i: number ) => string), t
|
|
|
220
224
|
qfilters.push(`${field} ${like} ${param(i++)}`);
|
|
221
225
|
args.push('%' + q + '%');
|
|
222
226
|
}
|
|
223
|
-
c.push(buildQ(field, attr.match
|
|
227
|
+
c.push(buildQ(field, q, attr.match));
|
|
224
228
|
}
|
|
225
229
|
}
|
|
226
230
|
if (qfilters.length > 0) {
|
|
@@ -238,7 +242,7 @@ export function buildQuery<S>(s: S, bparam: LikeType|((i: number ) => string), t
|
|
|
238
242
|
return { query: sql, params: args };
|
|
239
243
|
}
|
|
240
244
|
}
|
|
241
|
-
export function getId(attrs: Attributes): string {
|
|
245
|
+
export function getId(attrs: Attributes): string|undefined {
|
|
242
246
|
const qkeys = Object.keys(attrs);
|
|
243
247
|
for (const key of qkeys) {
|
|
244
248
|
const attr = attrs[key];
|
|
@@ -270,8 +274,8 @@ export function buildFieldsByAttributes(attrs: Attributes, fields?: string[]): s
|
|
|
270
274
|
export function isEmpty(s: string): boolean {
|
|
271
275
|
return !(s && s.length > 0);
|
|
272
276
|
}
|
|
273
|
-
export function buildQ(field: string,
|
|
274
|
-
const o = {};
|
|
277
|
+
export function buildQ(field: string, q: string, match?: string): any {
|
|
278
|
+
const o: any = {};
|
|
275
279
|
if (match === 'equal') {
|
|
276
280
|
o[field] = q;
|
|
277
281
|
} else if (match === 'prefix') {
|
|
@@ -293,7 +297,7 @@ export function buildMatch(v: string, match: string): string|RegExp {
|
|
|
293
297
|
export function isDateRange<T>(obj: T): boolean {
|
|
294
298
|
const keys: string[] = Object.keys(obj);
|
|
295
299
|
for (const key of keys) {
|
|
296
|
-
const v = obj[key];
|
|
300
|
+
const v = (obj as any)[key];
|
|
297
301
|
if (!(v instanceof Date)) {
|
|
298
302
|
return false;
|
|
299
303
|
}
|
|
@@ -303,7 +307,7 @@ export function isDateRange<T>(obj: T): boolean {
|
|
|
303
307
|
export function isNumberRange<T>(obj: T): boolean {
|
|
304
308
|
const keys: string[] = Object.keys(obj);
|
|
305
309
|
for (const key of keys) {
|
|
306
|
-
const v = obj[key];
|
|
310
|
+
const v = (obj as any)[key];
|
|
307
311
|
if (typeof v !== 'number') {
|
|
308
312
|
return false;
|
|
309
313
|
}
|
package/src/search.ts
CHANGED
|
@@ -4,8 +4,8 @@ export interface SearchResult<T> {
|
|
|
4
4
|
list: T[];
|
|
5
5
|
total?: number;
|
|
6
6
|
}
|
|
7
|
-
export function buildFromQuery<T>(query: (sql: string, args?: any[], m?: StringMap, bools?: Attribute[]) => Promise<T[]>, sql: string, params
|
|
8
|
-
if (limit <= 0) {
|
|
7
|
+
export function buildFromQuery<T>(query: (sql: string, args?: any[], m?: StringMap, bools?: Attribute[]) => Promise<T[]>, sql: string, params?: any[], limit?: number, offset?: number, mp?: StringMap, bools?: Attribute[], provider?: string, totalCol?: string): Promise<SearchResult<T>> {
|
|
8
|
+
if (!limit || limit <= 0) {
|
|
9
9
|
return query(sql, params, mp, bools).then(list => {
|
|
10
10
|
const total = (list ? list.length : undefined);
|
|
11
11
|
return {list, total};
|
|
@@ -27,7 +27,7 @@ export function buildFromQuery<T>(query: (sql: string, args?: any[], m?: StringM
|
|
|
27
27
|
} else {
|
|
28
28
|
const r0 = r[0];
|
|
29
29
|
const keys = Object.keys(r0);
|
|
30
|
-
return r0[keys[0]] as number;
|
|
30
|
+
return (r0 as any)[keys[0]] as number;
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
return Promise.all([resultPromise, countPromise]).then(r => {
|
|
@@ -37,7 +37,7 @@ export function buildFromQuery<T>(query: (sql: string, args?: any[], m?: StringM
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
export function queryAndCount<T>(query: (sql: string, args?: any[], m?: StringMap, bools?: Attribute[]) => Promise<T[]>, sql: string, params: any[], total: string, mp?: StringMap, bools?: Attribute[]): Promise<SearchResult<T>> {
|
|
40
|
+
export function queryAndCount<T>(query: (sql: string, args?: any[], m?: StringMap, bools?: Attribute[]) => Promise<T[]>, sql: string, params: any[]|undefined, total: string, mp?: StringMap, bools?: Attribute[]): Promise<SearchResult<T>> {
|
|
41
41
|
if (!total || total.length === 0) {
|
|
42
42
|
total = 'total';
|
|
43
43
|
}
|
|
@@ -45,9 +45,9 @@ export function queryAndCount<T>(query: (sql: string, args?: any[], m?: StringMa
|
|
|
45
45
|
if (!list || list.length === 0) {
|
|
46
46
|
return {list: [], total: 0};
|
|
47
47
|
}
|
|
48
|
-
const t = list[0][total] as number;
|
|
48
|
+
const t = (list[0] as any)[total] as number;
|
|
49
49
|
for (const obj of list) {
|
|
50
|
-
delete obj[total];
|
|
50
|
+
delete (obj as any)[total];
|
|
51
51
|
}
|
|
52
52
|
return {list, total: t};
|
|
53
53
|
});
|
|
@@ -57,7 +57,7 @@ const s = 'select';
|
|
|
57
57
|
const S = 'SELECT';
|
|
58
58
|
const d = ' distinct ';
|
|
59
59
|
const D = ' DISTINCT ';
|
|
60
|
-
export function buildPagingQuery(sql: string, limit: number, offset
|
|
60
|
+
export function buildPagingQuery(sql: string, limit: number, offset?: number, provider?: string): string {
|
|
61
61
|
if (limit === undefined || limit == null) {
|
|
62
62
|
limit = 0;
|
|
63
63
|
}
|
|
@@ -70,10 +70,13 @@ export function buildPagingQuery(sql: string, limit: number, offset: number, pro
|
|
|
70
70
|
return buildPagingQueryForOracle(sql, limit, offset);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
export function buildPagingQueryForOracle(sql: string, limit: number, offset
|
|
73
|
+
export function buildPagingQueryForOracle(sql: string, limit: number, offset?: number, total?: string) {
|
|
74
74
|
if (!total || total.length === 0) {
|
|
75
75
|
total = 'total';
|
|
76
76
|
}
|
|
77
|
+
if (!offset) {
|
|
78
|
+
offset = 0;
|
|
79
|
+
}
|
|
77
80
|
let l = d.length;
|
|
78
81
|
let i = sql.indexOf(d);
|
|
79
82
|
if (i < 0) {
|
package/src/services.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {attributes, buildToDelete, buildToInsert, buildToUpdate, exist, metadata
|
|
|
2
2
|
import {Attribute, Attributes, Statement, StringMap} from './metadata';
|
|
3
3
|
import {SearchResult} from './search';
|
|
4
4
|
|
|
5
|
-
export interface
|
|
5
|
+
export interface Filter {
|
|
6
6
|
fields?: string[];
|
|
7
7
|
sort?: string;
|
|
8
8
|
q?: string;
|
|
@@ -19,6 +19,7 @@ export class SqlLoader<T, ID> {
|
|
|
19
19
|
protected fromDB?: (v: T) => T) {
|
|
20
20
|
if (Array.isArray(attrs)) {
|
|
21
21
|
this.primaryKeys = attributes(attrs);
|
|
22
|
+
this.attributes = {} as any;
|
|
22
23
|
} else {
|
|
23
24
|
const m = metadata(attrs);
|
|
24
25
|
this.attributes = attrs;
|
|
@@ -26,27 +27,33 @@ export class SqlLoader<T, ID> {
|
|
|
26
27
|
this.map = m.map;
|
|
27
28
|
this.bools = m.bools;
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
if (this.metadata) {
|
|
31
|
+
this.metadata = this.metadata.bind(this);
|
|
32
|
+
}
|
|
30
33
|
this.all = this.all.bind(this);
|
|
31
34
|
this.load = this.load.bind(this);
|
|
32
35
|
this.exist = this.exist.bind(this);
|
|
33
36
|
}
|
|
34
|
-
metadata(): Attributes {
|
|
37
|
+
metadata?(): Attributes {
|
|
35
38
|
return this.attributes;
|
|
36
39
|
}
|
|
37
40
|
all(): Promise<T[]> {
|
|
38
41
|
const sql = `select * from ${this.table}`;
|
|
39
42
|
return this.query(sql, [], this.map);
|
|
40
43
|
}
|
|
41
|
-
load(id: ID, ctx?: any): Promise<T> {
|
|
44
|
+
load(id: ID, ctx?: any): Promise<T|null> {
|
|
42
45
|
const stmt = select<ID>(id, this.table, this.primaryKeys, this.param);
|
|
43
|
-
if (
|
|
46
|
+
if (!stmt) {
|
|
47
|
+
throw new Error('cannot build query by id');
|
|
48
|
+
}
|
|
49
|
+
const fn = this.fromDB;
|
|
50
|
+
if (fn) {
|
|
44
51
|
return this.query(stmt.query, stmt.params, this.map, ctx).then(res => {
|
|
45
52
|
if (!res || res.length === 0) {
|
|
46
53
|
return null;
|
|
47
54
|
} else {
|
|
48
55
|
const obj = res[0];
|
|
49
|
-
return
|
|
56
|
+
return fn(obj);
|
|
50
57
|
}
|
|
51
58
|
});
|
|
52
59
|
} else {
|
|
@@ -56,10 +63,13 @@ export class SqlLoader<T, ID> {
|
|
|
56
63
|
exist(id: ID, ctx?: any): Promise<boolean> {
|
|
57
64
|
const field = (this.primaryKeys[0].field ? this.primaryKeys[0].field : this.primaryKeys[0].name);
|
|
58
65
|
const stmt = exist<ID>(id, this.table, this.primaryKeys, this.param, field);
|
|
66
|
+
if (!stmt) {
|
|
67
|
+
throw new Error('cannot build query by id');
|
|
68
|
+
}
|
|
59
69
|
return this.query(stmt.query, stmt.params, this.map, undefined, ctx).then(res => (!res || res.length === 0) ? false : true);
|
|
60
70
|
}
|
|
61
71
|
}
|
|
62
|
-
export class SqlSearchLoader<T, ID, S extends
|
|
72
|
+
export class SqlSearchLoader<T, ID, S extends Filter> extends SqlLoader<T, ID> {
|
|
63
73
|
constructor(
|
|
64
74
|
protected find: (s: S, limit?: number, offset?: number|string, fields?: string[]) => Promise<SearchResult<T>>,
|
|
65
75
|
table: string,
|
|
@@ -77,7 +87,7 @@ export class SqlSearchLoader<T, ID, S extends SearchModel> extends SqlLoader<T,
|
|
|
77
87
|
export interface Manager {
|
|
78
88
|
exec(sql: string, args?: any[], ctx?: any): Promise<number>;
|
|
79
89
|
execBatch(statements: Statement[], firstSuccess?: boolean, ctx?: any): Promise<number>;
|
|
80
|
-
query<T>(sql: string, args?: any[], m?: StringMap,
|
|
90
|
+
query<T>(sql: string, args?: any[], m?: StringMap, bools?: Attribute[], ctx?: any): Promise<T[]>;
|
|
81
91
|
}
|
|
82
92
|
export function createSqlWriter<T, ID>(table: string,
|
|
83
93
|
manager: Manager,
|
|
@@ -151,7 +161,7 @@ export class SqlWriter<T, ID> extends SqlLoader<T, ID> {
|
|
|
151
161
|
}
|
|
152
162
|
}
|
|
153
163
|
}
|
|
154
|
-
export class SqlSearchWriter<T, ID, S extends
|
|
164
|
+
export class SqlSearchWriter<T, ID, S extends Filter> extends SqlWriter<T, ID> {
|
|
155
165
|
constructor(
|
|
156
166
|
protected find: (s: S, limit?: number, offset?: number|string, fields?: string[]) => Promise<SearchResult<T>>,
|
|
157
167
|
table: string,
|
|
@@ -169,7 +179,7 @@ export class SqlSearchWriter<T, ID, S extends SearchModel> extends SqlWriter<T,
|
|
|
169
179
|
return this.find(s, limit, offset, fields);
|
|
170
180
|
}
|
|
171
181
|
}
|
|
172
|
-
export function createSqlSearchWriter<T, ID, S extends
|
|
182
|
+
export function createSqlSearchWriter<T, ID, S extends Filter>(
|
|
173
183
|
find: (s: S, limit?: number, offset?: number|string, fields?: string[]) => Promise<SearchResult<T>>,
|
|
174
184
|
table: string,
|
|
175
185
|
manager: Manager,
|