@cheetah.js/orm 0.1.25 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bun/index.js +2197 -1
- package/dist/bun/index.js.map +22 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/migration/migrator.js +6 -2
- package/dist/migration/migrator.js.map +1 -1
- package/package.json +1 -1
package/dist/bun/index.js
CHANGED
|
@@ -225242,6 +225242,2201 @@ class Uuid extends ValueObject {
|
|
|
225242
225242
|
return /^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i.test(value);
|
|
225243
225243
|
}
|
|
225244
225244
|
}
|
|
225245
|
+
// ../../node_module
|
|
225246
|
+
var ENTITIES2 = "cheetah:entities";
|
|
225247
|
+
var PROPERTIES_METADATA2 = "cheetah:properties:metadata";
|
|
225248
|
+
var PROPERTIES_RELATIONS2 = "cheetah:properties:relations";
|
|
225249
|
+
var EVENTS_METADATA2 = "cheetah:events:metadata";
|
|
225250
|
+
// ../../node_mo
|
|
225251
|
+
function getDefaultLength2(type) {
|
|
225252
|
+
return null;
|
|
225253
|
+
}
|
|
225254
|
+
// ../../node_modules/bala
|
|
225255
|
+
var __decorate9 = function(decorators5, target, key, desc) {
|
|
225256
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
225257
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
225258
|
+
r = Reflect.decorate(decorators5, target, key, desc);
|
|
225259
|
+
else
|
|
225260
|
+
for (var i = decorators5.length - 1;i >= 0; i--)
|
|
225261
|
+
if (d = decorators5[i])
|
|
225262
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
225263
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
225264
|
+
};
|
|
225265
|
+
var __metadata7 = function(k, v) {
|
|
225266
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
225267
|
+
return Reflect.metadata(k, v);
|
|
225268
|
+
};
|
|
225269
|
+
var EntityStorage_1;
|
|
225270
|
+
var EntityStorage2 = class EntityStorage3 {
|
|
225271
|
+
static {
|
|
225272
|
+
EntityStorage_1 = this;
|
|
225273
|
+
}
|
|
225274
|
+
static instance;
|
|
225275
|
+
entities = new Map;
|
|
225276
|
+
constructor() {
|
|
225277
|
+
EntityStorage_1.instance = this;
|
|
225278
|
+
}
|
|
225279
|
+
add(entity, properties, relations, hooks3) {
|
|
225280
|
+
const entityName = entity.options?.tableName || entity.target.name.toLowerCase();
|
|
225281
|
+
const indexes = Metadata.get("indexes", entity.target) || [];
|
|
225282
|
+
this.entities.set(entity.target, {
|
|
225283
|
+
properties,
|
|
225284
|
+
hideProperties: Object.entries(properties).filter(([key, value]) => value.options.hidden).map(([key]) => key),
|
|
225285
|
+
relations,
|
|
225286
|
+
indexes: indexes.map((index) => {
|
|
225287
|
+
return {
|
|
225288
|
+
table: entityName,
|
|
225289
|
+
indexName: index.name.replace("[TABLE]", entityName),
|
|
225290
|
+
columnName: index.properties.join(",")
|
|
225291
|
+
};
|
|
225292
|
+
}),
|
|
225293
|
+
hooks: hooks3,
|
|
225294
|
+
tableName: entityName,
|
|
225295
|
+
...entity.options
|
|
225296
|
+
});
|
|
225297
|
+
}
|
|
225298
|
+
get(entity) {
|
|
225299
|
+
return this.entities.get(entity);
|
|
225300
|
+
}
|
|
225301
|
+
entries() {
|
|
225302
|
+
return this.entities.entries();
|
|
225303
|
+
}
|
|
225304
|
+
static getInstance() {
|
|
225305
|
+
return EntityStorage_1.instance;
|
|
225306
|
+
}
|
|
225307
|
+
async snapshot(values) {
|
|
225308
|
+
return {
|
|
225309
|
+
tableName: values.tableName,
|
|
225310
|
+
schema: values.schema || "public",
|
|
225311
|
+
indexes: values.indexes || [],
|
|
225312
|
+
columns: this.snapshotColumns(values)
|
|
225313
|
+
};
|
|
225314
|
+
}
|
|
225315
|
+
snapshotColumns(values) {
|
|
225316
|
+
let properties = Object.entries(values.properties).map(([key, value]) => {
|
|
225317
|
+
return {
|
|
225318
|
+
name: key,
|
|
225319
|
+
type: value.options.dbType ?? value.type.name,
|
|
225320
|
+
nullable: value.options?.nullable,
|
|
225321
|
+
default: value.options?.default,
|
|
225322
|
+
autoIncrement: value.options?.autoIncrement,
|
|
225323
|
+
primary: value.options?.isPrimary,
|
|
225324
|
+
unique: value.options?.unique,
|
|
225325
|
+
length: value.options?.length,
|
|
225326
|
+
isEnum: value.options?.isEnum,
|
|
225327
|
+
enumItems: value.options?.enumItems
|
|
225328
|
+
};
|
|
225329
|
+
});
|
|
225330
|
+
let relations = values.relations && values.relations.map((relation) => {
|
|
225331
|
+
const type = this.getFkType(relation);
|
|
225332
|
+
return {
|
|
225333
|
+
name: relation.propertyKey,
|
|
225334
|
+
type,
|
|
225335
|
+
nullable: relation.nullable,
|
|
225336
|
+
unique: relation.unique,
|
|
225337
|
+
length: relation.length || getDefaultLength2(type),
|
|
225338
|
+
default: relation.default,
|
|
225339
|
+
autoIncrement: relation.autoIncrement,
|
|
225340
|
+
primary: relation.isPrimary,
|
|
225341
|
+
foreignKeys: [
|
|
225342
|
+
{
|
|
225343
|
+
referencedColumnName: this.getFkKey(relation),
|
|
225344
|
+
referencedTableName: this.get(relation.entity()).tableName
|
|
225345
|
+
}
|
|
225346
|
+
]
|
|
225347
|
+
};
|
|
225348
|
+
});
|
|
225349
|
+
if (!relations) {
|
|
225350
|
+
relations = [];
|
|
225351
|
+
}
|
|
225352
|
+
if (!properties) {
|
|
225353
|
+
properties = [];
|
|
225354
|
+
}
|
|
225355
|
+
return [...properties, ...relations];
|
|
225356
|
+
}
|
|
225357
|
+
snapshotIndexes(values) {
|
|
225358
|
+
return Object.entries(values.properties).map(([key, value]) => {
|
|
225359
|
+
return {
|
|
225360
|
+
indexName: key,
|
|
225361
|
+
columnName: key,
|
|
225362
|
+
table: values.tableName
|
|
225363
|
+
};
|
|
225364
|
+
});
|
|
225365
|
+
}
|
|
225366
|
+
getFkType(relation) {
|
|
225367
|
+
const entity = this.get(relation.entity());
|
|
225368
|
+
if (!entity) {
|
|
225369
|
+
return "unknown";
|
|
225370
|
+
}
|
|
225371
|
+
return entity.properties[this.getFkKey(relation)].type.name;
|
|
225372
|
+
}
|
|
225373
|
+
getFkKey(relationShip) {
|
|
225374
|
+
if (typeof relationShip.fkKey === "undefined") {
|
|
225375
|
+
const entity = this.entities.get(relationShip.entity());
|
|
225376
|
+
const property3 = Object.entries(entity.properties).find(([key, value]) => value.options.isPrimary === true);
|
|
225377
|
+
if (!property3) {
|
|
225378
|
+
throw new Error(`Entity ${entity.tableName} does not have a primary key`);
|
|
225379
|
+
}
|
|
225380
|
+
return property3[0];
|
|
225381
|
+
}
|
|
225382
|
+
if (typeof relationShip.fkKey === "string") {
|
|
225383
|
+
return relationShip.fkKey;
|
|
225384
|
+
}
|
|
225385
|
+
const match = /\.(?<propriedade>[\w]+)/.exec(relationShip.fkKey.toString());
|
|
225386
|
+
return match ? match.groups.propriedade : "";
|
|
225387
|
+
}
|
|
225388
|
+
};
|
|
225389
|
+
EntityStorage2 = EntityStorage_1 = __decorate9([
|
|
225390
|
+
Service(),
|
|
225391
|
+
__metadata7("design:paramtypes", [])
|
|
225392
|
+
], EntityStorage2);
|
|
225393
|
+
|
|
225394
|
+
// ../../node_modules/balanced
|
|
225395
|
+
class ValueObject2 {
|
|
225396
|
+
value;
|
|
225397
|
+
constructor(value) {
|
|
225398
|
+
if (!this.validate(value)) {
|
|
225399
|
+
throw new HttpException(`Invalid value for ${this.constructor.name}`, 400);
|
|
225400
|
+
}
|
|
225401
|
+
this.setValue(value);
|
|
225402
|
+
}
|
|
225403
|
+
static from(value) {
|
|
225404
|
+
return new this(value);
|
|
225405
|
+
}
|
|
225406
|
+
getValue() {
|
|
225407
|
+
return this.value;
|
|
225408
|
+
}
|
|
225409
|
+
equals(vo) {
|
|
225410
|
+
return this.getValue() === vo.getValue();
|
|
225411
|
+
}
|
|
225412
|
+
setValue(value) {
|
|
225413
|
+
this.value = value;
|
|
225414
|
+
}
|
|
225415
|
+
}
|
|
225416
|
+
|
|
225417
|
+
// ../../node_modules/balance
|
|
225418
|
+
class BaseEntity2 {
|
|
225419
|
+
_oldValues = {};
|
|
225420
|
+
_changedValues = {};
|
|
225421
|
+
$_isPersisted = false;
|
|
225422
|
+
constructor() {
|
|
225423
|
+
return new Proxy(this, {
|
|
225424
|
+
set(target, p, newValue) {
|
|
225425
|
+
if (p.startsWith("$")) {
|
|
225426
|
+
target[p] = newValue;
|
|
225427
|
+
return true;
|
|
225428
|
+
}
|
|
225429
|
+
if (!target._oldValues[p]) {
|
|
225430
|
+
target._oldValues[p] = newValue;
|
|
225431
|
+
}
|
|
225432
|
+
if (target._oldValues[p] !== newValue) {
|
|
225433
|
+
target._changedValues[p] = newValue;
|
|
225434
|
+
}
|
|
225435
|
+
target[p] = newValue;
|
|
225436
|
+
return true;
|
|
225437
|
+
}
|
|
225438
|
+
});
|
|
225439
|
+
}
|
|
225440
|
+
static createQueryBuilder() {
|
|
225441
|
+
return new SqlBuilder5(this);
|
|
225442
|
+
}
|
|
225443
|
+
createQueryBuilder() {
|
|
225444
|
+
return new SqlBuilder5(this.constructor);
|
|
225445
|
+
}
|
|
225446
|
+
static async find(where, options) {
|
|
225447
|
+
return this.createQueryBuilder().select(options?.fields).setStrategy(options?.loadStrategy).load(options?.load).where(where).limit(options?.limit).offset(options?.offset).orderBy(options?.orderBy).executeAndReturnAll();
|
|
225448
|
+
}
|
|
225449
|
+
static async findOne(where, options) {
|
|
225450
|
+
return this.createQueryBuilder().select(options?.fields).setStrategy(options?.loadStrategy).load(options?.load).where(where).executeAndReturnFirst();
|
|
225451
|
+
}
|
|
225452
|
+
static async findOneOrFail(where, options) {
|
|
225453
|
+
return this.createQueryBuilder().select(options?.fields).setStrategy(options?.loadStrategy).load(options?.load).where(where).orderBy(options?.orderBy).executeAndReturnFirstOrFail();
|
|
225454
|
+
}
|
|
225455
|
+
static async findAll(options) {
|
|
225456
|
+
const builder = this.createQueryBuilder().select(options.fields).setStrategy(options?.loadStrategy).load(options?.load).offset(options?.offset).limit(options.limit).orderBy(options?.orderBy);
|
|
225457
|
+
return builder.executeAndReturnAll();
|
|
225458
|
+
}
|
|
225459
|
+
static async create(where) {
|
|
225460
|
+
return this.createQueryBuilder().insert(where).executeAndReturnFirstOrFail();
|
|
225461
|
+
}
|
|
225462
|
+
async save() {
|
|
225463
|
+
const qb = this.createQueryBuilder();
|
|
225464
|
+
if (this.$_isPersisted) {
|
|
225465
|
+
qb.update(this._changedValues);
|
|
225466
|
+
qb.setInstance(this);
|
|
225467
|
+
qb.where({ id: this._oldValues.id });
|
|
225468
|
+
} else {
|
|
225469
|
+
qb.insert(this._oldValues);
|
|
225470
|
+
}
|
|
225471
|
+
await qb.execute();
|
|
225472
|
+
qb.callHook("afterCreate", this);
|
|
225473
|
+
qb.callHook("afterUpdate", this);
|
|
225474
|
+
this._oldValues = {
|
|
225475
|
+
...this._oldValues,
|
|
225476
|
+
...this._changedValues
|
|
225477
|
+
};
|
|
225478
|
+
this._changedValues = {};
|
|
225479
|
+
}
|
|
225480
|
+
toJSON() {
|
|
225481
|
+
let data = {};
|
|
225482
|
+
let storage2 = EntityStorage2.getInstance();
|
|
225483
|
+
let entity = storage2.get(this.constructor);
|
|
225484
|
+
let allProperties = new Map(Object.entries(entity.properties).map(([key, value]) => [key, value]));
|
|
225485
|
+
for (const key in this) {
|
|
225486
|
+
if (key.startsWith("$") || key.startsWith("_")) {
|
|
225487
|
+
continue;
|
|
225488
|
+
}
|
|
225489
|
+
if (!allProperties.has(key)) {
|
|
225490
|
+
continue;
|
|
225491
|
+
}
|
|
225492
|
+
if (entity.hideProperties.includes(key)) {
|
|
225493
|
+
continue;
|
|
225494
|
+
}
|
|
225495
|
+
data[key] = this[key];
|
|
225496
|
+
}
|
|
225497
|
+
return data;
|
|
225498
|
+
}
|
|
225499
|
+
}
|
|
225500
|
+
|
|
225501
|
+
// ../../node_modules
|
|
225502
|
+
var processValuesForInsert2 = function(values) {
|
|
225503
|
+
for (const value in values) {
|
|
225504
|
+
if (extendsFrom2(ValueObject2, values[value].constructor.prototype)) {
|
|
225505
|
+
values[value] = values[value].getValue();
|
|
225506
|
+
continue;
|
|
225507
|
+
}
|
|
225508
|
+
if (values[value] instanceof BaseEntity2) {
|
|
225509
|
+
values[value] = values[value].id;
|
|
225510
|
+
}
|
|
225511
|
+
}
|
|
225512
|
+
};
|
|
225513
|
+
var processValuesForUpdate2 = function(values) {
|
|
225514
|
+
for (const value in values) {
|
|
225515
|
+
if (extendsFrom2(ValueObject2, values[value].constructor.prototype)) {
|
|
225516
|
+
values[value] = values[value].getValue();
|
|
225517
|
+
}
|
|
225518
|
+
}
|
|
225519
|
+
};
|
|
225520
|
+
var extendsFrom2 = function(baseClass, instance) {
|
|
225521
|
+
let proto = Object.getPrototypeOf(instance);
|
|
225522
|
+
while (proto) {
|
|
225523
|
+
if (proto === baseClass.prototype) {
|
|
225524
|
+
return true;
|
|
225525
|
+
}
|
|
225526
|
+
proto = Object.getPrototypeOf(proto);
|
|
225527
|
+
}
|
|
225528
|
+
return false;
|
|
225529
|
+
};
|
|
225530
|
+
var upEntity2 = function(values, entity, moment = undefined) {
|
|
225531
|
+
const entityStorage = EntityStorage2.getInstance();
|
|
225532
|
+
const entityOptions = entityStorage.get(entity);
|
|
225533
|
+
const instance = new entity;
|
|
225534
|
+
if (!entityOptions) {
|
|
225535
|
+
throw new Error("Entity not found");
|
|
225536
|
+
}
|
|
225537
|
+
const property3 = Object.entries(entityOptions.properties);
|
|
225538
|
+
const relations = entityOptions.relations;
|
|
225539
|
+
property3.forEach(([key, property4]) => {
|
|
225540
|
+
if (property4.options.onInsert && moment === "insert") {
|
|
225541
|
+
instance[key] = property4.options.onInsert();
|
|
225542
|
+
}
|
|
225543
|
+
if (property4.options.onInsert && moment === "update") {
|
|
225544
|
+
instance[key] = property4.options.onUpdate();
|
|
225545
|
+
}
|
|
225546
|
+
if (key in values) {
|
|
225547
|
+
instance[key] = values[key];
|
|
225548
|
+
}
|
|
225549
|
+
});
|
|
225550
|
+
if (relations) {
|
|
225551
|
+
for (const relation of relations) {
|
|
225552
|
+
if (relation.relation === "many-to-one") {
|
|
225553
|
+
instance[relation.propertyKey] = instance[relation.propertyKey];
|
|
225554
|
+
}
|
|
225555
|
+
}
|
|
225556
|
+
}
|
|
225557
|
+
return instance;
|
|
225558
|
+
};
|
|
225559
|
+
|
|
225560
|
+
class SqlBuilder5 {
|
|
225561
|
+
driver;
|
|
225562
|
+
entityStorage;
|
|
225563
|
+
statements = {};
|
|
225564
|
+
entity;
|
|
225565
|
+
model;
|
|
225566
|
+
aliases = new Set;
|
|
225567
|
+
lastKeyNotOperator = "";
|
|
225568
|
+
logger;
|
|
225569
|
+
updatedColumns = [];
|
|
225570
|
+
originalColumns = [];
|
|
225571
|
+
constructor(model) {
|
|
225572
|
+
const orm6 = Orm2.getInstance();
|
|
225573
|
+
this.driver = orm6.driverInstance;
|
|
225574
|
+
this.logger = orm6.logger;
|
|
225575
|
+
this.entityStorage = EntityStorage2.getInstance();
|
|
225576
|
+
this.getEntity(model);
|
|
225577
|
+
this.statements.hooks = this.entity.hooks;
|
|
225578
|
+
}
|
|
225579
|
+
select(columns) {
|
|
225580
|
+
const tableName = this.entity.tableName || this.model.name.toLowerCase();
|
|
225581
|
+
const schema = this.entity.schema || "public";
|
|
225582
|
+
this.statements.statement = "select";
|
|
225583
|
+
this.statements.columns = columns;
|
|
225584
|
+
this.originalColumns = columns || [];
|
|
225585
|
+
this.statements.alias = this.getAlias(tableName);
|
|
225586
|
+
this.statements.table = `"${schema}"."${tableName}"`;
|
|
225587
|
+
return this;
|
|
225588
|
+
}
|
|
225589
|
+
setStrategy(strategy = "joined") {
|
|
225590
|
+
this.statements.strategy = strategy;
|
|
225591
|
+
return this;
|
|
225592
|
+
}
|
|
225593
|
+
setInstance(instance) {
|
|
225594
|
+
this.statements.instance = instance;
|
|
225595
|
+
return this;
|
|
225596
|
+
}
|
|
225597
|
+
insert(values) {
|
|
225598
|
+
const { tableName, schema } = this.getTableName();
|
|
225599
|
+
processValuesForInsert2(values);
|
|
225600
|
+
this.statements.statement = "insert";
|
|
225601
|
+
this.statements.instance = upEntity2(values, this.model, "insert");
|
|
225602
|
+
this.statements.alias = this.getAlias(tableName);
|
|
225603
|
+
this.statements.table = `"${schema}"."${tableName}"`;
|
|
225604
|
+
this.statements.values = this.withUpdatedValues(this.withDefaultValues(values, this.entity), this.entity);
|
|
225605
|
+
this.reflectToValues();
|
|
225606
|
+
return this;
|
|
225607
|
+
}
|
|
225608
|
+
update(values) {
|
|
225609
|
+
const { tableName, schema } = this.getTableName();
|
|
225610
|
+
processValuesForUpdate2(values);
|
|
225611
|
+
this.statements.statement = "update";
|
|
225612
|
+
this.statements.alias = this.getAlias(tableName);
|
|
225613
|
+
this.statements.table = `${schema}.${tableName}`;
|
|
225614
|
+
this.statements.values = this.withUpdatedValues(values, this.entity);
|
|
225615
|
+
this.statements.instance = upEntity2(values, this.model, "update");
|
|
225616
|
+
return this;
|
|
225617
|
+
}
|
|
225618
|
+
where(where) {
|
|
225619
|
+
if (!where || Object.keys(where).length === 0) {
|
|
225620
|
+
return this;
|
|
225621
|
+
}
|
|
225622
|
+
this.statements.where = this.conditionToSql(where, this.statements.alias, this.model);
|
|
225623
|
+
return this;
|
|
225624
|
+
}
|
|
225625
|
+
orderBy(orderBy) {
|
|
225626
|
+
if (!orderBy) {
|
|
225627
|
+
return this;
|
|
225628
|
+
}
|
|
225629
|
+
this.statements.orderBy = this.objectToStringMap(orderBy);
|
|
225630
|
+
return this;
|
|
225631
|
+
}
|
|
225632
|
+
limit(limit) {
|
|
225633
|
+
this.statements.limit = limit;
|
|
225634
|
+
return this;
|
|
225635
|
+
}
|
|
225636
|
+
offset(offset) {
|
|
225637
|
+
this.statements.offset = offset;
|
|
225638
|
+
return this;
|
|
225639
|
+
}
|
|
225640
|
+
load(load) {
|
|
225641
|
+
load?.forEach((relationshipPath) => {
|
|
225642
|
+
this.addJoinForRelationshipPath(this.entity, relationshipPath);
|
|
225643
|
+
});
|
|
225644
|
+
if (this.statements.join) {
|
|
225645
|
+
this.statements.join = this.statements.join?.reverse();
|
|
225646
|
+
}
|
|
225647
|
+
if (this.statements.selectJoin) {
|
|
225648
|
+
this.statements.selectJoin = this.statements.selectJoin?.reverse();
|
|
225649
|
+
}
|
|
225650
|
+
return this;
|
|
225651
|
+
}
|
|
225652
|
+
addJoinForRelationshipPath(entity, relationshipPath) {
|
|
225653
|
+
const relationshipNames = relationshipPath.split(".");
|
|
225654
|
+
let currentEntity = entity;
|
|
225655
|
+
let currentAlias = this.statements.alias;
|
|
225656
|
+
let statement = this.statements.strategy === "joined" ? this.statements.join : this.statements.selectJoin;
|
|
225657
|
+
let nameAliasProperty = this.statements.strategy === "joined" ? "joinAlias" : "alias";
|
|
225658
|
+
relationshipNames.forEach((relationshipName, index) => {
|
|
225659
|
+
const relationship = currentEntity.relations.find((rel) => rel.propertyKey === relationshipName);
|
|
225660
|
+
if (!relationship) {
|
|
225661
|
+
throw new Error(`Relationship "${relationshipName}" not found in entity "${currentEntity.name}"`);
|
|
225662
|
+
}
|
|
225663
|
+
const isLastRelationship = index === relationshipNames.length - 1;
|
|
225664
|
+
if (index === (relationshipNames.length - 2 >= 0 ? relationshipNames.length - 2 : 0)) {
|
|
225665
|
+
const join = statement?.find((j) => j.joinProperty === relationshipName);
|
|
225666
|
+
if (join) {
|
|
225667
|
+
currentAlias = join[nameAliasProperty];
|
|
225668
|
+
}
|
|
225669
|
+
}
|
|
225670
|
+
if (relationship.relation === "many-to-one" && isLastRelationship) {
|
|
225671
|
+
this.applyJoin(relationship, {}, currentAlias);
|
|
225672
|
+
statement = this.statements.strategy === "joined" ? this.statements.join : this.statements.selectJoin;
|
|
225673
|
+
currentAlias = statement[statement.length - 1][nameAliasProperty];
|
|
225674
|
+
}
|
|
225675
|
+
currentEntity = this.entityStorage.get(relationship.entity());
|
|
225676
|
+
});
|
|
225677
|
+
}
|
|
225678
|
+
getPrimaryKeyColumnName(entity) {
|
|
225679
|
+
return "id";
|
|
225680
|
+
}
|
|
225681
|
+
async execute() {
|
|
225682
|
+
if (!this.statements.columns) {
|
|
225683
|
+
this.statements.columns = this.generateColumns();
|
|
225684
|
+
} else {
|
|
225685
|
+
this.extractAliasForColumns();
|
|
225686
|
+
this.filterInvalidColumns();
|
|
225687
|
+
}
|
|
225688
|
+
this.statements.join = this.statements.join?.reverse();
|
|
225689
|
+
this.includeUpdatedColumns();
|
|
225690
|
+
this.beforeHooks();
|
|
225691
|
+
const result = await this.driver.executeStatement(this.statements);
|
|
225692
|
+
this.logExecution(result);
|
|
225693
|
+
return result;
|
|
225694
|
+
}
|
|
225695
|
+
beforeHooks() {
|
|
225696
|
+
if (this.statements.statement === "update") {
|
|
225697
|
+
this.callHook("beforeUpdate", this.statements.instance);
|
|
225698
|
+
return;
|
|
225699
|
+
}
|
|
225700
|
+
if (this.statements.statement === "insert") {
|
|
225701
|
+
this.callHook("beforeCreate");
|
|
225702
|
+
return;
|
|
225703
|
+
}
|
|
225704
|
+
}
|
|
225705
|
+
afterHooks(model) {
|
|
225706
|
+
if (this.statements.statement === "update") {
|
|
225707
|
+
this.callHook("afterUpdate", this.statements.instance);
|
|
225708
|
+
return;
|
|
225709
|
+
}
|
|
225710
|
+
if (this.statements.statement === "insert") {
|
|
225711
|
+
this.callHook("afterCreate", model);
|
|
225712
|
+
return;
|
|
225713
|
+
}
|
|
225714
|
+
}
|
|
225715
|
+
async executeAndReturnFirst() {
|
|
225716
|
+
this.statements.limit = 1;
|
|
225717
|
+
const result = await this.execute();
|
|
225718
|
+
if (result.query.rows.length === 0) {
|
|
225719
|
+
return;
|
|
225720
|
+
}
|
|
225721
|
+
const entities7 = result.query.rows[0];
|
|
225722
|
+
const model = await this.transformToModel(this.model, this.statements, entities7);
|
|
225723
|
+
this.afterHooks(model);
|
|
225724
|
+
await this.handleSelectJoin(entities7, model);
|
|
225725
|
+
return model;
|
|
225726
|
+
}
|
|
225727
|
+
async executeAndReturnFirstOrFail() {
|
|
225728
|
+
this.statements.limit = 1;
|
|
225729
|
+
const result = await this.execute();
|
|
225730
|
+
if (result.query.rows.length === 0) {
|
|
225731
|
+
throw new Error("Result not found");
|
|
225732
|
+
}
|
|
225733
|
+
const entities7 = result.query.rows[0];
|
|
225734
|
+
const model = await this.transformToModel(this.model, this.statements, entities7);
|
|
225735
|
+
this.afterHooks(model);
|
|
225736
|
+
await this.handleSelectJoin(entities7, model);
|
|
225737
|
+
return model;
|
|
225738
|
+
}
|
|
225739
|
+
async executeAndReturnAll() {
|
|
225740
|
+
const result = await this.execute();
|
|
225741
|
+
if (result.query.rows.length === 0) {
|
|
225742
|
+
return [];
|
|
225743
|
+
}
|
|
225744
|
+
const rows = result.query.rows;
|
|
225745
|
+
const results = [];
|
|
225746
|
+
for (const row of rows) {
|
|
225747
|
+
const models = this.transformToModel(this.model, this.statements, row);
|
|
225748
|
+
this.afterHooks(models);
|
|
225749
|
+
await this.handleSelectJoin(row, models);
|
|
225750
|
+
results.push(models);
|
|
225751
|
+
}
|
|
225752
|
+
return results;
|
|
225753
|
+
}
|
|
225754
|
+
async handleSelectJoin(entities7, models) {
|
|
225755
|
+
if (!this.statements.selectJoin || this.statements.selectJoin.length === 0) {
|
|
225756
|
+
return;
|
|
225757
|
+
}
|
|
225758
|
+
for (const join of this.statements.selectJoin.reverse()) {
|
|
225759
|
+
let ids = entities7[`${join.originAlias}_${join.primaryKey}`];
|
|
225760
|
+
if (typeof ids === "undefined") {
|
|
225761
|
+
const selectJoined = this.statements.selectJoin.find((j) => j.joinEntity === join.originEntity);
|
|
225762
|
+
if (!selectJoined) {
|
|
225763
|
+
continue;
|
|
225764
|
+
}
|
|
225765
|
+
ids = this.findIdRecursively(models, selectJoined, join);
|
|
225766
|
+
}
|
|
225767
|
+
if (Array.isArray(ids)) {
|
|
225768
|
+
ids = ids.map((id) => this.t(id)).join(", ");
|
|
225769
|
+
}
|
|
225770
|
+
if (join.where) {
|
|
225771
|
+
join.where = `${join.where} AND ${join.alias}."${join.fkKey}" IN (${ids})`;
|
|
225772
|
+
} else {
|
|
225773
|
+
join.where = `${join.alias}."${join.fkKey}" IN (${ids})`;
|
|
225774
|
+
}
|
|
225775
|
+
if (join.columns && join.columns.length > 0) {
|
|
225776
|
+
join.columns = join.columns.map((column) => `${join.alias}."${column}" as "${join.alias}_${column}"`);
|
|
225777
|
+
} else {
|
|
225778
|
+
join.columns = this.getColumnsEntity(join.joinEntity, join.alias);
|
|
225779
|
+
}
|
|
225780
|
+
const child = await this.driver.executeStatement(join);
|
|
225781
|
+
this.logger.debug(`SQL: ${child.sql} [${Date.now() - child.startTime}ms]`);
|
|
225782
|
+
const property3 = this.entityStorage.get(this.model).relations.find((rel) => rel.propertyKey === join.joinProperty);
|
|
225783
|
+
const values = child.query.rows.map((row) => this.transformToModel(join.joinEntity, join, row));
|
|
225784
|
+
const path3 = this.getPathForSelectJoin(join);
|
|
225785
|
+
this.setValueByPath(models, path3, property3?.type === Array ? [...values] : values[0]);
|
|
225786
|
+
}
|
|
225787
|
+
return models;
|
|
225788
|
+
}
|
|
225789
|
+
getPathForSelectJoin(selectJoin) {
|
|
225790
|
+
const path3 = this.getPathForSelectJoinRecursive(this.statements, selectJoin);
|
|
225791
|
+
return path3.reverse();
|
|
225792
|
+
}
|
|
225793
|
+
setValueByPath(obj, path3, value) {
|
|
225794
|
+
let currentObj = obj;
|
|
225795
|
+
for (let i = 0;i < path3.length - 1; i++) {
|
|
225796
|
+
const key = path3[i];
|
|
225797
|
+
currentObj[key] = currentObj[key] || {};
|
|
225798
|
+
currentObj = currentObj[key];
|
|
225799
|
+
}
|
|
225800
|
+
currentObj[path3[path3.length - 1]] = value;
|
|
225801
|
+
}
|
|
225802
|
+
getPathForSelectJoinRecursive(statements, selectJoin) {
|
|
225803
|
+
const originJoin = this.statements.selectJoin.find((j) => j.joinEntity === selectJoin.originEntity);
|
|
225804
|
+
let pathInJoin = [];
|
|
225805
|
+
if (!originJoin) {
|
|
225806
|
+
return [selectJoin.joinProperty];
|
|
225807
|
+
}
|
|
225808
|
+
if (originJoin.originEntity !== statements.originEntity) {
|
|
225809
|
+
pathInJoin = this.getPathForSelectJoinRecursive(statements, originJoin);
|
|
225810
|
+
}
|
|
225811
|
+
return [selectJoin.joinProperty, ...pathInJoin];
|
|
225812
|
+
}
|
|
225813
|
+
findIdRecursively(models, selectJoined, join) {
|
|
225814
|
+
let ids = models[selectJoined.originProperty][join.primaryKey];
|
|
225815
|
+
if (typeof ids === "undefined") {
|
|
225816
|
+
const nextSelectJoined = this.statements.selectJoin.find((j) => j.joinEntity === selectJoined.originEntity);
|
|
225817
|
+
if (nextSelectJoined) {
|
|
225818
|
+
ids = this.findIdRecursively(models, nextSelectJoined, join);
|
|
225819
|
+
}
|
|
225820
|
+
}
|
|
225821
|
+
return ids;
|
|
225822
|
+
}
|
|
225823
|
+
generateColumns() {
|
|
225824
|
+
let columns = [
|
|
225825
|
+
...this.getColumnsEntity(this.model, this.statements.alias)
|
|
225826
|
+
];
|
|
225827
|
+
if (this.statements.join) {
|
|
225828
|
+
columns = [
|
|
225829
|
+
...columns,
|
|
225830
|
+
...this.statements.join.flatMap((join) => this.getColumnsEntity(join.joinEntity, join.joinAlias))
|
|
225831
|
+
];
|
|
225832
|
+
}
|
|
225833
|
+
return columns;
|
|
225834
|
+
}
|
|
225835
|
+
extractAliasForColumns() {
|
|
225836
|
+
this.statements.columns = this.statements.columns.map((column) => {
|
|
225837
|
+
return this.discoverColumnAlias(column);
|
|
225838
|
+
}).flat();
|
|
225839
|
+
}
|
|
225840
|
+
filterInvalidColumns() {
|
|
225841
|
+
this.statements.columns = this.statements.columns.filter(Boolean);
|
|
225842
|
+
}
|
|
225843
|
+
includeUpdatedColumns() {
|
|
225844
|
+
this.statements.columns.push(...this.updatedColumns);
|
|
225845
|
+
}
|
|
225846
|
+
logExecution(result) {
|
|
225847
|
+
this.logger.debug(`SQL: ${result.sql} [${Date.now() - result.startTime}ms]`);
|
|
225848
|
+
}
|
|
225849
|
+
startTransaction() {
|
|
225850
|
+
return this.driver.startTransaction();
|
|
225851
|
+
}
|
|
225852
|
+
commit() {
|
|
225853
|
+
return this.driver.commitTransaction();
|
|
225854
|
+
}
|
|
225855
|
+
rollback() {
|
|
225856
|
+
return this.driver.rollbackTransaction();
|
|
225857
|
+
}
|
|
225858
|
+
async inTransaction(callback) {
|
|
225859
|
+
await this.startTransaction();
|
|
225860
|
+
try {
|
|
225861
|
+
const result = await callback(this);
|
|
225862
|
+
await this.commit();
|
|
225863
|
+
return result;
|
|
225864
|
+
} catch (e) {
|
|
225865
|
+
await this.rollback();
|
|
225866
|
+
throw e;
|
|
225867
|
+
}
|
|
225868
|
+
}
|
|
225869
|
+
objectToStringMap(obj, parentKey = "") {
|
|
225870
|
+
let result = [];
|
|
225871
|
+
for (let key in obj) {
|
|
225872
|
+
if (obj.hasOwnProperty(key)) {
|
|
225873
|
+
let fullKey = parentKey ? `${parentKey}.${key}` : key;
|
|
225874
|
+
if (typeof obj[key] === "object" && obj[key] !== null) {
|
|
225875
|
+
result = result.concat(this.objectToStringMap(obj[key], fullKey));
|
|
225876
|
+
} else {
|
|
225877
|
+
result.push(`${this.discoverColumnAlias(fullKey, true)} ${obj[key]}`);
|
|
225878
|
+
}
|
|
225879
|
+
}
|
|
225880
|
+
}
|
|
225881
|
+
return result;
|
|
225882
|
+
}
|
|
225883
|
+
discoverColumnAlias(column, onlyAlias = false) {
|
|
225884
|
+
if (!column.includes(".")) {
|
|
225885
|
+
if (onlyAlias) {
|
|
225886
|
+
return `${this.statements.alias}."${column}"`;
|
|
225887
|
+
}
|
|
225888
|
+
return `${this.statements.alias}."${column}" as ${this.statements.alias}_${column}`;
|
|
225889
|
+
}
|
|
225890
|
+
if (typeof this.statements.join === "undefined" && typeof this.statements.selectJoin === "undefined") {
|
|
225891
|
+
throw new Error("Join not found");
|
|
225892
|
+
}
|
|
225893
|
+
const entities7 = column.split(".");
|
|
225894
|
+
let lastEntity = this.model;
|
|
225895
|
+
let lastAlias = this.statements.alias;
|
|
225896
|
+
const relationsMap = new Map(this.entity.relations.map((rel) => [rel.propertyKey, rel]));
|
|
225897
|
+
const joinMap = new Map;
|
|
225898
|
+
const joinSelectMap = new Map;
|
|
225899
|
+
this.statements.join?.forEach((join) => joinMap.set(join.joinProperty, join));
|
|
225900
|
+
this.statements.selectJoin?.forEach((join) => joinSelectMap.set(join.joinProperty, join));
|
|
225901
|
+
for (let i = 0;i < entities7.length; i++) {
|
|
225902
|
+
if (i === 0) {
|
|
225903
|
+
const relation = relationsMap.get(entities7[i]);
|
|
225904
|
+
lastEntity = relation?.entity();
|
|
225905
|
+
if (joinMap.has(entities7[i])) {
|
|
225906
|
+
lastAlias = joinMap.get(entities7[i]).joinAlias;
|
|
225907
|
+
} else {
|
|
225908
|
+
lastAlias = joinSelectMap.get(entities7[i])?.alias;
|
|
225909
|
+
return;
|
|
225910
|
+
}
|
|
225911
|
+
} else {
|
|
225912
|
+
if (i + 1 === entities7.length) {
|
|
225913
|
+
if (onlyAlias) {
|
|
225914
|
+
return `${lastAlias}."${entities7[i]}"`;
|
|
225915
|
+
}
|
|
225916
|
+
return `${lastAlias}."${entities7[i]}" as ${lastAlias}_${entities7[i]}`;
|
|
225917
|
+
}
|
|
225918
|
+
const lastStatement = joinMap.get(entities7[i]);
|
|
225919
|
+
lastEntity = lastStatement?.joinEntity;
|
|
225920
|
+
lastAlias = lastStatement?.joinAlias;
|
|
225921
|
+
}
|
|
225922
|
+
}
|
|
225923
|
+
return "";
|
|
225924
|
+
}
|
|
225925
|
+
getTableName() {
|
|
225926
|
+
const tableName = this.entity.tableName || this.model.name.toLowerCase();
|
|
225927
|
+
const schema = this.entity.schema || "public";
|
|
225928
|
+
return { tableName, schema };
|
|
225929
|
+
}
|
|
225930
|
+
addSimpleConditionToSql(key, value, alias = null, operator = "=") {
|
|
225931
|
+
const aliasToUse = alias || this.statements.alias;
|
|
225932
|
+
const valueByType = typeof value === "string" ? `'${value}'` : value;
|
|
225933
|
+
return `${aliasToUse}.${key} ${operator} ${valueByType}`;
|
|
225934
|
+
}
|
|
225935
|
+
addInConditionToSql(key, values, alias = null) {
|
|
225936
|
+
const aliasToUse = alias || this.statements.alias;
|
|
225937
|
+
return `${aliasToUse}.${key} IN (${values.map((val) => typeof val === "string" ? `'${val}'` : val).join(", ")})`;
|
|
225938
|
+
}
|
|
225939
|
+
addLogicalOperatorToSql(conditions, operator) {
|
|
225940
|
+
return `(${conditions.join(` ${operator} `)})`;
|
|
225941
|
+
}
|
|
225942
|
+
conditionToSql(condition, alias, model) {
|
|
225943
|
+
const sqlParts = [];
|
|
225944
|
+
const operators = ["$eq", "$ne", "$in", "$nin", "$like", "$gt", "$gte", "$lt", "$lte", "$and", "$or"];
|
|
225945
|
+
for (let [key, value] of Object.entries(condition)) {
|
|
225946
|
+
if (this.extendsFrom(ValueObject2, value.constructor.prototype)) {
|
|
225947
|
+
value = value.getValue();
|
|
225948
|
+
}
|
|
225949
|
+
if (!operators.includes(key)) {
|
|
225950
|
+
this.lastKeyNotOperator = key;
|
|
225951
|
+
}
|
|
225952
|
+
const entity = this.entityStorage.get(model);
|
|
225953
|
+
const relationShip = entity.relations?.find((rel) => rel.propertyKey === key);
|
|
225954
|
+
if (relationShip) {
|
|
225955
|
+
const sql = this.applyJoin(relationShip, value, alias);
|
|
225956
|
+
if (this.statements.strategy === "joined") {
|
|
225957
|
+
sqlParts.push(sql);
|
|
225958
|
+
}
|
|
225959
|
+
} else if (typeof value !== "object" || value === null) {
|
|
225960
|
+
if (key === "$eq") {
|
|
225961
|
+
sqlParts.push(this.addSimpleConditionToSql(this.lastKeyNotOperator, value, alias, "="));
|
|
225962
|
+
continue;
|
|
225963
|
+
}
|
|
225964
|
+
sqlParts.push(this.addSimpleConditionToSql(key, value, alias));
|
|
225965
|
+
} else if (!operators.includes(key) && Array.isArray(value)) {
|
|
225966
|
+
sqlParts.push(this.addInConditionToSql(key, value, alias));
|
|
225967
|
+
} else {
|
|
225968
|
+
if (["$or", "$and"].includes(key)) {
|
|
225969
|
+
sqlParts.push(this.addLogicalOperatorToSql(value.map((cond) => this.conditionToSql(cond, alias, model)), key.toUpperCase().replace("$", "")));
|
|
225970
|
+
}
|
|
225971
|
+
for (const operator of operators) {
|
|
225972
|
+
if (operator in value) {
|
|
225973
|
+
switch (operator) {
|
|
225974
|
+
case "$eq":
|
|
225975
|
+
sqlParts.push(this.addSimpleConditionToSql(key, value["$eq"], alias, "="));
|
|
225976
|
+
break;
|
|
225977
|
+
case "$ne":
|
|
225978
|
+
sqlParts.push(this.addSimpleConditionToSql(key, value["$ne"], alias, "!="));
|
|
225979
|
+
break;
|
|
225980
|
+
case "$in":
|
|
225981
|
+
sqlParts.push(this.addInConditionToSql(key, value["$in"], alias));
|
|
225982
|
+
break;
|
|
225983
|
+
case "$nin":
|
|
225984
|
+
sqlParts.push(`${alias}.${key} NOT IN (${value["$nin"].map((val) => this.t(val)).join(", ")})`);
|
|
225985
|
+
break;
|
|
225986
|
+
case "$like":
|
|
225987
|
+
sqlParts.push(`${alias}.${key} LIKE '${value["$like"]}'`);
|
|
225988
|
+
break;
|
|
225989
|
+
case "$gt":
|
|
225990
|
+
sqlParts.push(`${alias}.${key} > ${value["$gt"]}`);
|
|
225991
|
+
break;
|
|
225992
|
+
case "$gte":
|
|
225993
|
+
sqlParts.push(`${alias}.${key} >= ${value["$gte"]}`);
|
|
225994
|
+
break;
|
|
225995
|
+
case "$lt":
|
|
225996
|
+
sqlParts.push(`${alias}.${key} < ${value["$lt"]}`);
|
|
225997
|
+
break;
|
|
225998
|
+
case "$lte":
|
|
225999
|
+
sqlParts.push(`${alias}.${key} <= ${value["$lte"]}`);
|
|
226000
|
+
break;
|
|
226001
|
+
case "$and":
|
|
226002
|
+
case "$or":
|
|
226003
|
+
const parts = value[operator].map((cond) => this.conditionToSql(cond, alias, model));
|
|
226004
|
+
sqlParts.push(this.addLogicalOperatorToSql(parts, operator.toUpperCase().replace("$", "")));
|
|
226005
|
+
break;
|
|
226006
|
+
}
|
|
226007
|
+
}
|
|
226008
|
+
}
|
|
226009
|
+
}
|
|
226010
|
+
}
|
|
226011
|
+
if (sqlParts.length === 0) {
|
|
226012
|
+
return "";
|
|
226013
|
+
}
|
|
226014
|
+
return this.addLogicalOperatorToSql(sqlParts, "AND");
|
|
226015
|
+
}
|
|
226016
|
+
t(value) {
|
|
226017
|
+
return typeof value === "string" ? `'${value}'` : value;
|
|
226018
|
+
}
|
|
226019
|
+
applyJoin(relationShip, value, alias) {
|
|
226020
|
+
const { tableName, schema } = this.getTableName();
|
|
226021
|
+
const { tableName: joinTableName, schema: joinSchema, hooks: joinHooks } = this.entityStorage.get(relationShip.entity()) || {
|
|
226022
|
+
tableName: relationShip.entity().name.toLowerCase(),
|
|
226023
|
+
schema: "public"
|
|
226024
|
+
};
|
|
226025
|
+
let originPrimaryKey = "id";
|
|
226026
|
+
for (const prop in this.entity.properties) {
|
|
226027
|
+
if (this.entity.properties[prop].options.isPrimary) {
|
|
226028
|
+
originPrimaryKey = prop;
|
|
226029
|
+
break;
|
|
226030
|
+
}
|
|
226031
|
+
}
|
|
226032
|
+
const joinAlias = `${this.getAlias(joinTableName)}`;
|
|
226033
|
+
const joinWhere = this.conditionToSql(value, joinAlias, relationShip.entity());
|
|
226034
|
+
let on = "";
|
|
226035
|
+
switch (relationShip.relation) {
|
|
226036
|
+
case "one-to-many":
|
|
226037
|
+
on = `${joinAlias}."${this.getFkKey(relationShip)}" = ${alias}."${originPrimaryKey}"`;
|
|
226038
|
+
break;
|
|
226039
|
+
case "many-to-one":
|
|
226040
|
+
on = `${alias}."${relationShip.propertyKey}" = ${joinAlias}."${this.getFkKey(relationShip)}"`;
|
|
226041
|
+
break;
|
|
226042
|
+
}
|
|
226043
|
+
if (this.statements.strategy === "joined") {
|
|
226044
|
+
this.statements.join = this.statements.join || [];
|
|
226045
|
+
this.statements.join.push({
|
|
226046
|
+
joinAlias,
|
|
226047
|
+
joinTable: joinTableName,
|
|
226048
|
+
joinSchema: joinSchema || "public",
|
|
226049
|
+
joinWhere,
|
|
226050
|
+
joinProperty: relationShip.propertyKey,
|
|
226051
|
+
originAlias: alias,
|
|
226052
|
+
originSchema: schema,
|
|
226053
|
+
originTable: tableName,
|
|
226054
|
+
propertyKey: relationShip.propertyKey,
|
|
226055
|
+
joinEntity: relationShip.entity(),
|
|
226056
|
+
type: "LEFT",
|
|
226057
|
+
on,
|
|
226058
|
+
originalEntity: relationShip.originalEntity,
|
|
226059
|
+
hooks: joinHooks
|
|
226060
|
+
});
|
|
226061
|
+
} else {
|
|
226062
|
+
this.statements.selectJoin = this.statements.selectJoin || [];
|
|
226063
|
+
this.statements.selectJoin.push({
|
|
226064
|
+
statement: "select",
|
|
226065
|
+
columns: this.originalColumns.filter((column) => column.startsWith(`${relationShip.propertyKey}`)).map((column) => column.split(".")[1]) || [],
|
|
226066
|
+
table: `"${joinSchema || "public"}"."${joinTableName}"`,
|
|
226067
|
+
alias: joinAlias,
|
|
226068
|
+
where: joinWhere,
|
|
226069
|
+
joinProperty: relationShip.propertyKey,
|
|
226070
|
+
fkKey: this.getFkKey(relationShip),
|
|
226071
|
+
primaryKey: originPrimaryKey,
|
|
226072
|
+
originAlias: alias,
|
|
226073
|
+
originProperty: relationShip.propertyKey,
|
|
226074
|
+
joinEntity: relationShip.entity(),
|
|
226075
|
+
originEntity: relationShip.originalEntity,
|
|
226076
|
+
hooks: joinHooks
|
|
226077
|
+
});
|
|
226078
|
+
}
|
|
226079
|
+
return joinWhere;
|
|
226080
|
+
}
|
|
226081
|
+
getFkKey(relationShip) {
|
|
226082
|
+
if (typeof relationShip.fkKey === "undefined") {
|
|
226083
|
+
return "id";
|
|
226084
|
+
}
|
|
226085
|
+
if (typeof relationShip.fkKey === "string") {
|
|
226086
|
+
return relationShip.fkKey;
|
|
226087
|
+
}
|
|
226088
|
+
const match = /\.(?<propriedade>[\w]+)/.exec(relationShip.fkKey.toString());
|
|
226089
|
+
return match ? match.groups.propriedade : "";
|
|
226090
|
+
}
|
|
226091
|
+
getEntity(model) {
|
|
226092
|
+
const entity = this.entityStorage.get(model);
|
|
226093
|
+
this.model = model;
|
|
226094
|
+
if (!entity) {
|
|
226095
|
+
throw new Error("Entity not found");
|
|
226096
|
+
}
|
|
226097
|
+
this.entity = entity;
|
|
226098
|
+
}
|
|
226099
|
+
transformToModel(model, statement, data) {
|
|
226100
|
+
const instance = new model;
|
|
226101
|
+
instance.$_isPersisted = true;
|
|
226102
|
+
const entitiesByAlias = {
|
|
226103
|
+
[statement.alias]: instance
|
|
226104
|
+
};
|
|
226105
|
+
const entitiesOptions = new Map;
|
|
226106
|
+
entitiesOptions.set(statement.alias, this.entityStorage.get(instance.constructor));
|
|
226107
|
+
if (this.statements.join) {
|
|
226108
|
+
this.statements.join.forEach((join) => {
|
|
226109
|
+
const joinInstance = new join.joinEntity;
|
|
226110
|
+
joinInstance.$_isPersisted = true;
|
|
226111
|
+
entitiesByAlias[join.joinAlias] = joinInstance;
|
|
226112
|
+
entitiesOptions.set(join.joinAlias, this.entityStorage.get(joinInstance.constructor));
|
|
226113
|
+
});
|
|
226114
|
+
}
|
|
226115
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
226116
|
+
const [alias, prop] = key.split("_");
|
|
226117
|
+
const entity = entitiesByAlias[alias];
|
|
226118
|
+
if (!entity) {
|
|
226119
|
+
return;
|
|
226120
|
+
}
|
|
226121
|
+
const entityProperty = entitiesOptions.get(alias).properties[prop];
|
|
226122
|
+
if (entityProperty) {
|
|
226123
|
+
if (this.extendsFrom(ValueObject2, entityProperty.type.prototype)) {
|
|
226124
|
+
entity[prop] = new entityProperty.type(value);
|
|
226125
|
+
return;
|
|
226126
|
+
}
|
|
226127
|
+
entity[prop] = value;
|
|
226128
|
+
}
|
|
226129
|
+
});
|
|
226130
|
+
if (this.statements.join) {
|
|
226131
|
+
this.statements.join.forEach((join) => {
|
|
226132
|
+
const { joinAlias, originAlias, propertyKey } = join;
|
|
226133
|
+
const originEntity = entitiesByAlias[originAlias];
|
|
226134
|
+
const joinEntity = entitiesByAlias[joinAlias];
|
|
226135
|
+
const property3 = entitiesOptions.get(originAlias).relations.find((rel) => rel.propertyKey === propertyKey);
|
|
226136
|
+
if (!originEntity || !joinEntity) {
|
|
226137
|
+
return;
|
|
226138
|
+
}
|
|
226139
|
+
originEntity[propertyKey] = property3.type === Array ? originEntity[propertyKey] ? [...originEntity[propertyKey], joinEntity] : [joinEntity] : joinEntity;
|
|
226140
|
+
});
|
|
226141
|
+
}
|
|
226142
|
+
return instance;
|
|
226143
|
+
}
|
|
226144
|
+
getAlias(tableName) {
|
|
226145
|
+
const alias = tableName.split("").shift() || "";
|
|
226146
|
+
let counter = 1;
|
|
226147
|
+
let uniqueAlias = `${alias}${counter}`;
|
|
226148
|
+
while (this.aliases.has(uniqueAlias)) {
|
|
226149
|
+
counter++;
|
|
226150
|
+
uniqueAlias = `${alias}${counter}`;
|
|
226151
|
+
}
|
|
226152
|
+
this.aliases.add(uniqueAlias);
|
|
226153
|
+
return uniqueAlias;
|
|
226154
|
+
}
|
|
226155
|
+
getColumnsEntity(entity, alias) {
|
|
226156
|
+
const e = this.entityStorage.get(entity);
|
|
226157
|
+
if (!e) {
|
|
226158
|
+
throw new Error("Entity not found");
|
|
226159
|
+
}
|
|
226160
|
+
const columns = Object.keys(e.properties).map((key) => `${alias}."${key}" as "${alias}_${key}"`);
|
|
226161
|
+
if (e.relations) {
|
|
226162
|
+
for (const relation of e.relations) {
|
|
226163
|
+
if (relation.relation === "many-to-one") {
|
|
226164
|
+
columns.push(`${alias}."${relation.propertyKey}" as "${alias}_${relation.propertyKey}"`);
|
|
226165
|
+
}
|
|
226166
|
+
}
|
|
226167
|
+
}
|
|
226168
|
+
return columns;
|
|
226169
|
+
}
|
|
226170
|
+
withDefaultValues(values, entityOptions) {
|
|
226171
|
+
const property3 = Object.entries(entityOptions.properties).filter(([_, value]) => value.options.onInsert);
|
|
226172
|
+
const defaultProperties = Object.entries(entityOptions.properties).filter(([_, value]) => value.options.default);
|
|
226173
|
+
for (const [key, property4] of defaultProperties) {
|
|
226174
|
+
if (typeof values[key] === "undefined") {
|
|
226175
|
+
if (typeof property4.options.default === "function") {
|
|
226176
|
+
values[key] = (0, eval)(property4.options.default());
|
|
226177
|
+
} else {
|
|
226178
|
+
values[key] = (0, eval)(property4.options.default);
|
|
226179
|
+
}
|
|
226180
|
+
}
|
|
226181
|
+
}
|
|
226182
|
+
property3.forEach(([key, property4]) => {
|
|
226183
|
+
values[key] = property4.options.onInsert();
|
|
226184
|
+
this.updatedColumns.push(`${this.statements.alias}."${key}" as "${this.statements.alias}_${key}"`);
|
|
226185
|
+
});
|
|
226186
|
+
return values;
|
|
226187
|
+
}
|
|
226188
|
+
withUpdatedValues(values, entityOptions) {
|
|
226189
|
+
const property3 = Object.entries(entityOptions.properties).filter(([_, value]) => value.options.onUpdate);
|
|
226190
|
+
property3.forEach(([key, property4]) => {
|
|
226191
|
+
values[key] = property4.options.onUpdate();
|
|
226192
|
+
this.updatedColumns.push(`${this.statements.alias}."${key}" as "${this.statements.alias}_${key}"`);
|
|
226193
|
+
});
|
|
226194
|
+
return values;
|
|
226195
|
+
}
|
|
226196
|
+
extendsFrom(baseClass, instance) {
|
|
226197
|
+
if (!instance)
|
|
226198
|
+
return false;
|
|
226199
|
+
let proto = Object.getPrototypeOf(instance);
|
|
226200
|
+
while (proto) {
|
|
226201
|
+
if (proto === baseClass.prototype) {
|
|
226202
|
+
return true;
|
|
226203
|
+
}
|
|
226204
|
+
proto = Object.getPrototypeOf(proto);
|
|
226205
|
+
}
|
|
226206
|
+
return false;
|
|
226207
|
+
}
|
|
226208
|
+
callHook(type, model) {
|
|
226209
|
+
const hooks3 = this.statements.hooks?.filter((hook) => hook.type === type) || [];
|
|
226210
|
+
const instance = model || this.statements.instance;
|
|
226211
|
+
for (const hook of hooks3) {
|
|
226212
|
+
instance[hook.propertyName]();
|
|
226213
|
+
if (!model) {
|
|
226214
|
+
this.reflectToValues();
|
|
226215
|
+
}
|
|
226216
|
+
}
|
|
226217
|
+
}
|
|
226218
|
+
reflectToValues() {
|
|
226219
|
+
for (const key in this.statements.instance) {
|
|
226220
|
+
if (key.startsWith("$")) {
|
|
226221
|
+
continue;
|
|
226222
|
+
}
|
|
226223
|
+
if (key.startsWith("_")) {
|
|
226224
|
+
continue;
|
|
226225
|
+
}
|
|
226226
|
+
if (this.entity.properties[key]) {
|
|
226227
|
+
this.statements.values[key] = this.statements.instance[key];
|
|
226228
|
+
continue;
|
|
226229
|
+
}
|
|
226230
|
+
if (this.entity.relations.find((rel) => rel.propertyKey === key)) {
|
|
226231
|
+
this.statements.values[key] = this.statements.instance[key];
|
|
226232
|
+
}
|
|
226233
|
+
}
|
|
226234
|
+
}
|
|
226235
|
+
}
|
|
226236
|
+
|
|
226237
|
+
// ../../node_
|
|
226238
|
+
var __decorate10 = function(decorators5, target, key, desc) {
|
|
226239
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
226240
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
226241
|
+
r = Reflect.decorate(decorators5, target, key, desc);
|
|
226242
|
+
else
|
|
226243
|
+
for (var i = decorators5.length - 1;i >= 0; i--)
|
|
226244
|
+
if (d = decorators5[i])
|
|
226245
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
226246
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
226247
|
+
};
|
|
226248
|
+
var __metadata8 = function(k, v) {
|
|
226249
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
226250
|
+
return Reflect.metadata(k, v);
|
|
226251
|
+
};
|
|
226252
|
+
var Orm_1;
|
|
226253
|
+
var Orm2 = class Orm3 {
|
|
226254
|
+
static {
|
|
226255
|
+
Orm_1 = this;
|
|
226256
|
+
}
|
|
226257
|
+
logger;
|
|
226258
|
+
driverInstance;
|
|
226259
|
+
static instance;
|
|
226260
|
+
connection;
|
|
226261
|
+
constructor(logger3) {
|
|
226262
|
+
this.logger = logger3;
|
|
226263
|
+
Orm_1.instance = this;
|
|
226264
|
+
}
|
|
226265
|
+
static getInstance() {
|
|
226266
|
+
return Orm_1.instance;
|
|
226267
|
+
}
|
|
226268
|
+
setConnection(connection) {
|
|
226269
|
+
this.connection = connection;
|
|
226270
|
+
this.driverInstance = new this.connection.driver(connection);
|
|
226271
|
+
}
|
|
226272
|
+
createQueryBuilder(model) {
|
|
226273
|
+
return new SqlBuilder5(model);
|
|
226274
|
+
}
|
|
226275
|
+
connect() {
|
|
226276
|
+
return this.driverInstance.connect();
|
|
226277
|
+
}
|
|
226278
|
+
disconnect() {
|
|
226279
|
+
return this.driverInstance.disconnect();
|
|
226280
|
+
}
|
|
226281
|
+
};
|
|
226282
|
+
Orm2 = Orm_1 = __decorate10([
|
|
226283
|
+
Service(),
|
|
226284
|
+
__metadata8("design:paramtypes", [LoggerService])
|
|
226285
|
+
], Orm2);
|
|
226286
|
+
// ../../node_modules/
|
|
226287
|
+
var import_ts_morph2 = __toESM(require_ts_morph(), 1);
|
|
226288
|
+
var __decorate11 = function(decorators5, target, key, desc) {
|
|
226289
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
226290
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
226291
|
+
r = Reflect.decorate(decorators5, target, key, desc);
|
|
226292
|
+
else
|
|
226293
|
+
for (var i = decorators5.length - 1;i >= 0; i--)
|
|
226294
|
+
if (d = decorators5[i])
|
|
226295
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
226296
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
226297
|
+
};
|
|
226298
|
+
var __metadata9 = function(k, v) {
|
|
226299
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
226300
|
+
return Reflect.metadata(k, v);
|
|
226301
|
+
};
|
|
226302
|
+
var OrmService2 = class OrmService3 {
|
|
226303
|
+
orm;
|
|
226304
|
+
storage;
|
|
226305
|
+
allEntities = new Map;
|
|
226306
|
+
constructor(orm7, storage2, entityFile) {
|
|
226307
|
+
this.orm = orm7;
|
|
226308
|
+
this.storage = storage2;
|
|
226309
|
+
console.log("Preparing entities...");
|
|
226310
|
+
const files = new import_ts_morph2.Project({ skipLoadingLibFiles: true }).addSourceFilesAtPaths(entityFile ?? this.getSourceFilePaths());
|
|
226311
|
+
files.forEach((file) => {
|
|
226312
|
+
file.getClasses().forEach((classDeclaration) => {
|
|
226313
|
+
if (classDeclaration.getDecorator("Entity")) {
|
|
226314
|
+
const properties = classDeclaration.getProperties();
|
|
226315
|
+
const nullables = [];
|
|
226316
|
+
const defaults = {};
|
|
226317
|
+
const extendsClass = classDeclaration.getBaseClass();
|
|
226318
|
+
if (extendsClass) {
|
|
226319
|
+
const extendsProperties = extendsClass.getProperties();
|
|
226320
|
+
properties.push(...extendsProperties);
|
|
226321
|
+
}
|
|
226322
|
+
properties.forEach((property3) => {
|
|
226323
|
+
const propertyName = property3.getName();
|
|
226324
|
+
const isNullable = property3.hasQuestionToken();
|
|
226325
|
+
const initializer = property3.getInitializer();
|
|
226326
|
+
if (isNullable) {
|
|
226327
|
+
nullables.push(propertyName);
|
|
226328
|
+
}
|
|
226329
|
+
if (initializer) {
|
|
226330
|
+
const initializerKind = initializer.getKind();
|
|
226331
|
+
switch (initializerKind) {
|
|
226332
|
+
case import_ts_morph2.SyntaxKind.StringLiteral:
|
|
226333
|
+
defaults[propertyName] = initializer.getText();
|
|
226334
|
+
break;
|
|
226335
|
+
case import_ts_morph2.SyntaxKind.NumericLiteral:
|
|
226336
|
+
defaults[propertyName] = parseFloat(initializer.getText());
|
|
226337
|
+
break;
|
|
226338
|
+
case import_ts_morph2.SyntaxKind.NewExpression:
|
|
226339
|
+
case import_ts_morph2.SyntaxKind.CallExpression:
|
|
226340
|
+
break;
|
|
226341
|
+
default:
|
|
226342
|
+
defaults[propertyName] = () => initializer.getText();
|
|
226343
|
+
break;
|
|
226344
|
+
}
|
|
226345
|
+
}
|
|
226346
|
+
this.allEntities.set(classDeclaration.getName(), { nullables, defaults });
|
|
226347
|
+
});
|
|
226348
|
+
}
|
|
226349
|
+
});
|
|
226350
|
+
});
|
|
226351
|
+
}
|
|
226352
|
+
async onInit(customConfig = {}) {
|
|
226353
|
+
const configFile = globbySync2("cheetah.config.ts", { absolute: true });
|
|
226354
|
+
if (configFile.length === 0) {
|
|
226355
|
+
console.log("No config file found!");
|
|
226356
|
+
return;
|
|
226357
|
+
}
|
|
226358
|
+
const config = await import(configFile[0]);
|
|
226359
|
+
const setConfig = Object.keys(customConfig).length > 0 ? customConfig : config.default;
|
|
226360
|
+
this.orm.setConnection(setConfig);
|
|
226361
|
+
await this.orm.connect();
|
|
226362
|
+
if (typeof config.default.entities === "string") {
|
|
226363
|
+
const files = globbySync2([config.default.entities, "!node_modules"], { gitignore: true, absolute: true });
|
|
226364
|
+
for (const file of files) {
|
|
226365
|
+
await import(file);
|
|
226366
|
+
}
|
|
226367
|
+
}
|
|
226368
|
+
const entities8 = Metadata.get(ENTITIES2, Reflect);
|
|
226369
|
+
if (!entities8) {
|
|
226370
|
+
console.log("No entities found!");
|
|
226371
|
+
return;
|
|
226372
|
+
}
|
|
226373
|
+
for (const entity of entities8) {
|
|
226374
|
+
const nullableDefaultEntity = this.allEntities.get(entity.target.name);
|
|
226375
|
+
const properties = Metadata.get(PROPERTIES_METADATA2, entity.target);
|
|
226376
|
+
const relationship = Metadata.get(PROPERTIES_RELATIONS2, entity.target);
|
|
226377
|
+
const hooks3 = Metadata.get(EVENTS_METADATA2, entity.target);
|
|
226378
|
+
for (const property3 in properties) {
|
|
226379
|
+
if (nullableDefaultEntity?.nullables.includes(property3)) {
|
|
226380
|
+
properties[property3].options.nullable = true;
|
|
226381
|
+
}
|
|
226382
|
+
if (nullableDefaultEntity?.defaults[property3]) {
|
|
226383
|
+
properties[property3].options.default = nullableDefaultEntity?.defaults[property3];
|
|
226384
|
+
}
|
|
226385
|
+
}
|
|
226386
|
+
this.storage.add(entity, properties, relationship, hooks3);
|
|
226387
|
+
}
|
|
226388
|
+
console.log("Entities prepared!");
|
|
226389
|
+
}
|
|
226390
|
+
getSourceFilePaths() {
|
|
226391
|
+
const projectRoot = process.cwd();
|
|
226392
|
+
const getAllFiles = (dir) => {
|
|
226393
|
+
const patterns = [`${dir}/**/*.(ts|js)`, "!**/node_modules/**"];
|
|
226394
|
+
try {
|
|
226395
|
+
return globbySync2(patterns, { gitignore: true });
|
|
226396
|
+
} catch (error) {
|
|
226397
|
+
console.error("Erro ao obter arquivos:", error);
|
|
226398
|
+
return [];
|
|
226399
|
+
}
|
|
226400
|
+
};
|
|
226401
|
+
return getAllFiles(projectRoot);
|
|
226402
|
+
}
|
|
226403
|
+
};
|
|
226404
|
+
__decorate11([
|
|
226405
|
+
OnApplicationInit(),
|
|
226406
|
+
__metadata9("design:type", Function),
|
|
226407
|
+
__metadata9("design:paramtypes", [Object]),
|
|
226408
|
+
__metadata9("design:returntype", Promise)
|
|
226409
|
+
], OrmService2.prototype, "onInit", null);
|
|
226410
|
+
OrmService2 = __decorate11([
|
|
226411
|
+
Service(),
|
|
226412
|
+
__metadata9("design:paramtypes", [Orm2, EntityStorage2, String])
|
|
226413
|
+
], OrmService2);
|
|
226414
|
+
// ../../node_modules/balan
|
|
226415
|
+
var import_pg2 = __toESM(require_lib2(), 1);
|
|
226416
|
+
// ../../node_mo
|
|
226417
|
+
var CheetahOrm2 = new Cheetah({ exports: [Orm2, OrmService2, EntityStorage2] });
|
|
226418
|
+
// ../../node_modules/balance
|
|
226419
|
+
import * as path3 from "path";
|
|
226420
|
+
import * as fs5 from "fs";
|
|
226421
|
+
|
|
226422
|
+
// ../../node_modules/balanced-match
|
|
226423
|
+
class DiffCalculator {
|
|
226424
|
+
entities;
|
|
226425
|
+
constructor(entities9) {
|
|
226426
|
+
this.entities = entities9;
|
|
226427
|
+
}
|
|
226428
|
+
diff(snapshotBd, snapshotEntities) {
|
|
226429
|
+
let diffs = [];
|
|
226430
|
+
const bdTablesMap = new Map(snapshotBd.map((table) => [table.tableName, table]));
|
|
226431
|
+
const entityTablesMap = new Map(snapshotEntities.map((table) => [table.tableName, table]));
|
|
226432
|
+
const allTableNames = new Set([...bdTablesMap.keys(), ...entityTablesMap.keys()]);
|
|
226433
|
+
allTableNames.forEach((tableName) => {
|
|
226434
|
+
const bdTable = bdTablesMap.get(tableName);
|
|
226435
|
+
const entityTable = entityTablesMap.get(tableName);
|
|
226436
|
+
if (!entityTable) {
|
|
226437
|
+
diffs.push({
|
|
226438
|
+
tableName,
|
|
226439
|
+
colDiffs: [{ actionType: "DELETE", colName: "*" }]
|
|
226440
|
+
});
|
|
226441
|
+
} else if (!bdTable) {
|
|
226442
|
+
const colDiffs = entityTable.columns.flatMap((c) => {
|
|
226443
|
+
return this.createNewColumn(c, []);
|
|
226444
|
+
});
|
|
226445
|
+
diffs.push({
|
|
226446
|
+
tableName,
|
|
226447
|
+
newTable: true,
|
|
226448
|
+
schema: entityTable.schema ?? "public",
|
|
226449
|
+
colDiffs
|
|
226450
|
+
});
|
|
226451
|
+
this.checkIndexes(bdTable, entityTable, colDiffs);
|
|
226452
|
+
} else {
|
|
226453
|
+
const colDiffs = [];
|
|
226454
|
+
const bdColumnsMap = new Map(bdTable.columns.map((col) => [col.name, col]));
|
|
226455
|
+
const entityColumnsMap = new Map(entityTable.columns.map((col) => [col.name, col]));
|
|
226456
|
+
const allColumnNames = new Set([...bdColumnsMap.keys(), ...entityColumnsMap.keys()]);
|
|
226457
|
+
allColumnNames.forEach((colName) => {
|
|
226458
|
+
const bdCol = bdColumnsMap.get(colName);
|
|
226459
|
+
const entityCol = entityColumnsMap.get(colName);
|
|
226460
|
+
if (!entityCol) {
|
|
226461
|
+
colDiffs.push({
|
|
226462
|
+
actionType: "DELETE",
|
|
226463
|
+
colName: bdCol.name
|
|
226464
|
+
});
|
|
226465
|
+
} else if (!bdCol) {
|
|
226466
|
+
this.createNewColumn(entityCol, colDiffs);
|
|
226467
|
+
} else
|
|
226468
|
+
this.diffColumnSql(bdCol, entityCol, colDiffs);
|
|
226469
|
+
});
|
|
226470
|
+
if (colDiffs.length > 0) {
|
|
226471
|
+
diffs.push({
|
|
226472
|
+
tableName,
|
|
226473
|
+
schema: entityTable.schema ?? "public",
|
|
226474
|
+
colDiffs
|
|
226475
|
+
});
|
|
226476
|
+
}
|
|
226477
|
+
this.checkIndexes(bdTable, entityTable, colDiffs);
|
|
226478
|
+
}
|
|
226479
|
+
});
|
|
226480
|
+
return diffs;
|
|
226481
|
+
}
|
|
226482
|
+
checkIndexes(bdTable, entityTable, colDiffs) {
|
|
226483
|
+
if (bdTable && bdTable.indexes || entityTable && entityTable.indexes) {
|
|
226484
|
+
if (!bdTable || !bdTable.indexes) {
|
|
226485
|
+
colDiffs.push({
|
|
226486
|
+
actionType: "INDEX",
|
|
226487
|
+
colName: "*",
|
|
226488
|
+
indexTables: entityTable.indexes.map((index) => ({
|
|
226489
|
+
name: index.indexName,
|
|
226490
|
+
properties: index.columnName.split(",")
|
|
226491
|
+
}))
|
|
226492
|
+
});
|
|
226493
|
+
}
|
|
226494
|
+
if (!entityTable || !entityTable.indexes) {
|
|
226495
|
+
colDiffs.push({
|
|
226496
|
+
actionType: "INDEX",
|
|
226497
|
+
colName: "*",
|
|
226498
|
+
indexTables: bdTable.indexes.map((index) => ({ name: index.indexName }))
|
|
226499
|
+
});
|
|
226500
|
+
}
|
|
226501
|
+
}
|
|
226502
|
+
if (bdTable && bdTable.indexes && (entityTable && entityTable.indexes)) {
|
|
226503
|
+
const bdIndexesMap = new Map(bdTable.indexes.map((index) => [index.indexName, index]));
|
|
226504
|
+
const entityIndexesMap = new Map(entityTable.indexes.map((index) => [index.indexName, index]));
|
|
226505
|
+
const allIndexes = new Set([...bdIndexesMap.keys(), ...entityIndexesMap.keys()]);
|
|
226506
|
+
allIndexes.forEach((indexName) => {
|
|
226507
|
+
const bdIndex = bdIndexesMap.get(indexName);
|
|
226508
|
+
const entityIndex = entityIndexesMap.get(indexName);
|
|
226509
|
+
if (!entityIndex) {
|
|
226510
|
+
colDiffs.push({
|
|
226511
|
+
actionType: "INDEX",
|
|
226512
|
+
colName: bdIndex.columnName,
|
|
226513
|
+
indexTables: [{ name: indexName }]
|
|
226514
|
+
});
|
|
226515
|
+
} else if (!bdIndex) {
|
|
226516
|
+
colDiffs.push({
|
|
226517
|
+
actionType: "INDEX",
|
|
226518
|
+
colName: entityIndex.columnName,
|
|
226519
|
+
indexTables: [{ name: indexName, properties: entityIndex.columnName.split(",") }]
|
|
226520
|
+
});
|
|
226521
|
+
}
|
|
226522
|
+
});
|
|
226523
|
+
}
|
|
226524
|
+
}
|
|
226525
|
+
createNewColumn(entityCol, colDiffs) {
|
|
226526
|
+
const colType = this.convertEntityTypeToSqlType(entityCol.type);
|
|
226527
|
+
colDiffs.push({
|
|
226528
|
+
actionType: "CREATE",
|
|
226529
|
+
colName: entityCol.name,
|
|
226530
|
+
colType: colType.type,
|
|
226531
|
+
colLength: entityCol.length ?? colType.len,
|
|
226532
|
+
colChanges: {
|
|
226533
|
+
autoIncrement: entityCol.autoIncrement,
|
|
226534
|
+
default: entityCol.default,
|
|
226535
|
+
primary: entityCol.primary,
|
|
226536
|
+
unique: entityCol.unique,
|
|
226537
|
+
nullable: entityCol.nullable,
|
|
226538
|
+
enumItems: entityCol.enumItems,
|
|
226539
|
+
foreignKeys: entityCol.foreignKeys ?? []
|
|
226540
|
+
}
|
|
226541
|
+
});
|
|
226542
|
+
return colDiffs;
|
|
226543
|
+
}
|
|
226544
|
+
diffColumnType(bdCol, entityCol, colDiffs) {
|
|
226545
|
+
if (bdCol.type === "integer" && bdCol.primary) {
|
|
226546
|
+
bdCol.type = "numeric";
|
|
226547
|
+
bdCol.length = 11;
|
|
226548
|
+
}
|
|
226549
|
+
const colT = entityCol.isEnum ? { type: "USER-DEFINED", len: null } : this.convertEntityTypeToSqlType(entityCol.type);
|
|
226550
|
+
const colType = colT.type;
|
|
226551
|
+
const length = entityCol.length ?? colT.len;
|
|
226552
|
+
if (bdCol.type !== colType || bdCol.length !== length) {
|
|
226553
|
+
if (colType === "USER-DEFINED") {
|
|
226554
|
+
colDiffs.push({
|
|
226555
|
+
actionType: "DELETE",
|
|
226556
|
+
colName: entityCol.name
|
|
226557
|
+
});
|
|
226558
|
+
return;
|
|
226559
|
+
}
|
|
226560
|
+
colDiffs.push({
|
|
226561
|
+
actionType: "ALTER",
|
|
226562
|
+
colName: entityCol.name,
|
|
226563
|
+
colType,
|
|
226564
|
+
colLength: length
|
|
226565
|
+
});
|
|
226566
|
+
}
|
|
226567
|
+
}
|
|
226568
|
+
diffColumnDefault(bdCol, entityCol, colDiffs) {
|
|
226569
|
+
if (bdCol.default !== entityCol.default) {
|
|
226570
|
+
colDiffs.push({
|
|
226571
|
+
actionType: "ALTER",
|
|
226572
|
+
colName: entityCol.name,
|
|
226573
|
+
colChanges: { default: entityCol.default },
|
|
226574
|
+
colLength: entityCol.length
|
|
226575
|
+
});
|
|
226576
|
+
}
|
|
226577
|
+
}
|
|
226578
|
+
diffColumnPrimary(bdCol, entityCol, colDiffs) {
|
|
226579
|
+
if (bdCol.primary !== entityCol.primary) {
|
|
226580
|
+
colDiffs.push({
|
|
226581
|
+
actionType: "ALTER",
|
|
226582
|
+
colName: entityCol.name,
|
|
226583
|
+
colChanges: { primary: entityCol.primary },
|
|
226584
|
+
colLength: entityCol.length
|
|
226585
|
+
});
|
|
226586
|
+
}
|
|
226587
|
+
}
|
|
226588
|
+
diffColumnUnique(bdCol, entityCol, colDiffs) {
|
|
226589
|
+
if (bdCol.unique !== entityCol.unique) {
|
|
226590
|
+
if (bdCol.unique === false && entityCol.unique === undefined) {
|
|
226591
|
+
return;
|
|
226592
|
+
}
|
|
226593
|
+
colDiffs.push({
|
|
226594
|
+
actionType: "ALTER",
|
|
226595
|
+
colName: entityCol.name,
|
|
226596
|
+
colChanges: { unique: entityCol.unique || false },
|
|
226597
|
+
colLength: entityCol.length
|
|
226598
|
+
});
|
|
226599
|
+
}
|
|
226600
|
+
}
|
|
226601
|
+
diffForeignKey(bdCol, entityCol, colDiffs) {
|
|
226602
|
+
if (bdCol.foreignKeys || entityCol.foreignKeys) {
|
|
226603
|
+
const bdFKMap = new Map((bdCol.foreignKeys || []).map((fk) => [`${fk.referencedTableName}.${fk.referencedColumnName}`, fk]));
|
|
226604
|
+
const entityFKMap = new Map((entityCol.foreignKeys || []).map((fk) => [`${fk.referencedTableName}.${fk.referencedColumnName}`, fk]));
|
|
226605
|
+
const allFKs = new Set([...bdFKMap.keys(), ...entityFKMap.keys()]);
|
|
226606
|
+
allFKs.forEach((fkName) => {
|
|
226607
|
+
const bdFK = bdFKMap.get(fkName);
|
|
226608
|
+
const entityFK = entityFKMap.get(fkName);
|
|
226609
|
+
if (!entityFK) {
|
|
226610
|
+
colDiffs.push({
|
|
226611
|
+
actionType: "ALTER",
|
|
226612
|
+
colName: bdCol.name,
|
|
226613
|
+
colChanges: {
|
|
226614
|
+
foreignKeys: bdCol.foreignKeys?.filter((fk) => fk !== bdFK)
|
|
226615
|
+
}
|
|
226616
|
+
});
|
|
226617
|
+
}
|
|
226618
|
+
});
|
|
226619
|
+
}
|
|
226620
|
+
}
|
|
226621
|
+
diffColumnSql(bdCol, entityCol, colDiffs) {
|
|
226622
|
+
this.diffForeignKey(bdCol, entityCol, colDiffs);
|
|
226623
|
+
this.diffEnum(bdCol, entityCol, colDiffs);
|
|
226624
|
+
this.diffColumnType(bdCol, entityCol, colDiffs);
|
|
226625
|
+
this.diffColumnDefault(bdCol, entityCol, colDiffs);
|
|
226626
|
+
this.diffColumnPrimary(bdCol, entityCol, colDiffs);
|
|
226627
|
+
this.diffColumnUnique(bdCol, entityCol, colDiffs);
|
|
226628
|
+
this.diffColumnNullable(bdCol, entityCol, colDiffs);
|
|
226629
|
+
return colDiffs;
|
|
226630
|
+
}
|
|
226631
|
+
diffColumnNullable(bdCol, entityCol, colDiffs) {
|
|
226632
|
+
if (bdCol.nullable !== entityCol.nullable) {
|
|
226633
|
+
colDiffs.push({
|
|
226634
|
+
actionType: "ALTER",
|
|
226635
|
+
colName: entityCol.name,
|
|
226636
|
+
colChanges: { nullable: entityCol.nullable },
|
|
226637
|
+
colLength: entityCol.length
|
|
226638
|
+
});
|
|
226639
|
+
}
|
|
226640
|
+
}
|
|
226641
|
+
convertEntityTypeToSqlType(entityType) {
|
|
226642
|
+
switch (entityType) {
|
|
226643
|
+
case "Number":
|
|
226644
|
+
case "int":
|
|
226645
|
+
return { type: "numeric", len: 11 };
|
|
226646
|
+
case "bigint":
|
|
226647
|
+
return { type: "bigint" };
|
|
226648
|
+
case "float":
|
|
226649
|
+
return { type: "float4" };
|
|
226650
|
+
case "double":
|
|
226651
|
+
return { type: "float8" };
|
|
226652
|
+
case "decimal":
|
|
226653
|
+
return { type: "decimal" };
|
|
226654
|
+
case "String":
|
|
226655
|
+
case "varchar":
|
|
226656
|
+
return { type: "character varying", len: 255 };
|
|
226657
|
+
case "Boolean":
|
|
226658
|
+
return { type: "boolean" };
|
|
226659
|
+
case "Date":
|
|
226660
|
+
return { type: "timestamp" };
|
|
226661
|
+
case "Object":
|
|
226662
|
+
return { type: "json" };
|
|
226663
|
+
case "uuid":
|
|
226664
|
+
return { type: "uuid" };
|
|
226665
|
+
case "text":
|
|
226666
|
+
return { type: "text" };
|
|
226667
|
+
default:
|
|
226668
|
+
return { type: "character varying", len: 255 };
|
|
226669
|
+
}
|
|
226670
|
+
}
|
|
226671
|
+
diffEnum(bdCol, entityCol, colDiffs) {
|
|
226672
|
+
if (bdCol.enumItems || entityCol.enumItems) {
|
|
226673
|
+
if (bdCol.enumItems && entityCol.enumItems) {
|
|
226674
|
+
const allEnums = new Set([...bdCol.enumItems, ...entityCol.enumItems]);
|
|
226675
|
+
const differences = [...allEnums].filter((x) => !bdCol.enumItems?.includes(x) || !entityCol.enumItems?.includes(x));
|
|
226676
|
+
if (differences.length === 0) {
|
|
226677
|
+
return;
|
|
226678
|
+
}
|
|
226679
|
+
colDiffs.push({
|
|
226680
|
+
actionType: "ALTER",
|
|
226681
|
+
colName: entityCol.name,
|
|
226682
|
+
colChanges: {
|
|
226683
|
+
enumItems: entityCol.enumItems
|
|
226684
|
+
}
|
|
226685
|
+
});
|
|
226686
|
+
}
|
|
226687
|
+
if (!entityCol.enumItems) {
|
|
226688
|
+
colDiffs.push({
|
|
226689
|
+
actionType: "DELETE",
|
|
226690
|
+
colName: bdCol.name,
|
|
226691
|
+
colChanges: {
|
|
226692
|
+
enumItems: []
|
|
226693
|
+
}
|
|
226694
|
+
});
|
|
226695
|
+
} else if (!bdCol.enumItems) {
|
|
226696
|
+
colDiffs.push({
|
|
226697
|
+
actionType: "CREATE",
|
|
226698
|
+
colName: entityCol.name,
|
|
226699
|
+
colChanges: {
|
|
226700
|
+
enumItems: entityCol.enumItems
|
|
226701
|
+
}
|
|
226702
|
+
});
|
|
226703
|
+
}
|
|
226704
|
+
}
|
|
226705
|
+
}
|
|
226706
|
+
}
|
|
226707
|
+
|
|
226708
|
+
// ../../node_modules/balance
|
|
226709
|
+
class Migrator {
|
|
226710
|
+
config;
|
|
226711
|
+
orm;
|
|
226712
|
+
entities = new EntityStorage2;
|
|
226713
|
+
constructor() {
|
|
226714
|
+
this.orm = Orm2.getInstance();
|
|
226715
|
+
if (this.orm === undefined)
|
|
226716
|
+
this.orm = new Orm2(new LoggerService(new InjectorService));
|
|
226717
|
+
this.entities = EntityStorage2.getInstance();
|
|
226718
|
+
if (this.entities === undefined)
|
|
226719
|
+
this.entities = new EntityStorage2;
|
|
226720
|
+
}
|
|
226721
|
+
async initConfigFile(basePath = process.cwd()) {
|
|
226722
|
+
const paths = await globby2(["cheetah.config.ts"], { absolute: true, cwd: basePath });
|
|
226723
|
+
if (paths.length === 0) {
|
|
226724
|
+
throw new Error("Config file not found");
|
|
226725
|
+
}
|
|
226726
|
+
const config = await import(paths[0]);
|
|
226727
|
+
this.config = config.default;
|
|
226728
|
+
if (typeof this.config.entities === "string") {
|
|
226729
|
+
const paths2 = await globby2(this.config.entities, { absolute: true, cwd: basePath });
|
|
226730
|
+
for (const path4 of paths2) {
|
|
226731
|
+
await import(path4);
|
|
226732
|
+
}
|
|
226733
|
+
}
|
|
226734
|
+
const serv = new OrmService2(this.orm, this.entities);
|
|
226735
|
+
await serv.onInit(this.config);
|
|
226736
|
+
}
|
|
226737
|
+
async initMigration() {
|
|
226738
|
+
const snapshotBd = await this.snapshotBd();
|
|
226739
|
+
const snapshotEntities = await this.snapshotEntities();
|
|
226740
|
+
const calculator = new DiffCalculator(this.entities);
|
|
226741
|
+
return calculator.diff(snapshotBd, snapshotEntities);
|
|
226742
|
+
}
|
|
226743
|
+
async snapshotBd() {
|
|
226744
|
+
const snapshot = [];
|
|
226745
|
+
for (let [_, values] of this.entities.entries()) {
|
|
226746
|
+
const bd = await this.orm.driverInstance.snapshot(values.tableName);
|
|
226747
|
+
if (!bd) {
|
|
226748
|
+
continue;
|
|
226749
|
+
}
|
|
226750
|
+
snapshot.push(bd);
|
|
226751
|
+
}
|
|
226752
|
+
return snapshot;
|
|
226753
|
+
}
|
|
226754
|
+
async snapshotEntities() {
|
|
226755
|
+
const snapshot = [];
|
|
226756
|
+
for (let [_, values] of this.entities.entries()) {
|
|
226757
|
+
snapshot.push(await this.entities.snapshot(values));
|
|
226758
|
+
}
|
|
226759
|
+
return snapshot;
|
|
226760
|
+
}
|
|
226761
|
+
async createMigration(forceName = null) {
|
|
226762
|
+
const diff = await this.initMigration();
|
|
226763
|
+
const migrationDirectory = path3.join(process.cwd(), this.config.migrationPath ?? "database/migrations");
|
|
226764
|
+
const migrationFileName = (forceName ?? `migration_${new Date().toISOString().replace(/[^\d]/g, "")}`) + `.sql`;
|
|
226765
|
+
const migrationFilePath = path3.join(migrationDirectory, migrationFileName);
|
|
226766
|
+
if (!fs5.existsSync(migrationDirectory)) {
|
|
226767
|
+
fs5.mkdirSync(migrationDirectory, { recursive: true });
|
|
226768
|
+
}
|
|
226769
|
+
let sqlInstructions = [];
|
|
226770
|
+
diff.forEach((tableDiff) => {
|
|
226771
|
+
const tableName = tableDiff.tableName;
|
|
226772
|
+
const schema = tableDiff.schema;
|
|
226773
|
+
if (tableDiff.newTable) {
|
|
226774
|
+
const indexes = tableDiff.colDiffs.filter((colDiff) => colDiff.actionType === "INDEX");
|
|
226775
|
+
const creates = tableDiff.colDiffs.filter((colDiff) => colDiff.actionType === "CREATE");
|
|
226776
|
+
const fks = tableDiff.colDiffs.filter((colDiff) => colDiff.colChanges?.foreignKeys);
|
|
226777
|
+
sqlInstructions.push(this.orm.driverInstance.getCreateTableInstruction(schema, tableName, creates));
|
|
226778
|
+
indexes.forEach((colDiff) => {
|
|
226779
|
+
colDiff.indexTables = colDiff.indexTables?.filter((index) => index.name !== `${tableName}_pkey`);
|
|
226780
|
+
});
|
|
226781
|
+
fks.forEach((colDiff) => {
|
|
226782
|
+
colDiff.colChanges?.foreignKeys?.forEach((fk) => {
|
|
226783
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableFkInstruction(schema, tableName, colDiff, fk));
|
|
226784
|
+
});
|
|
226785
|
+
});
|
|
226786
|
+
sqlInstructions = sqlInstructions.map((sql) => sql.replace(/' '/g, ""));
|
|
226787
|
+
indexes.forEach((colDiff) => {
|
|
226788
|
+
if (colDiff.indexTables) {
|
|
226789
|
+
colDiff.indexTables.forEach((index) => {
|
|
226790
|
+
if (index.properties) {
|
|
226791
|
+
sqlInstructions.push(this.orm.driverInstance.getCreateIndex(index, schema, tableName));
|
|
226792
|
+
}
|
|
226793
|
+
});
|
|
226794
|
+
}
|
|
226795
|
+
});
|
|
226796
|
+
return;
|
|
226797
|
+
}
|
|
226798
|
+
const colChangesMap = new Map;
|
|
226799
|
+
tableDiff.colDiffs.reverse().forEach((colDiff) => {
|
|
226800
|
+
const colName = colDiff.colName;
|
|
226801
|
+
if (!colChangesMap.has(colName)) {
|
|
226802
|
+
colChangesMap.set(colName, []);
|
|
226803
|
+
}
|
|
226804
|
+
colChangesMap.get(colName)?.push(colDiff);
|
|
226805
|
+
});
|
|
226806
|
+
colChangesMap.forEach((colDiffs, colName) => {
|
|
226807
|
+
const colDiffInstructions = [];
|
|
226808
|
+
colDiffs.forEach((colDiff) => {
|
|
226809
|
+
switch (colDiff.actionType) {
|
|
226810
|
+
case "CREATE":
|
|
226811
|
+
this.orm.driverInstance.getAddColumn(schema, tableName, colName, colDiff, colDiffInstructions);
|
|
226812
|
+
break;
|
|
226813
|
+
case "DELETE":
|
|
226814
|
+
if (colDiff.colChanges?.enumItems && colDiff.colChanges?.enumItems.length === 0) {
|
|
226815
|
+
colDiffInstructions.push(this.orm.driverInstance.getDropTypeEnumInstruction({ name: `${schema}_${tableName}_${colName}_enum` }, schema, tableName));
|
|
226816
|
+
return;
|
|
226817
|
+
}
|
|
226818
|
+
this.orm.driverInstance.getDropColumn(colDiffInstructions, schema, tableName, colName);
|
|
226819
|
+
break;
|
|
226820
|
+
case "ALTER":
|
|
226821
|
+
this.applyColumnChanges(colDiff, colDiffInstructions, schema, tableName, colName);
|
|
226822
|
+
break;
|
|
226823
|
+
case "INDEX":
|
|
226824
|
+
if (colDiff.indexTables) {
|
|
226825
|
+
colDiff.indexTables.forEach((index) => {
|
|
226826
|
+
if (colDiffInstructions.find((instruction) => instruction.includes(index.name))) {
|
|
226827
|
+
return;
|
|
226828
|
+
}
|
|
226829
|
+
if (this.alreadyConstraint(sqlInstructions, index.name)) {
|
|
226830
|
+
return;
|
|
226831
|
+
}
|
|
226832
|
+
if (index.properties) {
|
|
226833
|
+
colDiffInstructions.push(this.orm.driverInstance.getCreateIndex(index, schema, tableName));
|
|
226834
|
+
} else {
|
|
226835
|
+
colDiffInstructions.push(this.orm.driverInstance.getDropIndex(index, schema, tableName));
|
|
226836
|
+
}
|
|
226837
|
+
});
|
|
226838
|
+
}
|
|
226839
|
+
break;
|
|
226840
|
+
}
|
|
226841
|
+
});
|
|
226842
|
+
if (colDiffInstructions.length > 0) {
|
|
226843
|
+
sqlInstructions.push(colDiffInstructions.join("\n"));
|
|
226844
|
+
}
|
|
226845
|
+
});
|
|
226846
|
+
});
|
|
226847
|
+
const migrationContent = sqlInstructions.join("\n");
|
|
226848
|
+
if (migrationContent.length === 0) {
|
|
226849
|
+
console.log("No changes detected");
|
|
226850
|
+
return;
|
|
226851
|
+
} else {
|
|
226852
|
+
fs5.writeFileSync(migrationFilePath, migrationContent);
|
|
226853
|
+
console.log(`Migration file created: ${migrationFilePath}`);
|
|
226854
|
+
}
|
|
226855
|
+
}
|
|
226856
|
+
async migrate() {
|
|
226857
|
+
const migrationTable = "cheetah_migrations";
|
|
226858
|
+
const migrationDirectory = path3.join(process.cwd(), this.config.migrationPath ?? "database/migrations");
|
|
226859
|
+
const migrationFiles = fs5.readdirSync(migrationDirectory).filter((file) => file.endsWith(".sql")).sort();
|
|
226860
|
+
if (migrationFiles.length === 0) {
|
|
226861
|
+
console.log("No migration files found");
|
|
226862
|
+
return;
|
|
226863
|
+
}
|
|
226864
|
+
this.orm.driverInstance.executeSql(`CREATE TABLE IF NOT EXISTS "${migrationTable}" ("migration_file" character varying(255) NOT NULL PRIMARY KEY UNIQUE);`);
|
|
226865
|
+
const migrated = await this.orm.driverInstance.executeSql(`SELECT * FROM "${migrationTable}" ORDER BY "migration_file" ASC;`);
|
|
226866
|
+
const lastMigration = migrated.rows[migrated.rows.length - 1];
|
|
226867
|
+
const lastMigrationIndex = migrationFiles.indexOf(lastMigration?.migration_file ?? "");
|
|
226868
|
+
const migrationsToExecute = migrationFiles.slice(lastMigrationIndex + 1);
|
|
226869
|
+
if (migrationsToExecute.length === 0) {
|
|
226870
|
+
console.log("Database is up to date");
|
|
226871
|
+
return;
|
|
226872
|
+
}
|
|
226873
|
+
for (const migrationFile of migrationsToExecute) {
|
|
226874
|
+
const migrationFilePath = path3.join(migrationDirectory, migrationFile);
|
|
226875
|
+
const migrationContent = fs5.readFileSync(migrationFilePath, { encoding: "utf-8" });
|
|
226876
|
+
const sqlInstructions = migrationContent.split(";").filter((sql) => sql.trim().length > 0);
|
|
226877
|
+
for (const sqlInstruction of sqlInstructions) {
|
|
226878
|
+
await this.orm.driverInstance.executeSql(sqlInstruction);
|
|
226879
|
+
}
|
|
226880
|
+
await this.orm.driverInstance.executeSql(`INSERT INTO "${migrationTable}" ("migration_file") VALUES ('${migrationFile}');`);
|
|
226881
|
+
console.log(`Migration executed: ${migrationFile}`);
|
|
226882
|
+
}
|
|
226883
|
+
}
|
|
226884
|
+
applyColumnChanges(colDiff, sqlInstructions, schema, tableName, colName) {
|
|
226885
|
+
if (colDiff.colType) {
|
|
226886
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableType(schema, tableName, colName, colDiff));
|
|
226887
|
+
}
|
|
226888
|
+
if (colDiff.colChanges?.enumItems) {
|
|
226889
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableEnumInstruction(schema, tableName, colName, colDiff));
|
|
226890
|
+
}
|
|
226891
|
+
if (colDiff.colChanges) {
|
|
226892
|
+
if (colDiff.colChanges.default !== undefined) {
|
|
226893
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableDefaultInstruction(schema, tableName, colName, colDiff));
|
|
226894
|
+
}
|
|
226895
|
+
if (colDiff.colChanges.primary !== undefined) {
|
|
226896
|
+
if (colDiff.colChanges.primary) {
|
|
226897
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTablePrimaryKeyInstruction(schema, tableName, colName, colDiff));
|
|
226898
|
+
} else {
|
|
226899
|
+
sqlInstructions.push(this.orm.driverInstance.getDropConstraint({ name: `${tableName}_pkey` }, schema, tableName));
|
|
226900
|
+
}
|
|
226901
|
+
}
|
|
226902
|
+
if (colDiff.colChanges.unique !== undefined && !this.alreadyConstraint(sqlInstructions, `${tableName}_${colName}_key`)) {
|
|
226903
|
+
if (colDiff.colChanges.unique) {
|
|
226904
|
+
sqlInstructions.push(this.orm.driverInstance.getAddUniqueConstraint(schema, tableName, colName));
|
|
226905
|
+
} else {
|
|
226906
|
+
}
|
|
226907
|
+
}
|
|
226908
|
+
if (colDiff.colChanges.nullable !== undefined) {
|
|
226909
|
+
if (colDiff.colChanges.nullable) {
|
|
226910
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableDropNullInstruction(schema, tableName, colName, colDiff));
|
|
226911
|
+
} else {
|
|
226912
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableDropNotNullInstruction(schema, tableName, colName, colDiff));
|
|
226913
|
+
}
|
|
226914
|
+
}
|
|
226915
|
+
if (colDiff.colChanges.foreignKeys !== undefined) {
|
|
226916
|
+
if (colDiff.colChanges.foreignKeys.length === 0) {
|
|
226917
|
+
sqlInstructions.push(this.orm.driverInstance.getDropConstraint({ name: `${tableName}_${colName}_fk` }, schema, tableName));
|
|
226918
|
+
}
|
|
226919
|
+
colDiff.colChanges.foreignKeys.forEach((fk) => {
|
|
226920
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableFkInstruction(schema, tableName, colDiff, fk));
|
|
226921
|
+
});
|
|
226922
|
+
}
|
|
226923
|
+
}
|
|
226924
|
+
}
|
|
226925
|
+
alreadyConstraint(sqlInstructions, s) {
|
|
226926
|
+
return sqlInstructions.some((sql) => sql.includes(`"${s}"`));
|
|
226927
|
+
}
|
|
226928
|
+
}
|
|
226929
|
+
// ../../node_modules/balanc
|
|
226930
|
+
import * as path4 from "path";
|
|
226931
|
+
import * as fs6 from "fs";
|
|
226932
|
+
|
|
226933
|
+
// ../../node_modules/balanced-matc
|
|
226934
|
+
class DiffCalculator2 {
|
|
226935
|
+
entities;
|
|
226936
|
+
constructor(entities10) {
|
|
226937
|
+
this.entities = entities10;
|
|
226938
|
+
}
|
|
226939
|
+
diff(snapshotBd, snapshotEntities) {
|
|
226940
|
+
let diffs = [];
|
|
226941
|
+
const bdTablesMap = new Map(snapshotBd.map((table) => [table.tableName, table]));
|
|
226942
|
+
const entityTablesMap = new Map(snapshotEntities.map((table) => [table.tableName, table]));
|
|
226943
|
+
const allTableNames = new Set([...bdTablesMap.keys(), ...entityTablesMap.keys()]);
|
|
226944
|
+
allTableNames.forEach((tableName) => {
|
|
226945
|
+
const bdTable = bdTablesMap.get(tableName);
|
|
226946
|
+
const entityTable = entityTablesMap.get(tableName);
|
|
226947
|
+
if (!entityTable) {
|
|
226948
|
+
diffs.push({
|
|
226949
|
+
tableName,
|
|
226950
|
+
colDiffs: [{ actionType: "DELETE", colName: "*" }]
|
|
226951
|
+
});
|
|
226952
|
+
} else if (!bdTable) {
|
|
226953
|
+
const colDiffs = entityTable.columns.flatMap((c) => {
|
|
226954
|
+
return this.createNewColumn(c, []);
|
|
226955
|
+
});
|
|
226956
|
+
diffs.push({
|
|
226957
|
+
tableName,
|
|
226958
|
+
newTable: true,
|
|
226959
|
+
schema: entityTable.schema ?? "public",
|
|
226960
|
+
colDiffs
|
|
226961
|
+
});
|
|
226962
|
+
this.checkIndexes(bdTable, entityTable, colDiffs);
|
|
226963
|
+
} else {
|
|
226964
|
+
const colDiffs = [];
|
|
226965
|
+
const bdColumnsMap = new Map(bdTable.columns.map((col) => [col.name, col]));
|
|
226966
|
+
const entityColumnsMap = new Map(entityTable.columns.map((col) => [col.name, col]));
|
|
226967
|
+
const allColumnNames = new Set([...bdColumnsMap.keys(), ...entityColumnsMap.keys()]);
|
|
226968
|
+
allColumnNames.forEach((colName) => {
|
|
226969
|
+
const bdCol = bdColumnsMap.get(colName);
|
|
226970
|
+
const entityCol = entityColumnsMap.get(colName);
|
|
226971
|
+
if (!entityCol) {
|
|
226972
|
+
colDiffs.push({
|
|
226973
|
+
actionType: "DELETE",
|
|
226974
|
+
colName: bdCol.name
|
|
226975
|
+
});
|
|
226976
|
+
} else if (!bdCol) {
|
|
226977
|
+
this.createNewColumn(entityCol, colDiffs);
|
|
226978
|
+
} else
|
|
226979
|
+
this.diffColumnSql(bdCol, entityCol, colDiffs);
|
|
226980
|
+
});
|
|
226981
|
+
if (colDiffs.length > 0) {
|
|
226982
|
+
diffs.push({
|
|
226983
|
+
tableName,
|
|
226984
|
+
schema: entityTable.schema ?? "public",
|
|
226985
|
+
colDiffs
|
|
226986
|
+
});
|
|
226987
|
+
}
|
|
226988
|
+
this.checkIndexes(bdTable, entityTable, colDiffs);
|
|
226989
|
+
}
|
|
226990
|
+
});
|
|
226991
|
+
return diffs;
|
|
226992
|
+
}
|
|
226993
|
+
checkIndexes(bdTable, entityTable, colDiffs) {
|
|
226994
|
+
if (bdTable && bdTable.indexes || entityTable && entityTable.indexes) {
|
|
226995
|
+
if (!bdTable || !bdTable.indexes) {
|
|
226996
|
+
colDiffs.push({
|
|
226997
|
+
actionType: "INDEX",
|
|
226998
|
+
colName: "*",
|
|
226999
|
+
indexTables: entityTable.indexes.map((index) => ({
|
|
227000
|
+
name: index.indexName,
|
|
227001
|
+
properties: index.columnName.split(",")
|
|
227002
|
+
}))
|
|
227003
|
+
});
|
|
227004
|
+
}
|
|
227005
|
+
if (!entityTable || !entityTable.indexes) {
|
|
227006
|
+
colDiffs.push({
|
|
227007
|
+
actionType: "INDEX",
|
|
227008
|
+
colName: "*",
|
|
227009
|
+
indexTables: bdTable.indexes.map((index) => ({ name: index.indexName }))
|
|
227010
|
+
});
|
|
227011
|
+
}
|
|
227012
|
+
}
|
|
227013
|
+
if (bdTable && bdTable.indexes && (entityTable && entityTable.indexes)) {
|
|
227014
|
+
const bdIndexesMap = new Map(bdTable.indexes.map((index) => [index.indexName, index]));
|
|
227015
|
+
const entityIndexesMap = new Map(entityTable.indexes.map((index) => [index.indexName, index]));
|
|
227016
|
+
const allIndexes = new Set([...bdIndexesMap.keys(), ...entityIndexesMap.keys()]);
|
|
227017
|
+
allIndexes.forEach((indexName) => {
|
|
227018
|
+
const bdIndex = bdIndexesMap.get(indexName);
|
|
227019
|
+
const entityIndex = entityIndexesMap.get(indexName);
|
|
227020
|
+
if (!entityIndex) {
|
|
227021
|
+
colDiffs.push({
|
|
227022
|
+
actionType: "INDEX",
|
|
227023
|
+
colName: bdIndex.columnName,
|
|
227024
|
+
indexTables: [{ name: indexName }]
|
|
227025
|
+
});
|
|
227026
|
+
} else if (!bdIndex) {
|
|
227027
|
+
colDiffs.push({
|
|
227028
|
+
actionType: "INDEX",
|
|
227029
|
+
colName: entityIndex.columnName,
|
|
227030
|
+
indexTables: [{ name: indexName, properties: entityIndex.columnName.split(",") }]
|
|
227031
|
+
});
|
|
227032
|
+
}
|
|
227033
|
+
});
|
|
227034
|
+
}
|
|
227035
|
+
}
|
|
227036
|
+
createNewColumn(entityCol, colDiffs) {
|
|
227037
|
+
const colType = this.convertEntityTypeToSqlType(entityCol.type);
|
|
227038
|
+
colDiffs.push({
|
|
227039
|
+
actionType: "CREATE",
|
|
227040
|
+
colName: entityCol.name,
|
|
227041
|
+
colType: colType.type,
|
|
227042
|
+
colLength: entityCol.length ?? colType.len,
|
|
227043
|
+
colChanges: {
|
|
227044
|
+
autoIncrement: entityCol.autoIncrement,
|
|
227045
|
+
default: entityCol.default,
|
|
227046
|
+
primary: entityCol.primary,
|
|
227047
|
+
unique: entityCol.unique,
|
|
227048
|
+
nullable: entityCol.nullable,
|
|
227049
|
+
enumItems: entityCol.enumItems,
|
|
227050
|
+
foreignKeys: entityCol.foreignKeys ?? []
|
|
227051
|
+
}
|
|
227052
|
+
});
|
|
227053
|
+
return colDiffs;
|
|
227054
|
+
}
|
|
227055
|
+
diffColumnType(bdCol, entityCol, colDiffs) {
|
|
227056
|
+
if (bdCol.type === "integer" && bdCol.primary) {
|
|
227057
|
+
bdCol.type = "numeric";
|
|
227058
|
+
bdCol.length = 11;
|
|
227059
|
+
}
|
|
227060
|
+
const colT = entityCol.isEnum ? { type: "USER-DEFINED", len: null } : this.convertEntityTypeToSqlType(entityCol.type);
|
|
227061
|
+
const colType = colT.type;
|
|
227062
|
+
const length = entityCol.length ?? colT.len;
|
|
227063
|
+
if (bdCol.type !== colType || bdCol.length !== length) {
|
|
227064
|
+
if (colType === "USER-DEFINED") {
|
|
227065
|
+
colDiffs.push({
|
|
227066
|
+
actionType: "DELETE",
|
|
227067
|
+
colName: entityCol.name
|
|
227068
|
+
});
|
|
227069
|
+
return;
|
|
227070
|
+
}
|
|
227071
|
+
colDiffs.push({
|
|
227072
|
+
actionType: "ALTER",
|
|
227073
|
+
colName: entityCol.name,
|
|
227074
|
+
colType,
|
|
227075
|
+
colLength: length
|
|
227076
|
+
});
|
|
227077
|
+
}
|
|
227078
|
+
}
|
|
227079
|
+
diffColumnDefault(bdCol, entityCol, colDiffs) {
|
|
227080
|
+
if (bdCol.default !== entityCol.default) {
|
|
227081
|
+
colDiffs.push({
|
|
227082
|
+
actionType: "ALTER",
|
|
227083
|
+
colName: entityCol.name,
|
|
227084
|
+
colChanges: { default: entityCol.default },
|
|
227085
|
+
colLength: entityCol.length
|
|
227086
|
+
});
|
|
227087
|
+
}
|
|
227088
|
+
}
|
|
227089
|
+
diffColumnPrimary(bdCol, entityCol, colDiffs) {
|
|
227090
|
+
if (bdCol.primary !== entityCol.primary) {
|
|
227091
|
+
colDiffs.push({
|
|
227092
|
+
actionType: "ALTER",
|
|
227093
|
+
colName: entityCol.name,
|
|
227094
|
+
colChanges: { primary: entityCol.primary },
|
|
227095
|
+
colLength: entityCol.length
|
|
227096
|
+
});
|
|
227097
|
+
}
|
|
227098
|
+
}
|
|
227099
|
+
diffColumnUnique(bdCol, entityCol, colDiffs) {
|
|
227100
|
+
if (bdCol.unique !== entityCol.unique) {
|
|
227101
|
+
if (bdCol.unique === false && entityCol.unique === undefined) {
|
|
227102
|
+
return;
|
|
227103
|
+
}
|
|
227104
|
+
colDiffs.push({
|
|
227105
|
+
actionType: "ALTER",
|
|
227106
|
+
colName: entityCol.name,
|
|
227107
|
+
colChanges: { unique: entityCol.unique || false },
|
|
227108
|
+
colLength: entityCol.length
|
|
227109
|
+
});
|
|
227110
|
+
}
|
|
227111
|
+
}
|
|
227112
|
+
diffForeignKey(bdCol, entityCol, colDiffs) {
|
|
227113
|
+
if (bdCol.foreignKeys || entityCol.foreignKeys) {
|
|
227114
|
+
const bdFKMap = new Map((bdCol.foreignKeys || []).map((fk) => [`${fk.referencedTableName}.${fk.referencedColumnName}`, fk]));
|
|
227115
|
+
const entityFKMap = new Map((entityCol.foreignKeys || []).map((fk) => [`${fk.referencedTableName}.${fk.referencedColumnName}`, fk]));
|
|
227116
|
+
const allFKs = new Set([...bdFKMap.keys(), ...entityFKMap.keys()]);
|
|
227117
|
+
allFKs.forEach((fkName) => {
|
|
227118
|
+
const bdFK = bdFKMap.get(fkName);
|
|
227119
|
+
const entityFK = entityFKMap.get(fkName);
|
|
227120
|
+
if (!entityFK) {
|
|
227121
|
+
colDiffs.push({
|
|
227122
|
+
actionType: "ALTER",
|
|
227123
|
+
colName: bdCol.name,
|
|
227124
|
+
colChanges: {
|
|
227125
|
+
foreignKeys: bdCol.foreignKeys?.filter((fk) => fk !== bdFK)
|
|
227126
|
+
}
|
|
227127
|
+
});
|
|
227128
|
+
}
|
|
227129
|
+
});
|
|
227130
|
+
}
|
|
227131
|
+
}
|
|
227132
|
+
diffColumnSql(bdCol, entityCol, colDiffs) {
|
|
227133
|
+
this.diffForeignKey(bdCol, entityCol, colDiffs);
|
|
227134
|
+
this.diffEnum(bdCol, entityCol, colDiffs);
|
|
227135
|
+
this.diffColumnType(bdCol, entityCol, colDiffs);
|
|
227136
|
+
this.diffColumnDefault(bdCol, entityCol, colDiffs);
|
|
227137
|
+
this.diffColumnPrimary(bdCol, entityCol, colDiffs);
|
|
227138
|
+
this.diffColumnUnique(bdCol, entityCol, colDiffs);
|
|
227139
|
+
this.diffColumnNullable(bdCol, entityCol, colDiffs);
|
|
227140
|
+
return colDiffs;
|
|
227141
|
+
}
|
|
227142
|
+
diffColumnNullable(bdCol, entityCol, colDiffs) {
|
|
227143
|
+
if (bdCol.nullable !== entityCol.nullable) {
|
|
227144
|
+
colDiffs.push({
|
|
227145
|
+
actionType: "ALTER",
|
|
227146
|
+
colName: entityCol.name,
|
|
227147
|
+
colChanges: { nullable: entityCol.nullable },
|
|
227148
|
+
colLength: entityCol.length
|
|
227149
|
+
});
|
|
227150
|
+
}
|
|
227151
|
+
}
|
|
227152
|
+
convertEntityTypeToSqlType(entityType) {
|
|
227153
|
+
switch (entityType) {
|
|
227154
|
+
case "Number":
|
|
227155
|
+
case "int":
|
|
227156
|
+
return { type: "numeric", len: 11 };
|
|
227157
|
+
case "bigint":
|
|
227158
|
+
return { type: "bigint" };
|
|
227159
|
+
case "float":
|
|
227160
|
+
return { type: "float4" };
|
|
227161
|
+
case "double":
|
|
227162
|
+
return { type: "float8" };
|
|
227163
|
+
case "decimal":
|
|
227164
|
+
return { type: "decimal" };
|
|
227165
|
+
case "String":
|
|
227166
|
+
case "varchar":
|
|
227167
|
+
return { type: "character varying", len: 255 };
|
|
227168
|
+
case "Boolean":
|
|
227169
|
+
return { type: "boolean" };
|
|
227170
|
+
case "Date":
|
|
227171
|
+
return { type: "timestamp" };
|
|
227172
|
+
case "Object":
|
|
227173
|
+
return { type: "json" };
|
|
227174
|
+
case "uuid":
|
|
227175
|
+
return { type: "uuid" };
|
|
227176
|
+
case "text":
|
|
227177
|
+
return { type: "text" };
|
|
227178
|
+
default:
|
|
227179
|
+
return { type: "character varying", len: 255 };
|
|
227180
|
+
}
|
|
227181
|
+
}
|
|
227182
|
+
diffEnum(bdCol, entityCol, colDiffs) {
|
|
227183
|
+
if (bdCol.enumItems || entityCol.enumItems) {
|
|
227184
|
+
if (bdCol.enumItems && entityCol.enumItems) {
|
|
227185
|
+
const allEnums = new Set([...bdCol.enumItems, ...entityCol.enumItems]);
|
|
227186
|
+
const differences = [...allEnums].filter((x) => !bdCol.enumItems?.includes(x) || !entityCol.enumItems?.includes(x));
|
|
227187
|
+
if (differences.length === 0) {
|
|
227188
|
+
return;
|
|
227189
|
+
}
|
|
227190
|
+
colDiffs.push({
|
|
227191
|
+
actionType: "ALTER",
|
|
227192
|
+
colName: entityCol.name,
|
|
227193
|
+
colChanges: {
|
|
227194
|
+
enumItems: entityCol.enumItems
|
|
227195
|
+
}
|
|
227196
|
+
});
|
|
227197
|
+
}
|
|
227198
|
+
if (!entityCol.enumItems) {
|
|
227199
|
+
colDiffs.push({
|
|
227200
|
+
actionType: "DELETE",
|
|
227201
|
+
colName: bdCol.name,
|
|
227202
|
+
colChanges: {
|
|
227203
|
+
enumItems: []
|
|
227204
|
+
}
|
|
227205
|
+
});
|
|
227206
|
+
} else if (!bdCol.enumItems) {
|
|
227207
|
+
colDiffs.push({
|
|
227208
|
+
actionType: "CREATE",
|
|
227209
|
+
colName: entityCol.name,
|
|
227210
|
+
colChanges: {
|
|
227211
|
+
enumItems: entityCol.enumItems
|
|
227212
|
+
}
|
|
227213
|
+
});
|
|
227214
|
+
}
|
|
227215
|
+
}
|
|
227216
|
+
}
|
|
227217
|
+
}
|
|
227218
|
+
|
|
227219
|
+
// ../../node_modules/balanc
|
|
227220
|
+
class Migrator2 {
|
|
227221
|
+
config;
|
|
227222
|
+
orm;
|
|
227223
|
+
entities = new EntityStorage;
|
|
227224
|
+
constructor() {
|
|
227225
|
+
this.orm = Orm2.getInstance();
|
|
227226
|
+
if (this.orm === undefined)
|
|
227227
|
+
this.orm = new Orm2(new LoggerService(new InjectorService));
|
|
227228
|
+
this.entities = EntityStorage.getInstance();
|
|
227229
|
+
if (this.entities === undefined)
|
|
227230
|
+
this.entities = new EntityStorage;
|
|
227231
|
+
}
|
|
227232
|
+
async initConfigFile(basePath = process.cwd()) {
|
|
227233
|
+
const paths = await globby2(["cheetah.config.ts"], { absolute: true, cwd: basePath });
|
|
227234
|
+
if (paths.length === 0) {
|
|
227235
|
+
throw new Error("Config file not found");
|
|
227236
|
+
}
|
|
227237
|
+
const config = await import(paths[0]);
|
|
227238
|
+
this.config = config.default;
|
|
227239
|
+
if (typeof this.config.entities === "string") {
|
|
227240
|
+
const paths2 = await globby2(this.config.entities, { absolute: true, cwd: basePath });
|
|
227241
|
+
for (const path5 of paths2) {
|
|
227242
|
+
await import(path5);
|
|
227243
|
+
}
|
|
227244
|
+
}
|
|
227245
|
+
const serv = new OrmService2(this.orm, this.entities);
|
|
227246
|
+
await serv.onInit(this.config);
|
|
227247
|
+
}
|
|
227248
|
+
async initMigration() {
|
|
227249
|
+
const snapshotBd = await this.snapshotBd();
|
|
227250
|
+
const snapshotEntities = await this.snapshotEntities();
|
|
227251
|
+
const calculator = new DiffCalculator2(this.entities);
|
|
227252
|
+
return calculator.diff(snapshotBd, snapshotEntities);
|
|
227253
|
+
}
|
|
227254
|
+
async snapshotBd() {
|
|
227255
|
+
const snapshot = [];
|
|
227256
|
+
for (let [_, values] of this.entities.entries()) {
|
|
227257
|
+
const bd = await this.orm.driverInstance.snapshot(values.tableName);
|
|
227258
|
+
if (!bd) {
|
|
227259
|
+
continue;
|
|
227260
|
+
}
|
|
227261
|
+
snapshot.push(bd);
|
|
227262
|
+
}
|
|
227263
|
+
return snapshot;
|
|
227264
|
+
}
|
|
227265
|
+
async snapshotEntities() {
|
|
227266
|
+
const snapshot = [];
|
|
227267
|
+
for (let [_, values] of this.entities.entries()) {
|
|
227268
|
+
snapshot.push(await this.entities.snapshot(values));
|
|
227269
|
+
}
|
|
227270
|
+
return snapshot;
|
|
227271
|
+
}
|
|
227272
|
+
async createMigration(forceName = null) {
|
|
227273
|
+
const diff = await this.initMigration();
|
|
227274
|
+
const migrationDirectory = path4.join(process.cwd(), this.config.migrationPath ?? "database/migrations");
|
|
227275
|
+
const migrationFileName = (forceName ?? `migration_${new Date().toISOString().replace(/[^\d]/g, "")}`) + `.sql`;
|
|
227276
|
+
const migrationFilePath = path4.join(migrationDirectory, migrationFileName);
|
|
227277
|
+
if (!fs6.existsSync(migrationDirectory)) {
|
|
227278
|
+
fs6.mkdirSync(migrationDirectory, { recursive: true });
|
|
227279
|
+
}
|
|
227280
|
+
let sqlInstructions = [];
|
|
227281
|
+
diff.forEach((tableDiff) => {
|
|
227282
|
+
const tableName = tableDiff.tableName;
|
|
227283
|
+
const schema = tableDiff.schema;
|
|
227284
|
+
if (tableDiff.newTable) {
|
|
227285
|
+
const indexes = tableDiff.colDiffs.filter((colDiff) => colDiff.actionType === "INDEX");
|
|
227286
|
+
const creates = tableDiff.colDiffs.filter((colDiff) => colDiff.actionType === "CREATE");
|
|
227287
|
+
const fks = tableDiff.colDiffs.filter((colDiff) => colDiff.colChanges?.foreignKeys);
|
|
227288
|
+
sqlInstructions.push(this.orm.driverInstance.getCreateTableInstruction(schema, tableName, creates));
|
|
227289
|
+
indexes.forEach((colDiff) => {
|
|
227290
|
+
colDiff.indexTables = colDiff.indexTables?.filter((index) => index.name !== `${tableName}_pkey`);
|
|
227291
|
+
});
|
|
227292
|
+
fks.forEach((colDiff) => {
|
|
227293
|
+
colDiff.colChanges?.foreignKeys?.forEach((fk) => {
|
|
227294
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableFkInstruction(schema, tableName, colDiff, fk));
|
|
227295
|
+
});
|
|
227296
|
+
});
|
|
227297
|
+
sqlInstructions = sqlInstructions.map((sql) => sql.replace(/' '/g, ""));
|
|
227298
|
+
indexes.forEach((colDiff) => {
|
|
227299
|
+
if (colDiff.indexTables) {
|
|
227300
|
+
colDiff.indexTables.forEach((index) => {
|
|
227301
|
+
if (index.properties) {
|
|
227302
|
+
sqlInstructions.push(this.orm.driverInstance.getCreateIndex(index, schema, tableName));
|
|
227303
|
+
}
|
|
227304
|
+
});
|
|
227305
|
+
}
|
|
227306
|
+
});
|
|
227307
|
+
return;
|
|
227308
|
+
}
|
|
227309
|
+
const colChangesMap = new Map;
|
|
227310
|
+
tableDiff.colDiffs.reverse().forEach((colDiff) => {
|
|
227311
|
+
const colName = colDiff.colName;
|
|
227312
|
+
if (!colChangesMap.has(colName)) {
|
|
227313
|
+
colChangesMap.set(colName, []);
|
|
227314
|
+
}
|
|
227315
|
+
colChangesMap.get(colName)?.push(colDiff);
|
|
227316
|
+
});
|
|
227317
|
+
colChangesMap.forEach((colDiffs, colName) => {
|
|
227318
|
+
const colDiffInstructions = [];
|
|
227319
|
+
colDiffs.forEach((colDiff) => {
|
|
227320
|
+
switch (colDiff.actionType) {
|
|
227321
|
+
case "CREATE":
|
|
227322
|
+
this.orm.driverInstance.getAddColumn(schema, tableName, colName, colDiff, colDiffInstructions);
|
|
227323
|
+
break;
|
|
227324
|
+
case "DELETE":
|
|
227325
|
+
if (colDiff.colChanges?.enumItems && colDiff.colChanges?.enumItems.length === 0) {
|
|
227326
|
+
colDiffInstructions.push(this.orm.driverInstance.getDropTypeEnumInstruction({ name: `${schema}_${tableName}_${colName}_enum` }, schema, tableName));
|
|
227327
|
+
return;
|
|
227328
|
+
}
|
|
227329
|
+
this.orm.driverInstance.getDropColumn(colDiffInstructions, schema, tableName, colName);
|
|
227330
|
+
break;
|
|
227331
|
+
case "ALTER":
|
|
227332
|
+
this.applyColumnChanges(colDiff, colDiffInstructions, schema, tableName, colName);
|
|
227333
|
+
break;
|
|
227334
|
+
case "INDEX":
|
|
227335
|
+
if (colDiff.indexTables) {
|
|
227336
|
+
colDiff.indexTables.forEach((index) => {
|
|
227337
|
+
if (colDiffInstructions.find((instruction) => instruction.includes(index.name))) {
|
|
227338
|
+
return;
|
|
227339
|
+
}
|
|
227340
|
+
if (this.alreadyConstraint(sqlInstructions, index.name)) {
|
|
227341
|
+
return;
|
|
227342
|
+
}
|
|
227343
|
+
if (index.properties) {
|
|
227344
|
+
colDiffInstructions.push(this.orm.driverInstance.getCreateIndex(index, schema, tableName));
|
|
227345
|
+
} else {
|
|
227346
|
+
colDiffInstructions.push(this.orm.driverInstance.getDropIndex(index, schema, tableName));
|
|
227347
|
+
}
|
|
227348
|
+
});
|
|
227349
|
+
}
|
|
227350
|
+
break;
|
|
227351
|
+
}
|
|
227352
|
+
});
|
|
227353
|
+
if (colDiffInstructions.length > 0) {
|
|
227354
|
+
sqlInstructions.push(colDiffInstructions.join("\n"));
|
|
227355
|
+
}
|
|
227356
|
+
});
|
|
227357
|
+
});
|
|
227358
|
+
const migrationContent = sqlInstructions.join("\n");
|
|
227359
|
+
if (migrationContent.length === 0) {
|
|
227360
|
+
console.log("No changes detected");
|
|
227361
|
+
return;
|
|
227362
|
+
} else {
|
|
227363
|
+
fs6.writeFileSync(migrationFilePath, migrationContent);
|
|
227364
|
+
console.log(`Migration file created: ${migrationFilePath}`);
|
|
227365
|
+
}
|
|
227366
|
+
}
|
|
227367
|
+
async migrate() {
|
|
227368
|
+
const migrationTable = "cheetah_migrations";
|
|
227369
|
+
const migrationDirectory = path4.join(process.cwd(), this.config.migrationPath ?? "database/migrations");
|
|
227370
|
+
const migrationFiles = fs6.readdirSync(migrationDirectory).filter((file) => file.endsWith(".sql")).sort();
|
|
227371
|
+
if (migrationFiles.length === 0) {
|
|
227372
|
+
console.log("No migration files found");
|
|
227373
|
+
return;
|
|
227374
|
+
}
|
|
227375
|
+
this.orm.driverInstance.executeSql(`CREATE TABLE IF NOT EXISTS "${migrationTable}" ("migration_file" character varying(255) NOT NULL PRIMARY KEY UNIQUE);`);
|
|
227376
|
+
const migrated = await this.orm.driverInstance.executeSql(`SELECT * FROM "${migrationTable}" ORDER BY "migration_file" ASC;`);
|
|
227377
|
+
const lastMigration = migrated.rows[migrated.rows.length - 1];
|
|
227378
|
+
const lastMigrationIndex = migrationFiles.indexOf(lastMigration?.migration_file ?? "");
|
|
227379
|
+
const migrationsToExecute = migrationFiles.slice(lastMigrationIndex + 1);
|
|
227380
|
+
if (migrationsToExecute.length === 0) {
|
|
227381
|
+
console.log("Database is up to date");
|
|
227382
|
+
return;
|
|
227383
|
+
}
|
|
227384
|
+
for (const migrationFile of migrationsToExecute) {
|
|
227385
|
+
const migrationFilePath = path4.join(migrationDirectory, migrationFile);
|
|
227386
|
+
const migrationContent = fs6.readFileSync(migrationFilePath, { encoding: "utf-8" });
|
|
227387
|
+
const sqlInstructions = migrationContent.split(";").filter((sql) => sql.trim().length > 0);
|
|
227388
|
+
for (const sqlInstruction of sqlInstructions) {
|
|
227389
|
+
await this.orm.driverInstance.executeSql(sqlInstruction);
|
|
227390
|
+
}
|
|
227391
|
+
await this.orm.driverInstance.executeSql(`INSERT INTO "${migrationTable}" ("migration_file") VALUES ('${migrationFile}');`);
|
|
227392
|
+
console.log(`Migration executed: ${migrationFile}`);
|
|
227393
|
+
}
|
|
227394
|
+
}
|
|
227395
|
+
applyColumnChanges(colDiff, sqlInstructions, schema, tableName, colName) {
|
|
227396
|
+
if (colDiff.colType) {
|
|
227397
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableType(schema, tableName, colName, colDiff));
|
|
227398
|
+
}
|
|
227399
|
+
if (colDiff.colChanges?.enumItems) {
|
|
227400
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableEnumInstruction(schema, tableName, colName, colDiff));
|
|
227401
|
+
}
|
|
227402
|
+
if (colDiff.colChanges) {
|
|
227403
|
+
if (colDiff.colChanges.default !== undefined) {
|
|
227404
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableDefaultInstruction(schema, tableName, colName, colDiff));
|
|
227405
|
+
}
|
|
227406
|
+
if (colDiff.colChanges.primary !== undefined) {
|
|
227407
|
+
if (colDiff.colChanges.primary) {
|
|
227408
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTablePrimaryKeyInstruction(schema, tableName, colName, colDiff));
|
|
227409
|
+
} else {
|
|
227410
|
+
sqlInstructions.push(this.orm.driverInstance.getDropConstraint({ name: `${tableName}_pkey` }, schema, tableName));
|
|
227411
|
+
}
|
|
227412
|
+
}
|
|
227413
|
+
if (colDiff.colChanges.unique !== undefined && !this.alreadyConstraint(sqlInstructions, `${tableName}_${colName}_key`)) {
|
|
227414
|
+
if (colDiff.colChanges.unique) {
|
|
227415
|
+
sqlInstructions.push(this.orm.driverInstance.getAddUniqueConstraint(schema, tableName, colName));
|
|
227416
|
+
} else {
|
|
227417
|
+
}
|
|
227418
|
+
}
|
|
227419
|
+
if (colDiff.colChanges.nullable !== undefined) {
|
|
227420
|
+
if (colDiff.colChanges.nullable) {
|
|
227421
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableDropNullInstruction(schema, tableName, colName, colDiff));
|
|
227422
|
+
} else {
|
|
227423
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableDropNotNullInstruction(schema, tableName, colName, colDiff));
|
|
227424
|
+
}
|
|
227425
|
+
}
|
|
227426
|
+
if (colDiff.colChanges.foreignKeys !== undefined) {
|
|
227427
|
+
if (colDiff.colChanges.foreignKeys.length === 0) {
|
|
227428
|
+
sqlInstructions.push(this.orm.driverInstance.getDropConstraint({ name: `${tableName}_${colName}_fk` }, schema, tableName));
|
|
227429
|
+
}
|
|
227430
|
+
colDiff.colChanges.foreignKeys.forEach((fk) => {
|
|
227431
|
+
sqlInstructions.push(this.orm.driverInstance.getAlterTableFkInstruction(schema, tableName, colDiff, fk));
|
|
227432
|
+
});
|
|
227433
|
+
}
|
|
227434
|
+
}
|
|
227435
|
+
}
|
|
227436
|
+
alreadyConstraint(sqlInstructions, s) {
|
|
227437
|
+
return sqlInstructions.some((sql) => sql.includes(`"${s}"`));
|
|
227438
|
+
}
|
|
227439
|
+
}
|
|
225245
227440
|
export {
|
|
225246
227441
|
getDefaultLength,
|
|
225247
227442
|
ValueObject,
|
|
@@ -225252,6 +227447,7 @@ export {
|
|
|
225252
227447
|
OrmService,
|
|
225253
227448
|
Orm,
|
|
225254
227449
|
OneToMany,
|
|
227450
|
+
Migrator2 as Migrator,
|
|
225255
227451
|
ManyToOne,
|
|
225256
227452
|
Index,
|
|
225257
227453
|
Entity,
|
|
@@ -225264,4 +227460,4 @@ export {
|
|
|
225264
227460
|
AfterCreate
|
|
225265
227461
|
};
|
|
225266
227462
|
|
|
225267
|
-
//# debugId=
|
|
227463
|
+
//# debugId=618FC71B2274874064756e2164756e21
|