refactor(queries): leverage new query syntax of drizzle-orm
This commit is contained in:
parent
fee9f0f39b
commit
395e8874cd
8 changed files with 31 additions and 42 deletions
|
@ -1,6 +1,7 @@
|
|||
import { drizzle } from 'drizzle-orm/node-postgres';
|
||||
import { Pool } from 'pg';
|
||||
import { getConfig } from '../core/TipiConfig/TipiConfig';
|
||||
import * as schema from './schema';
|
||||
|
||||
const connectionString = `postgresql://${getConfig().postgresUsername}:${getConfig().postgresPassword}@${getConfig().postgresHost}:${getConfig().postgresPort}/${
|
||||
getConfig().postgresDatabase
|
||||
|
@ -10,4 +11,5 @@ const pool = new Pool({
|
|||
connectionString,
|
||||
});
|
||||
|
||||
export const db = drizzle(pool);
|
||||
export const db = drizzle(pool, { schema });
|
||||
export type Database = typeof db;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { and, asc, eq, ne, notInArray } from 'drizzle-orm';
|
||||
import { Database } from '@/server/db';
|
||||
import { appTable, NewApp, AppStatus } from '../../db/schema';
|
||||
|
||||
export class AppQueries {
|
||||
private db;
|
||||
|
||||
constructor(p: NodePgDatabase) {
|
||||
constructor(p: Database) {
|
||||
this.db = p;
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,7 @@ export class AppQueries {
|
|||
* @param {string} appId - The id of the app to return
|
||||
*/
|
||||
public async getApp(appId: string) {
|
||||
const apps = await this.db.select().from(appTable).where(eq(appTable.id, appId));
|
||||
return apps[0];
|
||||
return this.db.query.appTable.findFirst({ where: eq(appTable.id, appId) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,14 +54,14 @@ export class AppQueries {
|
|||
* @param {AppStatus} status - The status of the apps to return
|
||||
*/
|
||||
public async getAppsByStatus(status: AppStatus) {
|
||||
return this.db.select().from(appTable).where(eq(appTable.status, status)).orderBy(asc(appTable.id));
|
||||
return this.db.query.appTable.findMany({ where: eq(appTable.status, status), orderBy: asc(appTable.id) });
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all apps installed sorted by id ascending
|
||||
*/
|
||||
public async getApps() {
|
||||
return this.db.select().from(appTable).orderBy(asc(appTable.id));
|
||||
return this.db.query.appTable.findMany({ orderBy: asc(appTable.id) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,10 +71,7 @@ export class AppQueries {
|
|||
* @param {string} id - The id of the app to exclude
|
||||
*/
|
||||
public async getAppsByDomain(domain: string, id: string) {
|
||||
return this.db
|
||||
.select()
|
||||
.from(appTable)
|
||||
.where(and(eq(appTable.domain, domain), eq(appTable.exposed, true), ne(appTable.id, id)));
|
||||
return this.db.query.appTable.findMany({ where: and(eq(appTable.domain, domain), eq(appTable.exposed, true), ne(appTable.id, id)) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { asc, eq } from 'drizzle-orm';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { Database } from '@/server/db';
|
||||
import { userTable, NewUser } from '../../db/schema';
|
||||
|
||||
export class AuthQueries {
|
||||
private db;
|
||||
|
||||
constructor(p: NodePgDatabase) {
|
||||
constructor(p: Database) {
|
||||
this.db = p;
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,7 @@ export class AuthQueries {
|
|||
* @param {string} username - The username of the user to return
|
||||
*/
|
||||
public async getUserByUsername(username: string) {
|
||||
const users = await this.db.select().from(userTable).where(eq(userTable.username, username.trim().toLowerCase()));
|
||||
return users[0];
|
||||
return this.db.query.userTable.findFirst({ where: eq(userTable.username, username.trim().toLowerCase()) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,12 +24,7 @@ export class AuthQueries {
|
|||
* @param {number} id - The id of the user to return
|
||||
*/
|
||||
public async getUserById(id: number) {
|
||||
const users = await this.db
|
||||
.select()
|
||||
.from(userTable)
|
||||
.where(eq(userTable.id, Number(id)));
|
||||
|
||||
return users[0];
|
||||
return this.db.query.userTable.findFirst({ where: eq(userTable.id, Number(id)) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,12 +33,7 @@ export class AuthQueries {
|
|||
* @param {number} id - The id of the user to return
|
||||
*/
|
||||
public async getUserDtoById(id: number) {
|
||||
const users = await this.db
|
||||
.select({ id: userTable.id, username: userTable.username, totpEnabled: userTable.totpEnabled, locale: userTable.locale })
|
||||
.from(userTable)
|
||||
.where(eq(userTable.id, Number(id)));
|
||||
|
||||
return users[0];
|
||||
return this.db.query.userTable.findFirst({ where: eq(userTable.id, Number(id)), columns: { id: true, username: true, totpEnabled: true, locale: true } });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,8 +63,7 @@ export class AuthQueries {
|
|||
* Returns the first operator found in the system
|
||||
*/
|
||||
public async getFirstOperator() {
|
||||
const users = await this.db.select().from(userTable).where(eq(userTable.operator, true)).orderBy(asc(userTable.id)).limit(1);
|
||||
return users[0];
|
||||
return this.db.query.userTable.findFirst({ where: eq(userTable.operator, true) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import validator from 'validator';
|
||||
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { App } from '@/server/db/schema';
|
||||
import { AppQueries } from '@/server/queries/apps/apps.queries';
|
||||
import { TranslatedError } from '@/server/utils/errors';
|
||||
import { Database } from '@/server/db';
|
||||
import { checkAppRequirements, checkEnvFile, generateEnvFile, getAvailableApps, ensureAppFolder, AppInfo, getAppInfo, getUpdateInfo } from './apps.helpers';
|
||||
import { getConfig } from '../../core/TipiConfig';
|
||||
import { EventDispatcher } from '../../core/EventDispatcher';
|
||||
|
@ -25,7 +25,7 @@ const filterApps = (apps: AppInfo[]): AppInfo[] => apps.sort(sortApps).filter(fi
|
|||
export class AppServiceClass {
|
||||
private queries;
|
||||
|
||||
constructor(p: NodePgDatabase) {
|
||||
constructor(p: Database) {
|
||||
this.queries = new AppQueries(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { faker } from '@faker-js/faker';
|
|||
import { TotpAuthenticator } from '@/server/utils/totp';
|
||||
import { generateSessionId } from '@/server/common/session.helpers';
|
||||
import { fromAny, fromPartial } from '@total-typescript/shoehorn';
|
||||
import { mockInsert, mockSelect } from '@/server/tests/drizzle-helpers';
|
||||
import { mockInsert, mockQuery, mockSelect } from '@/server/tests/drizzle-helpers';
|
||||
import { createDatabase, clearDatabase, closeDatabase, TestDatabase } from '@/server/tests/test-utils';
|
||||
import { encrypt } from '../../utils/encryption';
|
||||
import { setConfig } from '../../core/TipiConfig';
|
||||
|
@ -428,7 +428,7 @@ describe('Register', () => {
|
|||
// Arrange
|
||||
const req = {};
|
||||
const email = faker.internet.email();
|
||||
const mockDatabase = { select: mockSelect([]), insert: mockInsert([]) };
|
||||
const mockDatabase = { select: mockSelect([]), insert: mockInsert([]), query: mockQuery(undefined) };
|
||||
const newAuthService = new AuthServiceClass(fromAny(mockDatabase));
|
||||
|
||||
// Act & Assert
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import * as argon2 from 'argon2';
|
||||
import validator from 'validator';
|
||||
import { TotpAuthenticator } from '@/server/utils/totp';
|
||||
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { AuthQueries } from '@/server/queries/auth/auth.queries';
|
||||
import { Context } from '@/server/context';
|
||||
import { TranslatedError } from '@/server/utils/errors';
|
||||
import { Locales, getLocaleFromString } from '@/shared/internationalization/locales';
|
||||
import { generateSessionId } from '@/server/common/session.helpers';
|
||||
import { Database } from '@/server/db';
|
||||
import { getConfig } from '../../core/TipiConfig';
|
||||
import TipiCache from '../../core/TipiCache';
|
||||
import { fileExists, unlinkFile } from '../../common/fs.helpers';
|
||||
|
@ -21,7 +21,7 @@ type UsernamePasswordInput = {
|
|||
export class AuthServiceClass {
|
||||
private queries;
|
||||
|
||||
constructor(p: NodePgDatabase) {
|
||||
constructor(p: Database) {
|
||||
this.queries = new AuthQueries(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
export const mockSelect = <T>(returnValue: T) => jest.fn(() => ({ from: jest.fn(() => ({ where: jest.fn(() => returnValue) })) }));
|
||||
|
||||
export const mockInsert = <T>(returnValue: T) => jest.fn(() => ({ values: jest.fn(() => ({ returning: jest.fn(() => returnValue) })) }));
|
||||
|
||||
export const mockQuery = <T>(returnValue: T) => ({ userTable: { findFirst: jest.fn(() => returnValue) } });
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
/* eslint-disable no-restricted-syntax */
|
||||
import pg, { Pool } from 'pg';
|
||||
import { NodePgDatabase, drizzle } from 'drizzle-orm/node-postgres';
|
||||
import { drizzle } from 'drizzle-orm/node-postgres';
|
||||
import { runPostgresMigrations } from '../run-migration';
|
||||
import { getConfig } from '../core/TipiConfig';
|
||||
import { appTable, userTable } from '../db/schema';
|
||||
import * as schema from '../db/schema';
|
||||
import { Database } from '../db';
|
||||
|
||||
export type TestDatabase = {
|
||||
client: Pool;
|
||||
db: NodePgDatabase;
|
||||
db: Database;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -36,7 +37,7 @@ const createDatabase = async (testsuite: string): Promise<TestDatabase> => {
|
|||
connectionString: `postgresql://${getConfig().postgresUsername}:${getConfig().postgresPassword}@${getConfig().postgresHost}:${getConfig().postgresPort}/${testsuite}?connect_timeout=300`,
|
||||
});
|
||||
|
||||
return { client, db: drizzle(client) };
|
||||
return { client, db: drizzle(client, { schema }) };
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -45,8 +46,8 @@ const createDatabase = async (testsuite: string): Promise<TestDatabase> => {
|
|||
* @param {TestDatabase} database - database to clear
|
||||
*/
|
||||
const clearDatabase = async (database: TestDatabase) => {
|
||||
await database.db.delete(userTable);
|
||||
await database.db.delete(appTable);
|
||||
await database.db.delete(schema.userTable);
|
||||
await database.db.delete(schema.appTable);
|
||||
};
|
||||
|
||||
const closeDatabase = async (database: TestDatabase) => {
|
||||
|
|
Loading…
Reference in a new issue