You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.3 KiB
74 lines
2.3 KiB
import { dbGlobal } from "drizzle-pkg/lib/db";
|
|
import { quickNotes } from "drizzle-pkg/lib/schema/content";
|
|
import { eq } from "drizzle-orm";
|
|
import { nextIntegerId } from "../../utils/sqlite-id";
|
|
|
|
export const QUICK_NOTE_MAX_LENGTH = 200000;
|
|
|
|
export function normalizeQuickNoteContent(content: string): string {
|
|
return content.replaceAll("\r\n", "\n");
|
|
}
|
|
|
|
export function validateQuickNoteContentLength(content: string) {
|
|
if (content.length > QUICK_NOTE_MAX_LENGTH) {
|
|
throw createError({ statusCode: 400, statusMessage: "速记内容过长" });
|
|
}
|
|
}
|
|
|
|
export function isQuickNoteUniqueViolation(error: unknown): boolean {
|
|
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
if (!message.includes("UNIQUE constraint failed")) {
|
|
return false;
|
|
}
|
|
return message.includes("quick_notes.user_id") || message.includes("quick_notes_user_id_unique");
|
|
}
|
|
|
|
export async function getQuickNoteByUserId(userId: number) {
|
|
const [row] = await dbGlobal
|
|
.select()
|
|
.from(quickNotes)
|
|
.where(eq(quickNotes.userId, userId))
|
|
.limit(1);
|
|
return row ?? null;
|
|
}
|
|
|
|
export async function upsertQuickNoteByUserId(userId: number, content: string) {
|
|
const normalizedContent = normalizeQuickNoteContent(content);
|
|
validateQuickNoteContentLength(normalizedContent);
|
|
|
|
const existing = await getQuickNoteByUserId(userId);
|
|
if (!existing) {
|
|
try {
|
|
const id = await nextIntegerId(quickNotes, quickNotes.id);
|
|
await dbGlobal.insert(quickNotes).values({
|
|
id,
|
|
userId,
|
|
content: normalizedContent,
|
|
});
|
|
} catch (error) {
|
|
// 处理并发下“先查后插”触发的唯一键冲突:回退为 update。
|
|
if (!isQuickNoteUniqueViolation(error)) {
|
|
throw error;
|
|
}
|
|
await dbGlobal
|
|
.update(quickNotes)
|
|
.set({ content: normalizedContent })
|
|
.where(eq(quickNotes.userId, userId));
|
|
}
|
|
const inserted = await getQuickNoteByUserId(userId);
|
|
if (!inserted) {
|
|
throw new Error(`速记写入失败:userId=${userId}`);
|
|
}
|
|
return inserted;
|
|
}
|
|
|
|
await dbGlobal
|
|
.update(quickNotes)
|
|
.set({ content: normalizedContent })
|
|
.where(eq(quickNotes.userId, userId));
|
|
const updated = await getQuickNoteByUserId(userId);
|
|
if (!updated) {
|
|
throw new Error(`速记更新失败:userId=${userId}`);
|
|
}
|
|
return updated;
|
|
}
|
|
|