feat: things are happening...
This commit is contained in:
@@ -1,42 +1,73 @@
|
||||
import { Client } from "postgres";
|
||||
import config from "./config.ts";
|
||||
import {Maybe} from "./Maybe.ts";
|
||||
import {JSONObject} from "./JSON.ts";
|
||||
import { JSONObject } from "./JSON.ts";
|
||||
import { Result, StoccaTreError } from "./Result.ts";
|
||||
|
||||
type Interpolable = number | string | bigint | null | boolean;
|
||||
type UnionToIntersection<Union> =
|
||||
(Union extends any ? (x: Union) => any : never) extends (x: infer Intersection) => any
|
||||
? Intersection
|
||||
: never;
|
||||
type SQLWithArg<Arg> = Arg extends string ? `${string}$${Arg}${string}` : never;
|
||||
type SQLWithArgs<Args extends Record<string, Interpolable>> = UnionToIntersection<SQLWithArg<keyof Args>>;
|
||||
type ArgNamesInSQL<SQL extends string> =
|
||||
SQL extends `${string}$${infer Arg1} ${infer SQLAfterArg1}`
|
||||
? Arg1 extends `${infer Arg1NoTrailing}${";" | "," | "'" | "\"" | "(" | ")"}`
|
||||
? Arg1NoTrailing | ArgNamesInSQL<SQLAfterArg1>
|
||||
: Arg1 | ArgNamesInSQL<SQLAfterArg1>
|
||||
: SQL extends `${string}$${infer ArgN}`
|
||||
? ArgN extends `${infer ArgNNoTrailing}${";" | "," | "'" | "\"" | "(" | ")"}`
|
||||
? ArgNNoTrailing
|
||||
: ArgN
|
||||
: never;
|
||||
|
||||
type ParametrisedSQL = `${string}$${string}`;
|
||||
type IsPlainSQL<T> = T extends ParametrisedSQL ? never : T;
|
||||
type ArgsForSQL<SQL extends string> = SQL extends ParametrisedSQL
|
||||
? Record<ArgNamesInSQL<SQL>, Interpolable>
|
||||
: JSONObject | undefined;
|
||||
|
||||
// Helper for casting queries
|
||||
export type Q<T extends JSONObject> = Result<T[]>;
|
||||
|
||||
export type WithoutId<T> = Omit<T, "id">;
|
||||
|
||||
export interface StoccaTreDbConn {
|
||||
query<T extends JSONObject | JSONObject[]>(query: string): Promise<Maybe<T>>,
|
||||
query<Q extends string>(query: Q, ...args: Q extends IsPlainSQL<Q> ? [(JSONObject | undefined)?] : [ArgsForSQL<Q>]): Promise<Result<JSONObject[]>>;
|
||||
}
|
||||
|
||||
export default function createNewDbConnection(): StoccaTreDbConn {
|
||||
const postgresClient = new Client({
|
||||
hostname: config.hostname,
|
||||
password: config.password,
|
||||
user: config.username,
|
||||
database: "stocca_tre",
|
||||
port: config.port,
|
||||
});
|
||||
await postgresClient.connect();
|
||||
return {
|
||||
async queryMany<T extends JSONObject[]>(query: string): Promise<Maybe<{ rows: T, count: number }>> {
|
||||
try {
|
||||
const result = await postgresClient.queryArray<T>(query);
|
||||
return {
|
||||
just: {
|
||||
rows: result.rows,
|
||||
count: result.rowCount ?? NaN,
|
||||
},
|
||||
};
|
||||
} catch (e: unknown) {
|
||||
}
|
||||
},
|
||||
queryOne<T extends JSONObject>(query: string): Promise<Maybe<T>> {
|
||||
try {
|
||||
const result = await postgresClient.queryObject<T>(query);
|
||||
return { just: result };
|
||||
}
|
||||
export default async function createNewDbConnection(): Promise<Result<StoccaTreDbConn>> {
|
||||
let postgresClient: Client;
|
||||
try {
|
||||
postgresClient = new Client({
|
||||
user: config.dbUsername,
|
||||
database: "stocca_tre",
|
||||
hostname: config.hostname,
|
||||
port: config.dbPort,
|
||||
password: config.dbPassword,
|
||||
tls: {
|
||||
enabled: false,
|
||||
},
|
||||
});
|
||||
await postgresClient.connect();
|
||||
} catch (e: unknown) {
|
||||
const error = e as { message?: string };
|
||||
if (error.message) {
|
||||
return [new StoccaTreError(error.message).qualified("Error connecting to database: ")];
|
||||
}
|
||||
return [new StoccaTreError("Error connecting to database.")];
|
||||
}
|
||||
return [,
|
||||
{
|
||||
async query<Q extends string>(query: Q, ...args: Q extends IsPlainSQL<Q> ? [(JSONObject | undefined)?] : [ArgsForSQL<Q>]): Promise<Result<JSONObject[]>> {
|
||||
try {
|
||||
const result = <{rows: JSONObject[]}> await postgresClient.queryObject(query, args[0]);
|
||||
return [, result.rows];
|
||||
} catch (e: unknown) {
|
||||
const error = e as { message?: string };
|
||||
return [new StoccaTreError(error.message ?? "Internal database error.")];
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user