diff --git a/adminforth/dataConnectors/clickhouse.ts b/adminforth/dataConnectors/clickhouse.ts index 8e5d1ccf..ffa9db2f 100644 --- a/adminforth/dataConnectors/clickhouse.ts +++ b/adminforth/dataConnectors/clickhouse.ts @@ -499,6 +499,21 @@ class ClickhouseConnector extends AdminForthBaseConnector implements IAdminForth return res; } + async deleteMany({ resource, recordIds }: { resource: AdminForthResource; recordIds: any[] }): Promise { + const pkColumn = resource.dataSourceColumns.find((col) => col.primaryKey); + if (!pkColumn || !recordIds || recordIds.length === 0) { + return 0; + } + const paramNames = recordIds.map((_, idx) => `id${idx}`); + const conditions = paramNames.map((name) => `${pkColumn.name} = {${name}:${pkColumn._underlineType}}`).join(' OR '); + const queryParams = paramNames.reduce((acc, name, idx) => {acc[name] = recordIds[idx]; return acc;}, {} as Record); + await this.client.command({ + query: `ALTER TABLE ${this.dbName}.${resource.table} DELETE WHERE ${conditions}`, + query_params: queryParams, + }); + return recordIds.length ?? 0; + } + close() { this.client.disconnect(); } diff --git a/adminforth/dataConnectors/mongo.ts b/adminforth/dataConnectors/mongo.ts index 94487e26..63dc3754 100644 --- a/adminforth/dataConnectors/mongo.ts +++ b/adminforth/dataConnectors/mongo.ts @@ -397,6 +397,12 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS return res.deletedCount > 0; } + async deleteMany({ resource, recordIds }: { resource: AdminForthResource; recordIds: any[] }): Promise { + const collection = this.client.db().collection(resource.table); + const res = await collection.deleteMany({[this.getPrimaryKey(resource)]: { $in: recordIds }}); + return res.deletedCount ?? 0; + } + async close() { await this.client.close() } diff --git a/adminforth/dataConnectors/mysql.ts b/adminforth/dataConnectors/mysql.ts index 54df749d..37396c7c 100644 --- a/adminforth/dataConnectors/mysql.ts +++ b/adminforth/dataConnectors/mysql.ts @@ -420,6 +420,13 @@ class MysqlConnector extends AdminForthBaseConnector implements IAdminForthDataS return res.rowCount > 0; } + async deleteMany({ resource, recordIds }: { resource: AdminForthResource; recordIds: any[] }): Promise { + const placeholders = recordIds.map(() => '?').join(','); + const query = `DELETE FROM ${resource.table} WHERE ${this.getPrimaryKey(resource)} IN (${placeholders})`; + const [result] = await this.client.execute(query, recordIds); + return result.affectedRows ?? 0; + } + async close() { await this.client.end(); } diff --git a/adminforth/dataConnectors/postgres.ts b/adminforth/dataConnectors/postgres.ts index cf37610a..f145f611 100644 --- a/adminforth/dataConnectors/postgres.ts +++ b/adminforth/dataConnectors/postgres.ts @@ -455,6 +455,13 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa return res.rowCount > 0; } + async deleteMany({ resource, recordIds }: { resource: AdminForthResource; recordIds: any[] }): Promise { + const placeholders = recordIds.map((_, idx) => `$${idx + 1}`).join(', '); + const query = `DELETE FROM "${resource.table}" WHERE "${this.getPrimaryKey(resource)}" IN (${placeholders})`; + const res = await this.client.query(query, recordIds); + return res.rowCount ?? 0; + } + async close() { await this.client.end(); } diff --git a/adminforth/dataConnectors/sqlite.ts b/adminforth/dataConnectors/sqlite.ts index e3407b29..4dc612c8 100644 --- a/adminforth/dataConnectors/sqlite.ts +++ b/adminforth/dataConnectors/sqlite.ts @@ -382,6 +382,13 @@ class SQLiteConnector extends AdminForthBaseConnector implements IAdminForthData return res.changes > 0; } + async deleteMany({ resource, recordIds }: { resource: AdminForthResource, recordIds: any[] }): Promise { + const placeholders = recordIds.map(() => '?').join(','); + const q = this.client.prepare(`DELETE FROM ${resource.table} WHERE ${this.getPrimaryKey(resource)} IN (${placeholders})`); + const res = await q.run(...recordIds); + return res.changes ?? 0; + } + close() { this.client.close(); } diff --git a/adminforth/types/Back.ts b/adminforth/types/Back.ts index 59db5fc9..35aa1c8a 100644 --- a/adminforth/types/Back.ts +++ b/adminforth/types/Back.ts @@ -1760,6 +1760,8 @@ export interface IOperationalResource { update: (primaryKey: any, record: any) => Promise; delete: (primaryKey: any) => Promise; + + deleteMany?(recordIds: any[]): Promise; dataConnector: IAdminForthDataSourceConnectorBase; } diff --git a/dev-demo/Taskfile.yaml b/dev-demo/Taskfile.yaml index 2f5a8fd5..5533f9a9 100644 --- a/dev-demo/Taskfile.yaml +++ b/dev-demo/Taskfile.yaml @@ -30,6 +30,7 @@ vars: - "adminforth-quick-filters" - "adminforth-many2many" - "adminforth-background-jobs" + - "adminforth-auto-remove" ADAPTERS: - "adminforth-completion-adapter-open-ai-chat-gpt"