Skip to content

Commit

Permalink
Feat: Bypass custom logic option on set and delete commands. (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
rnwood authored Dec 10, 2024
1 parent ffadb0e commit cab76dd
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Microsoft.Xrm.Sdk;
using System;
using System.Linq;

namespace Rnwood.Dataverse.Data.PowerShell.Commands
{
public abstract class CustomLogicBypassableOrganizationServiceCmdlet : OrganizationServiceCmdlet
{
public abstract BusinessLogicTypes[] BypassBusinessLogicExecution { get; set; }

public abstract Guid[] BypassBusinessLogicExecutionStepIds { get; set; }

public enum BusinessLogicTypes
{
CustomSync,
CustomAsync
}

protected void ApplyBypassBusinessLogicExecution(OrganizationRequest request)
{
if (BypassBusinessLogicExecution?.Length > 0)
{
request.Parameters["BypassBusinessLogicExecution"] = string.Join(",", BypassBusinessLogicExecution.Select(o => o.ToString()));


}
else
{
request.Parameters.Remove("BypassBusinessLogicExecution");
}

if (BypassBusinessLogicExecutionStepIds?.Length > 0)
{
request.Parameters["BypassBusinessLogicExecutionStepIds"] = string.Join(",", BypassBusinessLogicExecutionStepIds.Select(id => id.ToString()));
}
else
{
request.Parameters.Remove("BypassBusinessLogicExecutionStepIds");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class InvokeDataverseSqlCmdlet : OrganizationServiceCmdlet
public string Sql { get; set; }

[Parameter]
public bool UseTdsEndpoint { get; set; }
public SwitchParameter UseTdsEndpoint { get; set; }

[Parameter]
public int Timeout { get; set; } = 600;
Expand All @@ -44,10 +44,13 @@ public class InvokeDataverseSqlCmdlet : OrganizationServiceCmdlet
public PSObject Parameters { get; set; }

[Parameter]
public int? BatchSize { get; private set; }
public int? BatchSize { get; set; }

[Parameter]
public int? MaxDegreeOfParallelism { get; private set; }
public int? MaxDegreeOfParallelism { get; set; }

[Parameter(HelpMessage = "Bypasses custom plugins. See Sql4Cds docs.")]
public SwitchParameter BypassCustomPluginExecution { get; set; }

protected override void BeginProcessing()
{
Expand All @@ -63,6 +66,11 @@ protected override void BeginProcessing()
this._sqlConnection.PreDelete += GetOnSqlConnectionConfirmatonRequiredHandler("Delete");
this._sqlConnection.PreUpdate += GetOnSqlConnectionConfirmatonRequiredHandler("Update");

if (BypassCustomPluginExecution)
{
_sqlConnection.BypassCustomPlugins = true;
}

if (BatchSize.HasValue)
{
_sqlConnection.BatchSize = BatchSize.Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@

namespace Rnwood.Dataverse.Data.PowerShell.Commands
{
public abstract class OrganizationServiceCmdlet : PSCmdlet


public abstract class OrganizationServiceCmdlet : PSCmdlet
{
public abstract ServiceClient Connection { get; set; }


}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Rnwood.Dataverse.Data.PowerShell.Commands
{
[Cmdlet(VerbsCommon.Remove, "DataverseRecord", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.Medium)]
///<summary>Deletes records from a Dataverse organization.</summary>
public class RemoveDataverseRecordCmdlet : OrganizationServiceCmdlet
public class RemoveDataverseRecordCmdlet : CustomLogicBypassableOrganizationServiceCmdlet
{
[Parameter(Mandatory = true)]
public override ServiceClient Connection { get; set; }
Expand All @@ -39,6 +39,13 @@ public class RemoveDataverseRecordCmdlet : OrganizationServiceCmdlet
[Parameter]
public SwitchParameter IfExists { get; set; }

[Parameter(HelpMessage = "Specifies the types of business logic (for example plugins) to bypass")]
public override BusinessLogicTypes[] BypassBusinessLogicExecution { get; set; }


[Parameter(HelpMessage = "Specifies the IDs of plugin steps to bypass")]
public override Guid[] BypassBusinessLogicExecutionStepIds { get; set; }

private class BatchItem
{
public BatchItem(PSObject inputObject, OrganizationRequest request, Action<OrganizationResponse> responseCompletion) : this(inputObject, request, responseCompletion, null)
Expand Down Expand Up @@ -97,27 +104,30 @@ private void Delete(string entityName, Guid id)

Entity record = Connection.RetrieveMultiple(getRecordWithMMColumns).Entities.Single();

Connection.Execute(new DisassociateRequest()
DisassociateRequest request = new DisassociateRequest()
{
Target = new EntityReference(manyToManyRelationshipMetadata.Entity1LogicalName,
record.GetAttributeValue<Guid>(
manyToManyRelationshipMetadata.Entity1IntersectAttribute)),
record.GetAttributeValue<Guid>(
manyToManyRelationshipMetadata.Entity1IntersectAttribute)),
RelatedEntities =
new EntityReferenceCollection()
{
new EntityReferenceCollection()
{
new EntityReference(manyToManyRelationshipMetadata.Entity2LogicalName,
record.GetAttributeValue<Guid>(
manyToManyRelationshipMetadata.Entity2IntersectAttribute))
},
},
Relationship = new Relationship(manyToManyRelationshipMetadata.SchemaName) { PrimaryEntityRole = EntityRole.Referencing }
});
};
ApplyBypassBusinessLogicExecution(request);
Connection.Execute(request);

WriteVerbose(string.Format("Deleted intersect record {0}:{1}", entityName, id));
}
}
else
{
DeleteRequest request = new DeleteRequest { Target = new EntityReference(entityName, id) };
ApplyBypassBusinessLogicExecution(request);

if (_nextBatchItems != null)
{
Expand All @@ -139,7 +149,9 @@ private void Delete(string entityName, Guid id)
{
try
{
Connection.Delete(entityName, id);
DeleteRequest deleteRequest = new DeleteRequest { Target = new EntityReference(entityName, id) };
ApplyBypassBusinessLogicExecution(deleteRequest);
Connection.Execute(deleteRequest);
}
catch (FaultException ex)
{
Expand Down Expand Up @@ -200,6 +212,7 @@ private void ProcessBatch()
Requests = new OrganizationRequestCollection(),
RequestId = Guid.NewGuid()
};
ApplyBypassBusinessLogicExecution(batchRequest);

batchRequest.Requests.AddRange(_nextBatchItems.Select(i => i.Request));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace Rnwood.Dataverse.Data.PowerShell.Commands
///<summary>Creates or updates records in a Dataverse environment. If a matching record is found then it will be updated, otherwise a new record is created (some options can override this).
///This command can also handle creation/update of intersect records(many to many relationships).</summary>

public class SetDataverseRecordCmdlet : OrganizationServiceCmdlet
public class SetDataverseRecordCmdlet : CustomLogicBypassableOrganizationServiceCmdlet
{
[Parameter(Mandatory = true, HelpMessage = "DataverseConnection instance obtained from Get-DataverseConnnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/)")]
public override ServiceClient Connection { get; set; }
Expand Down Expand Up @@ -75,6 +75,14 @@ public Hashtable LookupColumns
set;
}

[Parameter(HelpMessage = "Specifies the types of business logic (for example plugins) to bypass")]
public override BusinessLogicTypes[] BypassBusinessLogicExecution { get; set; }


[Parameter(HelpMessage = "Specifies the IDs of plugin steps to bypass")]
public override Guid[] BypassBusinessLogicExecutionStepIds { get; set; }


private class BatchItem
{
public BatchItem(PSObject inputObject, OrganizationRequest request, Action<OrganizationResponse> responseCompletion) : this(inputObject, request, responseCompletion, null)
Expand Down Expand Up @@ -182,6 +190,7 @@ private void ProcessBatch()
Requests = new OrganizationRequestCollection(),
RequestId = Guid.NewGuid()
};
ApplyBypassBusinessLogicExecution(batchRequest);

batchRequest.Requests.AddRange(_nextBatchItems.Select(i => i.Request));

Expand Down Expand Up @@ -336,6 +345,7 @@ protected override void ProcessRecord()
Assignee = ownerid,
Target = target.ToEntityReference()
};
ApplyBypassBusinessLogicExecution(request);

if (_nextBatchItems != null)
{
Expand Down Expand Up @@ -382,6 +392,7 @@ protected override void ProcessRecord()
State = stateCode,
Status = statuscode
};
ApplyBypassBusinessLogicExecution(request);

if (_nextBatchItems != null)
{
Expand Down Expand Up @@ -450,6 +461,7 @@ private bool UpsertRecord(EntityMetadata entityMetadata, Entity target)
PrimaryEntityRole = EntityRole.Referencing
},
};
ApplyBypassBusinessLogicExecution(request);

if (_nextBatchItems != null)
{
Expand Down Expand Up @@ -588,6 +600,7 @@ private void CreateNewRecord(EntityMetadata entityMetadata, Entity target)
PrimaryEntityRole = EntityRole.Referencing
},
};
ApplyBypassBusinessLogicExecution(request);

if (_nextBatchItems != null)
{
Expand Down Expand Up @@ -634,6 +647,7 @@ private void CreateNewRecord(EntityMetadata entityMetadata, Entity target)
{
Target = targetCreate
};
ApplyBypassBusinessLogicExecution(request);

if (_nextBatchItems != null)
{
Expand Down Expand Up @@ -802,6 +816,7 @@ private void UpdateExistingRecord(EntityMetadata entityMetadata, Entity target,
DataverseEntityConverter converter = new DataverseEntityConverter(Connection, entityMetadataFactory);

UpdateRequest request = new UpdateRequest() { Target = target };
ApplyBypassBusinessLogicExecution(request);
string updatedColumnSummary = GetColumnSummary(targetUpdate);

if (_nextBatchItems != null)
Expand Down
Binary file not shown.
21 changes: 18 additions & 3 deletions Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSql.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ Invokes a Dataverse SQL query using Sql4Cds and writes any resulting rows to the
## SYNTAX

```
Invoke-DataverseSql -Connection <ServiceClient> -Sql <String> [-UseTdsEndpoint <Boolean>] [-Timeout <Int32>]
[-Parameters <PSObject>] [-BatchSize <Int32>] [-MaxDegreeOfParallelism <Int32>]
Invoke-DataverseSql -Connection <ServiceClient> -Sql <String> [-UseTdsEndpoint] [-Timeout <Int32>]
[-Parameters <PSObject>] [-BatchSize <Int32>] [-MaxDegreeOfParallelism <Int32>] [-BypassCustomPluginExecution]
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
```

Expand Down Expand Up @@ -133,7 +133,7 @@ Accept wildcard characters: False
Let Sql4Cds use the TDS endpoint or not for compatible queries. The default is to not use this.

```yaml
Type: Boolean
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Expand Down Expand Up @@ -204,6 +204,21 @@ Accept pipeline input: False
Accept wildcard characters: False
```

### -BypassCustomPluginExecution
Bypasses custom plugins. See Sql4Cds docs.

```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).

Expand Down
19 changes: 17 additions & 2 deletions Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseRecord.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Deletes an existing Dataverse record.

```
Remove-DataverseRecord -Connection <ServiceClient> [-InputObject <PSObject>] -TableName <String> -Id <Guid>
[-BatchSize <UInt32>] [-IfExists] [-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm]
[<CommonParameters>]
[-BatchSize <UInt32>] [-IfExists] [-BypassBusinessLogicExecution <BusinessLogicTypes[]>]
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
```

## DESCRIPTION
Expand Down Expand Up @@ -179,6 +179,21 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -BypassBusinessLogicExecution
Specifies the types of business logic (for example plugins) to bypass
```yaml
Type: BusinessLogicTypes[]
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
Expand Down
19 changes: 17 additions & 2 deletions Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecord.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Creates or updates Dataverse records including M:M association/disassociation, s
Set-DataverseRecord -Connection <ServiceClient> -InputObject <PSObject> [-BatchSize <UInt32>]
-TableName <String> [-IgnoreProperties <String[]>] [-Id <Guid>] [-MatchOn <String[][]>] [-PassThru]
[-NoUpdate] [-NoCreate] [-NoUpdateColumns <String[]>] [-CallerId <Guid>] [-UpdateAllColumns] [-CreateOnly]
[-Upsert] [-LookupColumns <Hashtable>] [-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm]
[<CommonParameters>]
[-Upsert] [-LookupColumns <Hashtable>] [-BypassBusinessLogicExecution <BusinessLogicTypes[]>]
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
```

## DESCRIPTION
Expand Down Expand Up @@ -364,6 +364,21 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -BypassBusinessLogicExecution
Specifies the types of business logic (for example plugins) to bypass
```yaml
Type: BusinessLogicTypes[]
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
Expand Down

0 comments on commit cab76dd

Please sign in to comment.