anote-server-libs 0.2.1 → 0.2.5
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/models/ApiCall.js +37 -37
- package/models/ApiCall.ts +40 -40
- package/models/Migration.js +35 -35
- package/models/Migration.ts +40 -40
- package/models/repository/BaseModelRepository.js +156 -156
- package/models/repository/BaseModelRepository.ts +152 -152
- package/models/repository/MemoryCache.js +92 -92
- package/models/repository/MemoryCache.ts +87 -87
- package/models/repository/ModelDao.js +239 -238
- package/models/repository/ModelDao.ts +259 -259
- package/package.json +38 -38
- package/services/WithBody.js +60 -60
- package/services/WithBody.ts +56 -56
- package/services/WithTransaction.js +137 -137
- package/services/WithTransaction.ts +134 -134
- package/services/utils.js +197 -188
- package/services/utils.ts +180 -173
- package/tsconfig.json +30 -30
package/models/ApiCall.js
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ApiCallRepository = void 0;
|
|
4
|
-
const mssql_1 = require("mssql");
|
|
5
|
-
const ModelDao_1 = require("./repository/ModelDao");
|
|
6
|
-
class ApiCallRepository extends ModelDao_1.ModelDao {
|
|
7
|
-
constructor(pool, poolMssql, logger) {
|
|
8
|
-
super(pool, poolMssql, logger, 'api_call', 5, pool ? 'id=$1,"updatedOn"=$2,"responseCode"=$3,"responseJson"=$4,"expiresAt"=$5' :
|
|
9
|
-
'id=@1,"updatedOn"=@2,"responseCode"=@3,"responseJson"=@4,"expiresAt"=@5');
|
|
10
|
-
this.pool = pool;
|
|
11
|
-
this.poolMssql = poolMssql;
|
|
12
|
-
this.logger = logger;
|
|
13
|
-
}
|
|
14
|
-
buildObject(q) {
|
|
15
|
-
if (!q)
|
|
16
|
-
return undefined;
|
|
17
|
-
q.id = q.id.trim();
|
|
18
|
-
q.updatedOn = q.updatedOn && new Date(q.updatedOn);
|
|
19
|
-
q.responseCode = parseInt(q.responseCode, 10);
|
|
20
|
-
q.expiresAt = q.expiresAt && new Date(q.expiresAt);
|
|
21
|
-
return q;
|
|
22
|
-
}
|
|
23
|
-
serialize(instance, request) {
|
|
24
|
-
if (request) {
|
|
25
|
-
request.input('1', instance.id);
|
|
26
|
-
request.input('2', mssql_1.DateTimeOffset, instance.updatedOn);
|
|
27
|
-
request.input('3', instance.responseCode);
|
|
28
|
-
request.input('4', instance.responseJson);
|
|
29
|
-
request.input('5', mssql_1.DateTimeOffset, instance.expiresAt);
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
return [instance.id, instance.updatedOn, instance.responseCode, instance.responseJson, instance.expiresAt];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
exports.ApiCallRepository = ApiCallRepository;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiCallRepository = void 0;
|
|
4
|
+
const mssql_1 = require("mssql");
|
|
5
|
+
const ModelDao_1 = require("./repository/ModelDao");
|
|
6
|
+
class ApiCallRepository extends ModelDao_1.ModelDao {
|
|
7
|
+
constructor(pool, poolMssql, logger) {
|
|
8
|
+
super(pool, poolMssql, logger, 'api_call', 5, pool ? 'id=$1,"updatedOn"=$2,"responseCode"=$3,"responseJson"=$4,"expiresAt"=$5' :
|
|
9
|
+
'id=@1,"updatedOn"=@2,"responseCode"=@3,"responseJson"=@4,"expiresAt"=@5');
|
|
10
|
+
this.pool = pool;
|
|
11
|
+
this.poolMssql = poolMssql;
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
}
|
|
14
|
+
buildObject(q) {
|
|
15
|
+
if (!q)
|
|
16
|
+
return undefined;
|
|
17
|
+
q.id = q.id.trim();
|
|
18
|
+
q.updatedOn = q.updatedOn && new Date(q.updatedOn);
|
|
19
|
+
q.responseCode = parseInt(q.responseCode, 10);
|
|
20
|
+
q.expiresAt = q.expiresAt && new Date(q.expiresAt);
|
|
21
|
+
return q;
|
|
22
|
+
}
|
|
23
|
+
serialize(instance, request) {
|
|
24
|
+
if (request) {
|
|
25
|
+
request.input('1', instance.id);
|
|
26
|
+
request.input('2', mssql_1.DateTimeOffset, instance.updatedOn);
|
|
27
|
+
request.input('3', instance.responseCode);
|
|
28
|
+
request.input('4', instance.responseJson);
|
|
29
|
+
request.input('5', mssql_1.DateTimeOffset, instance.expiresAt);
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return [instance.id, instance.updatedOn, instance.responseCode, instance.responseJson, instance.expiresAt];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.ApiCallRepository = ApiCallRepository;
|
package/models/ApiCall.ts
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { ConnectionPool, DateTimeOffset, Request } from 'mssql';
|
|
2
|
-
import {Pool} from 'pg';
|
|
3
|
-
import {Logger} from 'winston';
|
|
4
|
-
import {Model, ModelDao} from './repository/ModelDao';
|
|
5
|
-
|
|
6
|
-
export interface ApiCall extends Model<string> {
|
|
7
|
-
responseCode: number;
|
|
8
|
-
responseJson: string;
|
|
9
|
-
expiresAt: Date;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class ApiCallRepository extends ModelDao<string, ApiCall> {
|
|
13
|
-
constructor(protected pool: Pool, protected poolMssql: ConnectionPool, protected logger: Logger) {
|
|
14
|
-
super(pool, poolMssql, logger, 'api_call', 5, pool ? 'id=$1,"updatedOn"=$2,"responseCode"=$3,"responseJson"=$4,"expiresAt"=$5' :
|
|
15
|
-
'id=@1,"updatedOn"=@2,"responseCode"=@3,"responseJson"=@4,"expiresAt"=@5');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
buildObject(q: any): ApiCall {
|
|
19
|
-
if(!q) return undefined;
|
|
20
|
-
q.id = q.id.trim();
|
|
21
|
-
q.updatedOn = q.updatedOn && new Date(q.updatedOn);
|
|
22
|
-
q.responseCode = parseInt(q.responseCode, 10);
|
|
23
|
-
q.expiresAt = q.expiresAt && new Date(q.expiresAt);
|
|
24
|
-
return q;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
serialize(instance: ApiCall, request?: Request) {
|
|
28
|
-
if(request) {
|
|
29
|
-
request.input('1', instance.id);
|
|
30
|
-
request.input('2', DateTimeOffset, instance.updatedOn);
|
|
31
|
-
request.input('3', instance.responseCode);
|
|
32
|
-
request.input('4', instance.responseJson);
|
|
33
|
-
request.input('5', DateTimeOffset, instance.expiresAt);
|
|
34
|
-
return undefined;
|
|
35
|
-
} else {
|
|
36
|
-
return [instance.id, instance.updatedOn, instance.responseCode, instance.responseJson, instance.expiresAt];
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
}
|
|
1
|
+
import { ConnectionPool, DateTimeOffset, Request } from 'mssql';
|
|
2
|
+
import {Pool} from 'pg';
|
|
3
|
+
import {Logger} from 'winston';
|
|
4
|
+
import {Model, ModelDao} from './repository/ModelDao';
|
|
5
|
+
|
|
6
|
+
export interface ApiCall extends Model<string> {
|
|
7
|
+
responseCode: number;
|
|
8
|
+
responseJson: string;
|
|
9
|
+
expiresAt: Date;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class ApiCallRepository extends ModelDao<string, ApiCall> {
|
|
13
|
+
constructor(protected pool: Pool, protected poolMssql: ConnectionPool, protected logger: Logger) {
|
|
14
|
+
super(pool, poolMssql, logger, 'api_call', 5, pool ? 'id=$1,"updatedOn"=$2,"responseCode"=$3,"responseJson"=$4,"expiresAt"=$5' :
|
|
15
|
+
'id=@1,"updatedOn"=@2,"responseCode"=@3,"responseJson"=@4,"expiresAt"=@5');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
buildObject(q: any): ApiCall {
|
|
19
|
+
if(!q) return undefined;
|
|
20
|
+
q.id = q.id.trim();
|
|
21
|
+
q.updatedOn = q.updatedOn && new Date(q.updatedOn);
|
|
22
|
+
q.responseCode = parseInt(q.responseCode, 10);
|
|
23
|
+
q.expiresAt = q.expiresAt && new Date(q.expiresAt);
|
|
24
|
+
return q;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
serialize(instance: ApiCall, request?: Request) {
|
|
28
|
+
if(request) {
|
|
29
|
+
request.input('1', instance.id);
|
|
30
|
+
request.input('2', DateTimeOffset, instance.updatedOn);
|
|
31
|
+
request.input('3', instance.responseCode);
|
|
32
|
+
request.input('4', instance.responseJson);
|
|
33
|
+
request.input('5', DateTimeOffset, instance.expiresAt);
|
|
34
|
+
return undefined;
|
|
35
|
+
} else {
|
|
36
|
+
return [instance.id, instance.updatedOn, instance.responseCode, instance.responseJson, instance.expiresAt];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
}
|
package/models/Migration.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MigrationRepository = void 0;
|
|
4
|
-
const ModelDao_1 = require("./repository/ModelDao");
|
|
5
|
-
class MigrationRepository extends ModelDao_1.ModelDao {
|
|
6
|
-
constructor(pool, poolMssql, logger) {
|
|
7
|
-
super(pool, poolMssql, logger, 'migration', 5, pool ? 'id=$1,hash=$2,"sqlUp"=$3,"sqlDown"=$4,state=$5' :
|
|
8
|
-
'id=@1,hash=@2,"sqlUp"=@3,"sqlDown"=@4,state=@5');
|
|
9
|
-
this.pool = pool;
|
|
10
|
-
this.poolMssql = poolMssql;
|
|
11
|
-
this.logger = logger;
|
|
12
|
-
}
|
|
13
|
-
buildObject(q) {
|
|
14
|
-
if (!q)
|
|
15
|
-
return undefined;
|
|
16
|
-
q.id = parseInt(q.id, 10);
|
|
17
|
-
q.hash = q.hash.trim();
|
|
18
|
-
q.state = parseInt(q.state, 10);
|
|
19
|
-
return q;
|
|
20
|
-
}
|
|
21
|
-
serialize(instance, request) {
|
|
22
|
-
if (request) {
|
|
23
|
-
request.input('1', instance.id);
|
|
24
|
-
request.input('2', instance.hash);
|
|
25
|
-
request.input('3', instance.sqlUp);
|
|
26
|
-
request.input('4', instance.sqlDown);
|
|
27
|
-
request.input('5', instance.state);
|
|
28
|
-
return undefined;
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
return [instance.id, instance.hash, instance.sqlUp, instance.sqlDown, instance.state];
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.MigrationRepository = MigrationRepository;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MigrationRepository = void 0;
|
|
4
|
+
const ModelDao_1 = require("./repository/ModelDao");
|
|
5
|
+
class MigrationRepository extends ModelDao_1.ModelDao {
|
|
6
|
+
constructor(pool, poolMssql, logger) {
|
|
7
|
+
super(pool, poolMssql, logger, 'migration', 5, pool ? 'id=$1,hash=$2,"sqlUp"=$3,"sqlDown"=$4,state=$5' :
|
|
8
|
+
'id=@1,hash=@2,"sqlUp"=@3,"sqlDown"=@4,state=@5');
|
|
9
|
+
this.pool = pool;
|
|
10
|
+
this.poolMssql = poolMssql;
|
|
11
|
+
this.logger = logger;
|
|
12
|
+
}
|
|
13
|
+
buildObject(q) {
|
|
14
|
+
if (!q)
|
|
15
|
+
return undefined;
|
|
16
|
+
q.id = parseInt(q.id, 10);
|
|
17
|
+
q.hash = q.hash.trim();
|
|
18
|
+
q.state = parseInt(q.state, 10);
|
|
19
|
+
return q;
|
|
20
|
+
}
|
|
21
|
+
serialize(instance, request) {
|
|
22
|
+
if (request) {
|
|
23
|
+
request.input('1', instance.id);
|
|
24
|
+
request.input('2', instance.hash);
|
|
25
|
+
request.input('3', instance.sqlUp);
|
|
26
|
+
request.input('4', instance.sqlDown);
|
|
27
|
+
request.input('5', instance.state);
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return [instance.id, instance.hash, instance.sqlUp, instance.sqlDown, instance.state];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.MigrationRepository = MigrationRepository;
|
package/models/Migration.ts
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { ConnectionPool, Request } from 'mssql';
|
|
2
|
-
import {Pool} from 'pg';
|
|
3
|
-
import {Logger} from 'winston';
|
|
4
|
-
import {ModelDao} from './repository/ModelDao';
|
|
5
|
-
|
|
6
|
-
export interface Migration {
|
|
7
|
-
id: number;
|
|
8
|
-
hash: string;
|
|
9
|
-
sqlUp: string;
|
|
10
|
-
sqlDown: string;
|
|
11
|
-
state: number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class MigrationRepository extends ModelDao<number, Migration> {
|
|
15
|
-
constructor(protected pool: Pool, protected poolMssql: ConnectionPool, protected logger: Logger) {
|
|
16
|
-
super(pool, poolMssql, logger, 'migration', 5, pool ? 'id=$1,hash=$2,"sqlUp"=$3,"sqlDown"=$4,state=$5' :
|
|
17
|
-
'id=@1,hash=@2,"sqlUp"=@3,"sqlDown"=@4,state=@5');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
buildObject(q: any): Migration {
|
|
21
|
-
if(!q) return undefined;
|
|
22
|
-
q.id = parseInt(q.id, 10);
|
|
23
|
-
q.hash = q.hash.trim();
|
|
24
|
-
q.state = parseInt(q.state, 10);
|
|
25
|
-
return q;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
serialize(instance: Migration, request?: Request) {
|
|
29
|
-
if(request) {
|
|
30
|
-
request.input('1', instance.id);
|
|
31
|
-
request.input('2', instance.hash);
|
|
32
|
-
request.input('3', instance.sqlUp);
|
|
33
|
-
request.input('4', instance.sqlDown);
|
|
34
|
-
request.input('5', instance.state);
|
|
35
|
-
return undefined;
|
|
36
|
-
} else {
|
|
37
|
-
return [instance.id, instance.hash, instance.sqlUp, instance.sqlDown, instance.state];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
1
|
+
import { ConnectionPool, Request } from 'mssql';
|
|
2
|
+
import {Pool} from 'pg';
|
|
3
|
+
import {Logger} from 'winston';
|
|
4
|
+
import {ModelDao} from './repository/ModelDao';
|
|
5
|
+
|
|
6
|
+
export interface Migration {
|
|
7
|
+
id: number;
|
|
8
|
+
hash: string;
|
|
9
|
+
sqlUp: string;
|
|
10
|
+
sqlDown: string;
|
|
11
|
+
state: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class MigrationRepository extends ModelDao<number, Migration> {
|
|
15
|
+
constructor(protected pool: Pool, protected poolMssql: ConnectionPool, protected logger: Logger) {
|
|
16
|
+
super(pool, poolMssql, logger, 'migration', 5, pool ? 'id=$1,hash=$2,"sqlUp"=$3,"sqlDown"=$4,state=$5' :
|
|
17
|
+
'id=@1,hash=@2,"sqlUp"=@3,"sqlDown"=@4,state=@5');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
buildObject(q: any): Migration {
|
|
21
|
+
if(!q) return undefined;
|
|
22
|
+
q.id = parseInt(q.id, 10);
|
|
23
|
+
q.hash = q.hash.trim();
|
|
24
|
+
q.state = parseInt(q.state, 10);
|
|
25
|
+
return q;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
serialize(instance: Migration, request?: Request) {
|
|
29
|
+
if(request) {
|
|
30
|
+
request.input('1', instance.id);
|
|
31
|
+
request.input('2', instance.hash);
|
|
32
|
+
request.input('3', instance.sqlUp);
|
|
33
|
+
request.input('4', instance.sqlDown);
|
|
34
|
+
request.input('5', instance.state);
|
|
35
|
+
return undefined;
|
|
36
|
+
} else {
|
|
37
|
+
return [instance.id, instance.hash, instance.sqlUp, instance.sqlDown, instance.state];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,156 +1,156 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BaseModelRepository = void 0;
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const node_forge_1 = require("node-forge");
|
|
6
|
-
const ApiCall_1 = require("../ApiCall");
|
|
7
|
-
const Migration_1 = require("../Migration");
|
|
8
|
-
class BaseModelRepository {
|
|
9
|
-
constructor(db, dbSpare, dbMssql, logger, cache) {
|
|
10
|
-
this.db = db;
|
|
11
|
-
this.dbSpare = dbSpare;
|
|
12
|
-
this.dbMssql = dbMssql;
|
|
13
|
-
this.logger = logger;
|
|
14
|
-
this.cache = cache;
|
|
15
|
-
if (db && dbSpare) {
|
|
16
|
-
const dbQuery = db.query.bind(db);
|
|
17
|
-
db.query = (function (text, values, cb) {
|
|
18
|
-
if ((this.idleCount + this.waitingCount) >= this.totalCount && this.totalCount === this.options.max)
|
|
19
|
-
return dbSpare.query(text, values, cb);
|
|
20
|
-
return dbQuery(text, values, cb);
|
|
21
|
-
}).bind(db);
|
|
22
|
-
}
|
|
23
|
-
this.Migration = new Migration_1.MigrationRepository(db, dbMssql, logger);
|
|
24
|
-
this.ApiCall = new ApiCall_1.ApiCallRepository(db, dbMssql, logger);
|
|
25
|
-
}
|
|
26
|
-
migrate(migrationsPath, callback) {
|
|
27
|
-
(this.db ? this.db.query('CREATE TABLE IF NOT EXISTS migration (' +
|
|
28
|
-
'id integer PRIMARY KEY,' +
|
|
29
|
-
'hash text NOT NULL,' +
|
|
30
|
-
'"sqlUp" text NOT NULL,' +
|
|
31
|
-
'"sqlDown" text NOT NULL,' +
|
|
32
|
-
'state integer NOT NULL' +
|
|
33
|
-
')') : this.dbMssql.query('if not exists (select * from sysobjects where name=\'migration\' and xtype=\'U\') CREATE TABLE migration (' +
|
|
34
|
-
'id int PRIMARY KEY,' +
|
|
35
|
-
'hash text NOT NULL,' +
|
|
36
|
-
'"sqlUp" text NOT NULL,' +
|
|
37
|
-
'"sqlDown" text NOT NULL,' +
|
|
38
|
-
'state int NOT NULL' +
|
|
39
|
-
')')).then(() => {
|
|
40
|
-
this.Migration.getAllBy('id').then((migrations) => {
|
|
41
|
-
if (migrations.find(migration => migration.state !== 0))
|
|
42
|
-
process.exit(4);
|
|
43
|
-
fs.readdir(migrationsPath, (_, files) => {
|
|
44
|
-
const migrationsAvailable = files
|
|
45
|
-
.filter(file => /[0-9]+\.sql/.test(file))
|
|
46
|
-
.map(file => parseInt(file.split('.sql')[0], 10))
|
|
47
|
-
.filter(file => file > 0)
|
|
48
|
-
.sort((a, b) => a - b)
|
|
49
|
-
.map(file => {
|
|
50
|
-
const content = fs.readFileSync(migrationsPath + file + '.sql', 'utf-8');
|
|
51
|
-
return {
|
|
52
|
-
id: file,
|
|
53
|
-
content: content,
|
|
54
|
-
hash: node_forge_1.md.sha256.create().update(content).digest().toHex()
|
|
55
|
-
};
|
|
56
|
-
});
|
|
57
|
-
if (migrationsAvailable.length === 0
|
|
58
|
-
|| migrationsAvailable.length
|
|
59
|
-
!== migrationsAvailable[migrationsAvailable.length - 1].id)
|
|
60
|
-
process.exit(5);
|
|
61
|
-
let highestCommon = 0;
|
|
62
|
-
while (highestCommon < migrations.length && highestCommon < migrationsAvailable.length
|
|
63
|
-
&& migrations[highestCommon].hash === migrationsAvailable[highestCommon].hash)
|
|
64
|
-
highestCommon++;
|
|
65
|
-
this.applyDownUntil(migrations, migrations.length, highestCommon).then(() => {
|
|
66
|
-
this.applyUpUntil(migrationsAvailable, highestCommon, migrationsAvailable.length).then(callback, process.exit);
|
|
67
|
-
}, process.exit);
|
|
68
|
-
});
|
|
69
|
-
}, () => process.exit(3));
|
|
70
|
-
}, () => process.exit(2));
|
|
71
|
-
}
|
|
72
|
-
lockTables(tables, client) {
|
|
73
|
-
if (this.db)
|
|
74
|
-
return Promise.all(tables.map(t => client.query('LOCK TABLE ' + t.table + ' IN EXCLUSIVE MODE')));
|
|
75
|
-
return Promise.all(tables.map(t => client.request().query('SELECT id FROM ' + t.table + ' WITH (UPDLOCK)')));
|
|
76
|
-
}
|
|
77
|
-
applyUpUntil(migrations, current, until) {
|
|
78
|
-
if (current < until)
|
|
79
|
-
return this.applyUp(migrations[current]).then(() => this.applyUpUntil(migrations, current + 1, until));
|
|
80
|
-
return Promise.resolve();
|
|
81
|
-
}
|
|
82
|
-
applyUp(migration) {
|
|
83
|
-
return new Promise((resolve, reject) => {
|
|
84
|
-
const sqlParts = migration.content.split('----');
|
|
85
|
-
this.Migration.create({
|
|
86
|
-
id: migration.id,
|
|
87
|
-
hash: migration.hash,
|
|
88
|
-
sqlUp: sqlParts[0],
|
|
89
|
-
sqlDown: sqlParts[1],
|
|
90
|
-
state: 2
|
|
91
|
-
}).then(() => {
|
|
92
|
-
(this.db || this.dbMssql).query(sqlParts[0], (err) => {
|
|
93
|
-
if (err) {
|
|
94
|
-
console.error(err);
|
|
95
|
-
reject(10);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
(this.db || this.dbMssql).query('UPDATE "migration" SET "state"=0 WHERE "id"=' + migration.id, (err2) => {
|
|
99
|
-
if (err2)
|
|
100
|
-
reject(11);
|
|
101
|
-
else
|
|
102
|
-
resolve();
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}, () => process.exit(9));
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
applyDownUntil(migrations, current, until) {
|
|
110
|
-
if (current > until) {
|
|
111
|
-
current--;
|
|
112
|
-
return this.applyDown(migrations[current]).then(() => this.applyDownUntil(migrations, current, until));
|
|
113
|
-
}
|
|
114
|
-
return Promise.resolve();
|
|
115
|
-
}
|
|
116
|
-
applyDown(migration) {
|
|
117
|
-
return new Promise((resolve, reject) => {
|
|
118
|
-
(this.db || this.dbMssql).query('UPDATE "migration" SET "state"=1 WHERE "id"=' + migration.id, (err) => {
|
|
119
|
-
if (err)
|
|
120
|
-
reject(6);
|
|
121
|
-
else
|
|
122
|
-
(this.db || this.dbMssql).query(migration.sqlDown, (err2) => {
|
|
123
|
-
if (err2) {
|
|
124
|
-
console.error(err2);
|
|
125
|
-
reject(7);
|
|
126
|
-
}
|
|
127
|
-
else
|
|
128
|
-
(this.db || this.dbMssql).query('DELETE FROM "migration" WHERE "id"=' + migration.id, (err3) => {
|
|
129
|
-
if (err3 && migration.id !== 1)
|
|
130
|
-
reject(8);
|
|
131
|
-
else {
|
|
132
|
-
if (migration.id === 1) {
|
|
133
|
-
(this.db ? this.db.query('CREATE TABLE IF NOT EXISTS migration (' +
|
|
134
|
-
'id integer PRIMARY KEY,' +
|
|
135
|
-
'hash text NOT NULL,' +
|
|
136
|
-
'"sqlUp" text NOT NULL,' +
|
|
137
|
-
'"sqlDown" text NOT NULL,' +
|
|
138
|
-
'state integer NOT NULL' +
|
|
139
|
-
')') : this.dbMssql.query('if not exists (select * from sysobjects where name=\'migration\' and xtype=\'U\') CREATE TABLE migration (' +
|
|
140
|
-
'id int PRIMARY KEY,' +
|
|
141
|
-
'hash text NOT NULL,' +
|
|
142
|
-
'"sqlUp" text NOT NULL,' +
|
|
143
|
-
'"sqlDown" text NOT NULL,' +
|
|
144
|
-
'state int NOT NULL' +
|
|
145
|
-
')')).then(() => resolve(), reject);
|
|
146
|
-
}
|
|
147
|
-
else
|
|
148
|
-
resolve();
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
exports.BaseModelRepository = BaseModelRepository;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseModelRepository = void 0;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const node_forge_1 = require("node-forge");
|
|
6
|
+
const ApiCall_1 = require("../ApiCall");
|
|
7
|
+
const Migration_1 = require("../Migration");
|
|
8
|
+
class BaseModelRepository {
|
|
9
|
+
constructor(db, dbSpare, dbMssql, logger, cache) {
|
|
10
|
+
this.db = db;
|
|
11
|
+
this.dbSpare = dbSpare;
|
|
12
|
+
this.dbMssql = dbMssql;
|
|
13
|
+
this.logger = logger;
|
|
14
|
+
this.cache = cache;
|
|
15
|
+
if (db && dbSpare) {
|
|
16
|
+
const dbQuery = db.query.bind(db);
|
|
17
|
+
db.query = (function (text, values, cb) {
|
|
18
|
+
if ((this.idleCount + this.waitingCount) >= this.totalCount && this.totalCount === this.options.max)
|
|
19
|
+
return dbSpare.query(text, values, cb);
|
|
20
|
+
return dbQuery(text, values, cb);
|
|
21
|
+
}).bind(db);
|
|
22
|
+
}
|
|
23
|
+
this.Migration = new Migration_1.MigrationRepository(db, dbMssql, logger);
|
|
24
|
+
this.ApiCall = new ApiCall_1.ApiCallRepository(db, dbMssql, logger);
|
|
25
|
+
}
|
|
26
|
+
migrate(migrationsPath, callback) {
|
|
27
|
+
(this.db ? this.db.query('CREATE TABLE IF NOT EXISTS migration (' +
|
|
28
|
+
'id integer PRIMARY KEY,' +
|
|
29
|
+
'hash text NOT NULL,' +
|
|
30
|
+
'"sqlUp" text NOT NULL,' +
|
|
31
|
+
'"sqlDown" text NOT NULL,' +
|
|
32
|
+
'state integer NOT NULL' +
|
|
33
|
+
')') : this.dbMssql.query('if not exists (select * from sysobjects where name=\'migration\' and xtype=\'U\') CREATE TABLE migration (' +
|
|
34
|
+
'id int PRIMARY KEY,' +
|
|
35
|
+
'hash text NOT NULL,' +
|
|
36
|
+
'"sqlUp" text NOT NULL,' +
|
|
37
|
+
'"sqlDown" text NOT NULL,' +
|
|
38
|
+
'state int NOT NULL' +
|
|
39
|
+
')')).then(() => {
|
|
40
|
+
this.Migration.getAllBy('id').then((migrations) => {
|
|
41
|
+
if (migrations.find(migration => migration.state !== 0))
|
|
42
|
+
process.exit(4);
|
|
43
|
+
fs.readdir(migrationsPath, (_, files) => {
|
|
44
|
+
const migrationsAvailable = files
|
|
45
|
+
.filter(file => /[0-9]+\.sql/.test(file))
|
|
46
|
+
.map(file => parseInt(file.split('.sql')[0], 10))
|
|
47
|
+
.filter(file => file > 0)
|
|
48
|
+
.sort((a, b) => a - b)
|
|
49
|
+
.map(file => {
|
|
50
|
+
const content = fs.readFileSync(migrationsPath + file + '.sql', 'utf-8');
|
|
51
|
+
return {
|
|
52
|
+
id: file,
|
|
53
|
+
content: content,
|
|
54
|
+
hash: node_forge_1.md.sha256.create().update(content).digest().toHex()
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
if (migrationsAvailable.length === 0
|
|
58
|
+
|| migrationsAvailable.length
|
|
59
|
+
!== migrationsAvailable[migrationsAvailable.length - 1].id)
|
|
60
|
+
process.exit(5);
|
|
61
|
+
let highestCommon = 0;
|
|
62
|
+
while (highestCommon < migrations.length && highestCommon < migrationsAvailable.length
|
|
63
|
+
&& migrations[highestCommon].hash === migrationsAvailable[highestCommon].hash)
|
|
64
|
+
highestCommon++;
|
|
65
|
+
this.applyDownUntil(migrations, migrations.length, highestCommon).then(() => {
|
|
66
|
+
this.applyUpUntil(migrationsAvailable, highestCommon, migrationsAvailable.length).then(callback, process.exit);
|
|
67
|
+
}, process.exit);
|
|
68
|
+
});
|
|
69
|
+
}, () => process.exit(3));
|
|
70
|
+
}, () => process.exit(2));
|
|
71
|
+
}
|
|
72
|
+
lockTables(tables, client) {
|
|
73
|
+
if (this.db)
|
|
74
|
+
return Promise.all(tables.map(t => client.query('LOCK TABLE ' + t.table + ' IN EXCLUSIVE MODE')));
|
|
75
|
+
return Promise.all(tables.map(t => client.request().query('SELECT id FROM ' + t.table + ' WITH (UPDLOCK)')));
|
|
76
|
+
}
|
|
77
|
+
applyUpUntil(migrations, current, until) {
|
|
78
|
+
if (current < until)
|
|
79
|
+
return this.applyUp(migrations[current]).then(() => this.applyUpUntil(migrations, current + 1, until));
|
|
80
|
+
return Promise.resolve();
|
|
81
|
+
}
|
|
82
|
+
applyUp(migration) {
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
|
+
const sqlParts = migration.content.split('----');
|
|
85
|
+
this.Migration.create({
|
|
86
|
+
id: migration.id,
|
|
87
|
+
hash: migration.hash,
|
|
88
|
+
sqlUp: sqlParts[0],
|
|
89
|
+
sqlDown: sqlParts[1],
|
|
90
|
+
state: 2
|
|
91
|
+
}).then(() => {
|
|
92
|
+
(this.db || this.dbMssql).query(sqlParts[0], (err) => {
|
|
93
|
+
if (err) {
|
|
94
|
+
console.error(err);
|
|
95
|
+
reject(10);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
(this.db || this.dbMssql).query('UPDATE "migration" SET "state"=0 WHERE "id"=' + migration.id, (err2) => {
|
|
99
|
+
if (err2)
|
|
100
|
+
reject(11);
|
|
101
|
+
else
|
|
102
|
+
resolve();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}, () => process.exit(9));
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
applyDownUntil(migrations, current, until) {
|
|
110
|
+
if (current > until) {
|
|
111
|
+
current--;
|
|
112
|
+
return this.applyDown(migrations[current]).then(() => this.applyDownUntil(migrations, current, until));
|
|
113
|
+
}
|
|
114
|
+
return Promise.resolve();
|
|
115
|
+
}
|
|
116
|
+
applyDown(migration) {
|
|
117
|
+
return new Promise((resolve, reject) => {
|
|
118
|
+
(this.db || this.dbMssql).query('UPDATE "migration" SET "state"=1 WHERE "id"=' + migration.id, (err) => {
|
|
119
|
+
if (err)
|
|
120
|
+
reject(6);
|
|
121
|
+
else
|
|
122
|
+
(this.db || this.dbMssql).query(migration.sqlDown, (err2) => {
|
|
123
|
+
if (err2) {
|
|
124
|
+
console.error(err2);
|
|
125
|
+
reject(7);
|
|
126
|
+
}
|
|
127
|
+
else
|
|
128
|
+
(this.db || this.dbMssql).query('DELETE FROM "migration" WHERE "id"=' + migration.id, (err3) => {
|
|
129
|
+
if (err3 && migration.id !== 1)
|
|
130
|
+
reject(8);
|
|
131
|
+
else {
|
|
132
|
+
if (migration.id === 1) {
|
|
133
|
+
(this.db ? this.db.query('CREATE TABLE IF NOT EXISTS migration (' +
|
|
134
|
+
'id integer PRIMARY KEY,' +
|
|
135
|
+
'hash text NOT NULL,' +
|
|
136
|
+
'"sqlUp" text NOT NULL,' +
|
|
137
|
+
'"sqlDown" text NOT NULL,' +
|
|
138
|
+
'state integer NOT NULL' +
|
|
139
|
+
')') : this.dbMssql.query('if not exists (select * from sysobjects where name=\'migration\' and xtype=\'U\') CREATE TABLE migration (' +
|
|
140
|
+
'id int PRIMARY KEY,' +
|
|
141
|
+
'hash text NOT NULL,' +
|
|
142
|
+
'"sqlUp" text NOT NULL,' +
|
|
143
|
+
'"sqlDown" text NOT NULL,' +
|
|
144
|
+
'state int NOT NULL' +
|
|
145
|
+
')')).then(() => resolve(), reject);
|
|
146
|
+
}
|
|
147
|
+
else
|
|
148
|
+
resolve();
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.BaseModelRepository = BaseModelRepository;
|