mirror of
https://github.com/ZeroCatDev/ClassworksKV.git
synced 2025-12-09 23:53:11 +00:00
Compare commits
No commits in common. "8e3b3df1ae4267ec1ae2f5ffb59e9330a9ab98c4" and "e65f84aa22b5960391c5649d57c8ff41564ac106" have entirely different histories.
8e3b3df1ae
...
e65f84aa22
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ClassworksKV",
|
||||
"version": "1.3.8",
|
||||
"version": "1.3.7",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ClassworksKV",
|
||||
"version": "1.3.8",
|
||||
"version": "1.3.7",
|
||||
"dependencies": {
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.59.0",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.205.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ClassworksKV",
|
||||
"version": "1.3.8",
|
||||
"version": "1.3.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node ./bin/www",
|
||||
|
||||
@ -298,25 +298,43 @@ router.post(
|
||||
req.connection.socket?.remoteAddress ||
|
||||
"";
|
||||
|
||||
// 使用优化的批量upsert方法
|
||||
const { results, errors: errorList } = await kvStore.batchUpsert(deviceId, data, creatorIp);
|
||||
const results = [];
|
||||
const errorList = [];
|
||||
|
||||
// 批量处理所有键值对
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
try {
|
||||
const result = await kvStore.upsert(deviceId, key, value, creatorIp);
|
||||
results.push({
|
||||
key: result.key,
|
||||
created: result.createdAt.getTime() === result.updatedAt.getTime(),
|
||||
});
|
||||
// 广播每个键的变更
|
||||
const uuid = res.locals.device?.uuid;
|
||||
if (uuid) {
|
||||
broadcastKeyChanged(uuid, {
|
||||
key: result.key,
|
||||
action: "upsert",
|
||||
created: result.createdAt.getTime() === result.updatedAt.getTime(),
|
||||
updatedAt: result.updatedAt,
|
||||
batch: true,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
errorList.push({
|
||||
key,
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
code: 200,
|
||||
message: "批量导入成功",
|
||||
data: {
|
||||
deviceId,
|
||||
summary: {
|
||||
total: Object.keys(data).length,
|
||||
successful: results.length,
|
||||
failed: errorList.length,
|
||||
},
|
||||
results: results.map(r => ({
|
||||
key: r.key,
|
||||
isNew: r.created,
|
||||
})),
|
||||
...(errorList.length > 0 && { errors: errorList }),
|
||||
},
|
||||
deviceId,
|
||||
total: Object.keys(data).length,
|
||||
successful: results.length,
|
||||
failed: errorList.length,
|
||||
results,
|
||||
errors: errorList.length > 0 ? errorList : undefined,
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@ -102,62 +102,6 @@ class KVStore {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建或更新键值对(优化性能)
|
||||
* @param {number} deviceId - 设备ID
|
||||
* @param {object} data - 键值对数据 {key1: value1, key2: value2, ...}
|
||||
* @param {string} creatorIp - 创建者IP,可选
|
||||
* @returns {object} {results: Array, errors: Array}
|
||||
*/
|
||||
async batchUpsert(deviceId, data, creatorIp = "") {
|
||||
const results = [];
|
||||
const errors = [];
|
||||
|
||||
// 使用事务处理所有操作
|
||||
await prisma.$transaction(async (tx) => {
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
try {
|
||||
const item = await tx.kVStore.upsert({
|
||||
where: {
|
||||
deviceId_key: {
|
||||
deviceId: deviceId,
|
||||
key: key,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
value,
|
||||
...(creatorIp && {creatorIp}),
|
||||
},
|
||||
create: {
|
||||
deviceId: deviceId,
|
||||
key: key,
|
||||
value,
|
||||
creatorIp,
|
||||
},
|
||||
});
|
||||
|
||||
results.push({
|
||||
key: item.key,
|
||||
created: item.createdAt.getTime() === item.updatedAt.getTime(),
|
||||
createdAt: item.createdAt,
|
||||
updatedAt: item.updatedAt,
|
||||
});
|
||||
} catch (error) {
|
||||
errors.push({
|
||||
key,
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 在事务完成后,一次性更新指标
|
||||
const totalKeys = await prisma.kVStore.count();
|
||||
keysTotal.set(totalKeys);
|
||||
|
||||
return { results, errors };
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过设备ID和键名删除
|
||||
* @param {number} deviceId - 设备ID
|
||||
@ -275,37 +219,6 @@ class KVStore {
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定设备的统计信息
|
||||
* @param {number} deviceId - 设备ID
|
||||
* @returns {object} 统计信息
|
||||
*/
|
||||
async getStats(deviceId) {
|
||||
const [totalKeys, oldestKey, newestKey] = await Promise.all([
|
||||
prisma.kVStore.count({
|
||||
where: { deviceId },
|
||||
}),
|
||||
prisma.kVStore.findFirst({
|
||||
where: { deviceId },
|
||||
orderBy: { createdAt: "asc" },
|
||||
select: { createdAt: true, key: true },
|
||||
}),
|
||||
prisma.kVStore.findFirst({
|
||||
where: { deviceId },
|
||||
orderBy: { updatedAt: "desc" },
|
||||
select: { updatedAt: true, key: true },
|
||||
}),
|
||||
]);
|
||||
|
||||
return {
|
||||
totalKeys,
|
||||
oldestKey: oldestKey?.key,
|
||||
oldestCreatedAt: oldestKey?.createdAt,
|
||||
newestKey: newestKey?.key,
|
||||
newestUpdatedAt: newestKey?.updatedAt,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default new KVStore();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user