added blocked database

This commit is contained in:
Maieul BOYER 2025-11-29 16:05:18 +01:00 committed by apetitco
parent 438cb10abb
commit 270c3297fd
3 changed files with 72 additions and 1 deletions

View file

@ -4,11 +4,13 @@ import { FastifyInstance, FastifyPluginAsync } from 'fastify';
import { isNullish } from '@shared/utils'; import { isNullish } from '@shared/utils';
import { Database as DbImpl } from './mixin/_base'; import { Database as DbImpl } from './mixin/_base';
import { IUserDb, UserImpl } from './mixin/user'; import { IUserDb, UserImpl } from './mixin/user';
import { IBlockedDb, BlockedImpl } from './mixin/blocked';
Object.assign(DbImpl.prototype, UserImpl); Object.assign(DbImpl.prototype, UserImpl);
Object.assign(DbImpl.prototype, BlockedImpl);
export interface Database extends DbImpl, IUserDb { } export interface Database extends DbImpl, IUserDb, IBlockedDb { }
// When using .decorate you have to specify added properties for Typescript // When using .decorate you have to specify added properties for Typescript
declare module 'fastify' { declare module 'fastify' {

View file

@ -7,3 +7,17 @@ CREATE TABLE IF NOT EXISTS user (
guest INTEGER NOT NULL DEFAULT 0, guest INTEGER NOT NULL DEFAULT 0,
oauth2 TEXT DEFAULT NULL oauth2 TEXT DEFAULT NULL
); );
CREATE TABLE IF NOT EXISTS blocked (
id INTEGER PRIMARY KEY NOT NULL,
user TEXT NOT NULL,
blocked TEXT NOT NULL,
FOREIGN KEY(user) REFERENCES user(id);
FOREIGN KEY(blocked) REFERENCES user(id);
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_blocked_user_pair
ON blocked(user, blocked);

View file

@ -0,0 +1,55 @@
import { isNullish } from '@shared/utils';
import type { Database } from './_base';
import { UserId } from './user';
// never use this directly
// describe every function in the object
export interface IBlockedDb extends Database {
getBlockedUserFor(id: UserId): BlockedData[],
addBlockedUserFor(id: UserId, blocked: UserId): void,
removeBlockedUserFor(id: UserId, blocked: UserId): void,
unblockAllUserFor(id: UserId): void,
};
export const BlockedImpl: Omit<IBlockedDb, keyof Database> = {
getBlockedUserFor(this: IBlockedDb, id: UserId): BlockedData[] {
const query = this.prepare('SELECT * FROM blocked WHERE user = @id');
const data = query.all({ id }) as Partial<BlockedData>[];
return data.map(blockedFromRow).filter(b => !isNullish(b));
},
unblockAllUserFor(this: IBlockedDb, id: UserId): void {
this.prepare('DELETE FROM blocked WHERE user = @id').run({ id });
},
addBlockedUserFor(this: IBlockedDb, id: UserId, blocked: UserId): void {
this.prepare('INSERT OR IGNORE INTO blocked (user, blocked) VALUES (@id, @blocked)').run({ id, blocked });
},
removeBlockedUserFor(this: IBlockedDb, id: UserId, blocked: UserId): void {
this.prepare('DELETE FROM blocked WHERE user = @id AND blocked = @blocked').run({ id, blocked });
},
};
export type BlockedId = number & { readonly __brand: unique symbol };
export type BlockedData = {
readonly id: BlockedId;
readonly user: UserId;
readonly blocked: UserId;
};
/**
* Get a blocked from a row
*
* @param row The data from sqlite
*
* @returns The blocked if it exists, undefined otherwise
*/
export function blockedFromRow(row?: Partial<BlockedData>): BlockedData | undefined {
if (isNullish(row)) return undefined;
if (isNullish(row.id)) return undefined;
if (isNullish(row.user)) return undefined;
if (isNullish(row.blocked)) return undefined;
return row as BlockedData;
}