speed 1.0.9 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +318 -2
- package/index.d.ts +2 -0
- package/index.js +6 -0
- package/index.js.map +1 -0
- package/package.json +2 -2
- package/speed.decorator.d.ts +7 -0
- package/speed.decorator.js +208 -0
- package/speed.decorator.js.map +1 -0
- package/speed.service.d.ts +9 -0
- package/speed.service.js +29 -0
- package/speed.service.js.map +1 -0
- package/tsconfig.json +10 -6
package/README.md
CHANGED
|
@@ -1,2 +1,318 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
## SpeedSQL
|
|
2
|
+
|
|
3
|
+
SQL injection for NestJS, similar mybatis.
|
|
4
|
+
|
|
5
|
+
### Introduction
|
|
6
|
+
|
|
7
|
+
- Follow NestJS Module injection mode.
|
|
8
|
+
- With the TypeScript Decorators, same as Java annotations.
|
|
9
|
+
- Similar to MyBatis used in Java.
|
|
10
|
+
- Support for the Prepared Statements.
|
|
11
|
+
- Support for Entity Injection.
|
|
12
|
+
- Support the Connection pools by mysql2 within.
|
|
13
|
+
|
|
14
|
+
### Install as a dependency
|
|
15
|
+
|
|
16
|
+
Setup SpeedSQL (NPM named `speed`) as dependency in *package.json* file `dependencies`
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"speed": "latest"
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Quick Start
|
|
25
|
+
|
|
26
|
+
- Prepare some entities and configurations.
|
|
27
|
+
|
|
28
|
+
*db.provider.ts*
|
|
29
|
+
```
|
|
30
|
+
import { createPool, Pool } from 'speed';
|
|
31
|
+
|
|
32
|
+
export const DbProviders = [
|
|
33
|
+
{
|
|
34
|
+
provide: 'SPEED_POOL',
|
|
35
|
+
useFactory: async (): Promise<Pool> => {
|
|
36
|
+
return await createPool({
|
|
37
|
+
host: 'localhost',
|
|
38
|
+
user: 'root',
|
|
39
|
+
port: 3306,
|
|
40
|
+
password: 'qwer1234',
|
|
41
|
+
database: 'test',
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
```
|
|
47
|
+
*entity/param.dto.ts*
|
|
48
|
+
```
|
|
49
|
+
export class ParamDto {
|
|
50
|
+
constructor(public name: string, public age: number) {}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
*entity/user.dto.ts*
|
|
54
|
+
```
|
|
55
|
+
export class UserDto {
|
|
56
|
+
constructor(public name: string, public age: number) {}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
* * *
|
|
61
|
+
|
|
62
|
+
- Import into the Module of NestJS
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
*app.mudule.ts*
|
|
66
|
+
```
|
|
67
|
+
import { Module } from '@nestjs/common';
|
|
68
|
+
import { AppController } from './app.controller';
|
|
69
|
+
import { AppService } from './app.service';
|
|
70
|
+
import { SpeedService } from 'speed';
|
|
71
|
+
import { DbProviders } from './db.providers';
|
|
72
|
+
|
|
73
|
+
@Module({
|
|
74
|
+
imports: [],
|
|
75
|
+
controllers: [AppController],
|
|
76
|
+
providers: [AppService, SpeedService, ...DbProviders],
|
|
77
|
+
})
|
|
78
|
+
export class AppModule {}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
* * *
|
|
82
|
+
|
|
83
|
+
- Define SpeedSQL within Services, use the Decorators as MyBatis.
|
|
84
|
+
|
|
85
|
+
*app.service.ts*
|
|
86
|
+
```
|
|
87
|
+
import { Injectable } from '@nestjs/common';
|
|
88
|
+
import { Delete, Update, Param, ResultType, Insert } from 'speed';
|
|
89
|
+
import { UserDto } from './entity/user.dto';
|
|
90
|
+
import { ParamDto } from './entity/param.dto';
|
|
91
|
+
|
|
92
|
+
@Injectable()
|
|
93
|
+
export class AppService {
|
|
94
|
+
@Update('update user set age = #{age} where name = #{name}')
|
|
95
|
+
setUserAge(@Param('name') name: string, @Param('age') age: number): number {return;}
|
|
96
|
+
|
|
97
|
+
@Delete('delete from user where name = #{name}')
|
|
98
|
+
deleteUser(@Param('name') name: string): number {return;}
|
|
99
|
+
|
|
100
|
+
@ResultType(UserDto)
|
|
101
|
+
@Select('select `name`, `age` from `user` where `uid` = #{uid} and `name` = #{name}')
|
|
102
|
+
getRecords(paramDto: ParamDto): UserDto[] {return;}
|
|
103
|
+
|
|
104
|
+
@Insert('insert into user (name, age) value (#{name}, #{age})')
|
|
105
|
+
addUser(user: UserDto): number {return;}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
* * *
|
|
110
|
+
|
|
111
|
+
- Use Your Services.
|
|
112
|
+
|
|
113
|
+
*app.controller.ts*
|
|
114
|
+
```
|
|
115
|
+
import { Controller, Get } from '@nestjs/common';
|
|
116
|
+
import { AppService } from './app.service';
|
|
117
|
+
import { ParamDto } from './entity/param.dto';
|
|
118
|
+
import { UserDto } from "./entity/create-cat.dto";
|
|
119
|
+
|
|
120
|
+
@Controller()
|
|
121
|
+
export class AppController {
|
|
122
|
+
constructor(private readonly appService: AppService) {}
|
|
123
|
+
|
|
124
|
+
@Get()
|
|
125
|
+
async getHello() {
|
|
126
|
+
await this.appService.setUserAge("zzz", 20);
|
|
127
|
+
return "hello world";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Configuration
|
|
134
|
+
|
|
135
|
+
The Connection pools configuration is exactly the same as mysql2's [createPool\(\)](https://github.com/sidorares/node-mysql2#using-promise-wrapper).
|
|
136
|
+
|
|
137
|
+
The usual format is as follows:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
{
|
|
141
|
+
host: '127.0.0.1',
|
|
142
|
+
user: 'root',
|
|
143
|
+
port: 3306,
|
|
144
|
+
password: '123456',
|
|
145
|
+
database: 'test',
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
* * *
|
|
150
|
+
Like common NestJS Modules, SpeedSQL uses [Asynchronous providers](https://docs.nestjs.com/fundamentals/async-providers) to inject it's Connection Pool for startup.
|
|
151
|
+
|
|
152
|
+
- Make file ```db.provider.ts```
|
|
153
|
+
```
|
|
154
|
+
import { createPool, Pool } from 'speed';
|
|
155
|
+
|
|
156
|
+
export const DbProviders = [
|
|
157
|
+
{
|
|
158
|
+
provide: 'SPEED_POOL',
|
|
159
|
+
useFactory: async (): Promise<Pool> => {
|
|
160
|
+
return await createPool({
|
|
161
|
+
host: 'localhost',
|
|
162
|
+
user: 'root',
|
|
163
|
+
port: 3306,
|
|
164
|
+
password: 'qwer1234',
|
|
165
|
+
database: 'test',
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
```
|
|
171
|
+
- Put ```db.provider.ts``` in NestJS app src dir and set it as a provider.
|
|
172
|
+
```
|
|
173
|
+
import { Module } from '@nestjs/common';
|
|
174
|
+
import { AppController } from './app.controller';
|
|
175
|
+
import { AppService } from './app.service';
|
|
176
|
+
import { SpeedService } from 'speed';
|
|
177
|
+
import { DbProviders } from './db.providers';
|
|
178
|
+
|
|
179
|
+
@Module({
|
|
180
|
+
imports: [],
|
|
181
|
+
controllers: [AppController],
|
|
182
|
+
providers: [AppService, SpeedService, ...DbProviders],
|
|
183
|
+
})
|
|
184
|
+
export class AppModule {}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Parameter with named (for Prepared Statements)
|
|
188
|
+
|
|
189
|
+
As with MyBatis, SpeedSQL is possible to pass a value to a bind parameter as a named parameter to ensure readability and prevent SQL Injection attacks.
|
|
190
|
+
|
|
191
|
+
Unlike [Prepared Statements](https://github.com/sidorares/node-mysql2#using-prepared-statements) in mysql2, SpeedSQL can be pass param value with named to make SQL more clearer.
|
|
192
|
+
|
|
193
|
+
**Parameter with named value can support ```@Select```, ```@Insert```, ```@Update```, ```@Delete``` all the CRUD operations.**
|
|
194
|
+
|
|
195
|
+
* * *
|
|
196
|
+
|
|
197
|
+
SpeedSQL has two Parameter with named modes.
|
|
198
|
+
|
|
199
|
+
> Note that you can only choose ONE of the modes at ONE statement.
|
|
200
|
+
|
|
201
|
+
**Object as Parameters**
|
|
202
|
+
|
|
203
|
+
- Creates a conditional entity class with the same attribute and parameter names.
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
export class ParamDto {
|
|
207
|
+
constructor(public name: string, public age: number) {}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- Inject values as parameter entities.
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
import { ResultType, Select } from 'speed';
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@ResultType(UserDto)
|
|
218
|
+
@Select('select `name`, `age` from `user` where `uid` = #{uid} and `name` = #{name}')
|
|
219
|
+
getRecords(paramDto: ParamDto): UserDto[]{return;}
|
|
220
|
+
```
|
|
221
|
+
- So we can start to use.
|
|
222
|
+
```
|
|
223
|
+
const users: UserDto[] = await this.appService.getRecords(
|
|
224
|
+
new ParamDto("zzz", 10)
|
|
225
|
+
);
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Named Value as Parameters**
|
|
229
|
+
|
|
230
|
+
Annotate the parameter value name with the parameter annotation '@Param', which corresponds to the SQL value name.
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
import { ResultType, Select, Param } from 'speed';
|
|
234
|
+
|
|
235
|
+
@ResultType(UserDto)
|
|
236
|
+
@Select(select `name`, `age` from `user` where `uid` = #{uid} and `name` = #{name}')
|
|
237
|
+
getRecords(@Param('uid') uid:number, @Param('name') name:string): UserDto[]{return;}
|
|
238
|
+
```
|
|
239
|
+
So we can start to use.
|
|
240
|
+
```
|
|
241
|
+
const users: UserDto[] = await this.appService.getRecords('zzz', 10);
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Select
|
|
245
|
+
|
|
246
|
+
SpeedSQL uses ```@ResultType``` to annotate the resulting entity.
|
|
247
|
+
|
|
248
|
+
Select returns an array of annotated entity (```@ResultType```).
|
|
249
|
+
|
|
250
|
+
- Create a entity:
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
export class UserDto {
|
|
254
|
+
constructor(public name: string, public age: number) {}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
- And Select.
|
|
258
|
+
```
|
|
259
|
+
import { ResultType, Select, Param } from 'speed';
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
@ResultType(UserDto)
|
|
263
|
+
@Select('select `name`, `age` from user where uid = #{uid} and name = #{name} ')
|
|
264
|
+
getRecords(@Param('uid') uid:number, @Param('name') name:string): UserDto[] {return;}
|
|
265
|
+
```
|
|
266
|
+
- The return Array will contains entities, and field name will correspond to the attributes of the entity.
|
|
267
|
+
|
|
268
|
+
If the field name and attribute are not the same, the value of different name will be lost. The solution is to use SQL's ```AS``` to alias the field name to correspond to the attributes of the entity.
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
import { ResultType, Select, Param } from 'speed';
|
|
273
|
+
|
|
274
|
+
@ResultType(UserDto)
|
|
275
|
+
@Select('select `realname` as `name`, `age` from user where uid = #{uid} and name = #{name} ')
|
|
276
|
+
getRecords(@Param('uid') uid:number, @Param('name') name:string): UserDto[] {return;}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
### Insert
|
|
281
|
+
|
|
282
|
+
Parameter with named is also supported in ```@Insert```.
|
|
283
|
+
|
|
284
|
+
The ```@Insert``` return value is <u>the new inserted ID</u>, which can also be ignored.
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
import { Insert } from 'speed';
|
|
288
|
+
|
|
289
|
+
@Insert('insert into user (name, age) value (#{name}, #{age})')
|
|
290
|
+
addUser(user: UserDto): number {return;}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Update and Delete
|
|
294
|
+
|
|
295
|
+
Parameter with named is also supported in ```@Update``` and ```@Delete```.
|
|
296
|
+
|
|
297
|
+
The ```@Update``` and ```@Delete``` returns number is <u>the effected rows</u>, which can also be ignored.
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
import { Delete, Update, Param } from 'speed';
|
|
301
|
+
|
|
302
|
+
@Update('update user set age = #{age} where name = #{name}')
|
|
303
|
+
setUserAge(@Param('name') name: string, @Param('age') age: number): number {return;}
|
|
304
|
+
|
|
305
|
+
@Delete('delete from user where name = #{name}')
|
|
306
|
+
deleteUser(@Param('name') name: string): number {return;}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
### About
|
|
311
|
+
|
|
312
|
+
Github:[https://github.com/speedphp/speedsql](https://github.com/speedphp/speedsql)
|
|
313
|
+
|
|
314
|
+
The SpeedSQL project follows the open source agreement of the ```MIT License```.
|
|
315
|
+
|
|
316
|
+
Thanks: [NestJS](https://nestjs.com/),[mysql2](https://github.com/sidorares/node-mysql2),[MyBatis](https://mybatis.org/).
|
|
317
|
+
|
|
318
|
+
Issue: [https://github.com/SpeedPHP/speedsql/issues](https://github.com/SpeedPHP/speedsql/issues)
|
package/index.d.ts
ADDED
package/index.js
ADDED
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;AAAA,uCAAkC;AAClC,qCAAgC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare function log(message?: any, ...optionalParams: any[]): void;
|
|
2
|
+
declare function ResultType(constructorFunction: any): (target: any, propertyKey: string) => void;
|
|
3
|
+
declare function Param(name: string): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
|
|
4
|
+
declare function Insert(sql: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
5
|
+
declare function Update(sql: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
6
|
+
declare function Select(sql: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
7
|
+
export { log, Param, ResultType, Select, Insert, Update, Update as Delete };
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
|
|
12
|
+
return { next: verb(0), "throw": verb(1), "return": verb(2) };
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (_) try {
|
|
17
|
+
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [0, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var speed_service_1 = require("./speed.service");
|
|
38
|
+
var paramMetadataKey = Symbol('param');
|
|
39
|
+
function log(message) {
|
|
40
|
+
var optionalParams = [];
|
|
41
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
42
|
+
optionalParams[_i - 1] = arguments[_i];
|
|
43
|
+
}
|
|
44
|
+
console.log.apply(console, [message].concat(optionalParams));
|
|
45
|
+
}
|
|
46
|
+
exports.log = log;
|
|
47
|
+
function ResultType(constructorFunction) {
|
|
48
|
+
var newConstructorFunction = function () {
|
|
49
|
+
var args = [];
|
|
50
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
51
|
+
args[_i] = arguments[_i];
|
|
52
|
+
}
|
|
53
|
+
var func = function () {
|
|
54
|
+
return new (constructorFunction.bind.apply(constructorFunction, [void 0].concat(args)))();
|
|
55
|
+
};
|
|
56
|
+
func.prototype = constructorFunction.prototype;
|
|
57
|
+
return new func();
|
|
58
|
+
};
|
|
59
|
+
newConstructorFunction.prototype = constructorFunction.prototype;
|
|
60
|
+
return function (target, propertyKey) {
|
|
61
|
+
speed_service_1.resultTypeMap.set([target.constructor.name, propertyKey].toString(), newConstructorFunction());
|
|
62
|
+
//never return
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
exports.ResultType = ResultType;
|
|
66
|
+
function Param(name) {
|
|
67
|
+
return function (target, propertyKey, parameterIndex) {
|
|
68
|
+
var existingParameters = Reflect.getOwnMetadata(paramMetadataKey, target, propertyKey) || [];
|
|
69
|
+
existingParameters.push([name, parameterIndex]);
|
|
70
|
+
Reflect.defineMetadata(paramMetadataKey, existingParameters, target, propertyKey);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
exports.Param = Param;
|
|
74
|
+
function convertSQLParams(args, target, propertyKey, decoratorSQL) {
|
|
75
|
+
var queryValues = [];
|
|
76
|
+
var argsVal;
|
|
77
|
+
if (typeof args[0] === 'object') {
|
|
78
|
+
argsVal = new Map(Object.getOwnPropertyNames(args[0]).map(function (valName) { return [
|
|
79
|
+
valName,
|
|
80
|
+
args[0][valName],
|
|
81
|
+
]; }));
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
var existingParameters = Reflect.getOwnMetadata(paramMetadataKey, target, propertyKey);
|
|
85
|
+
argsVal = new Map(existingParameters.map(function (_a) {
|
|
86
|
+
var argName = _a[0], argIdx = _a[1];
|
|
87
|
+
return [argName, args[argIdx]];
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
var regExp = /#{(\w+)}/g;
|
|
91
|
+
decoratorSQL.matchAll(regExp).slice().forEach(function (match) {
|
|
92
|
+
var replaceTag = match[0], matchName = match[1];
|
|
93
|
+
decoratorSQL = decoratorSQL.replace(new RegExp(replaceTag, 'g'), '?');
|
|
94
|
+
queryValues.push(argsVal.get(matchName));
|
|
95
|
+
});
|
|
96
|
+
return [decoratorSQL, queryValues];
|
|
97
|
+
}
|
|
98
|
+
function queryForExecute(sql, args, target, propertyKey) {
|
|
99
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
100
|
+
var sqlValues, newSql, result, _a;
|
|
101
|
+
return __generator(this, function (_b) {
|
|
102
|
+
switch (_b.label) {
|
|
103
|
+
case 0:
|
|
104
|
+
sqlValues = [];
|
|
105
|
+
newSql = sql;
|
|
106
|
+
if (args.length > 0) {
|
|
107
|
+
_a = convertSQLParams(args, target, propertyKey, sql), newSql = _a[0], sqlValues = _a[1];
|
|
108
|
+
}
|
|
109
|
+
return [4 /*yield*/, speed_service_1.speedPromisePool.query(newSql, sqlValues)];
|
|
110
|
+
case 1:
|
|
111
|
+
result = (_b.sent())[0];
|
|
112
|
+
return [2 /*return*/, result];
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function Insert(sql) {
|
|
118
|
+
return function (target, propertyKey, descriptor) {
|
|
119
|
+
var _this = this;
|
|
120
|
+
descriptor.value = function () {
|
|
121
|
+
var args = [];
|
|
122
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
123
|
+
args[_i] = arguments[_i];
|
|
124
|
+
}
|
|
125
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
126
|
+
var result;
|
|
127
|
+
return __generator(this, function (_a) {
|
|
128
|
+
switch (_a.label) {
|
|
129
|
+
case 0: return [4 /*yield*/, queryForExecute(sql, args, target, propertyKey)];
|
|
130
|
+
case 1:
|
|
131
|
+
result = _a.sent();
|
|
132
|
+
return [2 /*return*/, result.insertId];
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
exports.Insert = Insert;
|
|
140
|
+
function Update(sql) {
|
|
141
|
+
return function (target, propertyKey, descriptor) {
|
|
142
|
+
var _this = this;
|
|
143
|
+
descriptor.value = function () {
|
|
144
|
+
var args = [];
|
|
145
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
146
|
+
args[_i] = arguments[_i];
|
|
147
|
+
}
|
|
148
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
149
|
+
var result;
|
|
150
|
+
return __generator(this, function (_a) {
|
|
151
|
+
switch (_a.label) {
|
|
152
|
+
case 0: return [4 /*yield*/, queryForExecute(sql, args, target, propertyKey)];
|
|
153
|
+
case 1:
|
|
154
|
+
result = _a.sent();
|
|
155
|
+
return [2 /*return*/, result.affectedRows];
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
exports.Update = Update;
|
|
163
|
+
exports.Delete = Update;
|
|
164
|
+
function Select(sql) {
|
|
165
|
+
return function (target, propertyKey, descriptor) {
|
|
166
|
+
var _this = this;
|
|
167
|
+
descriptor.value = function () {
|
|
168
|
+
var args = [];
|
|
169
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
170
|
+
args[_i] = arguments[_i];
|
|
171
|
+
}
|
|
172
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
173
|
+
var sqlValues, rows, records, resultType, _loop_1, rowIndex, _a;
|
|
174
|
+
return __generator(this, function (_b) {
|
|
175
|
+
switch (_b.label) {
|
|
176
|
+
case 0:
|
|
177
|
+
sqlValues = [];
|
|
178
|
+
if (args.length > 0) {
|
|
179
|
+
_a = convertSQLParams(args, target, propertyKey, sql), sql = _a[0], sqlValues = _a[1];
|
|
180
|
+
}
|
|
181
|
+
return [4 /*yield*/, speed_service_1.speedPromisePool.query(sql, sqlValues)];
|
|
182
|
+
case 1:
|
|
183
|
+
rows = (_b.sent())[0];
|
|
184
|
+
if (Object.keys(rows).length === 0) {
|
|
185
|
+
return [2 /*return*/];
|
|
186
|
+
}
|
|
187
|
+
records = [];
|
|
188
|
+
resultType = speed_service_1.resultTypeMap.get([target.constructor.name, propertyKey].toString());
|
|
189
|
+
_loop_1 = function (rowIndex) {
|
|
190
|
+
var entity = Object.create(resultType);
|
|
191
|
+
Object.getOwnPropertyNames(resultType).forEach(function (propertyRow) {
|
|
192
|
+
if (rows[rowIndex].hasOwnProperty(propertyRow)) {
|
|
193
|
+
Object.defineProperty(entity, propertyRow, Object.getOwnPropertyDescriptor(rows[rowIndex], propertyRow));
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
records.push(entity);
|
|
197
|
+
};
|
|
198
|
+
for (rowIndex in rows) {
|
|
199
|
+
_loop_1(rowIndex);
|
|
200
|
+
}
|
|
201
|
+
return [2 /*return*/, records];
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
exports.Select = Select;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speed.decorator.js","sourceRoot":"","sources":["speed.decorator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Pool, createPool } from 'mysql2';
|
|
2
|
+
import { Pool as PromisePool } from 'mysql2/promise';
|
|
3
|
+
declare let speedPromisePool: PromisePool;
|
|
4
|
+
declare const resultTypeMap: Map<string, any>;
|
|
5
|
+
export declare class SpeedService {
|
|
6
|
+
private pool;
|
|
7
|
+
constructor(pool: Pool);
|
|
8
|
+
}
|
|
9
|
+
export { speedPromisePool, resultTypeMap, createPool, Pool };
|
package/speed.service.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
9
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
10
|
+
};
|
|
11
|
+
var common_1 = require("@nestjs/common");
|
|
12
|
+
var mysql2_1 = require("mysql2");
|
|
13
|
+
exports.createPool = mysql2_1.createPool;
|
|
14
|
+
var speedPromisePool;
|
|
15
|
+
exports.speedPromisePool = speedPromisePool;
|
|
16
|
+
var resultTypeMap = new Map();
|
|
17
|
+
exports.resultTypeMap = resultTypeMap;
|
|
18
|
+
var SpeedService = (function () {
|
|
19
|
+
function SpeedService(pool) {
|
|
20
|
+
this.pool = pool;
|
|
21
|
+
exports.speedPromisePool = speedPromisePool = pool.promise();
|
|
22
|
+
}
|
|
23
|
+
return SpeedService;
|
|
24
|
+
}());
|
|
25
|
+
SpeedService = __decorate([
|
|
26
|
+
common_1.Injectable(),
|
|
27
|
+
__param(0, common_1.Inject('SPEED_POOL'))
|
|
28
|
+
], SpeedService);
|
|
29
|
+
exports.SpeedService = SpeedService;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speed.service.js","sourceRoot":"","sources":["speed.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AACpD,mCAA0C;AAYA,yCAAU;AATpD,IAAI,gBAA6B,CAAC;AASzB,4CAAgB;AARzB,MAAM,aAAa,GAAG,IAAI,GAAG,EAAe,CAAC;AAQlB,sCAAa;AALxC,IAAa,YAAY,GAAzB;IACI,YAA0C,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;QAChD,2BAAA,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IACtC,CAAC;CACJ,CAAA;AAJY,YAAY;IADxB,mBAAU,EAAE;IAEI,WAAA,eAAM,CAAC,YAAY,CAAC,CAAA;;GADxB,YAAY,CAIxB;AAJY,oCAAY"}
|
package/tsconfig.json
CHANGED
|
@@ -8,14 +8,18 @@
|
|
|
8
8
|
"allowSyntheticDefaultImports": true,
|
|
9
9
|
"target": "es2017",
|
|
10
10
|
"sourceMap": true,
|
|
11
|
-
"outDir": "./
|
|
11
|
+
"outDir": "./",
|
|
12
12
|
"baseUrl": "./",
|
|
13
|
-
"incremental": true,
|
|
14
13
|
"skipLibCheck": true,
|
|
15
14
|
"strictNullChecks": false,
|
|
16
15
|
"noImplicitAny": false,
|
|
17
|
-
"strictBindCallApply": false,
|
|
18
16
|
"forceConsistentCasingInFileNames": false,
|
|
19
|
-
"noFallthroughCasesInSwitch": false
|
|
20
|
-
|
|
21
|
-
}
|
|
17
|
+
"noFallthroughCasesInSwitch": false,
|
|
18
|
+
"types": []
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"index.ts",
|
|
22
|
+
"speed.decorator.ts",
|
|
23
|
+
"speed.service.ts"
|
|
24
|
+
]
|
|
25
|
+
}
|