// 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; interface ORM { create: (data: T) => Promise; update: (id: any, data: Partial) => Promise; save: (data: Partial) => ORMQueryBuilder; select: () => Promise; findById: (id: any) => Promise; delete: (id: any) => Promise; where: (conditions: Record) => ORMQueryBuilder; count: () => Promise; page: (page: number, pageSize: number) => ORMQueryBuilder; } interface ORMQueryBuilder { where: (conditions: Record) => ORMQueryBuilder; count: () => Promise; page: (page: number, pageSize: number) => ORMQueryBuilder; select: () => Promise; } function createORMQueryBuilder( db: Database, table: string ): ORMQueryBuilder { let conditions: Record = {}; 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 = { where: (newConditions: Record): ORMQueryBuilder => { conditions = { ...conditions, ...newConditions }; return queryBuilder; }, count: async (): Promise => { 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 => { const newLimit = pageSize; const newOffset = (page - 1) * pageSize; limit = newLimit; offset = newOffset; return queryBuilder; }, select: async (): Promise => { 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 ): { 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( db: Database, table: string, data: Partial, conditions: Record ): Promise { 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(table: string): ORM { const db = getDatabase(); const ormInstance: ORM = { create: async (data: T): Promise => { 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): Promise => { 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): ORMQueryBuilder => { const queryBuilder = createORMQueryBuilder(db, table); const originalWhere = queryBuilder.where; queryBuilder.where = (conditions: Record): ORMQueryBuilder => { const updatedQueryBuilder = originalWhere(conditions); updatedQueryBuilder.select = async (): Promise => { await executeUpdate(db, table, data, conditions); return []; }; return updatedQueryBuilder; }; return queryBuilder; }, select: (): Promise => { return createORMQueryBuilder(db, table).select(); }, findById: async (id: any): Promise => { 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 => { const query = `DELETE FROM ${table} WHERE id = $1`; await db.execute(query, [id]); }, where: (conditions: Record): ORMQueryBuilder => { return createORMQueryBuilder(db, table).where(conditions); }, count: (): Promise => { return createORMQueryBuilder(db, table).count(); }, page: (page: number, pageSize: number): ORMQueryBuilder => { return createORMQueryBuilder(db, table).page(page, pageSize); }, }; return ormInstance; }