初次提交

This commit is contained in:
2024-10-30 14:31:08 +08:00
commit ebfefc2295
13 changed files with 1902 additions and 0 deletions

182
src/database.ts Normal file
View File

@ -0,0 +1,182 @@
import { Pool, PoolClient, QueryResult, QueryResultRow } from "pg";
import { BasicEntity } from "./entity";
import { DeleteBuilder, IDeleteBuilder, IInsertBuilder, InsertBuilder, ISelectBuilder, IUpdateBuilder, SelectBuilder, UpdateBuilder } from "./query";
import { Class } from "./types";
import { formatSQL } from "./util";
interface IPostgresClient {
/**
* 执行sql语句
* @param sql sql语句
* @param args sql参数
*/
query<R>(sql: string, args?: any[]): Promise<QueryResult<R[]>>;
/** 开启事务 */
trans(): Promise<void>;
/**
* 查询实体
* @param Entity 实体
* @param alias 别名
*/
select<E extends BasicEntity>(Entity: Class<E>, alias?: string): ISelectBuilder<E>;
/**
* 进行数据库插入
* @param Entity 实体
*/
insert<E extends BasicEntity>(Entity: Class<E>): IInsertBuilder<E>;
/**
* 进行实体更新
* @param Entity 实体
*/
update<E extends BasicEntity>(Entity: Class<E>): IUpdateBuilder<E>;
/**
* 进行实体删除
* @param Entity 实体
*/
del<E extends BasicEntity>(Entity: Class<E>): IDeleteBuilder<E>;
}
interface IPostgresConfig {
host?: string
port?: number
user?: string
password?: string
database?: string
max?: number
}
class PostgresClient implements IPostgresClient {
#client: PoolClient
#transOn = false;
constructor(client: PoolClient) {
this.#client = client;
}
public query<R>(sql: string, args?: any[] | Record<string, any>): Promise<QueryResult<R[]>> { return this.#client.query(args ? formatSQL(sql, args) : sql); }
public async trans() {
await this.query("begin")
this.#transOn = true;
}
public get transOn() { return this.#transOn; }
public release() { this.#client.release(); }
public select<E extends BasicEntity>(Entity: Class<E>, alias?: string): ISelectBuilder<E> { return new SelectBuilder(this.query.bind(this), Entity, alias); }
public insert<E extends BasicEntity>(Entity: Class<E>): IInsertBuilder<E> { return new InsertBuilder(this.query.bind(this), Entity); }
public update<E extends BasicEntity>(Entity: Class<E>): IUpdateBuilder<E> { return new UpdateBuilder(this.query.bind(this), Entity); }
public del<E extends BasicEntity>(Entity: Class<E>): IDeleteBuilder<E> { return new DeleteBuilder(this.query.bind(this), Entity); }
};
/** 数据库操作相关 */
export namespace database {
let pool: Pool | null = null;
let confLoader!: () => IPostgresConfig
function getPool() {
if (!pool) {
const conf = confLoader();
pool = new Pool({
host: conf.host,
port: conf.port,
user: conf.user,
password: conf.password,
database: conf.database,
max: conf.max,
ssl: false,
});
}
return pool;
}
/**
* 配置数据库
* @param loader 配置加载器
*/
export function config(loader: () => IPostgresConfig) {
confLoader = loader;
}
/**
* 直接执行sql语句
* @param sql sql语句
* @param args sql参数
*/
export function query<R extends QueryResultRow>(sql: string, args?: any[] | Record<string, any>) { return getPool().query<R>(args ? formatSQL(sql, args) : sql); }
/**
* 查询实体
* @param Entity 实体
* @param alias 别名
*/
export function select<E extends BasicEntity>(Entity: Class<E>, alias?: string): ISelectBuilder<E> { return new SelectBuilder(database.query, Entity, alias); }
/**
* 进行数据库插入
* @param Entity 实体
*/
export function insert<E extends BasicEntity>(Entity: Class<E>): IInsertBuilder<E> { return new InsertBuilder(database.query, Entity); }
/**
* 进行实体更新
* @param Entity 实体
*/
export function update<E extends BasicEntity>(Entity: Class<E>): IUpdateBuilder<E> { return new UpdateBuilder(database.query, Entity); }
/**
* 进行实体删除
* @param Entity 实体
*/
export function del<E extends BasicEntity>(Entity: Class<E>): IDeleteBuilder<E> { return new DeleteBuilder(database.query, Entity); }
/**
* 连接数据库
* @param callback 回调
*/
export async function connect<R>(callback: (client: PostgresClient) => R | Promise<R>): Promise<R> {
const conn = await getPool().connect();
const client = new PostgresClient(conn);
let ret: R;
try {
ret = await callback(client);
if (client.transOn) await client.query("commit");
}
catch (err) {
if (client.transOn) await client.query("rollback");
throw err;
}
finally {
client.release();
}
return ret;
}
/**
* 执行事务操作
* @param callback 回调
*/
export function transaction<R>(callback: (client: PostgresClient) => R | Promise<R>): Promise<R> {
return connect(async (client) => {
await client.trans();
return callback(client);
});
};
/** 关闭数据库 */
export function close() {
if (pool) pool.end().catch((err) => console.error(err));
}
}