|
1 | 1 | import betterSqlite3 from 'better-sqlite3'; |
2 | | -import { IAdminForthDataSourceConnector, IAdminForthSingleFilter, IAdminForthAndOrFilter, AdminForthResource, AdminForthResourceColumn } from '../types/Back.js'; |
| 2 | +import { IAdminForthDataSourceConnector, IAdminForthSingleFilter, IAdminForthAndOrFilter, AdminForthResource, AdminForthResourceColumn, AdminForthConfig } from '../types/Back.js'; |
3 | 3 | import AdminForthBaseConnector from './baseConnector.js'; |
4 | 4 | import dayjs from 'dayjs'; |
5 | 5 | import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types/Common.js'; |
@@ -38,16 +38,47 @@ class SQLiteConnector extends AdminForthBaseConnector implements IAdminForthData |
38 | 38 | })); |
39 | 39 | } |
40 | 40 |
|
41 | | - async discoverFields(resource: AdminForthResource): Promise<{[key: string]: AdminForthResourceColumn}> { |
| 41 | + async checkCascadeWhenUploadPlugin(resource: AdminForthResource, config: AdminForthConfig) { |
| 42 | + const currentResource = config.resources.find(r => r.resourceId === resource.resourceId); |
| 43 | + if (!currentResource) return; |
| 44 | + const hasUploadPlugin = currentResource.plugins?.some(p => p.className === "UploadPlugin"); |
| 45 | + |
| 46 | + if (hasUploadPlugin) { |
| 47 | + const tableName = (resource.table); |
| 48 | + afLogger.warn(`Table "${tableName}" has ON DELETE CASCADE, which may conflict with adminForth UploadPlugin.`); |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + async hasSQLiteCascadeFk(resource: AdminForthResource, config: AdminForthConfig, fkMap: { [colName: string]: boolean }): Promise<boolean> { |
| 53 | + |
| 54 | + const hasAdminCascade = resource.columns?.some(c => c.foreignResource?.onDelete === 'cascade'); |
| 55 | + if (!hasAdminCascade) return false; |
| 56 | + |
| 57 | + const hasDbCascade = Object.values(fkMap).some(v => v); |
| 58 | + console.log("resource.resourceId" , resource.resourceId); |
| 59 | + |
| 60 | + if (hasDbCascade) { |
| 61 | + const tableName = (resource.table); |
| 62 | + afLogger.warn( |
| 63 | + |
| 64 | + `Table "${tableName}" has ON DELETE CASCADE, which may conflict with adminForth cascade deletion` |
| 65 | + ); |
| 66 | + } |
| 67 | + |
| 68 | + return hasDbCascade; |
| 69 | + } |
| 70 | + |
| 71 | + async discoverFields(resource: AdminForthResource, config: AdminForthConfig): Promise<{[key: string]: AdminForthResourceColumn}> { |
| 72 | + await this.checkCascadeWhenUploadPlugin(resource, config); |
| 73 | + |
42 | 74 | const tableName = resource.table; |
43 | 75 | const stmt = this.client.prepare(`PRAGMA table_info(${tableName})`); |
44 | 76 | const rows = await stmt.all(); |
45 | 77 | const fkStmt = this.client.prepare(`PRAGMA foreign_key_list(${tableName})`); |
46 | 78 | const fkRows = await fkStmt.all(); |
47 | 79 | const fkMap: { [colName: string]: boolean } = {}; |
48 | | - fkRows.forEach(fk => { |
49 | | - fkMap[fk.from] = fk.on_delete?.toUpperCase() === 'CASCADE'; |
50 | | - }); |
| 80 | + fkRows.forEach(fk => {fkMap[fk.from] = fk.on_delete?.toUpperCase() === 'CASCADE';}) |
| 81 | + await this.hasSQLiteCascadeFk(resource, config, fkMap); |
51 | 82 | const fieldTypes = {}; |
52 | 83 | rows.forEach((row) => { |
53 | 84 | const field: any = {}; |
@@ -94,9 +125,6 @@ class SQLiteConnector extends AdminForthBaseConnector implements IAdminForthData |
94 | 125 | field.primaryKey = row.pk == 1; |
95 | 126 |
|
96 | 127 | field.cascade = fkMap[row.name] || false; |
97 | | - if (field.cascade) { |
98 | | - afLogger.warn(`The database has ON DELETE CASCADE, which may conflict with adminForth cascade deletion and upload logic. Please remove it.`); |
99 | | - } |
100 | 128 | field.default = row.dflt_value; |
101 | 129 | fieldTypes[row.name] = field |
102 | 130 | }); |
|
0 commit comments