From 0a9a2767d0c4de24f218ebe1fbc4f46aaf8f6e29 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Thu, 21 Sep 2023 09:10:31 +0200 Subject: [PATCH] optimize column retrieval --- system/services/database/DbInfoService.cfc | 6 ++- .../presideObjects/SqlSchemaSynchronizer.cfc | 42 +++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/system/services/database/DbInfoService.cfc b/system/services/database/DbInfoService.cfc index c39d24e030..d934ebf8db 100644 --- a/system/services/database/DbInfoService.cfc +++ b/system/services/database/DbInfoService.cfc @@ -40,7 +40,7 @@ component { public query function getTableColumns( required string tableName, required string dsn, boolean detail=false ) { var columns = ""; var attrCol = { - type: ( variables.hasModernDbInfo && !detail ) ? "columns_minimal" : "columns", + type: ( variables.hasModernDbInfo && !arguments.detail ) ? "columns_minimal" : "columns", name: "columns", table: arguments.tableName, datasource: arguments.dsn @@ -106,4 +106,8 @@ component { return constraints; } + + public boolean function hasModernDbInfo(){ + return variables.hasModernDbInfo; + } } \ No newline at end of file diff --git a/system/services/presideObjects/SqlSchemaSynchronizer.cfc b/system/services/presideObjects/SqlSchemaSynchronizer.cfc index fa6b71795d..f0d1f0ade9 100644 --- a/system/services/presideObjects/SqlSchemaSynchronizer.cfc +++ b/system/services/presideObjects/SqlSchemaSynchronizer.cfc @@ -51,6 +51,7 @@ component { dbVersion.append( obj.sql.table.version ); } } + StructDelete( variables, "columnCache" ); // cache no longer required, release memory dbVersion.sort( "text" ); dbVersion = Hash( dbVersion.toList() ); if ( ( versions.db.db ?: "" ) neq dbVersion ) { @@ -167,7 +168,7 @@ component { ) { var adapter = _getAdapter( dsn = arguments.dsn ); var tableExists = _tableExists( tableName=arguments.tableName, dsn=arguments.dsn ); - var tableColumns = tableExists ? QueryColumnData( _getTableColumns( tableName=arguments.tableName, dsn=arguments.dsn ), "COLUMN_NAME" ) : []; + var tableColumns = tableExists ? _getTableColumns( tableName=arguments.tableName, dsn=arguments.dsn ) : []; var columnSql = ""; var colName = ""; var column = ""; @@ -346,7 +347,7 @@ component { , required boolean skipSync ) { - var columnsFromDb = _getTableColumns( tableName=arguments.tableName, dsn=arguments.dsn, detail=true ); + var columnsFromDb = _getTableColumnsWithForeignKeys( tableName=arguments.tableName, dsn=arguments.dsn, detail=true ); var indexesFromDb = _getTableIndexes( tableName=arguments.tableName, dsn=arguments.dsn ); var dbColumnNames = ValueList( columnsFromDb.column_name ); var colsSql = arguments.generatedSql.columns; @@ -702,7 +703,30 @@ component { return variables._tableCache[ arguments.dsn ][ arguments.tableName ] ?: false; } - private query function _getTableColumns() { + private array function _getTableColumns() { + try { + if ( _getDbInfoService().hasModernDbInfo() ){ + // with the faster version, we can fetch the entire schema in one call. + if ( !StructKeyExists( variables, "columnCache" )){ + variables.columnCache = _getTableColumnCache( argumentCollection = arguments ); + } + if ( StructKeyExists( variables.columnCache, arguments.tableName ) ) { + return variables.columnCache[ arguments.tableName ]; + } else { + return []; + } + } + var tableColumns = _getDbInfoService().getTableColumns( argumentCollection = arguments ); + return QueryColumnData( tableColumns, "COLUMN_NAME" ); + } catch( any e ) { + if ( e.message contains "there is no table that match the following pattern" ) { + return []; + } + rethrow; + } + } + + private query function _getTableColumnsWithForeignKeys() { try { return _getDbInfoService().getTableColumns( argumentCollection = arguments ); } catch( any e ) { @@ -771,6 +795,18 @@ component { } } + private struct function _getTableColumnCache(){ + var srcColumns = _getDbInfoService().getTableColumns( tableName="%", dsn=arguments.dsn, detail=false ); + var columns = {}; + loop query=srcColumns { + if ( !StructKeyExists( columns, srcColumns.table_name ) ) { + columns[ srcColumns.table_name ] = []; + } + ArrayAppend( columns[ srcColumns.table_name ], srcColumns.column_name ); + } + return columns; + } + // GETTERS AND SETTERS