accio-orm 0.1.0
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/LICENSE +21 -0
- package/README.md +482 -0
- package/dist/connection/Connection.d.ts +29 -0
- package/dist/connection/Connection.js +63 -0
- package/dist/connection/types.d.ts +7 -0
- package/dist/connection/types.js +2 -0
- package/dist/decorators/Column.d.ts +23 -0
- package/dist/decorators/Column.js +34 -0
- package/dist/decorators/PrimaryColumn.d.ts +9 -0
- package/dist/decorators/PrimaryColumn.js +26 -0
- package/dist/decorators/Table.d.ts +10 -0
- package/dist/decorators/Table.js +21 -0
- package/dist/examples/test-connection.d.ts +1 -0
- package/dist/examples/test-connection.js +36 -0
- package/dist/examples/test-decorators.d.ts +1 -0
- package/dist/examples/test-decorators.js +40 -0
- package/dist/examples/test-metadata.d.ts +1 -0
- package/dist/examples/test-metadata.js +110 -0
- package/dist/examples/test-querybuilder.d.ts +1 -0
- package/dist/examples/test-querybuilder.js +142 -0
- package/dist/examples/test-repository.d.ts +1 -0
- package/dist/examples/test-repository.js +111 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +23 -0
- package/dist/metadata/MetadataStorage.d.ts +30 -0
- package/dist/metadata/MetadataStorage.js +82 -0
- package/dist/metadata/types.d.ts +7 -0
- package/dist/metadata/types.js +2 -0
- package/dist/query/QueryBuilder.d.ts +64 -0
- package/dist/query/QueryBuilder.js +180 -0
- package/dist/repository/Repository.d.ts +43 -0
- package/dist/repository/Repository.js +156 -0
- package/dist/utils/entityMapper.d.ts +9 -0
- package/dist/utils/entityMapper.js +22 -0
- package/package.json +72 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Table = Table;
|
|
4
|
+
exports.getTableName = getTableName;
|
|
5
|
+
require("reflect-metadata");
|
|
6
|
+
const TABLE_NAME_KEY = Symbol('table:name');
|
|
7
|
+
/**
|
|
8
|
+
* Decorator to mark a class as a database table
|
|
9
|
+
* @param tableName - The name of the database table
|
|
10
|
+
*/
|
|
11
|
+
function Table(tableName) {
|
|
12
|
+
return function (target) {
|
|
13
|
+
Reflect.defineMetadata(TABLE_NAME_KEY, tableName, target);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* helper to retrieve the table name from a class
|
|
18
|
+
*/
|
|
19
|
+
function getTableName(target) {
|
|
20
|
+
return Reflect.getMetadata(TABLE_NAME_KEY, target);
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Connection_1 = require("@/connection/Connection");
|
|
4
|
+
async function testConnection() {
|
|
5
|
+
console.log('creating connection...');
|
|
6
|
+
const db = (0, Connection_1.connect)({
|
|
7
|
+
host: 'localhost',
|
|
8
|
+
database: 'accio_db',
|
|
9
|
+
user: 'accio_db',
|
|
10
|
+
password: 'accio_db'
|
|
11
|
+
});
|
|
12
|
+
console.log('testing connection...');
|
|
13
|
+
const isConnected = await db.testConnection();
|
|
14
|
+
if (isConnected) {
|
|
15
|
+
console.log('✅ connection successfull');
|
|
16
|
+
const result = await db.query('SELECT NOW()');
|
|
17
|
+
console.log('current time from database:', result.rows[0].now);
|
|
18
|
+
await db.query(`
|
|
19
|
+
CREATE TABLE IF NOT EXISTS test_table (
|
|
20
|
+
if SERIAL PRIMARY KEY,
|
|
21
|
+
name TEXT
|
|
22
|
+
)
|
|
23
|
+
`);
|
|
24
|
+
console.log('✅ created test table');
|
|
25
|
+
await db.query('INSERT INTO test_table (name) VALUES ($1)', ['Test User']);
|
|
26
|
+
console.log('✅ inserted test data');
|
|
27
|
+
const users = await db.query('SELECT * FROM test_table');
|
|
28
|
+
console.log('✅ query resylts:', users.rows);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.log('❌ connection failed');
|
|
32
|
+
}
|
|
33
|
+
await db.close();
|
|
34
|
+
console.log('connection closed');
|
|
35
|
+
}
|
|
36
|
+
testConnection().catch(console.error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
require("reflect-metadata");
|
|
13
|
+
const Column_1 = require("@/decorators/Column");
|
|
14
|
+
const Column_2 = require("@/decorators/Column");
|
|
15
|
+
const PrimaryColumn_1 = require("@/decorators/PrimaryColumn");
|
|
16
|
+
const Table_1 = require("@/decorators/Table");
|
|
17
|
+
const Table_2 = require("@/decorators/Table");
|
|
18
|
+
let User = class User {
|
|
19
|
+
};
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, PrimaryColumn_1.PrimaryColumn)(),
|
|
22
|
+
__metadata("design:type", Number)
|
|
23
|
+
], User.prototype, "id", void 0);
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, Column_1.Column)(),
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], User.prototype, "name", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, Column_1.Column)({ name: 'user_age' }),
|
|
30
|
+
__metadata("design:type", Number)
|
|
31
|
+
], User.prototype, "age", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, Column_1.Column)({ nullable: false }),
|
|
34
|
+
__metadata("design:type", String)
|
|
35
|
+
], User.prototype, "email", void 0);
|
|
36
|
+
User = __decorate([
|
|
37
|
+
(0, Table_1.Table)('users')
|
|
38
|
+
], User);
|
|
39
|
+
console.log('Table name:', (0, Table_2.getTableName)(User));
|
|
40
|
+
console.log('Columns:', (0, Column_2.getColumns)(User));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
require("reflect-metadata");
|
|
13
|
+
const Column_1 = require("../decorators/Column");
|
|
14
|
+
const PrimaryColumn_1 = require("../decorators/PrimaryColumn");
|
|
15
|
+
const Table_1 = require("../decorators/Table");
|
|
16
|
+
const MetadataStorage_1 = require("../metadata/MetadataStorage");
|
|
17
|
+
// Valid entity
|
|
18
|
+
let User = class User {
|
|
19
|
+
};
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, PrimaryColumn_1.PrimaryColumn)(),
|
|
22
|
+
__metadata("design:type", Number)
|
|
23
|
+
], User.prototype, "id", void 0);
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, Column_1.Column)(),
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], User.prototype, "name", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, Column_1.Column)({ name: 'user_age' }),
|
|
30
|
+
__metadata("design:type", Number)
|
|
31
|
+
], User.prototype, "age", void 0);
|
|
32
|
+
User = __decorate([
|
|
33
|
+
(0, Table_1.Table)('users')
|
|
34
|
+
], User);
|
|
35
|
+
// Test valid entity
|
|
36
|
+
console.log('=== Testing Valid Entity ===');
|
|
37
|
+
const userMetadata = MetadataStorage_1.MetadataStorage.getEntityMetadata(User);
|
|
38
|
+
console.log('Table:', userMetadata.tableName);
|
|
39
|
+
console.log('Primary Column:', userMetadata.primaryColumn);
|
|
40
|
+
console.log('All Columns:');
|
|
41
|
+
userMetadata.columns.forEach((col) => {
|
|
42
|
+
console.log(` - ${col.propertyKey} → ${col.columnName} (primary: ${col.isPrimary})`);
|
|
43
|
+
});
|
|
44
|
+
// Test convenience methods
|
|
45
|
+
console.log('\n=== Convenience Methods ===');
|
|
46
|
+
console.log('Table name:', MetadataStorage_1.MetadataStorage.getTableName(User));
|
|
47
|
+
console.log('Primary column:', MetadataStorage_1.MetadataStorage.getPrimaryColumn(User));
|
|
48
|
+
// Test validation errors
|
|
49
|
+
console.log('\n=== Testing Validation Errors ===');
|
|
50
|
+
// Missing @Table
|
|
51
|
+
class NoTable {
|
|
52
|
+
}
|
|
53
|
+
__decorate([
|
|
54
|
+
(0, PrimaryColumn_1.PrimaryColumn)(),
|
|
55
|
+
__metadata("design:type", Number)
|
|
56
|
+
], NoTable.prototype, "id", void 0);
|
|
57
|
+
try {
|
|
58
|
+
MetadataStorage_1.MetadataStorage.getEntityMetadata(NoTable);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.log('✓ Caught missing @Table:', error.message);
|
|
62
|
+
}
|
|
63
|
+
// No columns
|
|
64
|
+
let NoColumns = class NoColumns {
|
|
65
|
+
};
|
|
66
|
+
NoColumns = __decorate([
|
|
67
|
+
(0, Table_1.Table)('empty')
|
|
68
|
+
], NoColumns);
|
|
69
|
+
try {
|
|
70
|
+
MetadataStorage_1.MetadataStorage.getEntityMetadata(NoColumns);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.log('✓ Caught no columns:', error.message);
|
|
74
|
+
}
|
|
75
|
+
// No primary key
|
|
76
|
+
let NoPrimaryKey = class NoPrimaryKey {
|
|
77
|
+
};
|
|
78
|
+
__decorate([
|
|
79
|
+
(0, Column_1.Column)(),
|
|
80
|
+
__metadata("design:type", String)
|
|
81
|
+
], NoPrimaryKey.prototype, "name", void 0);
|
|
82
|
+
NoPrimaryKey = __decorate([
|
|
83
|
+
(0, Table_1.Table)('no_pk')
|
|
84
|
+
], NoPrimaryKey);
|
|
85
|
+
try {
|
|
86
|
+
MetadataStorage_1.MetadataStorage.getEntityMetadata(NoPrimaryKey);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.log('✓ Caught no primary key:', error.message);
|
|
90
|
+
}
|
|
91
|
+
// Multiple primary keys
|
|
92
|
+
let MultiplePrimaryKeys = class MultiplePrimaryKeys {
|
|
93
|
+
};
|
|
94
|
+
__decorate([
|
|
95
|
+
(0, PrimaryColumn_1.PrimaryColumn)(),
|
|
96
|
+
__metadata("design:type", Number)
|
|
97
|
+
], MultiplePrimaryKeys.prototype, "id", void 0);
|
|
98
|
+
__decorate([
|
|
99
|
+
(0, PrimaryColumn_1.PrimaryColumn)(),
|
|
100
|
+
__metadata("design:type", Number)
|
|
101
|
+
], MultiplePrimaryKeys.prototype, "userId", void 0);
|
|
102
|
+
MultiplePrimaryKeys = __decorate([
|
|
103
|
+
(0, Table_1.Table)('multi_pk')
|
|
104
|
+
], MultiplePrimaryKeys);
|
|
105
|
+
try {
|
|
106
|
+
MetadataStorage_1.MetadataStorage.getEntityMetadata(MultiplePrimaryKeys);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.log('✓ Caught multiple primary keys:', error.message);
|
|
110
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
require("reflect-metadata");
|
|
13
|
+
const Connection_1 = require("../connection/Connection");
|
|
14
|
+
const Column_1 = require("../decorators/Column");
|
|
15
|
+
const PrimaryColumn_1 = require("../decorators/PrimaryColumn");
|
|
16
|
+
const Table_1 = require("../decorators/Table");
|
|
17
|
+
let User = class User {
|
|
18
|
+
};
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, PrimaryColumn_1.PrimaryColumn)(),
|
|
21
|
+
__metadata("design:type", Number)
|
|
22
|
+
], User.prototype, "id", void 0);
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, Column_1.Column)(),
|
|
25
|
+
__metadata("design:type", String)
|
|
26
|
+
], User.prototype, "name", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, Column_1.Column)(),
|
|
29
|
+
__metadata("design:type", Number)
|
|
30
|
+
], User.prototype, "age", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, Column_1.Column)(),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], User.prototype, "city", void 0);
|
|
35
|
+
User = __decorate([
|
|
36
|
+
(0, Table_1.Table)('users')
|
|
37
|
+
], User);
|
|
38
|
+
async function testQueryBuilder() {
|
|
39
|
+
console.log('=== Testing QueryBuilder ===\n');
|
|
40
|
+
const db = (0, Connection_1.connect)({
|
|
41
|
+
host: 'localhost',
|
|
42
|
+
database: 'accio_db',
|
|
43
|
+
user: 'accio_db',
|
|
44
|
+
password: 'accio_db'
|
|
45
|
+
});
|
|
46
|
+
const userRepo = db.getRepository(User);
|
|
47
|
+
try {
|
|
48
|
+
// Setup: Insert test data
|
|
49
|
+
console.log('Setting up test data...');
|
|
50
|
+
const testUsers = [
|
|
51
|
+
{ name: 'Alice', age: 25, city: 'NYC' },
|
|
52
|
+
{ name: 'Bob', age: 30, city: 'LA' },
|
|
53
|
+
{ name: 'Charlie', age: 25, city: 'NYC' },
|
|
54
|
+
{ name: 'Diana', age: 35, city: 'Chicago' },
|
|
55
|
+
{ name: 'Eve', age: 25, city: 'LA' }
|
|
56
|
+
];
|
|
57
|
+
for (const userData of testUsers) {
|
|
58
|
+
const user = new User();
|
|
59
|
+
Object.assign(user, userData);
|
|
60
|
+
await userRepo.insert(user);
|
|
61
|
+
}
|
|
62
|
+
console.log('✓ Inserted test data\n');
|
|
63
|
+
// Test 1: Simple WHERE
|
|
64
|
+
console.log('1. Simple WHERE (age = 25)');
|
|
65
|
+
const query1 = userRepo.where({ age: 25 });
|
|
66
|
+
console.log('SQL:', query1.toSQL());
|
|
67
|
+
const result1 = await query1.find();
|
|
68
|
+
console.log('✓ Results:', result1.length, 'users');
|
|
69
|
+
result1.forEach((u) => console.log(` - ${u.name}, ${u.age}, ${u.city}`));
|
|
70
|
+
// Test 2: Multiple WHERE (AND)
|
|
71
|
+
console.log('\n2. Multiple WHERE (age = 25 AND city = NYC)');
|
|
72
|
+
const query2 = userRepo.where({ age: 25 }).where({ city: 'NYC' });
|
|
73
|
+
console.log('SQL:', query2.toSQL());
|
|
74
|
+
const result2 = await query2.find();
|
|
75
|
+
console.log('✓ Results:', result2.length, 'users');
|
|
76
|
+
result2.forEach((u) => console.log(` - ${u.name}, ${u.age}, ${u.city}`));
|
|
77
|
+
// Test 3: ORDER BY
|
|
78
|
+
console.log('\n3. ORDER BY age DESC');
|
|
79
|
+
const query3 = userRepo.where({ city: 'NYC' }).orderBy('age', 'DESC');
|
|
80
|
+
console.log('SQL:', query3.toSQL());
|
|
81
|
+
const result3 = await query3.find();
|
|
82
|
+
console.log('✓ Results:');
|
|
83
|
+
result3.forEach((u) => console.log(` - ${u.name}, ${u.age}, ${u.city}`));
|
|
84
|
+
// Test 4: LIMIT
|
|
85
|
+
console.log('\n4. LIMIT 2');
|
|
86
|
+
const query4 = userRepo.where({ age: 25 }).limit(2);
|
|
87
|
+
console.log('SQL:', query4.toSQL());
|
|
88
|
+
const result4 = await query4.find();
|
|
89
|
+
console.log('✓ Results:', result4.length, 'users');
|
|
90
|
+
result4.forEach((u) => console.log(` - ${u.name}, ${u.age}, ${u.city}`));
|
|
91
|
+
// Test 5: OFFSET
|
|
92
|
+
console.log('\n5. OFFSET 1 LIMIT 2');
|
|
93
|
+
const query5 = userRepo.where({ age: 25 }).offset(1).limit(2);
|
|
94
|
+
console.log('SQL:', query5.toSQL());
|
|
95
|
+
const result5 = await query5.find();
|
|
96
|
+
console.log('✓ Results:', result5.length, 'users');
|
|
97
|
+
result5.forEach((u) => console.log(` - ${u.name}, ${u.age}, ${u.city}`));
|
|
98
|
+
// Test 6: findOne
|
|
99
|
+
console.log('\n6. findOne (first user in NYC)');
|
|
100
|
+
const query6 = userRepo.where({ city: 'NYC' });
|
|
101
|
+
console.log('SQL:', query6.toSQL());
|
|
102
|
+
const result6 = await query6.findOne();
|
|
103
|
+
console.log('✓ Result:', result6);
|
|
104
|
+
// Test 7: count
|
|
105
|
+
console.log('\n7. count (age = 25)');
|
|
106
|
+
const count = await userRepo.where({ age: 25 }).count();
|
|
107
|
+
console.log('✓ Count:', count);
|
|
108
|
+
// Test 8: exists
|
|
109
|
+
console.log('\n8. exists (city = Seattle)');
|
|
110
|
+
const exists = await userRepo.where({ city: 'Seattle' }).exists();
|
|
111
|
+
console.log('✓ Exists:', exists);
|
|
112
|
+
// Test 9: IN clause (array values)
|
|
113
|
+
console.log('\n9. IN clause (city IN [NYC, LA])');
|
|
114
|
+
const query9 = userRepo.where({ city: ['NYC', 'LA'] });
|
|
115
|
+
console.log('SQL:', query9.toSQL());
|
|
116
|
+
const result9 = await query9.find();
|
|
117
|
+
console.log('✓ Results:', result9.length, 'users');
|
|
118
|
+
result9.forEach((u) => console.log(` - ${u.name}, ${u.age}, ${u.city}`));
|
|
119
|
+
// Test 10: Complex query
|
|
120
|
+
console.log('\n10. Complex query (age IN [25, 30] AND city = NYC, ORDER BY name)');
|
|
121
|
+
const query10 = userRepo
|
|
122
|
+
.where({ age: [25, 30] })
|
|
123
|
+
.where({ city: 'NYC' })
|
|
124
|
+
.orderBy('name', 'ASC');
|
|
125
|
+
console.log('SQL:', query10.toSQL());
|
|
126
|
+
const result10 = await query10.find();
|
|
127
|
+
console.log('✓ Results:', result10.length, 'users');
|
|
128
|
+
result10.forEach((u) => console.log(` - ${u.name}, ${u.age}, ${u.city}`));
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
console.error('Error:', error);
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
// Cleanup: Delete test data
|
|
135
|
+
console.log('\nCleaning up...');
|
|
136
|
+
await db.query('TRUNCATE TABLE users RESTART IDENTITY');
|
|
137
|
+
console.log('✓ Cleaned up');
|
|
138
|
+
await db.close();
|
|
139
|
+
console.log('Connection closed');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
testQueryBuilder().catch(console.error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
require("reflect-metadata");
|
|
13
|
+
const Connection_1 = require("../connection/Connection");
|
|
14
|
+
const Column_1 = require("../decorators/Column");
|
|
15
|
+
const PrimaryColumn_1 = require("../decorators/PrimaryColumn");
|
|
16
|
+
const Table_1 = require("../decorators/Table");
|
|
17
|
+
let User = class User {
|
|
18
|
+
};
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, PrimaryColumn_1.PrimaryColumn)(),
|
|
21
|
+
__metadata("design:type", Number)
|
|
22
|
+
], User.prototype, "id", void 0);
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, Column_1.Column)(),
|
|
25
|
+
__metadata("design:type", String)
|
|
26
|
+
], User.prototype, "name", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, Column_1.Column)(),
|
|
29
|
+
__metadata("design:type", Number)
|
|
30
|
+
], User.prototype, "age", void 0);
|
|
31
|
+
User = __decorate([
|
|
32
|
+
(0, Table_1.Table)('users')
|
|
33
|
+
], User);
|
|
34
|
+
async function testRepository() {
|
|
35
|
+
console.log('=== Testing Repository ===\n');
|
|
36
|
+
// Connect to database
|
|
37
|
+
const db = (0, Connection_1.connect)({
|
|
38
|
+
host: 'localhost',
|
|
39
|
+
database: 'accio_db',
|
|
40
|
+
user: 'accio_db',
|
|
41
|
+
password: 'accio_db'
|
|
42
|
+
});
|
|
43
|
+
// Get repository
|
|
44
|
+
const userRepo = db.getRepository(User);
|
|
45
|
+
try {
|
|
46
|
+
// Test 1: Insert a new user
|
|
47
|
+
console.log('1. Testing INSERT...');
|
|
48
|
+
const newUser = new User();
|
|
49
|
+
newUser.name = 'Alice';
|
|
50
|
+
newUser.age = 25;
|
|
51
|
+
const savedUser = await userRepo.insert(newUser);
|
|
52
|
+
console.log('✓ Inserted user:', savedUser);
|
|
53
|
+
// Test 2: Find by ID
|
|
54
|
+
console.log('\n2. Testing FIND BY ID...');
|
|
55
|
+
const foundUser = await userRepo.findById(savedUser.id);
|
|
56
|
+
console.log('✓ Found user:', foundUser);
|
|
57
|
+
// Test 3: Update
|
|
58
|
+
console.log('\n3. Testing UPDATE...');
|
|
59
|
+
if (foundUser) {
|
|
60
|
+
foundUser.age = 26;
|
|
61
|
+
const updatedUser = await userRepo.update(foundUser);
|
|
62
|
+
console.log('✓ Updated user:', updatedUser);
|
|
63
|
+
}
|
|
64
|
+
// Test 4: Save (should update since ID exists)
|
|
65
|
+
console.log('\n4. Testing SAVE (update)...');
|
|
66
|
+
if (foundUser) {
|
|
67
|
+
foundUser.name = 'Alice Updated';
|
|
68
|
+
const savedAgain = await userRepo.save(foundUser);
|
|
69
|
+
console.log('✓ Saved user:', savedAgain);
|
|
70
|
+
}
|
|
71
|
+
// Test 5: Save (should insert since no ID)
|
|
72
|
+
console.log('\n5. Testing SAVE (insert)...');
|
|
73
|
+
const anotherUser = new User();
|
|
74
|
+
anotherUser.name = 'Bob';
|
|
75
|
+
anotherUser.age = 30;
|
|
76
|
+
const insertedViaSave = await userRepo.save(anotherUser);
|
|
77
|
+
console.log('✓ Inserted via save:', insertedViaSave);
|
|
78
|
+
// Test 6: Find all
|
|
79
|
+
console.log('\n6. Testing FIND ALL...');
|
|
80
|
+
const allUsers = await userRepo.findAll();
|
|
81
|
+
console.log(`✓ Found ${allUsers.length} users:`, allUsers);
|
|
82
|
+
// Test 7: Count
|
|
83
|
+
console.log('\n7. Testing COUNT...');
|
|
84
|
+
const count = await userRepo.count();
|
|
85
|
+
console.log(`✓ Total users: ${count}`);
|
|
86
|
+
// Test 8: Exists
|
|
87
|
+
console.log('\n8. Testing EXISTS...');
|
|
88
|
+
const exists = await userRepo.exists(savedUser.id);
|
|
89
|
+
console.log(`✓ User ${savedUser.id} exists:`, exists);
|
|
90
|
+
const notExists = await userRepo.exists(99999);
|
|
91
|
+
console.log(`✓ User 99999 exists:`, notExists);
|
|
92
|
+
// Test 9: Delete
|
|
93
|
+
console.log('\n9. Testing DELETE...');
|
|
94
|
+
await userRepo.delete(savedUser);
|
|
95
|
+
console.log('✓ Deleted user');
|
|
96
|
+
const deletedUser = await userRepo.findById(savedUser.id);
|
|
97
|
+
console.log('✓ User after delete:', deletedUser);
|
|
98
|
+
// Test 10: Delete by ID
|
|
99
|
+
console.log('\n10. Testing DELETE BY ID...');
|
|
100
|
+
await userRepo.deleteById(insertedViaSave.id);
|
|
101
|
+
console.log('✓ Deleted by ID');
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('Error:', error);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
await db.close();
|
|
108
|
+
console.log('\nConnection closed');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
testRepository().catch(console.error);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { connect, Connection } from './connection/Connection';
|
|
2
|
+
export { ConnectionConfig } from './connection/types';
|
|
3
|
+
export { Column, ColumnMetadata, ColumnOptions } from './decorators/Column';
|
|
4
|
+
export { PrimaryColumn } from './decorators/PrimaryColumn';
|
|
5
|
+
export { Table } from './decorators/Table';
|
|
6
|
+
export { Repository } from './repository/Repository';
|
|
7
|
+
export { QueryBuilder } from './query/QueryBuilder';
|
|
8
|
+
export { MetadataStorage } from './metadata/MetadataStorage';
|
|
9
|
+
export { EntityMetadata } from './metadata/types';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetadataStorage = exports.QueryBuilder = exports.Repository = exports.Table = exports.PrimaryColumn = exports.Column = exports.Connection = exports.connect = void 0;
|
|
4
|
+
// Connection
|
|
5
|
+
var Connection_1 = require("./connection/Connection");
|
|
6
|
+
Object.defineProperty(exports, "connect", { enumerable: true, get: function () { return Connection_1.connect; } });
|
|
7
|
+
Object.defineProperty(exports, "Connection", { enumerable: true, get: function () { return Connection_1.Connection; } });
|
|
8
|
+
// Decorators
|
|
9
|
+
var Column_1 = require("./decorators/Column");
|
|
10
|
+
Object.defineProperty(exports, "Column", { enumerable: true, get: function () { return Column_1.Column; } });
|
|
11
|
+
var PrimaryColumn_1 = require("./decorators/PrimaryColumn");
|
|
12
|
+
Object.defineProperty(exports, "PrimaryColumn", { enumerable: true, get: function () { return PrimaryColumn_1.PrimaryColumn; } });
|
|
13
|
+
var Table_1 = require("./decorators/Table");
|
|
14
|
+
Object.defineProperty(exports, "Table", { enumerable: true, get: function () { return Table_1.Table; } });
|
|
15
|
+
// Repository
|
|
16
|
+
var Repository_1 = require("./repository/Repository");
|
|
17
|
+
Object.defineProperty(exports, "Repository", { enumerable: true, get: function () { return Repository_1.Repository; } });
|
|
18
|
+
// Query Builder
|
|
19
|
+
var QueryBuilder_1 = require("./query/QueryBuilder");
|
|
20
|
+
Object.defineProperty(exports, "QueryBuilder", { enumerable: true, get: function () { return QueryBuilder_1.QueryBuilder; } });
|
|
21
|
+
// Metadata
|
|
22
|
+
var MetadataStorage_1 = require("./metadata/MetadataStorage");
|
|
23
|
+
Object.defineProperty(exports, "MetadataStorage", { enumerable: true, get: function () { return MetadataStorage_1.MetadataStorage; } });
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ColumnMetadata } from '@/decorators/Column';
|
|
2
|
+
import type { EntityConstructor, EntityMetadata } from './types';
|
|
3
|
+
export declare class MetadataStorage {
|
|
4
|
+
private static metadataCache;
|
|
5
|
+
/**
|
|
6
|
+
* Extract all metadata from an entity class
|
|
7
|
+
* @param entityClass - The entity class to extract metadata from
|
|
8
|
+
* @returns complete entity metadata
|
|
9
|
+
* @throws Error if entity is missing required decorators
|
|
10
|
+
*/
|
|
11
|
+
static getEntityMetadata(entityClass: EntityConstructor): EntityMetadata;
|
|
12
|
+
/**
|
|
13
|
+
* Validate that an entity has all required metadata
|
|
14
|
+
* @param entityClass - the entity class to validate
|
|
15
|
+
* @returns true if valid, throws error otherwise
|
|
16
|
+
*/
|
|
17
|
+
static validateEntity(entityClass: EntityConstructor): boolean;
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param entityClass
|
|
21
|
+
* @returns get the table name
|
|
22
|
+
*/
|
|
23
|
+
static getTableName(entityCLass: EntityConstructor): string;
|
|
24
|
+
static getColumns(entityClass: EntityConstructor): ColumnMetadata[];
|
|
25
|
+
static getPrimaryColumn(entityClass: EntityConstructor): ColumnMetadata;
|
|
26
|
+
/**
|
|
27
|
+
* Clear the metadata cache (useful for testing)
|
|
28
|
+
*/
|
|
29
|
+
static clearCache(): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetadataStorage = void 0;
|
|
4
|
+
const Column_1 = require("@/decorators/Column");
|
|
5
|
+
const Table_1 = require("@/decorators/Table");
|
|
6
|
+
class MetadataStorage {
|
|
7
|
+
/**
|
|
8
|
+
* Extract all metadata from an entity class
|
|
9
|
+
* @param entityClass - The entity class to extract metadata from
|
|
10
|
+
* @returns complete entity metadata
|
|
11
|
+
* @throws Error if entity is missing required decorators
|
|
12
|
+
*/
|
|
13
|
+
static getEntityMetadata(entityClass) {
|
|
14
|
+
if (this.metadataCache.has(entityClass)) {
|
|
15
|
+
return this.metadataCache.get(entityClass);
|
|
16
|
+
}
|
|
17
|
+
const tableName = (0, Table_1.getTableName)(entityClass);
|
|
18
|
+
if (!tableName) {
|
|
19
|
+
throw new Error(`Entity ${entityClass.name} is missing @Table decorator.
|
|
20
|
+
Did you forget to add @Table('table_name') to the class?
|
|
21
|
+
`);
|
|
22
|
+
}
|
|
23
|
+
const columns = (0, Column_1.getColumns)(entityClass);
|
|
24
|
+
if (columns.length === 0) {
|
|
25
|
+
throw new Error(`Entity ${entityClass.name} has no columns defined.
|
|
26
|
+
Did you forget to add @Column() or @PrimaryColumn() decorators?`);
|
|
27
|
+
}
|
|
28
|
+
const primaryColumns = columns.filter((col) => col.isPrimary);
|
|
29
|
+
if (primaryColumns.length === 0) {
|
|
30
|
+
throw new Error(`Entity ${entityClass.name} has no primary key defined.
|
|
31
|
+
Add @PrimaryColumn() to one of your properties.`);
|
|
32
|
+
}
|
|
33
|
+
if (primaryColumns.length > 1) {
|
|
34
|
+
throw new Error(`Entity ${entityClass.name} has multiple primary keys:
|
|
35
|
+
${primaryColumns.map((c) => c.propertyKey).join(', ')}.
|
|
36
|
+
Only one primary key is supported.`);
|
|
37
|
+
}
|
|
38
|
+
const primaryColumn = primaryColumns[0];
|
|
39
|
+
const metadata = {
|
|
40
|
+
tableName,
|
|
41
|
+
columns,
|
|
42
|
+
primaryColumn
|
|
43
|
+
};
|
|
44
|
+
this.metadataCache.set(entityClass, metadata);
|
|
45
|
+
return metadata;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Validate that an entity has all required metadata
|
|
49
|
+
* @param entityClass - the entity class to validate
|
|
50
|
+
* @returns true if valid, throws error otherwise
|
|
51
|
+
*/
|
|
52
|
+
static validateEntity(entityClass) {
|
|
53
|
+
this.getEntityMetadata(entityClass);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param entityClass
|
|
59
|
+
* @returns get the table name
|
|
60
|
+
*/
|
|
61
|
+
static getTableName(entityCLass) {
|
|
62
|
+
return this.getEntityMetadata(entityCLass).tableName;
|
|
63
|
+
}
|
|
64
|
+
static getColumns(entityClass) {
|
|
65
|
+
return this.getEntityMetadata(entityClass).columns;
|
|
66
|
+
}
|
|
67
|
+
static getPrimaryColumn(entityClass) {
|
|
68
|
+
const metadata = this.getEntityMetadata(entityClass);
|
|
69
|
+
if (!metadata.primaryColumn) {
|
|
70
|
+
throw new Error(`Entity ${entityClass.name} has no primary key`);
|
|
71
|
+
}
|
|
72
|
+
return metadata.primaryColumn;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Clear the metadata cache (useful for testing)
|
|
76
|
+
*/
|
|
77
|
+
static clearCache() {
|
|
78
|
+
this.metadataCache.clear();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.MetadataStorage = MetadataStorage;
|
|
82
|
+
MetadataStorage.metadataCache = new Map();
|