fix an issue with db
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ export function createDatabase(config) {
|
||||
|
||||
const db = new Database(config.dbPath);
|
||||
initializeSchema(db);
|
||||
runMigrations(db, config);
|
||||
initializeAttachments(db);
|
||||
runMigrations(db, config);
|
||||
return db;
|
||||
}
|
||||
|
||||
@@ -265,6 +265,59 @@ export function runMigrations(db, {dropLegacyChats = false} = {}) {
|
||||
ensureColumn("users", userColumns, "role", "ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('user', 'admin'))");
|
||||
ensureColumn("users", userColumns, "session_version", "ALTER TABLE users ADD COLUMN session_version INTEGER DEFAULT 0");
|
||||
db.prepare("UPDATE users SET session_version = 0 WHERE session_version IS NULL").run();
|
||||
|
||||
// Older databases allowed usernames that differed only by case. Repair those
|
||||
// rows before adding the case-insensitive uniqueness guarantee. Keep the first
|
||||
// account unchanged and give later accounts a stable, recoverable username;
|
||||
// moving their owned rows prevents orphaned workspace data.
|
||||
const conflictingUsers = db.prepare(`
|
||||
SELECT LOWER(username) AS username_lower
|
||||
FROM users
|
||||
GROUP BY LOWER(username)
|
||||
HAVING COUNT(*) > 1
|
||||
`).all();
|
||||
if (conflictingUsers.length > 0) {
|
||||
const ownershipColumns = [
|
||||
["chat_sessions", "username"],
|
||||
["chat_memories", "username"],
|
||||
["persona_chat_state", "username"],
|
||||
["personas", "username"],
|
||||
["personas", "source_creator_username"],
|
||||
["user_settings", "username"],
|
||||
["persona_market", "creator_username"],
|
||||
["persona_versions", "username"],
|
||||
["prompt_templates", "username"],
|
||||
["persona_market_favorites", "username"],
|
||||
["persona_market_ratings", "username"],
|
||||
["persona_market_reports", "reporter_username"],
|
||||
["attachments", "username"],
|
||||
["upload_leases", "username"],
|
||||
["workspace_operation_leases", "username"]
|
||||
];
|
||||
const existingTables = new Set(db.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all().map(({name}) => name));
|
||||
const updateStatements = ownershipColumns
|
||||
.filter(([table]) => existingTables.has(table))
|
||||
.map(([table, column]) => [
|
||||
table,
|
||||
column,
|
||||
db.prepare(`UPDATE "${table}" SET "${column}" = ? WHERE "${column}" = ?`)
|
||||
]);
|
||||
const repairConflicts = db.transaction(() => {
|
||||
db.pragma("defer_foreign_keys = ON");
|
||||
for (const {username_lower: usernameLower} of conflictingUsers) {
|
||||
const rows = db.prepare("SELECT rowid, username FROM users WHERE LOWER(username) = ? ORDER BY rowid").all(usernameLower);
|
||||
for (const row of rows.slice(1)) {
|
||||
const suffix = `-legacy-${row.rowid}`;
|
||||
const nextUsername = `${row.username.slice(0, Math.max(1, 64 - suffix.length))}${suffix}`;
|
||||
for (const [, , statement] of updateStatements) {
|
||||
statement.run(nextUsername, row.username);
|
||||
}
|
||||
db.prepare("UPDATE users SET username = ? WHERE username = ?").run(nextUsername, row.username);
|
||||
}
|
||||
}
|
||||
});
|
||||
repairConflicts();
|
||||
}
|
||||
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS users_username_lower ON users (LOWER(username))");
|
||||
|
||||
const personaColumns = db.prepare("PRAGMA table_info(personas)").all();
|
||||
|
||||
Reference in New Issue
Block a user