masterrecord 0.3.32 → 0.3.33
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.
|
@@ -193,6 +193,11 @@ class migrationMySQLQuery {
|
|
|
193
193
|
var queryVar = "";
|
|
194
194
|
//console.log("Dsfdsfdsf---------", table)
|
|
195
195
|
for (var key in table) {
|
|
196
|
+
// Skip metadata properties (indexes, __compositeIndexes, __name, etc.)
|
|
197
|
+
if(key === 'indexes' || key.startsWith('__')){
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
|
|
196
201
|
if(typeof table[key] === "object"){
|
|
197
202
|
|
|
198
203
|
if(table[key].type !== "hasOne" && table[key].type !== "hasMany" && table[key].type !== "hasManyThrough"){
|
|
@@ -196,6 +196,11 @@ class migrationPostgresQuery {
|
|
|
196
196
|
var queryVar = "";
|
|
197
197
|
|
|
198
198
|
for (var key in table) {
|
|
199
|
+
// Skip metadata properties (indexes, __compositeIndexes, __name, etc.)
|
|
200
|
+
if(key === 'indexes' || key.startsWith('__')){
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
199
204
|
if(typeof table[key] === "object"){
|
|
200
205
|
if(table[key].type !== "hasOne" && table[key].type !== "hasMany" && table[key].type !== "hasManyThrough"){
|
|
201
206
|
queryVar += `${this.#columnMapping(table[key])}, `;
|
|
@@ -147,6 +147,11 @@ class migrationSQLiteQuery {
|
|
|
147
147
|
createTable(table){
|
|
148
148
|
var queryVar = "";
|
|
149
149
|
for (var key in table) {
|
|
150
|
+
// Skip metadata properties (indexes, __compositeIndexes, __name, etc.)
|
|
151
|
+
if(key === 'indexes' || key.startsWith('__')){
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
150
155
|
if(typeof table[key] === "object"){
|
|
151
156
|
var col = table[key];
|
|
152
157
|
// Skip relationship-only fields
|
|
@@ -156,7 +161,7 @@ class migrationSQLiteQuery {
|
|
|
156
161
|
queryVar += `${this.#columnMapping(col)}, `;
|
|
157
162
|
}
|
|
158
163
|
}
|
|
159
|
-
|
|
164
|
+
|
|
160
165
|
return `CREATE TABLE IF NOT EXISTS ${table.__name} (${queryVar.replace(/,\s*$/, "")});`;
|
|
161
166
|
|
|
162
167
|
/*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "masterrecord",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.33",
|
|
4
4
|
"description": "An Object-relational mapping for the Master framework. Master Record connects classes to relational database tables to establish a database with almost zero-configuration ",
|
|
5
5
|
"main": "MasterRecord.js",
|
|
6
6
|
"bin": {
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: Index Bug Fix - createTable should not generate "undefined undefined NOT NULL"
|
|
3
|
+
*
|
|
4
|
+
* Verifies that .index() method doesn't cause malformed column definitions in CREATE TABLE statements
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
console.log("╔════════════════════════════════════════════════════════════════╗");
|
|
8
|
+
console.log("║ Index Bug Fix Test - createTable() Method ║");
|
|
9
|
+
console.log("╚════════════════════════════════════════════════════════════════╝\n");
|
|
10
|
+
|
|
11
|
+
const MigrationSQLiteQuery = require('../Migrations/migrationSQLiteQuery.js');
|
|
12
|
+
const MigrationMySQLQuery = require('../Migrations/migrationMySQLQuery.js');
|
|
13
|
+
const MigrationPostgresQuery = require('../Migrations/migrationPostgresQuery.js');
|
|
14
|
+
|
|
15
|
+
let passed = 0;
|
|
16
|
+
let failed = 0;
|
|
17
|
+
|
|
18
|
+
function assert(condition, message) {
|
|
19
|
+
if (!condition) {
|
|
20
|
+
console.log(`❌ FAIL: ${message}`);
|
|
21
|
+
failed++;
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function test(description, fn) {
|
|
28
|
+
try {
|
|
29
|
+
fn();
|
|
30
|
+
console.log(`✓ ${description}`);
|
|
31
|
+
passed++;
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.log(`✗ ${description}`);
|
|
34
|
+
console.log(` Error: ${error.message}`);
|
|
35
|
+
failed++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Mock table object with indexes property (simulates what EntityModel creates)
|
|
40
|
+
const mockTable = {
|
|
41
|
+
__name: 'TestTable',
|
|
42
|
+
id: {
|
|
43
|
+
name: 'id',
|
|
44
|
+
type: 'integer',
|
|
45
|
+
nullable: false,
|
|
46
|
+
primary: true,
|
|
47
|
+
autoIncrement: true
|
|
48
|
+
},
|
|
49
|
+
organization_id: {
|
|
50
|
+
name: 'organization_id',
|
|
51
|
+
type: 'integer',
|
|
52
|
+
nullable: false,
|
|
53
|
+
indexes: ['idx_org'] // This property on the column caused the original bug
|
|
54
|
+
},
|
|
55
|
+
name: {
|
|
56
|
+
name: 'name',
|
|
57
|
+
type: 'string',
|
|
58
|
+
nullable: false
|
|
59
|
+
},
|
|
60
|
+
// This is the problematic property that was being treated as a column
|
|
61
|
+
indexes: ['idx_org']
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
console.log("Testing SQLite Query Builder...\n");
|
|
65
|
+
|
|
66
|
+
test('SQLite createTable should skip indexes property', () => {
|
|
67
|
+
const sqliteQuery = new MigrationSQLiteQuery();
|
|
68
|
+
const sql = sqliteQuery.createTable(mockTable);
|
|
69
|
+
|
|
70
|
+
assert(!sql.includes('undefined undefined'),
|
|
71
|
+
`SQL should not contain "undefined undefined" but got: ${sql}`);
|
|
72
|
+
assert(sql.includes('id'), 'Should include id column');
|
|
73
|
+
assert(sql.includes('organization_id'), 'Should include organization_id column');
|
|
74
|
+
assert(sql.includes('name'), 'Should include name column');
|
|
75
|
+
assert(sql.startsWith('CREATE TABLE IF NOT EXISTS TestTable'),
|
|
76
|
+
'Should start with CREATE TABLE');
|
|
77
|
+
|
|
78
|
+
console.log(` Generated SQL: ${sql}\n`);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
console.log("Testing MySQL Query Builder...\n");
|
|
82
|
+
|
|
83
|
+
test('MySQL createTable should skip indexes property', () => {
|
|
84
|
+
const mysqlQuery = new MigrationMySQLQuery();
|
|
85
|
+
const sql = mysqlQuery.createTable(mockTable);
|
|
86
|
+
|
|
87
|
+
assert(!sql.includes('undefined undefined'),
|
|
88
|
+
`SQL should not contain "undefined undefined" but got: ${sql}`);
|
|
89
|
+
assert(sql.includes('id'), 'Should include id column');
|
|
90
|
+
assert(sql.includes('organization_id'), 'Should include organization_id column');
|
|
91
|
+
assert(sql.includes('name'), 'Should include name column');
|
|
92
|
+
assert(sql.startsWith('CREATE TABLE IF NOT EXISTS `TestTable`'),
|
|
93
|
+
'Should start with CREATE TABLE');
|
|
94
|
+
|
|
95
|
+
console.log(` Generated SQL: ${sql}\n`);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
console.log("Testing PostgreSQL Query Builder...\n");
|
|
99
|
+
|
|
100
|
+
test('PostgreSQL createTable should skip indexes property', () => {
|
|
101
|
+
const postgresQuery = new MigrationPostgresQuery();
|
|
102
|
+
const sql = postgresQuery.createTable(mockTable);
|
|
103
|
+
|
|
104
|
+
assert(!sql.includes('undefined undefined'),
|
|
105
|
+
`SQL should not contain "undefined undefined" but got: ${sql}`);
|
|
106
|
+
assert(sql.includes('id'), 'Should include id column');
|
|
107
|
+
assert(sql.includes('organization_id'), 'Should include organization_id column');
|
|
108
|
+
assert(sql.includes('name'), 'Should include name column');
|
|
109
|
+
assert(sql.startsWith('CREATE TABLE IF NOT EXISTS "TestTable"'),
|
|
110
|
+
'Should start with CREATE TABLE');
|
|
111
|
+
|
|
112
|
+
console.log(` Generated SQL: ${sql}\n`);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
console.log("Testing metadata properties filtering...\n");
|
|
116
|
+
|
|
117
|
+
test('Should skip __compositeIndexes and other __ properties', () => {
|
|
118
|
+
const tableWithMetadata = {
|
|
119
|
+
...mockTable,
|
|
120
|
+
__compositeIndexes: [['col1', 'col2']],
|
|
121
|
+
__someOtherMetadata: 'value'
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const sqliteQuery = new MigrationSQLiteQuery();
|
|
125
|
+
const sql = sqliteQuery.createTable(tableWithMetadata);
|
|
126
|
+
|
|
127
|
+
assert(!sql.includes('undefined undefined'),
|
|
128
|
+
`SQL should not contain "undefined undefined" but got: ${sql}`);
|
|
129
|
+
|
|
130
|
+
const columnCount = (sql.match(/,/g) || []).length + 1;
|
|
131
|
+
assert(columnCount === 3, `Should have exactly 3 columns (id, organization_id, name), got ${columnCount}`);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
console.log("Testing relationships filtering...\n");
|
|
135
|
+
|
|
136
|
+
test('Should handle table with relationships correctly', () => {
|
|
137
|
+
const tableWithRelations = {
|
|
138
|
+
__name: 'User',
|
|
139
|
+
id: {
|
|
140
|
+
name: 'id',
|
|
141
|
+
type: 'integer',
|
|
142
|
+
nullable: false,
|
|
143
|
+
primary: true
|
|
144
|
+
},
|
|
145
|
+
name: {
|
|
146
|
+
name: 'name',
|
|
147
|
+
type: 'string',
|
|
148
|
+
nullable: false
|
|
149
|
+
},
|
|
150
|
+
posts: {
|
|
151
|
+
name: 'posts',
|
|
152
|
+
type: 'hasMany',
|
|
153
|
+
target: 'Post'
|
|
154
|
+
},
|
|
155
|
+
profile: {
|
|
156
|
+
name: 'profile',
|
|
157
|
+
type: 'hasOne',
|
|
158
|
+
target: 'Profile'
|
|
159
|
+
},
|
|
160
|
+
indexes: ['idx_user_name']
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const sqliteQuery = new MigrationSQLiteQuery();
|
|
164
|
+
const sql = sqliteQuery.createTable(tableWithRelations);
|
|
165
|
+
|
|
166
|
+
assert(!sql.includes('hasMany'), 'Should not include hasMany');
|
|
167
|
+
assert(!sql.includes('hasOne'), 'Should not include hasOne');
|
|
168
|
+
assert(!sql.includes('undefined undefined'),
|
|
169
|
+
`SQL should not contain "undefined undefined" but got: ${sql}`);
|
|
170
|
+
assert(sql.includes('id'), 'Should include id column');
|
|
171
|
+
assert(sql.includes('name'), 'Should include name column');
|
|
172
|
+
assert(!sql.includes('posts'), 'Should not include posts relationship');
|
|
173
|
+
assert(!sql.includes('profile'), 'Should not include profile relationship');
|
|
174
|
+
|
|
175
|
+
console.log(` Generated SQL: ${sql}\n`);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
console.log("\n" + "=".repeat(64));
|
|
179
|
+
console.log(`Test Results: ${passed} passed, ${failed} failed`);
|
|
180
|
+
console.log("=".repeat(64));
|
|
181
|
+
|
|
182
|
+
if (failed > 0) {
|
|
183
|
+
console.log("\n❌ Some tests failed!");
|
|
184
|
+
process.exit(1);
|
|
185
|
+
} else {
|
|
186
|
+
console.log("\n✅ All tests passed!");
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|