mirror of https://gitee.com/godoos/godoos.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
6.6 KiB
213 lines
6.6 KiB
// src/api/local/orm/orm.ts
|
|
import { getDatabase } from './db';
|
|
import Database from '@tauri-apps/plugin-sql';
|
|
// const userORM = createORM<{ id: number; name: string; role: string }>('users');
|
|
// // 查询并分页
|
|
// await userORM.where({ role: 'admin' }).page(1, 10).select();
|
|
// // 更新数据
|
|
// await userORM.save({ role: 'admin' }).where({ id: 1 }).select();
|
|
// // 统计数量
|
|
// const total = await userORM.where({ role: 'admin' }).count();
|
|
type Model = Record<string, any>;
|
|
|
|
interface ORM<T extends Model> {
|
|
create: (data: T) => Promise<void>;
|
|
update: (id: any, data: Partial<T>) => Promise<void>;
|
|
save: (data: Partial<T>) => ORMQueryBuilder<T>;
|
|
select: () => Promise<T[]>;
|
|
findById: (id: any) => Promise<T | null>;
|
|
delete: (id: any) => Promise<void>;
|
|
where: (conditions: Record<string, any>) => ORMQueryBuilder<T>;
|
|
count: () => Promise<number>;
|
|
page: (page: number, pageSize: number) => ORMQueryBuilder<T>;
|
|
}
|
|
|
|
interface ORMQueryBuilder<T extends Model> {
|
|
where: (conditions: Record<string, any>) => ORMQueryBuilder<T>;
|
|
count: () => Promise<number>;
|
|
page: (page: number, pageSize: number) => ORMQueryBuilder<T>;
|
|
select: () => Promise<T[]>;
|
|
}
|
|
|
|
function createORMQueryBuilder<T extends Model>(
|
|
db: Database,
|
|
table: string
|
|
): ORMQueryBuilder<T> {
|
|
let conditions: Record<string, any> = {};
|
|
let limit: number | null = null;
|
|
let offset: number | null = null;
|
|
|
|
function buildWhereClause(): { clause: string; values: any[] } {
|
|
const clauses = [];
|
|
const values = [];
|
|
|
|
for (const key in conditions) {
|
|
if (conditions.hasOwnProperty(key)) {
|
|
clauses.push(`${key} = $${values.length + 1}`);
|
|
values.push(conditions[key]);
|
|
}
|
|
}
|
|
|
|
const whereClause = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
return { clause: whereClause, values };
|
|
}
|
|
|
|
const queryBuilder: ORMQueryBuilder<T> = {
|
|
where: (newConditions: Record<string, any>): ORMQueryBuilder<T> => {
|
|
conditions = { ...conditions, ...newConditions };
|
|
return queryBuilder;
|
|
},
|
|
count: async (): Promise<number> => {
|
|
const { clause, values } = buildWhereClause();
|
|
const query = `SELECT COUNT(*) as count FROM ${table} ${clause}`;
|
|
const result: any = await db.select(query, values);
|
|
return result[0]?.count || 0;
|
|
},
|
|
page: (page: number, pageSize: number): ORMQueryBuilder<T> => {
|
|
const newLimit = pageSize;
|
|
const newOffset = (page - 1) * pageSize;
|
|
limit = newLimit;
|
|
offset = newOffset;
|
|
return queryBuilder;
|
|
},
|
|
select: async (): Promise<T[]> => {
|
|
const { clause, values } = buildWhereClause();
|
|
|
|
let limitClause = '';
|
|
if (limit !== null && offset !== null) {
|
|
limitClause = `LIMIT ${limit} OFFSET ${offset}`;
|
|
}
|
|
|
|
const query = `SELECT * FROM ${table} ${clause} ${limitClause}`;
|
|
const result = await db.select(query, values);
|
|
return result as T[];
|
|
},
|
|
};
|
|
|
|
return queryBuilder;
|
|
}
|
|
|
|
function buildWhereClauseFromConditions(
|
|
conditions: Record<string, any>
|
|
): { clause: string; values: any[] } {
|
|
const clauses = [];
|
|
const values = [];
|
|
|
|
for (const key in conditions) {
|
|
if (conditions.hasOwnProperty(key)) {
|
|
clauses.push(`${key} = $${values.length + 1}`);
|
|
values.push(conditions[key]);
|
|
}
|
|
}
|
|
|
|
const whereClause = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
return { clause: whereClause, values };
|
|
}
|
|
|
|
async function executeUpdate<T extends Model>(
|
|
db: Database,
|
|
table: string,
|
|
data: Partial<T>,
|
|
conditions: Record<string, any>
|
|
): Promise<void> {
|
|
const now = new Date().toISOString();
|
|
const timestampedData = { ...data, updated_at: now };
|
|
const setClause = Object.keys(timestampedData)
|
|
.map((key, i) => `${key} = $${i + 1}`)
|
|
.join(', ');
|
|
const values = Object.values(timestampedData);
|
|
|
|
const { clause: whereClause, values: whereValues } = buildWhereClauseFromConditions(conditions);
|
|
|
|
const query = `UPDATE ${table} SET ${setClause} ${whereClause}`;
|
|
await db.execute(query, [...values, ...whereValues]);
|
|
}
|
|
|
|
export function createORM<T extends Model>(table: string): ORM<T> {
|
|
const db = getDatabase();
|
|
|
|
const ormInstance: ORM<T> = {
|
|
create: async (data: T): Promise<void> => {
|
|
const now = new Date().toISOString();
|
|
const timestampedData = {
|
|
...data,
|
|
created_at: now,
|
|
updated_at: now,
|
|
};
|
|
|
|
const columns = Object.keys(timestampedData).join(', ');
|
|
const placeholders = Object.keys(timestampedData)
|
|
.map((_, i) => `$${i + 1}`)
|
|
.join(', ');
|
|
const values = Object.values(timestampedData);
|
|
|
|
const query = `INSERT INTO ${table} (${columns}) VALUES (${placeholders})`;
|
|
await db.execute(query, values);
|
|
},
|
|
|
|
update: async (id: any, data: Partial<T>): Promise<void> => {
|
|
const now = new Date().toISOString();
|
|
const timestampedData = {
|
|
...data,
|
|
updated_at: now,
|
|
};
|
|
|
|
const setClause = Object.keys(timestampedData)
|
|
.map((key, i) => `${key} = $${i + 1}`)
|
|
.join(', ');
|
|
|
|
const values = Object.values(timestampedData);
|
|
const query = `UPDATE ${table} SET ${setClause} WHERE id = $${values.length + 1}`;
|
|
values.push(id);
|
|
|
|
await db.execute(query, values);
|
|
},
|
|
|
|
save: (data: Partial<T>): ORMQueryBuilder<T> => {
|
|
const queryBuilder = createORMQueryBuilder<T>(db, table);
|
|
|
|
const originalWhere = queryBuilder.where;
|
|
queryBuilder.where = (conditions: Record<string, any>): ORMQueryBuilder<T> => {
|
|
const updatedQueryBuilder = originalWhere(conditions);
|
|
|
|
updatedQueryBuilder.select = async (): Promise<T[]> => {
|
|
await executeUpdate(db, table, data, conditions);
|
|
return [];
|
|
};
|
|
|
|
return updatedQueryBuilder;
|
|
};
|
|
|
|
return queryBuilder;
|
|
},
|
|
|
|
select: (): Promise<T[]> => {
|
|
return createORMQueryBuilder<T>(db, table).select();
|
|
},
|
|
|
|
findById: async (id: any): Promise<T | null> => {
|
|
const query = `SELECT * FROM ${table} WHERE id = $1`;
|
|
const result: any = await db.select(query, [id]);
|
|
return result.length > 0 ? (result[0] as T) : null;
|
|
},
|
|
|
|
delete: async (id: any): Promise<void> => {
|
|
const query = `DELETE FROM ${table} WHERE id = $1`;
|
|
await db.execute(query, [id]);
|
|
},
|
|
|
|
where: (conditions: Record<string, any>): ORMQueryBuilder<T> => {
|
|
return createORMQueryBuilder<T>(db, table).where(conditions);
|
|
},
|
|
|
|
count: (): Promise<number> => {
|
|
return createORMQueryBuilder<T>(db, table).count();
|
|
},
|
|
|
|
page: (page: number, pageSize: number): ORMQueryBuilder<T> => {
|
|
return createORMQueryBuilder<T>(db, table).page(page, pageSize);
|
|
},
|
|
};
|
|
|
|
return ormInstance;
|
|
}
|