@aetherframework/database 1.1.0 → 1.1.2
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/examples/mysql-test-pressure.js +1530 -0
- package/examples/test-direct.js +116 -0
- package/examples/transaction_example.js +127 -0
- package/package.json +3 -1
- package/src/DatabaseManager.js +565 -0
- package/src/core/ConnectionManager.js +351 -0
- package/src/core/DatabaseFactory.js +188 -0
- package/src/core/MongoQueryBuilder.js +576 -0
- package/src/core/PluginManager.js +968 -0
- package/src/core/QueryBuilder.js +4394 -0
- package/src/core/TransactionManager.js +40 -0
- package/src/drivers/clickhouse-driver.js +272 -0
- package/src/drivers/index.js +273 -0
- package/src/drivers/mongodb-driver.js +87 -0
- package/src/drivers/mssql-driver.js +117 -0
- package/src/drivers/mysql-driver.js +169 -0
- package/src/drivers/oracle-driver.js +101 -0
- package/src/drivers/postgres-driver.js +234 -0
- package/src/drivers/redis-driver.js +52 -0
- package/src/drivers/sqlite-driver.js +67 -0
- package/src/middleware/connection-pool.js +455 -0
- package/src/middleware/performance-monitor.js +652 -0
- package/src/middleware/query-cache.js +500 -0
- package/src/middleware/query-logger.js +262 -0
- package/src/plugins/AuditPlugin.js +447 -0
- package/src/plugins/BasePlugin.js +418 -0
- package/src/plugins/BatchOperationPlugin.js +165 -0
- package/src/plugins/CachePlugin.js +407 -0
- package/src/plugins/CtePlugin.js +523 -0
- package/src/plugins/DistributedPlugin.js +543 -0
- package/src/plugins/EncryptionPlugin.js +211 -0
- package/src/plugins/FullTextSearchPlugin.js +164 -0
- package/src/plugins/GeospatialPlugin.js +219 -0
- package/src/plugins/GraphQLPlugin.js +162 -0
- package/src/plugins/HookPlugin.js +211 -0
- package/src/plugins/JsonPlugin.js +366 -0
- package/src/plugins/OptimisticLockPlugin.js +374 -0
- package/src/plugins/PerformancePlugin.js +175 -0
- package/src/plugins/ResiliencePlugin.js +114 -0
- package/src/plugins/ShardingPlugin.js +227 -0
- package/src/plugins/SoftDeletePlugin.js +258 -0
- package/src/plugins/SyncPlugin.js +373 -0
- package/src/plugins/VersioningPlugin.js +314 -0
- package/src/plugins/WindowFunctionPlugin.js +343 -0
- package/src/utils/config-loader.js +632 -0
- package/src/utils/error-handler.js +724 -0
- package/src/utils/migration-runner.js +1066 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// test-direct.js
|
|
2
|
+
import DatabaseManager from "../src/DatabaseManager.js";
|
|
3
|
+
|
|
4
|
+
const config = {
|
|
5
|
+
default: "primary",
|
|
6
|
+
connections: {
|
|
7
|
+
primary: {
|
|
8
|
+
type: "mysql",
|
|
9
|
+
enabled: true,
|
|
10
|
+
host: "127.0.0.1",
|
|
11
|
+
port: 3306,
|
|
12
|
+
user: "root",
|
|
13
|
+
password: "123456",
|
|
14
|
+
database: "test_db",
|
|
15
|
+
connectionLimit: 10,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
console.log("🚀 Aether QueryBuilder 最终功能验证测试\n");
|
|
21
|
+
|
|
22
|
+
const db = new DatabaseManager(config);
|
|
23
|
+
|
|
24
|
+
async function runTest() {
|
|
25
|
+
try {
|
|
26
|
+
await db.init();
|
|
27
|
+
console.log("✅ DatabaseManager 初始化成功\n");
|
|
28
|
+
|
|
29
|
+
// 准备测试环境
|
|
30
|
+
await db.execute("DROP TABLE IF EXISTS users");
|
|
31
|
+
await db.execute(`
|
|
32
|
+
CREATE TABLE users (
|
|
33
|
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
34
|
+
name VARCHAR(255) NOT NULL,
|
|
35
|
+
email VARCHAR(255) UNIQUE,
|
|
36
|
+
age INT,
|
|
37
|
+
status BOOLEAN DEFAULT true,
|
|
38
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
39
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
|
40
|
+
`);
|
|
41
|
+
console.log("✅ 测试表已重建\n");
|
|
42
|
+
|
|
43
|
+
// ==================== 业务测试 ====================
|
|
44
|
+
console.log("📝 1. 插入测试数据");
|
|
45
|
+
await db
|
|
46
|
+
.table("users")
|
|
47
|
+
.insert({
|
|
48
|
+
name: "张三",
|
|
49
|
+
email: "zhangsan@example.com",
|
|
50
|
+
age: 25,
|
|
51
|
+
})
|
|
52
|
+
.execute();
|
|
53
|
+
|
|
54
|
+
await db
|
|
55
|
+
.table("users")
|
|
56
|
+
.insert({
|
|
57
|
+
name: "李四",
|
|
58
|
+
email: "lisi@example.com",
|
|
59
|
+
age: 28,
|
|
60
|
+
})
|
|
61
|
+
.execute();
|
|
62
|
+
|
|
63
|
+
console.log("🔍 2. 查询所有用户");
|
|
64
|
+
const users = await db.table("users").select("*").execute();
|
|
65
|
+
console.table(users);
|
|
66
|
+
|
|
67
|
+
console.log("\n📊 3. 条件查询 + 排序");
|
|
68
|
+
const youngUsers = await db
|
|
69
|
+
.table("users")
|
|
70
|
+
.select("id", "name", "age")
|
|
71
|
+
.where("age", ">", 20)
|
|
72
|
+
.orderBy("age", "DESC")
|
|
73
|
+
.execute();
|
|
74
|
+
console.table(youngUsers);
|
|
75
|
+
|
|
76
|
+
console.log("\n✏️ 4. 更新数据");
|
|
77
|
+
await db
|
|
78
|
+
.table("users")
|
|
79
|
+
.where("name", "张三")
|
|
80
|
+
.update({ age: 30, status: false })
|
|
81
|
+
.execute();
|
|
82
|
+
|
|
83
|
+
console.log("\n🗑️ 5. 删除数据");
|
|
84
|
+
await db.table("users").where("name", "李四").delete().execute();
|
|
85
|
+
|
|
86
|
+
console.log("\n📦 6. 批量插入");
|
|
87
|
+
await db
|
|
88
|
+
.table("users")
|
|
89
|
+
.insert([
|
|
90
|
+
{ name: "王五", email: "wangwu@example.com", age: 32 },
|
|
91
|
+
{ name: "赵六", email: "zhaoliu@example.com", age: 29 },
|
|
92
|
+
{ name: "孙七", email: "sunqi@example.com", age: 35 },
|
|
93
|
+
])
|
|
94
|
+
.execute();
|
|
95
|
+
|
|
96
|
+
console.log("\n🎯 7. 复杂查询测试");
|
|
97
|
+
const result = await db
|
|
98
|
+
.table("users")
|
|
99
|
+
.select("id", "name", "age")
|
|
100
|
+
.where("age", ">=", 30)
|
|
101
|
+
.orderBy("age", "DESC")
|
|
102
|
+
.execute();
|
|
103
|
+
console.table(result);
|
|
104
|
+
|
|
105
|
+
console.log("\n✅ 所有测试全部通过!");
|
|
106
|
+
console.log("🎉 QueryBuilder 已达到生产可用标准");
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error("\n❌ 测试失败:", error.message);
|
|
109
|
+
console.error(error);
|
|
110
|
+
} finally {
|
|
111
|
+
await db.close();
|
|
112
|
+
console.log("\n🔌 数据库连接已安全关闭");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
runTest();
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// packages/database/examples/transaction_example.js
|
|
2
|
+
import DatabaseManager from '../src/DatabaseManager.js';
|
|
3
|
+
|
|
4
|
+
async function transactionExample() {
|
|
5
|
+
console.log("🚀 Starting transaction examples...\n");
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
// Single database configuration with retry settings
|
|
9
|
+
const singleDbConfig = {
|
|
10
|
+
enabled: true,
|
|
11
|
+
default: "primary",
|
|
12
|
+
connections: {
|
|
13
|
+
primary: {
|
|
14
|
+
type: "mysql",
|
|
15
|
+
host: "127.0.0.1",
|
|
16
|
+
port: 3306,
|
|
17
|
+
user: "root",
|
|
18
|
+
password: "123456",
|
|
19
|
+
database: "transaction_db",
|
|
20
|
+
enabled: true,
|
|
21
|
+
retry: {
|
|
22
|
+
maxAttempts: 3,
|
|
23
|
+
delay: 1000,
|
|
24
|
+
backoff: true
|
|
25
|
+
},
|
|
26
|
+
pool: {
|
|
27
|
+
min: 0,
|
|
28
|
+
max: 10
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// 在函数作用域内定义变量
|
|
35
|
+
let singleDb = null;
|
|
36
|
+
let multiDb = null;
|
|
37
|
+
let orderId = null;
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
// EXAMPLE 1: Basic transaction (single database)
|
|
41
|
+
console.log("💳 Example 1: Basic transaction (single database)");
|
|
42
|
+
singleDb = new DatabaseManager(singleDbConfig);
|
|
43
|
+
await singleDb.init();
|
|
44
|
+
|
|
45
|
+
// 执行简单事务
|
|
46
|
+
const singleResult = await singleDb.transaction(async (trx) => {
|
|
47
|
+
// 创建测试表 - 使用原始查询而不是预处理语句
|
|
48
|
+
await trx.query(`
|
|
49
|
+
CREATE TABLE IF NOT EXISTS test_transactions (
|
|
50
|
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
51
|
+
name VARCHAR(100) NOT NULL,
|
|
52
|
+
amount DECIMAL(10,2) NOT NULL,
|
|
53
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
54
|
+
)
|
|
55
|
+
`);
|
|
56
|
+
|
|
57
|
+
// 插入数据 - 使用预处理语句
|
|
58
|
+
const insertResult = await trx.query(
|
|
59
|
+
"INSERT INTO test_transactions (name, amount) VALUES (?, ?)",
|
|
60
|
+
["Test Transaction", 100.50]
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
console.log(`✅ Inserted record with ID: ${insertResult.insertId}`);
|
|
64
|
+
|
|
65
|
+
// 查询数据 - 使用预处理语句
|
|
66
|
+
const selectResult = await trx.query(
|
|
67
|
+
"SELECT * FROM test_transactions WHERE id = ?",
|
|
68
|
+
[insertResult.insertId]
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
console.log(`✅ Retrieved record:`, selectResult);
|
|
72
|
+
|
|
73
|
+
// 更新数据 - 使用预处理语句
|
|
74
|
+
await trx.query(
|
|
75
|
+
"UPDATE test_transactions SET amount = ? WHERE id = ?",
|
|
76
|
+
[200.75, insertResult.insertId]
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
console.log(`✅ Updated record ${insertResult.insertId}`);
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
success: true,
|
|
83
|
+
insertedId: insertResult.insertId,
|
|
84
|
+
message: "Single database transaction completed successfully"
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
console.log(`🎉 Single database transaction result:`, singleResult);
|
|
89
|
+
|
|
90
|
+
// 清理测试表
|
|
91
|
+
await singleDb.query("DROP TABLE IF EXISTS test_transactions");
|
|
92
|
+
console.log("🧹 Cleaned up test table");
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
success: true,
|
|
96
|
+
message: "Transaction examples completed successfully"
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error("❌ Transaction example failed:", error.message);
|
|
101
|
+
console.error("Error stack:", error.stack);
|
|
102
|
+
|
|
103
|
+
// 清理代码
|
|
104
|
+
if (singleDb) {
|
|
105
|
+
try {
|
|
106
|
+
console.log("🔄 Starting cleanup after transaction failure...");
|
|
107
|
+
await singleDb.query("DROP TABLE IF EXISTS test_transactions");
|
|
108
|
+
console.log("✅ Cleanup completed");
|
|
109
|
+
} catch (cleanupError) {
|
|
110
|
+
console.error("⚠️ Cleanup failed:", cleanupError.message);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
success: false,
|
|
116
|
+
error: error.message,
|
|
117
|
+
timestamp: new Date().toISOString()
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error("❌ Transaction example failed:", error.message);
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export default transactionExample;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aetherframework/database",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Zero-dependency, multi-database integration for AetherJS API framework with advanced query builder and connection pooling",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -48,6 +48,8 @@
|
|
|
48
48
|
"connection-pool.js",
|
|
49
49
|
"query-builder.js",
|
|
50
50
|
"drivers/",
|
|
51
|
+
"src",
|
|
52
|
+
"examples",
|
|
51
53
|
"types.js",
|
|
52
54
|
"README.md",
|
|
53
55
|
"LICENSE"
|