class VKChangeTrackingSetup extends RunBase { VKChangeTrackingSetupMode setupMode; DialogField setupModeFld; #define.CurrentVersion(1) #localMacro.CurrentList setupMode #endmacro } public void run() { new AifChangeTrackingPermission().assert(); info(strFmt("Change tracking setup mode '%1'", enum2str(setupMode))); this.setupDbChangeTracking(); // Add here the methods to enable change tracking for your queries this.setupMagentoProducts(); this.setupMDAProducts(); // Make sure that the batch job which updates change trackng version is scheduled ttsBegin; AifChangeTrackingVersionUpdateJob::createBatchJob(); ttsCommit; CodeAccessPermission::revertAssert(); } protected Object dialog() { DialogRunbase dialog; DialogGroup dialogGroup; dialog = super(); dialog.caption("Setup change tracking scopes"); dialogGroup = dialog.addGroup(); DialogGroup.columns(2); dialogGroup.frameType(FormFrameType::Thin); dialog.addImage(931); dialog.addText("The option 'Install all scopes' will disable existing scopes before re-installing them. This will discard any previously tracked versions.", 500); dialogGroup = dialog.addGroup(); setupModeFld = dialog.addFieldValue(enumStr(VKChangeTrackingSetupMode), setupMode); return dialog; } protected void disableQueryChangeTracking(AifChangeTrackingScope _scope) { AifChangeTrackingConfiguration::disableChangeTracking(_scope); AifChangeTrackingConfiguration::deleteTouchTriggers(_scope); } protected void enableQueryChangeTracking( Query _query, AifChangeTrackingScope _scope, boolean _createInsertTriggers = true, boolean _createUpdateTriggers = true, boolean _createDeleteTriggers = true) { AifChangeTrackingConfiguration::enableChangeTrackingForQuery( _scope, _query, AifChangeTrackingType::SqlChangeTracking, _createDeleteTriggers); if (_createInsertTriggers) AifChangeTrackingConfiguration::createTouchTriggersForQuery(_scope, AifChangeTrackingTriggerType::AfterInsert, _query); if (_createUpdateTriggers) AifChangeTrackingConfiguration::createTouchTriggersForQuery(_scope, AifChangeTrackingTriggerType::AfterUpdate, _query); } public boolean getFromDialog() { boolean ret; ret = super(); setupMode = setupModeFld.value(); return ret; } public container pack() { return [#CurrentVersion, #CurrentList]; } protected void scheduleCtVersionUpdates() { if (setupMode != VKChangeTrackingSetupMode::Disable) AifChangeTrackingVersionUpdateJob::createBatchJob(); } protected void setupDbChangeTracking() { if (setupMode != VKChangeTrackingSetupMode::Disable && !AifChangeTrackingConfiguration::isChangeTrackingEnabled()) { AifChangeTrackingConfiguration::enableChangeTracking(true); } info(AifChangeTrackingConfiguration::isChangeTrackingEnabled() ? "Database change tracking is enabled" : "Database change tracking is disabled"); } private void setupMagentoProducts() { this.setupQueryChangeTracking(queryStr(MagentoProductChangeTracking), 'MagentoProducts'); } protected void setupMDAProducts() { this.setupQueryChangeTracking(queryStr(MDAProductInfoChangeTracking), 'MDAProducts'); } protected void setupQueryChangeTracking( str _queryName, AifChangeTrackingScope _scope, boolean _createInsertTriggers = true, boolean _createUpdateTriggers = true, boolean _createDeleteTriggers = true) { Query query; AifChangeTracking changeTracking; boolean isEnabled; setPrefix(strFmt("Change tracking scope '%1'", _scope)); query = new Query(_queryName); changeTracking = AifChangeTracking::construct(query, _scope, AifChangeTrackingType::SqlChangeTracking); isEnabled = changeTracking.isChangeTrackingEnabledForQuery(); switch (setupMode) { case VKChangeTrackingSetupMode::InstallNew: if (!isEnabled) this.enableQueryChangeTracking(query, _scope, _createInsertTriggers, _createUpdateTriggers, _createDeleteTriggers); break; case VKChangeTrackingSetupMode::InstallAll: if (isEnabled) this.disableQueryChangeTracking(_scope); this.enableQueryChangeTracking(query, _scope, _createInsertTriggers, _createUpdateTriggers, _createDeleteTriggers); break; case VKChangeTrackingSetupMode::Disable: if (isEnabled) this.disableQueryChangeTracking(_scope); } info(changeTracking.isChangeTrackingEnabledForQuery()? "Change tracking for query is enabled" : "Change tracking for query is disabled"); } public boolean unpack(container packedClass) { Version version = RunBase::getVersion(packedClass); switch (version) { case #CurrentVersion: [version, #CurrentList] = packedClass; break; default: return false; } return true; } public static VKChangeTrackingSetup construct() { return new VKChangeTrackingSetup(); } public static void Main(Args _args) { VKChangeTrackingSetup::MainOnServer(_args); } private server static void MainOnServer(Args _arhs) { VKChangeTrackingSetup changeTrackingSetup; changeTrackingSetup = VKChangeTrackingSetup::construct(); if (changeTrackingSetup.prompt()) { changeTrackingSetup.run(); } }
class VKChangeTrackingHelper { AifChangeTracking changeTracking; AifChangeTrackingScope scope; UnknownNoYes fullSyncRequired; } public AifChangeTrackingTable getChanges() { AifChangeTrackingTable changeTrackingTable; utcDateTime lastSyncDate; lastSyncDate = VKChangeTrackingScope::getLastSyncDate(scope); changeTracking.getChanges(lastSyncDate, changeTrackingTable); return changeTrackingTable; } public boolean isFullSyncRequired() { utcDateTime lastSyncDate; if (fullSyncRequired == UnknownNoYes::Unknown) { lastSyncDate = VKChangeTrackingScope::getLastSyncDate(scope); if (changeTracking.isFullSynchronizationRequired(lastSyncDate)) fullSyncRequired = UnknownNoYes::Yes; else fullSyncRequired = UnknownNoYes::No; } return fullSyncRequired == UnknownNoYes::Yes; } public void new(Query _query, AifChangeTrackingScope _scope) { scope = _scope; changeTracking = AifChangeTracking::construct(_query); }
public static boolean exist(AifChangeTrackingScope _scope) { return _scope && ( select RecId from VKChangeTrackingScope where VKChangeTrackingScope.Scope == _scope).RecId != 0; } public static VKChangeTrackingScope find(AifChangeTrackingScope _scope, boolean _forUpdate = false) { VKChangeTrackingScope changeTrackingScope; changeTrackingScope.selectForUpdate(_forUpdate); if (_scope) { select firstOnly changeTrackingScope where changeTrackingScope.Scope == _scope; } return changeTrackingScope; } public static utcDateTime getLastSyncDate(AifChangeTrackingScope _scope) { VKChangeTrackingScope changeTrackingScope; changeTrackingScope = VKChangeTrackingScope::find(_scope); return changeTrackingScope.LastSyncDate; } public static void updateLastSyncDate( AifChangeTrackingScope _scope, utcDateTime _dateTime = DateTimeUtil::getSystemDateTime()) { VKChangeTrackingScope changeTrackingScope; ttsBegin; changeTrackingScope = VKChangeTrackingScope::find(_scope, true); if (!changeTrackingScope) { changeTrackingScope.Scope = _scope; } changeTrackingScope.LastSyncDate = _dateTime; changeTrackingScope.write(); ttsCommit; }
if ( exportMode == VKInterfaceExportMode::Delta && !changeTrackingHelper.isFullSyncRequired()) { qbds = qbds.addDataSource(tableNum(AifChangeTrackingTable)); // should be joined to primary datasource of change tracking query. In this case we are tracking changes on the InventTable qbds.addRange(fieldNum(AifChangeTrackingTable, RecId)) .value(strFmt('(%1.RecId == %2.KeyField_RecId)', qbdsInventTable.name(), qbds.name())); }AifChangeTrackingTable is temporary table and is filled in by helper class. The instance of this temp table should be added to QueryRun:
queryRun = new QueryRun(query); if ( exportMode == VKInterfaceExportMode::Delta && !changeTrackingHelper.isFullSyncRequired()) { queryRun.setRecord(changeTrackingHelper.getChanges()); } while (queryRun.next()) { //.... }by Aris Xanthopoulos
DaxOnline.org is free platform that allows you to quickly store and reuse snippets, notes, articles related to Dynamics AX.
Authors are allowed to set their own AdSense units.
Join us.