add notelinks tabel for note to note references

This commit is contained in:
Arkaprava Gaine
2026-08-05 10:51:08 +02:00
committed by Fred Cabassut
parent c640868957
commit 331c56981d
7 changed files with 1323 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
CREATE TABLE `note_links` (
`source_note_id` text NOT NULL,
`target_note_id` text NOT NULL,
FOREIGN KEY (`source_note_id`) REFERENCES `notes`(`id`) ON UPDATE no action ON DELETE cascade,
FOREIGN KEY (`target_note_id`) REFERENCES `notes`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
CREATE INDEX `note_links_source_idx` ON `note_links` (`source_note_id`);--> statement-breakpoint
CREATE INDEX `note_links_target_idx` ON `note_links` (`target_note_id`);
File diff suppressed because it is too large Load Diff
+7
View File
@@ -29,6 +29,13 @@
"when": 1774037379518,
"tag": "0003_uneven_tomorrow_man",
"breakpoints": true
},
{
"idx": 4,
"version": "6",
"when": 1785824271578,
"tag": "0004_violet_nicolaos",
"breakpoints": true
}
]
}
+7
View File
@@ -226,6 +226,13 @@ sqlite.exec(`
created_at INTEGER NOT NULL,
last_used_at INTEGER
);
CREATE TABLE IF NOT EXISTS note_links (
source_note_id TEXT NOT NULL REFERENCES notes(id) ON DELETE CASCADE,
target_note_id TEXT NOT NULL REFERENCES notes(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS note_links_source_idx ON note_links(source_note_id);
CREATE INDEX IF NOT EXISTS note_links_target_idx ON note_links(target_note_id);
`);
// Replace old tags unique index with compound index including user_id
@@ -0,0 +1,44 @@
import { describe, it, expect } from 'vitest';
import { eq } from 'drizzle-orm';
import { createTestDb } from './test-helpers.js';
import { notes, noteLinks, users } from './schema.js';
describe('noteLinks schema', () => {
it('should store a source/target link row', () => {
const { db } = createTestDb();
db.insert(users)
.values({ email: 'a@test.com', displayName: 'A', role: 'user', authProvider: 'password', createdAt: new Date() })
.run();
db.insert(notes)
.values([
{ id: 'source-note', userId: 1, title: 'Source', content: '', createdAt: new Date(), updatedAt: new Date() },
{ id: 'target-note', userId: 1, title: 'Target', content: '', createdAt: new Date(), updatedAt: new Date() }
])
.run();
db.insert(noteLinks).values({ sourceNoteId: 'source-note', targetNoteId: 'target-note' }).run();
const rows = db.select().from(noteLinks).all();
expect(rows).toEqual([{ sourceNoteId: 'source-note', targetNoteId: 'target-note' }]);
});
it('should cascade-delete link rows when the source note is deleted', () => {
const { db, sqlite } = createTestDb();
sqlite.pragma('foreign_keys = ON');
db.insert(users)
.values({ email: 'a@test.com', displayName: 'A', role: 'user', authProvider: 'password', createdAt: new Date() })
.run();
db.insert(notes)
.values([
{ id: 'source-note', userId: 1, title: 'Source', content: '', createdAt: new Date(), updatedAt: new Date() },
{ id: 'target-note', userId: 1, title: 'Target', content: '', createdAt: new Date(), updatedAt: new Date() }
])
.run();
db.insert(noteLinks).values({ sourceNoteId: 'source-note', targetNoteId: 'target-note' }).run();
db.delete(notes).where(eq(notes.id, 'source-note')).run();
expect(db.select().from(noteLinks).all()).toEqual([]);
});
});
+16
View File
@@ -80,6 +80,22 @@ export const noteTags = sqliteTable(
]
);
export const noteLinks = sqliteTable(
'note_links',
{
sourceNoteId: text('source_note_id')
.references(() => notes.id, { onDelete: 'cascade' })
.notNull(),
targetNoteId: text('target_note_id')
.references(() => notes.id, { onDelete: 'cascade' })
.notNull()
},
(table) => [
index('note_links_source_idx').on(table.sourceNoteId),
index('note_links_target_idx').on(table.targetNoteId)
]
);
export const attachments = sqliteTable('attachments', {
id: text('id').primaryKey(),
userId: integer('user_id')
+7
View File
@@ -68,6 +68,13 @@ export function createTestDb(options?: { seedUser?: boolean }) {
CREATE INDEX note_tags_note_id_idx ON note_tags(note_id);
CREATE INDEX note_tags_tag_id_idx ON note_tags(tag_id);
CREATE TABLE note_links (
source_note_id TEXT NOT NULL REFERENCES notes(id) ON DELETE CASCADE,
target_note_id TEXT NOT NULL REFERENCES notes(id) ON DELETE CASCADE
);
CREATE INDEX note_links_source_idx ON note_links(source_note_id);
CREATE INDEX note_links_target_idx ON note_links(target_note_id);
CREATE TABLE note_collaborators (
note_id TEXT NOT NULL REFERENCES notes(id) ON DELETE CASCADE,
user_id INTEGER NOT NULL REFERENCES users(id),