From e031e00e3ad411ce24c334c834fcaec8839b128c Mon Sep 17 00:00:00 2001 From: Brayden Tan Date: Thu, 5 Sep 2024 14:11:16 +0800 Subject: [PATCH] DATAAPI-31 new annotation to enable deleted change queue detail --- README.md | 1 + interceptors/DataApiInterceptors.cfc | 17 +++++++++++++++++ services/DataApiConfigurationService.cfc | 15 +++++++++++++++ services/DataApiQueueService.cfc | 17 ++++++++++++----- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e762e01..1b74d57 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Additional _optional_ annotation options at the _object_ level are: * `dataApiCategory`: For the HTML documentation. Allows sub-groups of entities. Especially useful for large APIs. * `dataApiQueueEnabled`: Whether or not the change queue is enabled for this object * `dataApiQueue`: Specific queue name for this object +* `dataApiQueueDeleteDetail`: Whether or not the deleted record detail is available in the change queue data for this object * `dataApiSortOrder`: Sort order for paginated results. Default is date last modified ascending. * `dataApiSavedFilters`: Comma-separated list of saved filters to apply to all requests to this object (e.g. only return active records) * `dataApiIgnoreDefaultFilters`: Comma-separated list of ignore default filters to apply to all requests to this object diff --git a/interceptors/DataApiInterceptors.cfc b/interceptors/DataApiInterceptors.cfc index 3878f3c..e1260f8 100755 --- a/interceptors/DataApiInterceptors.cfc +++ b/interceptors/DataApiInterceptors.cfc @@ -3,6 +3,7 @@ component extends="coldbox.system.Interceptor" { property name="dataApiService" inject="delayedInjector:dataApiService"; property name="dataApiQueueService" inject="delayedInjector:dataApiQueueService"; property name="dataApiConfigurationService" inject="delayedInjector:dataApiConfigurationService"; + property name="presideObjectService" inject="delayedInjector:presideObjectService"; property name="interceptorService" inject="coldbox:InterceptorService"; variables._applicationLoaded = false; @@ -116,6 +117,22 @@ component extends="coldbox.system.Interceptor" { if( isEmptyString( interceptData.id ?: "" ) ){ interceptData.deletedIds = dataApiQueueService.getDeletedRecordIds( argumentCollection = interceptData ); + + if ( ArrayLen( interceptData.deletedIds ) && dataApiConfigurationService.isObjectQueueDeleteDetailEnabled( objectName=interceptData.objectName ) ) { + var deletedQuery = presideObjectService.selectData( + objectName = interceptData.objectName + , filter = { id=interceptData.deletedIds } + , selectFields = dataApiConfigurationService.getSelectFields( entity=dataApiConfigurationService.getObjectEntity( objectName=interceptData.objectName ) ) + ); + + if ( deletedQuery.recordcount ) { + interceptData.deletedRecords = {}; + + for ( var row in deletedQuery ) { + interceptData.deletedRecords[ row.id ] = row; + } + } + } } } diff --git a/services/DataApiConfigurationService.cfc b/services/DataApiConfigurationService.cfc index eab3be1..d75df88 100755 --- a/services/DataApiConfigurationService.cfc +++ b/services/DataApiConfigurationService.cfc @@ -574,6 +574,21 @@ component { } ); } + public boolean function isObjectQueueDeleteDetailEnabled( required string objectName, string namespace=_getDataApiNamespace() ) { + var args = arguments; + var cacheKey = "isObjectQueueDeleteDetailEnabled-#arguments.objectName#-#arguments.namespace#"; + + return _simpleLocalCache( cacheKey, function(){ + if ( !isObjectQueueEnabled( args.objectName, args.namespace ) ) { + return false; + } + + var queueDeleteDetailEnabled = $getPresideObjectService().getObjectAttribute( args.objectName, "dataApiQueueDeleteDetail#_getNamespaceWithSeparator( args.namespace )#" ); + + return _isTrue( queueDeleteDetailEnabled ); + } ); + } + public struct function getDefaultQueueConfig() { return { name = "" diff --git a/services/DataApiQueueService.cfc b/services/DataApiQueueService.cfc index 6fa5468..7da8fbd 100755 --- a/services/DataApiQueueService.cfc +++ b/services/DataApiQueueService.cfc @@ -59,6 +59,7 @@ component { , recordId = record.record_id , queueId = record.id , timestamp = _unixTimestamp( record.dateCreated ) + , record = IsJson( record.data ) ? DeserializeJson( record.data ) : {} } ); break; case "update": @@ -243,10 +244,11 @@ component { } public void function queueDelete( - string objectName = "" - , string id = "" - , any filter = {} - , array deletedIds = [] + string objectName = "" + , string id = "" + , any filter = {} + , array deletedIds = [] + , struct deletedRecords = {} ) { if( !Len( filter.id ?: "" ) && !Len( filter[ "#objectName#.id" ] ?: "" ) && arrayLen( deletedIds ) ) { filter = { id = deletedIds }; @@ -257,7 +259,11 @@ component { value = ListToArray( value ); } for( var id in value ) { - queueDelete( arguments.objectName, id ); + queueDelete( + objectName = arguments.objectName + , id = id + , deletedRecords = arguments.deletedRecords + ); } return; } @@ -283,6 +289,7 @@ component { , namespace = namespace , queue_name = queueSettings.name , operation = "delete" + , data = StructKeyExists( arguments.deletedRecords, arguments.id ) ? SerializeJSON( arguments.deletedRecords[ arguments.id ] ) : "" } ); }