@dbcube/schema-builder 1.0.17 → 1.0.19
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/index.cjs +372 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +46 -1
- package/dist/index.d.ts +46 -1
- package/dist/index.js +371 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
CubeValidator: () => CubeValidator,
|
|
34
|
+
DependencyResolver: () => DependencyResolver,
|
|
34
35
|
Schema: () => Schema,
|
|
35
36
|
UIUtils: () => UIUtils,
|
|
36
37
|
default: () => index_default
|
|
@@ -38,9 +39,9 @@ __export(index_exports, {
|
|
|
38
39
|
module.exports = __toCommonJS(index_exports);
|
|
39
40
|
|
|
40
41
|
// src/lib/Schema.ts
|
|
41
|
-
var
|
|
42
|
+
var import_fs4 = __toESM(require("fs"));
|
|
42
43
|
var import_core = require("@dbcube/core");
|
|
43
|
-
var
|
|
44
|
+
var import_path3 = __toESM(require("path"));
|
|
44
45
|
|
|
45
46
|
// src/lib/FileUtils.ts
|
|
46
47
|
var fs = __toESM(require("fs"));
|
|
@@ -405,7 +406,7 @@ var CubeValidator = class {
|
|
|
405
406
|
filePath,
|
|
406
407
|
lineNumber
|
|
407
408
|
});
|
|
408
|
-
} else if (!this.isOptionCompatibleWithType(option, columnType)) {
|
|
409
|
+
} else if (columnType !== "unknown" && !this.isOptionCompatibleWithType(option, columnType)) {
|
|
409
410
|
errors.push({
|
|
410
411
|
itemName: fileName,
|
|
411
412
|
error: `Option '${option}' is not compatible with type '${columnType}'`,
|
|
@@ -424,6 +425,18 @@ var CubeValidator = class {
|
|
|
424
425
|
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
425
426
|
return;
|
|
426
427
|
}
|
|
428
|
+
if (this.isInsideForeignKeyObject(content, lineNumber - 1)) {
|
|
429
|
+
const validForeignKeyProperties = ["table", "column"];
|
|
430
|
+
if (!validForeignKeyProperties.includes(propertyName)) {
|
|
431
|
+
errors.push({
|
|
432
|
+
itemName: fileName,
|
|
433
|
+
error: `Invalid foreign key property '${propertyName}'. Valid foreign key properties: ${validForeignKeyProperties.join(", ")}`,
|
|
434
|
+
filePath,
|
|
435
|
+
lineNumber
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
427
440
|
if (this.isInsideColumnsBlock(content, lineNumber - 1)) {
|
|
428
441
|
if (!this.validProperties.includes(propertyName)) {
|
|
429
442
|
errors.push({
|
|
@@ -592,6 +605,227 @@ var CubeValidator = class {
|
|
|
592
605
|
}
|
|
593
606
|
return columnsStartLine !== -1 && columnsEndLine !== -1 && lineIndex > columnsStartLine && lineIndex < columnsEndLine;
|
|
594
607
|
}
|
|
608
|
+
isInsideForeignKeyObject(content, lineIndex) {
|
|
609
|
+
const lines = content.split("\n");
|
|
610
|
+
for (let i = lineIndex; i >= 0; i--) {
|
|
611
|
+
const line = lines[i];
|
|
612
|
+
if (/foreign\s*:\s*\{/.test(line)) {
|
|
613
|
+
let braceCount = 0;
|
|
614
|
+
for (let j = i; j <= lineIndex; j++) {
|
|
615
|
+
const currentLine = lines[j];
|
|
616
|
+
const openBraces = (currentLine.match(/\{/g) || []).length;
|
|
617
|
+
const closeBraces = (currentLine.match(/\}/g) || []).length;
|
|
618
|
+
braceCount += openBraces - closeBraces;
|
|
619
|
+
if (braceCount === 0 && j > i) {
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return braceCount > 0;
|
|
624
|
+
}
|
|
625
|
+
if (line.trim() === "}" || line.includes("};")) {
|
|
626
|
+
break;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// src/lib/DependencyResolver.ts
|
|
634
|
+
var import_fs3 = __toESM(require("fs"));
|
|
635
|
+
var import_path2 = __toESM(require("path"));
|
|
636
|
+
var DependencyResolver = class {
|
|
637
|
+
/**
|
|
638
|
+
* Resolves table dependencies and creates execution order
|
|
639
|
+
*/
|
|
640
|
+
static resolveDependencies(cubeFiles, cubeType = "table") {
|
|
641
|
+
const tableDependencies = this.extractDependencies(cubeFiles, cubeType);
|
|
642
|
+
const orderedTables = this.topologicalSort(tableDependencies);
|
|
643
|
+
const executionOrder = {
|
|
644
|
+
tables: cubeType === "table" ? orderedTables : [],
|
|
645
|
+
seeders: cubeType === "seeder" ? orderedTables : [],
|
|
646
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
647
|
+
};
|
|
648
|
+
this.saveExecutionOrder(executionOrder);
|
|
649
|
+
return executionOrder;
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Extracts dependencies from cube files
|
|
653
|
+
*/
|
|
654
|
+
static extractDependencies(cubeFiles, cubeType) {
|
|
655
|
+
const dependencies = [];
|
|
656
|
+
for (const file of cubeFiles) {
|
|
657
|
+
let filePath;
|
|
658
|
+
if (import_path2.default.isAbsolute(file)) {
|
|
659
|
+
filePath = file;
|
|
660
|
+
} else if (import_fs3.default.existsSync(file)) {
|
|
661
|
+
filePath = import_path2.default.resolve(file);
|
|
662
|
+
} else {
|
|
663
|
+
filePath = import_path2.default.join(process.cwd(), "dbcube", "cubes", file);
|
|
664
|
+
}
|
|
665
|
+
try {
|
|
666
|
+
const tableNameResult = FileUtils_default.extracTableNameFromCube(filePath);
|
|
667
|
+
const tableName = tableNameResult.status === 200 ? tableNameResult.message : import_path2.default.basename(file, `.${cubeType}.cube`);
|
|
668
|
+
const deps = this.extractForeignKeyReferences(filePath);
|
|
669
|
+
dependencies.push({
|
|
670
|
+
tableName,
|
|
671
|
+
filePath,
|
|
672
|
+
dependencies: deps
|
|
673
|
+
});
|
|
674
|
+
} catch (error) {
|
|
675
|
+
console.error(`Error processing ${filePath}:`, error);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return dependencies;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Extracts foreign key references from a cube file
|
|
682
|
+
*/
|
|
683
|
+
static extractForeignKeyReferences(filePath) {
|
|
684
|
+
const dependencies = [];
|
|
685
|
+
try {
|
|
686
|
+
const content = import_fs3.default.readFileSync(filePath, "utf8");
|
|
687
|
+
const lines = content.split("\n");
|
|
688
|
+
let insideForeignKey = false;
|
|
689
|
+
let braceCount = 0;
|
|
690
|
+
for (const line of lines) {
|
|
691
|
+
if (/foreign\s*:\s*\{/.test(line)) {
|
|
692
|
+
insideForeignKey = true;
|
|
693
|
+
braceCount = 1;
|
|
694
|
+
const sameLineMatch = line.match(/table\s*:\s*["']([^"']+)["']/);
|
|
695
|
+
if (sameLineMatch) {
|
|
696
|
+
dependencies.push(sameLineMatch[1]);
|
|
697
|
+
insideForeignKey = false;
|
|
698
|
+
braceCount = 0;
|
|
699
|
+
}
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
if (insideForeignKey) {
|
|
703
|
+
braceCount += (line.match(/\{/g) || []).length;
|
|
704
|
+
braceCount -= (line.match(/\}/g) || []).length;
|
|
705
|
+
const tableMatch = line.match(/table\s*:\s*["']([^"']+)["']/);
|
|
706
|
+
if (tableMatch) {
|
|
707
|
+
dependencies.push(tableMatch[1]);
|
|
708
|
+
}
|
|
709
|
+
if (braceCount === 0) {
|
|
710
|
+
insideForeignKey = false;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
} catch (error) {
|
|
715
|
+
console.error(`Error reading file ${filePath}:`, error);
|
|
716
|
+
}
|
|
717
|
+
return dependencies;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Performs topological sort to determine execution order
|
|
721
|
+
*/
|
|
722
|
+
static topologicalSort(dependencies) {
|
|
723
|
+
const graph = /* @__PURE__ */ new Map();
|
|
724
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
725
|
+
const tableMap = /* @__PURE__ */ new Map();
|
|
726
|
+
for (const dep of dependencies) {
|
|
727
|
+
graph.set(dep.tableName, dep.dependencies);
|
|
728
|
+
inDegree.set(dep.tableName, 0);
|
|
729
|
+
tableMap.set(dep.tableName, dep);
|
|
730
|
+
}
|
|
731
|
+
for (const dep of dependencies) {
|
|
732
|
+
for (const dependency of dep.dependencies) {
|
|
733
|
+
if (inDegree.has(dependency)) {
|
|
734
|
+
inDegree.set(dep.tableName, (inDegree.get(dep.tableName) || 0) + 1);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
const queue = [];
|
|
739
|
+
const result = [];
|
|
740
|
+
for (const [table, degree] of inDegree) {
|
|
741
|
+
if (degree === 0) {
|
|
742
|
+
queue.push(table);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
while (queue.length > 0) {
|
|
746
|
+
const current = queue.shift();
|
|
747
|
+
result.push(current);
|
|
748
|
+
const currentDeps = graph.get(current) || [];
|
|
749
|
+
for (const neighbor of currentDeps) {
|
|
750
|
+
if (inDegree.has(neighbor)) {
|
|
751
|
+
const newDegree = (inDegree.get(neighbor) || 0) - 1;
|
|
752
|
+
inDegree.set(neighbor, newDegree);
|
|
753
|
+
if (newDegree === 0) {
|
|
754
|
+
queue.push(neighbor);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
if (result.length !== dependencies.length) {
|
|
760
|
+
for (const dep of dependencies) {
|
|
761
|
+
if (!result.includes(dep.tableName)) {
|
|
762
|
+
result.push(dep.tableName);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return result;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Saves the execution order to .dbcube/orderexecute.json
|
|
770
|
+
*/
|
|
771
|
+
static saveExecutionOrder(order) {
|
|
772
|
+
try {
|
|
773
|
+
const projectRoot = process.cwd();
|
|
774
|
+
const dbcubeDir = import_path2.default.join(projectRoot, ".dbcube");
|
|
775
|
+
const orderFile = import_path2.default.join(dbcubeDir, "orderexecute.json");
|
|
776
|
+
if (!import_fs3.default.existsSync(dbcubeDir)) {
|
|
777
|
+
import_fs3.default.mkdirSync(dbcubeDir, { recursive: true });
|
|
778
|
+
}
|
|
779
|
+
import_fs3.default.writeFileSync(orderFile, JSON.stringify(order, null, 2), "utf8");
|
|
780
|
+
} catch (error) {
|
|
781
|
+
console.error("\u274C Failed to save execution order:", error);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Loads the execution order from .dbcube/orderexecute.json
|
|
786
|
+
*/
|
|
787
|
+
static loadExecutionOrder() {
|
|
788
|
+
try {
|
|
789
|
+
const projectRoot = process.cwd();
|
|
790
|
+
const orderFile = import_path2.default.join(projectRoot, ".dbcube", "orderexecute.json");
|
|
791
|
+
if (!import_fs3.default.existsSync(orderFile)) {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
const content = import_fs3.default.readFileSync(orderFile, "utf8");
|
|
795
|
+
return JSON.parse(content);
|
|
796
|
+
} catch (error) {
|
|
797
|
+
console.error("\u274C Failed to load execution order:", error);
|
|
798
|
+
return null;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Orders cube files based on saved execution order
|
|
803
|
+
*/
|
|
804
|
+
static orderCubeFiles(cubeFiles, cubeType) {
|
|
805
|
+
const executionOrder = this.loadExecutionOrder();
|
|
806
|
+
if (!executionOrder) {
|
|
807
|
+
return cubeFiles;
|
|
808
|
+
}
|
|
809
|
+
const orderList = cubeType === "table" ? executionOrder.tables : executionOrder.seeders;
|
|
810
|
+
const orderedFiles = [];
|
|
811
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
812
|
+
for (const file of cubeFiles) {
|
|
813
|
+
const filePath = import_path2.default.isAbsolute(file) ? file : import_path2.default.join(process.cwd(), "dbcube", "cubes", file);
|
|
814
|
+
const tableNameResult = FileUtils_default.extracTableNameFromCube(filePath);
|
|
815
|
+
const tableName = tableNameResult.status === 200 ? tableNameResult.message : import_path2.default.basename(file, `.${cubeType}.cube`);
|
|
816
|
+
fileMap.set(tableName, file);
|
|
817
|
+
}
|
|
818
|
+
for (const tableName of orderList) {
|
|
819
|
+
if (fileMap.has(tableName)) {
|
|
820
|
+
orderedFiles.push(fileMap.get(tableName));
|
|
821
|
+
fileMap.delete(tableName);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
for (const [, file] of fileMap) {
|
|
825
|
+
orderedFiles.push(file);
|
|
826
|
+
}
|
|
827
|
+
return orderedFiles;
|
|
828
|
+
}
|
|
595
829
|
};
|
|
596
830
|
|
|
597
831
|
// src/lib/Schema.ts
|
|
@@ -623,7 +857,7 @@ var Schema = class {
|
|
|
623
857
|
return {
|
|
624
858
|
isValid: false,
|
|
625
859
|
error: {
|
|
626
|
-
itemName:
|
|
860
|
+
itemName: import_path3.default.basename(filePath, import_path3.default.extname(filePath)),
|
|
627
861
|
error: `Error reading database directive: ${dbResult.message}`,
|
|
628
862
|
filePath,
|
|
629
863
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -632,7 +866,7 @@ var Schema = class {
|
|
|
632
866
|
}
|
|
633
867
|
const cubeDbName = dbResult.message;
|
|
634
868
|
const configInstance = new import_core.Config();
|
|
635
|
-
const configFilePath =
|
|
869
|
+
const configFilePath = import_path3.default.resolve(process.cwd(), "dbcube.config.js");
|
|
636
870
|
const configFn = require(configFilePath);
|
|
637
871
|
if (typeof configFn === "function") {
|
|
638
872
|
configFn(configInstance);
|
|
@@ -659,7 +893,7 @@ var Schema = class {
|
|
|
659
893
|
return {
|
|
660
894
|
isValid: false,
|
|
661
895
|
error: {
|
|
662
|
-
itemName:
|
|
896
|
+
itemName: import_path3.default.basename(filePath, import_path3.default.extname(filePath)),
|
|
663
897
|
error: `Database configuration '${cubeDbName}' not found in dbcube.config.js. Available: ${availableText}`,
|
|
664
898
|
filePath,
|
|
665
899
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -671,7 +905,7 @@ var Schema = class {
|
|
|
671
905
|
return {
|
|
672
906
|
isValid: false,
|
|
673
907
|
error: {
|
|
674
|
-
itemName:
|
|
908
|
+
itemName: import_path3.default.basename(filePath, import_path3.default.extname(filePath)),
|
|
675
909
|
error: `Database configuration validation failed: ${error.message}`,
|
|
676
910
|
filePath,
|
|
677
911
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -684,7 +918,7 @@ var Schema = class {
|
|
|
684
918
|
*/
|
|
685
919
|
findDatabaseLineNumber(filePath) {
|
|
686
920
|
try {
|
|
687
|
-
const content =
|
|
921
|
+
const content = import_fs4.default.readFileSync(filePath, "utf8");
|
|
688
922
|
const lines = content.split("\n");
|
|
689
923
|
for (let i = 0; i < lines.length; i++) {
|
|
690
924
|
if (lines[i].includes("@database")) {
|
|
@@ -696,9 +930,65 @@ var Schema = class {
|
|
|
696
930
|
return 1;
|
|
697
931
|
}
|
|
698
932
|
}
|
|
933
|
+
/**
|
|
934
|
+
* Extracts foreign key dependencies from a cube file
|
|
935
|
+
*/
|
|
936
|
+
extractForeignKeyDependencies(filePath) {
|
|
937
|
+
const dependencies = [];
|
|
938
|
+
try {
|
|
939
|
+
const content = import_fs4.default.readFileSync(filePath, "utf8");
|
|
940
|
+
const lines = content.split("\n");
|
|
941
|
+
let insideForeignKey = false;
|
|
942
|
+
let braceCount = 0;
|
|
943
|
+
for (const line of lines) {
|
|
944
|
+
if (/foreign\s*:\s*\{/.test(line)) {
|
|
945
|
+
insideForeignKey = true;
|
|
946
|
+
braceCount = 1;
|
|
947
|
+
const sameLineMatch = line.match(/table\s*:\s*["']([^"']+)["']/);
|
|
948
|
+
if (sameLineMatch) {
|
|
949
|
+
dependencies.push(sameLineMatch[1]);
|
|
950
|
+
insideForeignKey = false;
|
|
951
|
+
braceCount = 0;
|
|
952
|
+
}
|
|
953
|
+
continue;
|
|
954
|
+
}
|
|
955
|
+
if (insideForeignKey) {
|
|
956
|
+
braceCount += (line.match(/\{/g) || []).length;
|
|
957
|
+
braceCount -= (line.match(/\}/g) || []).length;
|
|
958
|
+
const tableMatch = line.match(/table\s*:\s*["']([^"']+)["']/);
|
|
959
|
+
if (tableMatch) {
|
|
960
|
+
dependencies.push(tableMatch[1]);
|
|
961
|
+
}
|
|
962
|
+
if (braceCount === 0) {
|
|
963
|
+
insideForeignKey = false;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
} catch (error) {
|
|
968
|
+
console.error(`Error reading dependencies from ${filePath}:`, error);
|
|
969
|
+
}
|
|
970
|
+
return dependencies;
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* Finds the line number where a foreign key table reference is located
|
|
974
|
+
*/
|
|
975
|
+
findForeignKeyLineNumber(filePath, tableName) {
|
|
976
|
+
try {
|
|
977
|
+
const content = import_fs4.default.readFileSync(filePath, "utf8");
|
|
978
|
+
const lines = content.split("\n");
|
|
979
|
+
for (let i = 0; i < lines.length; i++) {
|
|
980
|
+
if (lines[i].includes(`table: "${tableName}"`) || lines[i].includes(`table: '${tableName}'`)) {
|
|
981
|
+
return i + 1;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
return 1;
|
|
985
|
+
} catch {
|
|
986
|
+
return 1;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
699
989
|
async createDatabase() {
|
|
700
990
|
const startTime = Date.now();
|
|
701
|
-
const rootPath =
|
|
991
|
+
const rootPath = import_path3.default.resolve(process.cwd());
|
|
702
992
|
UIUtils.showOperationHeader(" CREATING DATABASE", this.name, "\u{1F5C4}\uFE0F");
|
|
703
993
|
await UIUtils.showItemProgress("Preparando e instalando base de datos", 1, 1);
|
|
704
994
|
try {
|
|
@@ -742,33 +1032,52 @@ var Schema = class {
|
|
|
742
1032
|
}
|
|
743
1033
|
async refreshTables() {
|
|
744
1034
|
const startTime = Date.now();
|
|
745
|
-
const cubesDir =
|
|
746
|
-
if (!
|
|
1035
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube", "cubes");
|
|
1036
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
747
1037
|
throw new Error("\u274C The cubes folder does not exist");
|
|
748
1038
|
}
|
|
749
1039
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
|
|
750
1040
|
if (cubeFiles.length === 0) {
|
|
751
1041
|
throw new Error("\u274C There are no cubes to execute");
|
|
752
1042
|
}
|
|
1043
|
+
DependencyResolver.resolveDependencies(cubeFiles, "table");
|
|
1044
|
+
const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, "table");
|
|
753
1045
|
UIUtils.showOperationHeader("EXECUTING REFRESH TABLES", this.name, "\u{1F504}");
|
|
754
1046
|
let totalTablesProcessed = 0;
|
|
755
1047
|
let successCount = 0;
|
|
756
1048
|
let errorCount = 0;
|
|
757
1049
|
const processedTables = [];
|
|
758
1050
|
const errors = [];
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
const
|
|
762
|
-
const
|
|
1051
|
+
const failedTables = /* @__PURE__ */ new Set();
|
|
1052
|
+
for (let index = 0; index < orderedCubeFiles.length; index++) {
|
|
1053
|
+
const file = orderedCubeFiles[index];
|
|
1054
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1055
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
763
1056
|
if (stats.isFile()) {
|
|
764
1057
|
const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
765
|
-
const tableName = getTableName.status === 200 ? getTableName.message :
|
|
766
|
-
await UIUtils.showItemProgress(tableName, index + 1,
|
|
1058
|
+
const tableName = getTableName.status === 200 ? getTableName.message : import_path3.default.basename(file, ".table.cube");
|
|
1059
|
+
await UIUtils.showItemProgress(tableName, index + 1, orderedCubeFiles.length);
|
|
767
1060
|
try {
|
|
768
1061
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
769
1062
|
if (!validation.isValid && validation.error) {
|
|
770
1063
|
UIUtils.showItemError(tableName, validation.error.error);
|
|
771
1064
|
errors.push(validation.error);
|
|
1065
|
+
failedTables.add(tableName);
|
|
1066
|
+
errorCount++;
|
|
1067
|
+
continue;
|
|
1068
|
+
}
|
|
1069
|
+
const dependencies = this.extractForeignKeyDependencies(filePath);
|
|
1070
|
+
const missingDependencies = dependencies.filter((dep) => failedTables.has(dep));
|
|
1071
|
+
if (missingDependencies.length > 0) {
|
|
1072
|
+
const dependencyError = {
|
|
1073
|
+
itemName: tableName,
|
|
1074
|
+
error: `Cannot refresh table '${tableName}' because it depends on failed table(s): ${missingDependencies.join(", ")}`,
|
|
1075
|
+
filePath,
|
|
1076
|
+
lineNumber: this.findForeignKeyLineNumber(filePath, missingDependencies[0])
|
|
1077
|
+
};
|
|
1078
|
+
UIUtils.showItemError(tableName, dependencyError.error);
|
|
1079
|
+
errors.push(dependencyError);
|
|
1080
|
+
failedTables.add(tableName);
|
|
772
1081
|
errorCount++;
|
|
773
1082
|
continue;
|
|
774
1083
|
}
|
|
@@ -825,6 +1134,7 @@ var Schema = class {
|
|
|
825
1134
|
};
|
|
826
1135
|
UIUtils.showItemError(tableName, error.message);
|
|
827
1136
|
errors.push(processError);
|
|
1137
|
+
failedTables.add(tableName);
|
|
828
1138
|
errorCount++;
|
|
829
1139
|
}
|
|
830
1140
|
}
|
|
@@ -844,33 +1154,52 @@ var Schema = class {
|
|
|
844
1154
|
}
|
|
845
1155
|
async freshTables() {
|
|
846
1156
|
const startTime = Date.now();
|
|
847
|
-
const cubesDir =
|
|
848
|
-
if (!
|
|
1157
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube", "cubes");
|
|
1158
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
849
1159
|
throw new Error("\u274C The cubes folder does not exist");
|
|
850
1160
|
}
|
|
851
1161
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
|
|
852
1162
|
if (cubeFiles.length === 0) {
|
|
853
1163
|
throw new Error("\u274C There are no cubes to execute");
|
|
854
1164
|
}
|
|
1165
|
+
DependencyResolver.resolveDependencies(cubeFiles, "table");
|
|
1166
|
+
const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, "table");
|
|
855
1167
|
UIUtils.showOperationHeader("EXECUTING FRESH TABLES", this.name);
|
|
856
1168
|
let totalTablesProcessed = 0;
|
|
857
1169
|
let successCount = 0;
|
|
858
1170
|
let errorCount = 0;
|
|
859
1171
|
const processedTables = [];
|
|
860
1172
|
const errors = [];
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
const
|
|
864
|
-
const
|
|
1173
|
+
const failedTables = /* @__PURE__ */ new Set();
|
|
1174
|
+
for (let index = 0; index < orderedCubeFiles.length; index++) {
|
|
1175
|
+
const file = orderedCubeFiles[index];
|
|
1176
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1177
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
865
1178
|
if (stats.isFile()) {
|
|
866
1179
|
const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
867
|
-
const tableName = getTableName.status === 200 ? getTableName.message :
|
|
868
|
-
await UIUtils.showItemProgress(tableName, index + 1,
|
|
1180
|
+
const tableName = getTableName.status === 200 ? getTableName.message : import_path3.default.basename(file, ".table.cube");
|
|
1181
|
+
await UIUtils.showItemProgress(tableName, index + 1, orderedCubeFiles.length);
|
|
869
1182
|
try {
|
|
870
1183
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
871
1184
|
if (!validation.isValid && validation.error) {
|
|
872
1185
|
UIUtils.showItemError(tableName, validation.error.error);
|
|
873
1186
|
errors.push(validation.error);
|
|
1187
|
+
failedTables.add(tableName);
|
|
1188
|
+
errorCount++;
|
|
1189
|
+
continue;
|
|
1190
|
+
}
|
|
1191
|
+
const dependencies = this.extractForeignKeyDependencies(filePath);
|
|
1192
|
+
const missingDependencies = dependencies.filter((dep) => failedTables.has(dep));
|
|
1193
|
+
if (missingDependencies.length > 0) {
|
|
1194
|
+
const dependencyError = {
|
|
1195
|
+
itemName: tableName,
|
|
1196
|
+
error: `Cannot create table '${tableName}' because it depends on failed table(s): ${missingDependencies.join(", ")}`,
|
|
1197
|
+
filePath,
|
|
1198
|
+
lineNumber: this.findForeignKeyLineNumber(filePath, missingDependencies[0])
|
|
1199
|
+
};
|
|
1200
|
+
UIUtils.showItemError(tableName, dependencyError.error);
|
|
1201
|
+
errors.push(dependencyError);
|
|
1202
|
+
failedTables.add(tableName);
|
|
874
1203
|
errorCount++;
|
|
875
1204
|
continue;
|
|
876
1205
|
}
|
|
@@ -925,6 +1254,7 @@ var Schema = class {
|
|
|
925
1254
|
};
|
|
926
1255
|
UIUtils.showItemError(tableName, error.message);
|
|
927
1256
|
errors.push(processError);
|
|
1257
|
+
failedTables.add(tableName);
|
|
928
1258
|
errorCount++;
|
|
929
1259
|
}
|
|
930
1260
|
}
|
|
@@ -944,28 +1274,29 @@ var Schema = class {
|
|
|
944
1274
|
}
|
|
945
1275
|
async executeSeeders() {
|
|
946
1276
|
const startTime = Date.now();
|
|
947
|
-
const cubesDir =
|
|
948
|
-
if (!
|
|
1277
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube", "cubes");
|
|
1278
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
949
1279
|
throw new Error("\u274C The cubes folder does not exist");
|
|
950
1280
|
}
|
|
951
1281
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "seeder.cube");
|
|
952
1282
|
if (cubeFiles.length === 0) {
|
|
953
1283
|
throw new Error("\u274C There are no cubes to execute");
|
|
954
1284
|
}
|
|
1285
|
+
const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, "seeder");
|
|
955
1286
|
UIUtils.showOperationHeader("EXECUTING SEEDERS", this.name, "\u{1F331}");
|
|
956
1287
|
let totalSeedersProcessed = 0;
|
|
957
1288
|
let successCount = 0;
|
|
958
1289
|
let errorCount = 0;
|
|
959
1290
|
const processedSeeders = [];
|
|
960
1291
|
const errors = [];
|
|
961
|
-
for (let index = 0; index <
|
|
962
|
-
const file =
|
|
963
|
-
const filePath =
|
|
964
|
-
const stats =
|
|
1292
|
+
for (let index = 0; index < orderedCubeFiles.length; index++) {
|
|
1293
|
+
const file = orderedCubeFiles[index];
|
|
1294
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1295
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
965
1296
|
if (stats.isFile()) {
|
|
966
1297
|
const getSeederName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
967
|
-
const seederName = getSeederName.status === 200 ? getSeederName.message :
|
|
968
|
-
await UIUtils.showItemProgress(seederName, index + 1,
|
|
1298
|
+
const seederName = getSeederName.status === 200 ? getSeederName.message : import_path3.default.basename(file, ".seeder.cube");
|
|
1299
|
+
await UIUtils.showItemProgress(seederName, index + 1, orderedCubeFiles.length);
|
|
969
1300
|
try {
|
|
970
1301
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
971
1302
|
if (!validation.isValid && validation.error) {
|
|
@@ -1015,9 +1346,9 @@ var Schema = class {
|
|
|
1015
1346
|
}
|
|
1016
1347
|
async executeTriggers() {
|
|
1017
1348
|
const startTime = Date.now();
|
|
1018
|
-
const cubesDir =
|
|
1019
|
-
const triggersDirExit =
|
|
1020
|
-
if (!
|
|
1349
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube", "cubes");
|
|
1350
|
+
const triggersDirExit = import_path3.default.join(process.cwd(), "dbcube", "triggers");
|
|
1351
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
1021
1352
|
throw new Error("\u274C The cubes folder does not exist");
|
|
1022
1353
|
}
|
|
1023
1354
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "trigger.cube");
|
|
@@ -1032,11 +1363,11 @@ var Schema = class {
|
|
|
1032
1363
|
const errors = [];
|
|
1033
1364
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
1034
1365
|
const file = cubeFiles[index];
|
|
1035
|
-
const filePath =
|
|
1036
|
-
const stats =
|
|
1366
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1367
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
1037
1368
|
if (stats.isFile()) {
|
|
1038
1369
|
const getTriggerName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
1039
|
-
const triggerName = getTriggerName.status === 200 ? getTriggerName.message :
|
|
1370
|
+
const triggerName = getTriggerName.status === 200 ? getTriggerName.message : import_path3.default.basename(file, ".trigger.cube");
|
|
1040
1371
|
await UIUtils.showItemProgress(triggerName, index + 1, cubeFiles.length);
|
|
1041
1372
|
try {
|
|
1042
1373
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -1107,7 +1438,7 @@ ${import_chalk2.default.red("\u{1F6AB}")} ${import_chalk2.default.bold.red("ERRO
|
|
|
1107
1438
|
const errorLocation = `${filePath}:${lineStr}:${columnStr}`;
|
|
1108
1439
|
console.log(`${import_chalk2.default.cyan("[code]")} ${import_chalk2.default.yellow(errorLocation)}`);
|
|
1109
1440
|
try {
|
|
1110
|
-
const codeLines =
|
|
1441
|
+
const codeLines = import_fs4.default.readFileSync(filePath, "utf-8").split("\n");
|
|
1111
1442
|
const start = Math.max(0, lineNum - 3);
|
|
1112
1443
|
const end = Math.min(codeLines.length, lineNum + 2);
|
|
1113
1444
|
for (let i = start; i < end; i++) {
|
|
@@ -1130,6 +1461,7 @@ var index_default = Schema;
|
|
|
1130
1461
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1131
1462
|
0 && (module.exports = {
|
|
1132
1463
|
CubeValidator,
|
|
1464
|
+
DependencyResolver,
|
|
1133
1465
|
Schema,
|
|
1134
1466
|
UIUtils
|
|
1135
1467
|
});
|