db/events: rework tags, make event_id a FK to events again, drop value_2 and value_3

This commit is contained in:
Alex Gleason 2023-09-05 16:11:38 -05:00
parent 4708839fd6
commit 2ff40c8fc5
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
3 changed files with 79 additions and 24 deletions

View File

@ -29,9 +29,7 @@ interface EventFTSRow {
interface TagRow {
tag: string;
value_1: string | null;
value_2: string | null;
value_3: string | null;
value: string;
event_id: string;
}

View File

@ -34,17 +34,14 @@ function insertEvent(event: Event): Promise<void> {
}
const tagCounts: Record<string, number> = {};
const tags = event.tags.reduce<Insertable<TagRow>[]>((results, tag) => {
const tagName = tag[0];
tagCounts[tagName] = (tagCounts[tagName] || 0) + 1;
const tags = event.tags.reduce<Insertable<TagRow>[]>((results, [name, value]) => {
tagCounts[name] = (tagCounts[name] || 0) + 1;
if (tagConditions[tagName]?.({ event, count: tagCounts[tagName] - 1 })) {
if (value && tagConditions[name]?.({ event, count: tagCounts[name] - 1 })) {
results.push({
event_id: event.id,
tag: tagName,
value_1: tag[1] || null,
value_2: tag[2] || null,
value_3: tag[3] || null,
tag: name,
value,
});
}
@ -111,7 +108,7 @@ function getFilterQuery(filter: DittoFilter) {
query = query
.leftJoin('tags', 'tags.event_id', 'events.id')
.where('tags.tag', '=', tag)
.where('tags.value_1', 'in', value) as typeof query;
.where('tags.value', 'in', value) as typeof query;
}
}
@ -157,19 +154,11 @@ async function getFilters<K extends number>(
/** Delete events based on filters from the database. */
function deleteFilters<K extends number>(filters: DittoFilter<K>[]) {
if (!filters.length) return Promise.resolve([]);
const query = getFiltersQuery(filters);
return db.transaction().execute(async (trx) => {
const query = getFiltersQuery(filters).clearSelect().select('id');
await trx.deleteFrom('tags')
.where('event_id', 'in', () => query)
.where('tag', 'not in', ['d', 'proxy'])
.execute();
return trx.deleteFrom('events')
.where('id', 'in', () => query)
.execute();
});
return db.deleteFrom('events')
.where('id', 'in', () => query.clearSelect().select('id'))
.execute();
}
/** Get number of events that would be returned by filters. */

View File

@ -0,0 +1,68 @@
import { Kysely, sql } from '@/deps.ts';
export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.createTable('tags_new')
.addColumn('tag', 'text', (col) => col.notNull())
.addColumn('value', 'text', (col) => col.notNull())
.addColumn('event_id', 'text', (col) => col.references('events.id').onDelete('cascade'))
.execute();
await sql`
INSERT INTO tags_new (tag, value, event_id)
SELECT tag, value_1 as value, event_id
FROM tags
WHERE value_1 IS NOT NULL
`.execute(db);
await db.schema
.dropTable('tags')
.execute();
await db.schema
.alterTable('tags_new')
.renameTo('tags').execute();
await db.schema
.createIndex('idx_tags_tag')
.on('tags')
.column('tag')
.execute();
await db.schema
.createIndex('idx_tags_value')
.on('tags')
.column('value')
.execute();
await db.schema
.createIndex('idx_tags_event_id')
.on('tags')
.column('event_id')
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema.dropTable('tags').execute();
await db.schema
.createTable('tags')
.addColumn('tag', 'text', (col) => col.notNull())
.addColumn('value_1', 'text')
.addColumn('value_2', 'text')
.addColumn('value_3', 'text')
.addColumn('event_id', 'text', (col) => col.notNull())
.execute();
await db.schema
.createIndex('idx_tags_tag')
.on('tags')
.column('tag')
.execute();
await db.schema
.createIndex('idx_tags_value_1')
.on('tags')
.column('value_1')
.execute();
}