From 1367490f6d3787a46bc25a29b1d3bda940186f42 Mon Sep 17 00:00:00 2001 From: Emanuel Palm Date: Fri, 18 Oct 2024 21:42:11 +0200 Subject: [PATCH] new command Get-AzDataTable to get tables available on storage account --- CHANGELOG.md | 8 + GitVersion.yml | 146 ++++-- docs/help/Add-AzDataTableEntity.md | 270 +++++----- docs/help/Clear-AzDataTable.md | 148 +++--- docs/help/Get-AzDataTable.md | 96 ++++ docs/help/Get-AzDataTableEntity.md | 402 +++++++-------- docs/help/New-AzDataTable.md | 130 ++--- docs/help/New-AzDataTableContext.md | 468 +++++++++--------- docs/help/Remove-AzDataTable.md | 130 ++--- docs/help/Remove-AzDataTableEntity.md | 2 +- docs/help/Update-AzDataTableEntity.md | 2 +- .../AzBobbyTables.Core/AzDataTableService.cs | 128 ++++- .../Cmdlets/AzDataTableOperationCommand.cs | 9 + .../Cmdlets/GetAzDataTable.cs | 67 +++ .../Cmdlets/NewAzDataTableContext.cs | 15 +- source/AzBobbyTables.psd1 | 1 + tests/AzuriteIntegration.Tests.ps1 | 47 +- tests/Get-AzDataTable.Tests.ps1 | 57 +++ tests/New-AzDataTableContext.Tests.ps1 | 10 +- 19 files changed, 1292 insertions(+), 844 deletions(-) create mode 100644 docs/help/Get-AzDataTable.md create mode 100644 source/AzBobbyTables.PS/Cmdlets/GetAzDataTable.cs create mode 100644 tests/Get-AzDataTable.Tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index a916d6c..e4875c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ The format is based on and uses the types of changes according to [Keep a Change ## [Unreleased] +### Added + +- Added command `Get-AzDataTable` to get the names of tables in a storage account [#77](https://github.com/PalmEmanuel/AzBobbyTables/issues/77) + +### Changed + +- Implemented TableServiceClient to support operations on tables in the storage account. + ## [3.2.1] - 2024-07-09 ### Fixed diff --git a/GitVersion.yml b/GitVersion.yml index 8a1d5ff..38e6df5 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,40 +1,116 @@ -mode: ContinuousDelivery -next-version: 0.0.1 -major-version-bump-message: '(breaking\schange|breaking|major)\b' -minor-version-bump-message: '(adds?|features?|minor)\b' -patch-version-bump-message: '\s?(fix|patch)' +assembly-versioning-scheme: MajorMinorPatch +assembly-file-versioning-scheme: MajorMinorPatch +tag-prefix: '[vV]?' +version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* +major-version-bump-message: '\+semver:\s?(breaking|major)' +minor-version-bump-message: '\+semver:\s?(feature|minor)' +patch-version-bump-message: '\+semver:\s?(fix|patch)' no-bump-message: '\+semver:\s?(none|skip)' -assembly-informational-format: '{NuGetVersionV2}+Sha.{Sha}.Date.{CommitDate}' +tag-pre-release-weight: 60000 +commit-date-format: yyyy-MM-dd +merge-message-formats: {} +update-build-number: true +semantic-version-format: Strict +strategies: +- Fallback +- ConfiguredNextVersion +- MergeMessage +- TaggedCommit +- TrackReleaseBranches +- VersionInBranchName branches: - master: - tag: preview - regex: ^main$ - pull-request: - tag: PR - feature: - tag: useBranchName - increment: Minor - regex: f(eature(s)?)?[\/-] - source-branches: ['master'] - hotfix: - tag: fix + main: + label: 'preview' + increment: Patch + prevent-increment: + of-merged-branch: true + track-merge-target: false + track-merge-message: true + regex: ^master$|^main$ + source-branches: [] + is-source-branch-for: [] + tracks-release-branches: false + is-release-branch: false + is-main-branch: true + pre-release-weight: 55000 + release: + mode: ManualDeployment + label: beta increment: Patch - regex: (hot)?fix(es)?[\/-] - source-branches: ['master'] - + prevent-increment: + of-merged-branch: true + when-branch-merged: false + when-current-commit-tagged: false + track-merge-target: false + track-merge-message: true + regex: ^releases?[/-](?.+) + source-branches: + - main + is-source-branch-for: [] + tracks-release-branches: false + is-release-branch: true + is-main-branch: false + pre-release-weight: 30000 + feature: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + prevent-increment: + when-current-commit-tagged: false + track-merge-message: true + regex: ^features?[/-](?.+) + source-branches: + - main + - release + is-source-branch-for: [] + is-main-branch: false + pre-release-weight: 30000 + pull-request: + mode: ContinuousDelivery + label: PullRequest + increment: Inherit + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false + label-number-pattern: '[/-](?\d+)' + track-merge-message: true + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - main + - release + - feature + is-source-branch-for: [] + pre-release-weight: 30000 + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + prevent-increment: + when-current-commit-tagged: false + track-merge-message: false + regex: (?.+) + source-branches: + - main + - release + - feature + - pull-request + is-source-branch-for: [] + is-main-branch: false ignore: sha: [] -merge-message-formats: {} - - -# feature: -# tag: useBranchName -# increment: Minor -# regex: f(eature(s)?)?[/-] -# source-branches: ['master'] -# hotfix: -# tag: fix -# increment: Patch -# regex: (hot)?fix(es)?[/-] -# source-branches: ['master'] - +mode: ContinuousDelivery +label: '{BranchName}' +increment: Inherit +prevent-increment: + of-merged-branch: false + when-branch-merged: false + when-current-commit-tagged: true +track-merge-target: false +track-merge-message: true +commit-message-incrementing: Enabled +regex: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false \ No newline at end of file diff --git a/docs/help/Add-AzDataTableEntity.md b/docs/help/Add-AzDataTableEntity.md index 741bce9..e3e4ea1 100644 --- a/docs/help/Add-AzDataTableEntity.md +++ b/docs/help/Add-AzDataTableEntity.md @@ -1,136 +1,136 @@ ---- -external help file: AzBobbyTables.PS.dll-Help.xml -Module Name: AzBobbyTables -online version: -schema: 2.0.0 ---- - -# Add-AzDataTableEntity - -## SYNOPSIS - -Add one or more entities to an Azure Table. - -## SYNTAX - -``` -Add-AzDataTableEntity -Context -Entity [-Force] [-CreateTableIfNotExists] - [] -``` - -## DESCRIPTION - -Add one or more entities to an Azure Table, as an array of either Hashtables or PSObjects. - -## EXAMPLES - -### Example 1 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString -PS C:\> $User = @{ FirstName = 'Bobby'; LastName = 'Tables'; PartitionKey = 'Example'; RowKey = '1' } -PS C:\> Add-AzDataTableEntity -Entity $User -Context $Context -``` - -Add the user "Bobby Tables" to a table using a connection string. - -### Example 2 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -SharedAccessSignature $SAS -PS C:\> $Users = @( ->> @{ FirstName = 'Bobby'; LastName = 'Tables'; PartitionKey = 'Example'; RowKey = '1' }, ->> @{ FirstName = 'Bobby Junior'; LastName = 'Tables'; PartitionKey = 'Example'; RowKey = '2' } ) -PS C:\> Add-AzDataTableEntity -Entity $Users -Context $Context -Force -``` - -Add multiple users to a table using a shared access signature URL, overwriting any existing rows. - -## PARAMETERS - -### -Context - -A context object created by New-AzDataTableContext, with authentication information for the table to operate on. - -```yaml -Type: AzDataTableContext -Parameter Sets: (All) -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -CreateTableIfNotExists - -If the table should be created if it does not exist. - -```yaml -Type: SwitchParameter -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Entity - -The entities to add to the table. - -```yaml -Type: Object[] -Parameter Sets: (All) -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: True (ByValue) -Accept wildcard characters: False -``` - -### -Force - -Overwrites provided entities if they exist. - -```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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### System.Collections.Hashtable[] or System.Management.Automation.PSObject[] - -This cmdlet takes either an array of hashtables or psobjects as input to the Entity parameter, which can also be provided through the pipeline. - -## OUTPUTS - -### System.Object - -## NOTES - -Regarding Dates, DateTime, and DateTimeOffset: - -The underlying Azure.Data.Tables SDK expects to work with DateTime fields in UTC format for conversion to DateTimeOffset objects. When submitting a DateTimeOffset object to the SDK, it will be converted to UTC timezone rather than preserving the existing timezone/offset info. Similarly, if a `DateTime` object is submitted in the entity with its Kind set to "local" or "unspecified", the SDK will return an error and state that `Azure SDK requires it to be UTC`. While there isn't any change needed to get `DateTimeOffset` objects to work with AzBobbyTables, the workaround for `DateTime` objects is to set the property to a new `DateTime` object with its `Kind` property set to `Utc`. e.g. `$obj.Time = $obj.Time.ToUniversalFormat()`. [Related issue](https://github.com/Azure/azure-sdk-for-net/issues/30644). - -It is possible via the Azure Storage Explorer to set DateTime fields with offsets other than UTC/+00:00. Note that searches with queries set to type `DateTime` do properly calculate to a specific moment, and find equivilent moments. e.g. a `-Filter` set to `Time eq datetime'2023-12-26T18:05:40.5345634+00:00'` will match an entry where the Time property is set to `2023-12-26T17:05:40.5345634-01:00`. - +--- +external help file: AzBobbyTables.PS.dll-Help.xml +Module Name: AzBobbyTables +online version: +schema: 2.0.0 +--- + +# Add-AzDataTableEntity + +## SYNOPSIS + +Add one or more entities to an Azure Table. + +## SYNTAX + +``` +Add-AzDataTableEntity -Context -Entity [-Force] [-CreateTableIfNotExists] + [] +``` + +## DESCRIPTION + +Add one or more entities to an Azure Table, as an array of either Hashtables or PSObjects. + +## EXAMPLES + +### Example 1 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> $User = @{ FirstName = 'Bobby'; LastName = 'Tables'; PartitionKey = 'Example'; RowKey = '1' } +PS C:\> Add-AzDataTableEntity -Entity $User -Context $Context +``` + +Add the user "Bobby Tables" to a table using a connection string. + +### Example 2 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -SharedAccessSignature $SAS +PS C:\> $Users = @( +>> @{ FirstName = 'Bobby'; LastName = 'Tables'; PartitionKey = 'Example'; RowKey = '1' }, +>> @{ FirstName = 'Bobby Junior'; LastName = 'Tables'; PartitionKey = 'Example'; RowKey = '2' } ) +PS C:\> Add-AzDataTableEntity -Entity $Users -Context $Context -Force +``` + +Add multiple users to a table using a shared access signature URL, overwriting any existing rows. + +## PARAMETERS + +### -Context + +A context object created by New-AzDataTableContext, with authentication information for the table to operate on. + +```yaml +Type: AzDataTableContext +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -CreateTableIfNotExists + +If the table should be created if it does not exist. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Entity + +The entities to add to the table. + +```yaml +Type: Object[] +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -Force + +Overwrites provided entities if they exist. + +```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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.Collections.Hashtable[] or System.Management.Automation.PSObject[] + +This cmdlet takes either an array of hashtables or psobjects as input to the Entity parameter, which can also be provided through the pipeline. + +## OUTPUTS + +### System.Object + +## NOTES + +Regarding Dates, DateTime, and DateTimeOffset: + +The underlying Azure.Data.Tables SDK expects to work with DateTime fields in UTC format for conversion to DateTimeOffset objects. When submitting a DateTimeOffset object to the SDK, it will be converted to UTC timezone rather than preserving the existing timezone/offset info. Similarly, if a `DateTime` object is submitted in the entity with its Kind set to "local" or "unspecified", the SDK will return an error and state that `Azure SDK requires it to be UTC`. While there isn't any change needed to get `DateTimeOffset` objects to work with AzBobbyTables, the workaround for `DateTime` objects is to set the property to a new `DateTime` object with its `Kind` property set to `Utc`. e.g. `$obj.Time = $obj.Time.ToUniversalFormat()`. [Related issue](https://github.com/Azure/azure-sdk-for-net/issues/30644). + +It is possible via the Azure Storage Explorer to set DateTime fields with offsets other than UTC/+00:00. Note that searches with queries set to type `DateTime` do properly calculate to a specific moment, and find equivilent moments. e.g. a `-Filter` set to `Time eq datetime'2023-12-26T18:05:40.5345634+00:00'` will match an entry where the Time property is set to `2023-12-26T17:05:40.5345634-01:00`. + ## RELATED LINKS diff --git a/docs/help/Clear-AzDataTable.md b/docs/help/Clear-AzDataTable.md index ff25849..2753c32 100644 --- a/docs/help/Clear-AzDataTable.md +++ b/docs/help/Clear-AzDataTable.md @@ -1,75 +1,75 @@ ---- -external help file: AzBobbyTables.PS.dll-Help.xml -Module Name: AzBobbyTables -online version: -schema: 2.0.0 ---- - -# Clear-AzDataTable - -## SYNOPSIS - -Clear all entities from an Azure Table. - -## SYNTAX - -``` -Clear-AzDataTable -Context [] -``` - -## DESCRIPTION - -Clear all entities from an Azure Table. - -## EXAMPLES - -### Example 1 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString -PS C:\> Clear-AzDataTable -Context $Context -``` - -Clear all entities from a table using a connection string. - -### Example 2 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -ManagedIdentity -PS C:\> Clear-AzDataTable $Context -``` - -Clear all entities from a table using a managed identity. - -## PARAMETERS - -### -Context - -A context object created by New-AzDataTableContext, with authentication information for the table to operate on. - -```yaml -Type: AzDataTableContext -Parameter Sets: (All) -Aliases: - -Required: True -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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### None - -## OUTPUTS - -### None - -## NOTES - +--- +external help file: AzBobbyTables.PS.dll-Help.xml +Module Name: AzBobbyTables +online version: +schema: 2.0.0 +--- + +# Clear-AzDataTable + +## SYNOPSIS + +Clear all entities from an Azure Table. + +## SYNTAX + +``` +Clear-AzDataTable -Context [] +``` + +## DESCRIPTION + +Clear all entities from an Azure Table. + +## EXAMPLES + +### Example 1 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> Clear-AzDataTable -Context $Context +``` + +Clear all entities from a table using a connection string. + +### Example 2 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -ManagedIdentity +PS C:\> Clear-AzDataTable $Context +``` + +Clear all entities from a table using a managed identity. + +## PARAMETERS + +### -Context + +A context object created by New-AzDataTableContext, with authentication information for the table to operate on. + +```yaml +Type: AzDataTableContext +Parameter Sets: (All) +Aliases: + +Required: True +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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +## OUTPUTS + +### None + +## NOTES + ## RELATED LINKS diff --git a/docs/help/Get-AzDataTable.md b/docs/help/Get-AzDataTable.md new file mode 100644 index 0000000..17a065b --- /dev/null +++ b/docs/help/Get-AzDataTable.md @@ -0,0 +1,96 @@ +--- +external help file: AzBobbyTables.PS.dll-Help.xml +Module Name: AzBobbyTables +online version: +schema: 2.0.0 +--- + +# Get-AzDataTable + +## SYNOPSIS + +Get the names of all tables in the storage account. + +## SYNTAX + +``` +Get-AzDataTable -Context [-Filter ] + [] +``` + +## DESCRIPTION + +Get the names of all tables in the storage account. + +The optional `-Filter` parameter can be used to filter the tables returned. For more information on the filter syntax, see the Azure Table service documentation: + +https://learn.microsoft.com/en-us/rest/api/storageservices/Querying-Tables-and-Entities + +## EXAMPLES + +### Example 1 + +```powershell +PS C:\> Get-AzDataTable -Context $Context +``` + +Gets all table names in the storage account. + +### Example 2 + +```powershell +PS C:\> Get-AzDataTable -Context $Context -Filter "TableName eq '$MyTableName'" +``` + +Gets the table named `$MyTableName` to see if it exists. + +## PARAMETERS + +### -Context + +A context object created by New-AzDataTableContext, with authentication information for the storage account to operate on. + +```yaml +Type: AzDataTableContext +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Filter + +A string to filter the tables returned. For more information on the filter syntax, see the Azure Table service documentation: + +https://learn.microsoft.com/en-us/rest/api/storageservices/Querying-Tables-and-Entities + +```yaml +Type: String +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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +## OUTPUTS + +### System.String + +## NOTES + +## RELATED LINKS diff --git a/docs/help/Get-AzDataTableEntity.md b/docs/help/Get-AzDataTableEntity.md index 681822e..dd1daed 100644 --- a/docs/help/Get-AzDataTableEntity.md +++ b/docs/help/Get-AzDataTableEntity.md @@ -1,202 +1,202 @@ ---- -external help file: AzBobbyTables.PS.dll-Help.xml -Module Name: AzBobbyTables -online version: -schema: 2.0.0 ---- - -# Get-AzDataTableEntity - -## SYNOPSIS - -Get one or more entities from an Azure Table. - -## SYNTAX - -### TableOperation (Default) -``` -Get-AzDataTableEntity -Context [-Filter ] [-Property ] [-First ] - [-Skip ] [-Sort ] [] -``` - -### Count -``` -Get-AzDataTableEntity -Context [-Count] - [] -``` - -## DESCRIPTION - -Get either all entities from an Azure Table, or those matching a provided OData filter. - -Documentation on querying tables and entities: - -## EXAMPLES - -### Example 1 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString -PS C:\> $UserEntity = Get-AzDataTableEntity -Filter "FirstName eq 'Bobby' and LastName eq 'Tables'" -Context $Context -``` - -Get the user "Bobby Tables" from the table using a connection string. - -### Example 2 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString -PS C:\> $UserCount = Get-AzDataTableEntity -Filter "LastName eq 'Tables'" -Context $Context -Count -``` - -Use the Count parameter to get only the number of users matching the filter, using a connection string. - -### Example 3 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ManagedIdentity -StorageAccountName $Name -PS C:\> $UserEntities = Get-AzDataTableEntity -Sort 'Id','Age' -First 100 -Skip 500 -Context $Context -``` - -Skipping the first 100 entities, get 500 entities sorted by id and age from the table using a managed identity for authorization. - -### Example 4 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -SharedAccessSignature $SAS -PS C:\> $UserEntities = Get-AzDataTableEntity -Property 'FirstName','Age' -Context $Context -``` - -Get only the properties "FirstName" and "Age" for all entities found in the table using a shared access signature URL. - -## PARAMETERS - -### -Context - -A context object created by New-AzDataTableContext, with authentication information for the table to operate on. - -```yaml -Type: AzDataTableContext -Parameter Sets: (All) -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Count - -Specifies to only get the number of matching entities in the table, and not the data itself. - -```yaml -Type: SwitchParameter -Parameter Sets: Count -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Filter - -The OData filter to use in the query. -Documentation on querying tables and entities: - -```yaml -Type: String -Parameter Sets: TableOperation -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -First - -Gets only the specified number of objects. Enter the number of objects to get. - -```yaml -Type: Int32 -Parameter Sets: TableOperation -Aliases: Top, Take - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Property - -One or several names of properties, to specify data to return for the entities. - -```yaml -Type: String[] -Parameter Sets: TableOperation -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Skip - -Ignores the specified number of objects and then gets the remaining objects. Enter the number of objects to skip. - -```yaml -Type: Int32 -Parameter Sets: TableOperation -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Sort - -Specifies one or several property names that to sort the entities by. If several properties are provided, the entities are sorted in the order that the property names are provided. - -Note that using this parameter may slow down the command a lot when working with large data sets! - -```yaml -Type: String[] -Parameter Sets: TableOperation -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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### None - -## OUTPUTS - -### System.Management.Automation.PSObject - -## NOTES - +--- +external help file: AzBobbyTables.PS.dll-Help.xml +Module Name: AzBobbyTables +online version: +schema: 2.0.0 +--- + +# Get-AzDataTableEntity + +## SYNOPSIS + +Get one or more entities from an Azure Table. + +## SYNTAX + +### TableOperation (Default) +``` +Get-AzDataTableEntity -Context [-Filter ] [-Property ] [-First ] + [-Skip ] [-Sort ] [] +``` + +### Count +``` +Get-AzDataTableEntity -Context [-Count] + [] +``` + +## DESCRIPTION + +Get either all entities from an Azure Table, or those matching a provided OData filter. + +Documentation on querying tables and entities: + +## EXAMPLES + +### Example 1 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> $UserEntity = Get-AzDataTableEntity -Filter "FirstName eq 'Bobby' and LastName eq 'Tables'" -Context $Context +``` + +Get the user "Bobby Tables" from the table using a connection string. + +### Example 2 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> $UserCount = Get-AzDataTableEntity -Filter "LastName eq 'Tables'" -Context $Context -Count +``` + +Use the Count parameter to get only the number of users matching the filter, using a connection string. + +### Example 3 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ManagedIdentity -StorageAccountName $Name +PS C:\> $UserEntities = Get-AzDataTableEntity -Sort 'Id','Age' -First 100 -Skip 500 -Context $Context +``` + +Skipping the first 100 entities, get 500 entities sorted by id and age from the table using a managed identity for authorization. + +### Example 4 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -SharedAccessSignature $SAS +PS C:\> $UserEntities = Get-AzDataTableEntity -Property 'FirstName','Age' -Context $Context +``` + +Get only the properties "FirstName" and "Age" for all entities found in the table using a shared access signature URL. + +## PARAMETERS + +### -Context + +A context object created by New-AzDataTableContext, with authentication information for the table to operate on. + +```yaml +Type: AzDataTableContext +Parameter Sets: (All) +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Count + +Specifies to only get the number of matching entities in the table, and not the data itself. + +```yaml +Type: SwitchParameter +Parameter Sets: Count +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Filter + +The OData filter to use in the query. +Documentation on querying tables and entities: + +```yaml +Type: String +Parameter Sets: TableOperation +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -First + +Gets only the specified number of objects. Enter the number of objects to get. + +```yaml +Type: Int32 +Parameter Sets: TableOperation +Aliases: Top, Take + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Property + +One or several names of properties, to specify data to return for the entities. + +```yaml +Type: String[] +Parameter Sets: TableOperation +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Skip + +Ignores the specified number of objects and then gets the remaining objects. Enter the number of objects to skip. + +```yaml +Type: Int32 +Parameter Sets: TableOperation +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Sort + +Specifies one or several property names that to sort the entities by. If several properties are provided, the entities are sorted in the order that the property names are provided. + +Note that using this parameter may slow down the command a lot when working with large data sets! + +```yaml +Type: String[] +Parameter Sets: TableOperation +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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +## OUTPUTS + +### System.Management.Automation.PSObject + +## NOTES + ## RELATED LINKS diff --git a/docs/help/New-AzDataTable.md b/docs/help/New-AzDataTable.md index db0daff..4702b7b 100644 --- a/docs/help/New-AzDataTable.md +++ b/docs/help/New-AzDataTable.md @@ -1,66 +1,66 @@ ---- -external help file: AzBobbyTables.PS.dll-Help.xml -Module Name: AzBobbyTables -online version: -schema: 2.0.0 ---- - -# New-AzDataTable - -## SYNOPSIS - -Create a new table. - -## SYNTAX - -``` -New-AzDataTable -Context [] -``` - -## DESCRIPTION - -Create a new table. - -## EXAMPLES - -### Example 1 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString -PS C:\> New-AzDataTable -Context $Context -``` - -Create a new table using a connection string for the storage account. - -## PARAMETERS - -### -Context - -A context object created by New-AzDataTableContext, with authentication information for the table to operate on. - -```yaml -Type: AzDataTableContext -Parameter Sets: (All) -Aliases: - -Required: True -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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### None - -## OUTPUTS - -### None - -## NOTES - +--- +external help file: AzBobbyTables.PS.dll-Help.xml +Module Name: AzBobbyTables +online version: +schema: 2.0.0 +--- + +# New-AzDataTable + +## SYNOPSIS + +Create a new table. + +## SYNTAX + +``` +New-AzDataTable -Context [] +``` + +## DESCRIPTION + +Create a new table. + +## EXAMPLES + +### Example 1 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> New-AzDataTable -Context $Context +``` + +Create a new table using a connection string for the storage account. + +## PARAMETERS + +### -Context + +A context object created by New-AzDataTableContext, with authentication information for the table to operate on. + +```yaml +Type: AzDataTableContext +Parameter Sets: (All) +Aliases: + +Required: True +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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +## OUTPUTS + +### None + +## NOTES + ## RELATED LINKS diff --git a/docs/help/New-AzDataTableContext.md b/docs/help/New-AzDataTableContext.md index 50b9fda..e3d8656 100644 --- a/docs/help/New-AzDataTableContext.md +++ b/docs/help/New-AzDataTableContext.md @@ -1,235 +1,235 @@ ---- -external help file: AzBobbyTables.PS.dll-Help.xml -Module Name: AzBobbyTables -online version: -schema: 2.0.0 ---- - -# New-AzDataTableContext - -## SYNOPSIS - -Creates a context object with authentication information for the table to operate on, to be used in other commands. - -## SYNTAX - -### ConnectionString -``` -New-AzDataTableContext -TableName -ConnectionString - [] -``` - -### SAS -``` -New-AzDataTableContext -TableName -SharedAccessSignature - [] -``` - -### Key -``` -New-AzDataTableContext -TableName -StorageAccountName -StorageAccountKey - [] -``` - -### Token -``` -New-AzDataTableContext -TableName -StorageAccountName -Token - [] -``` - -### ManagedIdentity -``` -New-AzDataTableContext -TableName -StorageAccountName [-ManagedIdentity] [-ClientId ] - [] -``` - -## DESCRIPTION - -Creates a context object with authentication information for the table to operate on, to be used in other commands. - -## EXAMPLES - -### Example 1 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString -``` - -Creates a context object using the table name and a connection string. - -### Example 2 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -StorageAccountKey $Key -``` - -Creates a context object using the table name, storage account name and a storage account access key. - -### Example 3 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -SharedAccessSignature $SAS -``` - -Creates a context object using the table name and a shared access signature URL. - -### Example 4 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -ManagedIdentity -``` - -Creates a context object using the table name, storage account name and a managed identity for authorization. - -### Example 5 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -Token $Token -``` - -Creates a context object using the table name, storage account name and an access token. - -## PARAMETERS - -### -ClientId - -Specifies the client id when using a user-assigned managed identity. - -```yaml -Type: String -Parameter Sets: ManagedIdentity -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -ConnectionString - -The connection string to the storage account. - -```yaml -Type: String -Parameter Sets: ConnectionString -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -ManagedIdentity - -Specifies that the command is run by a managed identity (such as in an Azure Function), and authorization will be handled using that identity. - -```yaml -Type: SwitchParameter -Parameter Sets: ManagedIdentity -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -SharedAccessSignature - -The table service SAS URL. The table endpoint of the storage account, with the shared access token appended to it. - -```yaml -Type: Uri -Parameter Sets: SAS -Aliases: SAS - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -StorageAccountKey - -The storage account access key. - -```yaml -Type: String -Parameter Sets: Key -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -StorageAccountName - -The name of the storage account. - -```yaml -Type: String -Parameter Sets: Key, Token, ManagedIdentity -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -TableName - -The name of the table. - -```yaml -Type: String -Parameter Sets: (All) -Aliases: - -Required: True -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Token - -An access token to use for authorization. - -```yaml -Type: String -Parameter Sets: Token -Aliases: - -Required: True -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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### None - -## OUTPUTS - -### System.Object - -## NOTES - +--- +external help file: AzBobbyTables.PS.dll-Help.xml +Module Name: AzBobbyTables +online version: +schema: 2.0.0 +--- + +# New-AzDataTableContext + +## SYNOPSIS + +Creates a context object with authentication information for the table to operate on, to be used in other commands. + +## SYNTAX + +### ConnectionString +``` +New-AzDataTableContext [-TableName ] -ConnectionString + [] +``` + +### SAS +``` +New-AzDataTableContext [-TableName ] -SharedAccessSignature + [] +``` + +### Key +``` +New-AzDataTableContext [-TableName ] -StorageAccountName -StorageAccountKey + [] +``` + +### Token +``` +New-AzDataTableContext [-TableName ] -StorageAccountName -Token + [] +``` + +### ManagedIdentity +``` +New-AzDataTableContext [-TableName ] -StorageAccountName [-ManagedIdentity] + [-ClientId ] [] +``` + +## DESCRIPTION + +Creates a context object with authentication information for the table to operate on, to be used in other commands. + +## EXAMPLES + +### Example 1 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +``` + +Creates a context object using the table name and a connection string. + +### Example 2 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -StorageAccountKey $Key +``` + +Creates a context object using the table name, storage account name and a storage account access key. + +### Example 3 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -SharedAccessSignature $SAS +``` + +Creates a context object using the table name and a shared access signature URL. + +### Example 4 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -ManagedIdentity +``` + +Creates a context object using the table name, storage account name and a managed identity for authorization. + +### Example 5 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -Token $Token +``` + +Creates a context object using the table name, storage account name and an access token. + +## PARAMETERS + +### -ClientId + +Specifies the client id when using a user-assigned managed identity. + +```yaml +Type: String +Parameter Sets: ManagedIdentity +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ConnectionString + +The connection string to the storage account. + +```yaml +Type: String +Parameter Sets: ConnectionString +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ManagedIdentity + +Specifies that the command is run by a managed identity (such as in an Azure Function), and authorization will be handled using that identity. + +```yaml +Type: SwitchParameter +Parameter Sets: ManagedIdentity +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -SharedAccessSignature + +The table service SAS URL. The table endpoint of the storage account, with the shared access token appended to it. + +```yaml +Type: Uri +Parameter Sets: SAS +Aliases: SAS + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -StorageAccountKey + +The storage account access key. + +```yaml +Type: String +Parameter Sets: Key +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -StorageAccountName + +The name of the storage account. + +```yaml +Type: String +Parameter Sets: Key, Token, ManagedIdentity +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -TableName + +The name of the table. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Token + +An access token to use for authorization. + +```yaml +Type: String +Parameter Sets: Token +Aliases: + +Required: True +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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +## OUTPUTS + +### System.Object + +## NOTES + ## RELATED LINKS diff --git a/docs/help/Remove-AzDataTable.md b/docs/help/Remove-AzDataTable.md index 46af468..f32dd1e 100644 --- a/docs/help/Remove-AzDataTable.md +++ b/docs/help/Remove-AzDataTable.md @@ -1,66 +1,66 @@ ---- -external help file: AzBobbyTables.PS.dll-Help.xml -Module Name: AzBobbyTables -online version: -schema: 2.0.0 ---- - -# Remove-AzDataTable - -## SYNOPSIS - -Delete an existing table. - -## SYNTAX - -``` -Remove-AzDataTable -Context [] -``` - -## DESCRIPTION - -Delete an existing table. - -## EXAMPLES - -### Example 1 - -```powershell -PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString -PS C:\> Remove-AzDataTable -Context $Context -``` - -Remove an existing table using a connection string for the storage account. - -## PARAMETERS - -### -Context - -A context object created by New-AzDataTableContext, with authentication information for the table to operate on. - -```yaml -Type: AzDataTableContext -Parameter Sets: (All) -Aliases: - -Required: True -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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### None - -## OUTPUTS - -### None - -## NOTES - +--- +external help file: AzBobbyTables.PS.dll-Help.xml +Module Name: AzBobbyTables +online version: +schema: 2.0.0 +--- + +# Remove-AzDataTable + +## SYNOPSIS + +Delete an existing table. + +## SYNTAX + +``` +Remove-AzDataTable -Context [] +``` + +## DESCRIPTION + +Delete an existing table. + +## EXAMPLES + +### Example 1 + +```powershell +PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> Remove-AzDataTable -Context $Context +``` + +Remove an existing table using a connection string for the storage account. + +## PARAMETERS + +### -Context + +A context object created by New-AzDataTableContext, with authentication information for the table to operate on. + +```yaml +Type: AzDataTableContext +Parameter Sets: (All) +Aliases: + +Required: True +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, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +## OUTPUTS + +### None + +## NOTES + ## RELATED LINKS diff --git a/docs/help/Remove-AzDataTableEntity.md b/docs/help/Remove-AzDataTableEntity.md index da5349f..0cafa83 100644 --- a/docs/help/Remove-AzDataTableEntity.md +++ b/docs/help/Remove-AzDataTableEntity.md @@ -133,4 +133,4 @@ This cmdlet takes either an array of hashtables or psobjects as input to the Ent ## NOTES -## RELATED LINKS +## RELATED LINKS diff --git a/docs/help/Update-AzDataTableEntity.md b/docs/help/Update-AzDataTableEntity.md index 4bf947f..9f8daf7 100644 --- a/docs/help/Update-AzDataTableEntity.md +++ b/docs/help/Update-AzDataTableEntity.md @@ -119,4 +119,4 @@ This cmdlet takes either an array of hashtables or psobjects as input to the Ent ## NOTES -## RELATED LINKS +## RELATED LINKS diff --git a/source/AzBobbyTables.Core/AzDataTableService.cs b/source/AzBobbyTables.Core/AzDataTableService.cs index a46ec47..455c03a 100644 --- a/source/AzBobbyTables.Core/AzDataTableService.cs +++ b/source/AzBobbyTables.Core/AzDataTableService.cs @@ -12,6 +12,7 @@ namespace PipeHow.AzBobbyTables.Core; public class AzDataTableService { private TableClient? TableClient { get; set; } + private TableServiceClient? TableServiceClient { get; set; } /// /// Cancellation token used within the AzDataTableService. @@ -55,15 +56,22 @@ public static AzDataTableService CreateWithConnectionString(string connectionStr try { var dataTableService = new AzDataTableService(cancellationToken); - - TableClient client = new(connectionString, tableName); - if (createIfNotExists) + TableServiceClient serviceClient = new(connectionString); + + if (tableName is not null) { - CreateIfNotExists(client, cancellationToken); + TableClient client = new(connectionString, tableName); + + if (createIfNotExists && !string.IsNullOrWhiteSpace(tableName)) + { + CreateIfNotExists(client, cancellationToken); + } + + dataTableService.TableClient = client; } - dataTableService.TableClient = client; + dataTableService.TableServiceClient = serviceClient; return dataTableService; } catch (Exception ex) @@ -78,15 +86,24 @@ public static AzDataTableService CreateWithStorageKey(string storageAccountName, { var dataTableService = new AzDataTableService(cancellationToken); var tableEndpoint = new Uri($"https://{storageAccountName}.table.core.windows.net/{tableName}"); - - TableClient client = new(tableEndpoint, tableName, new TableSharedKeyCredential(storageAccountName, storageAccountKey)); - if (createIfNotExists) + var sasCredential = new TableSharedKeyCredential(storageAccountName, storageAccountKey); + + TableServiceClient serviceClient = new(tableEndpoint, sasCredential); + + if (tableName is not null) { - CreateIfNotExists(client, cancellationToken); + TableClient client = new(tableEndpoint, tableName, sasCredential); + + if (createIfNotExists && !string.IsNullOrWhiteSpace(tableName)) + { + CreateIfNotExists(client, cancellationToken); + } + + dataTableService.TableClient = client; } - dataTableService.TableClient = client; + dataTableService.TableServiceClient = serviceClient; return dataTableService; } catch (Exception ex) @@ -102,14 +119,20 @@ public static AzDataTableService CreateWithToken(string storageAccountName, stri var dataTableService = new AzDataTableService(cancellationToken); var tableEndpoint = new Uri($"https://{storageAccountName}.table.core.windows.net/{tableName}"); - TableClient client = new(tableEndpoint, tableName, new ExternalTokenCredential(token, DateTimeOffset.Now.Add(TimeSpan.FromHours(1)))); + TableServiceClient serviceClient = new(tableEndpoint, new ExternalTokenCredential(token, DateTimeOffset.Now.Add(TimeSpan.FromHours(1)))); - if (createIfNotExists) + if (tableName is not null) { - CreateIfNotExists(client, cancellationToken); - } + TableClient client = new(tableEndpoint, tableName, new ExternalTokenCredential(token, DateTimeOffset.Now.Add(TimeSpan.FromHours(1)))); + + if (createIfNotExists && !string.IsNullOrWhiteSpace(tableName)) + { + CreateIfNotExists(client, cancellationToken); + } - dataTableService.TableClient = client; + dataTableService.TableClient = client; + } + dataTableService.TableServiceClient = serviceClient; return dataTableService; } catch (Exception ex) @@ -126,22 +149,30 @@ public static AzDataTableService CreateWithSAS(Uri sasUrl, string tableName, boo // The credential is built only using the token var sasCredential = new AzureSasCredential(sasUrl.Query); + // Extract the base URL (without the table name) + var baseUrl = new Uri(sasUrl.GetLeftPart(UriPartial.Authority)); + // If the user did not specify a full endpoint to the table if (!sasUrl.ToString().Contains($"/{tableName}?")) { // Insert the table name before the URL parameters var urlParts = sasUrl.ToString().Split('?'); - sasUrl = new Uri($"{urlParts.First()}{tableName}?{urlParts.Last()}"); + sasUrl = new Uri($"{urlParts.First().TrimEnd('/')}/{tableName}?{urlParts.Last()}"); } - - TableClient client = new(sasUrl, sasCredential); - if (createIfNotExists) + TableServiceClient serviceClient = new TableServiceClient(baseUrl, sasCredential); + if (tableName is not null) { - CreateIfNotExists(client, cancellationToken); - } + TableClient client = new(sasUrl, sasCredential); - dataTableService.TableClient = client; + if (createIfNotExists && !string.IsNullOrWhiteSpace(tableName)) + { + CreateIfNotExists(client, cancellationToken); + } + + dataTableService.TableClient = client; + } + dataTableService.TableServiceClient = serviceClient; return dataTableService; } catch (Exception ex) @@ -150,8 +181,32 @@ public static AzDataTableService CreateWithSAS(Uri sasUrl, string tableName, boo } } + /// + /// Get a list of tables from the storage account. + /// + /// The filter string to use in the query. + /// The list of tables as strings. + public IEnumerable GetTables(string filter) + { + try + { + var tables = TableServiceClient!.Query(filter, null, CancellationToken); + // Return Name property of each table + return tables.Select(t => t.Name); + } + catch (Exception ex) + { + throw new AzDataTableException(new ErrorRecord(ex, "GetTablesError", ErrorCategory.InvalidOperation, null)); + } + } + + /// + /// Remove a table from the storage account. + /// public void RemoveTable() { + ValidateTableClient(); + try { TableClient?.Delete(); @@ -170,6 +225,8 @@ public void RemoveTable() /// The result of the transaction. public void RemoveEntitiesFromTable(IEnumerable hashtables, bool validateEtag = true) { + ValidateTableClient(); + try { var transactions = new List(); @@ -204,6 +261,8 @@ public void RemoveEntitiesFromTable(IEnumerable hashtables, bool vali /// The result of the transaction. public void RemoveEntitiesFromTable(IEnumerable psobjects, bool validateEtag = true) { + ValidateTableClient(); + try { var transactions = new List(); @@ -246,6 +305,8 @@ public void RemoveEntitiesFromTable(IEnumerable psobjects, bool valida /// The result of the transaction. public void AddEntitiesToTable(IEnumerable hashtables, bool overwrite = false) { + ValidateTableClient(); + try { var transactions = new List(); @@ -290,6 +351,8 @@ public void AddEntitiesToTable(IEnumerable hashtables, bool overwrite /// The result of the transaction. public void AddEntitiesToTable(IEnumerable psobjects, bool overwrite = false) { + ValidateTableClient(); + try { var transactions = new List(); @@ -334,6 +397,8 @@ public void AddEntitiesToTable(IEnumerable psobjects, bool overwrite = /// The result of the transaction. public void UpdateEntitiesInTable(IEnumerable hashtables, bool validateEtag = true) { + ValidateTableClient(); + try { var transactions = new List(); @@ -377,6 +442,8 @@ public void UpdateEntitiesInTable(IEnumerable hashtables, bool valida /// The result of the transaction. public void UpdateEntitiesInTable(IEnumerable psobjects, bool validateEtag = true) { + ValidateTableClient(); + try { var transactions = new List(); @@ -420,6 +487,8 @@ public void UpdateEntitiesInTable(IEnumerable psobjects, bool validate /// The result of the query. public IEnumerable GetEntitiesFromTable(string query, string[] properties = null!, int? top = null, int? skip = null, string[] orderBy = null!) { + ValidateTableClient(); + try { // Declare type as IAsyncEnumerable to be able to overwrite it with LINQ results further down @@ -475,6 +544,8 @@ public IEnumerable GetEntitiesFromTable(string query, string[] propert /// public void ClearTable() { + ValidateTableClient(); + try { var entities = TableClient!.Query((string)null!, null, new[] { "PartitionKey", "RowKey" }); @@ -496,6 +567,8 @@ public void ClearTable() /// private void SubmitTransaction(IList transactions) { + ValidateTableClient(); + // Transactions only support up to 100 entities of the same partitionkey // Loop through transactions grouped by partitionkey foreach (var group in transactions.GroupBy(t => t.Entity.PartitionKey)) @@ -507,4 +580,15 @@ private void SubmitTransaction(IList transactions) } } } + + /// + /// Validate that the TableName is set in the context. + /// + private void ValidateTableClient() + { + if (TableClient is null) + { + throw new AzDataTableException(new ErrorRecord(new InvalidOperationException("Table name is not set in the TableContext, please create a new context for this operation!"), "TableClientError", ErrorCategory.InvalidOperation, null)); + } + } } diff --git a/source/AzBobbyTables.PS/Cmdlets/AzDataTableOperationCommand.cs b/source/AzBobbyTables.PS/Cmdlets/AzDataTableOperationCommand.cs index 9938889..ccc3f86 100644 --- a/source/AzBobbyTables.PS/Cmdlets/AzDataTableOperationCommand.cs +++ b/source/AzBobbyTables.PS/Cmdlets/AzDataTableOperationCommand.cs @@ -44,6 +44,15 @@ protected override void BeginProcessing() // Determine way to create AzDataTableService by using the provided Context, created with from New-AzDataTableContext private AzDataTableService CreateWithContext(AzDataTableContext context, bool createIfNotExists, CancellationToken cancellationToken = default) { + if (string.IsNullOrWhiteSpace(context.TableName) && createIfNotExists) + { + throw new AzDataTableException(new ErrorRecord( + new InvalidOperationException("The provided TableContext must have a table name specified to create it."), + "TableNameRequiredError", + ErrorCategory.InvalidArgument, + null)); + } + try { return context.ConnectionType switch diff --git a/source/AzBobbyTables.PS/Cmdlets/GetAzDataTable.cs b/source/AzBobbyTables.PS/Cmdlets/GetAzDataTable.cs new file mode 100644 index 0000000..901534c --- /dev/null +++ b/source/AzBobbyTables.PS/Cmdlets/GetAzDataTable.cs @@ -0,0 +1,67 @@ +using System; +using System.Linq; +using System.Management.Automation; + +namespace PipeHow.AzBobbyTables.Cmdlets; + +/// +/// Get one or more Azure Tables. +/// +[Cmdlet(VerbsCommon.Get, "AzDataTable")] +[OutputType(typeof(PSObject))] +public class GetAzDataTable : AzDataTableOperationCommand +{ + /// + /// The context used for the table, created with New-AzDataTableContext. + /// + [Parameter(Mandatory = true)] + public AzDataTableContext Context { get; set; } + + /// + /// The filter to use in the query. + /// + [Parameter()] + [ValidateNotNullOrEmpty] + public string Filter { get; set; } + + /// + /// The process step of the pipeline. + /// + protected override void ProcessRecord() + { + if (tableService is null) + { + WriteError(new ErrorRecord(new InvalidOperationException("Could not establish connection!"), "ConnectionError", ErrorCategory.ConnectionError, null)); + return; + } + + if (!string.IsNullOrWhiteSpace(Context.TableName)) + { + WriteWarning("Table name exists in the context but is not used in this command. To verify the existence of a specific table, use the -Filter parameter."); + } + + string filterMessage = "Finding "; + if (MyInvocation.BoundParameters.ContainsKey("Filter")) + { + filterMessage += $"all tables matching filter '{Filter}'."; + } + else + { + filterMessage += "all tables on storage account in provided context."; + } + WriteVerbose(filterMessage); + + try + { + var tables = tableService.GetTables(Filter); + foreach (var table in tables) + { + WriteObject(table); + } + } + catch (AzDataTableException ex) + { + WriteError(ex.ErrorRecord); + } + } +} diff --git a/source/AzBobbyTables.PS/Cmdlets/NewAzDataTableContext.cs b/source/AzBobbyTables.PS/Cmdlets/NewAzDataTableContext.cs index ae03abf..25a2acc 100644 --- a/source/AzBobbyTables.PS/Cmdlets/NewAzDataTableContext.cs +++ b/source/AzBobbyTables.PS/Cmdlets/NewAzDataTableContext.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Management.Automation; namespace PipeHow.AzBobbyTables.Cmdlets; @@ -12,11 +13,11 @@ public class NewAzDataTableContext : AzDataTableCommand // Inherit only base beh /// /// The name of the table. /// - [Parameter(Mandatory = true, ParameterSetName = "ConnectionString")] - [Parameter(Mandatory = true, ParameterSetName = "SAS")] - [Parameter(Mandatory = true, ParameterSetName = "Key")] - [Parameter(Mandatory = true, ParameterSetName = "Token")] - [Parameter(Mandatory = true, ParameterSetName = "ManagedIdentity")] + [Parameter(ParameterSetName = "ConnectionString")] + [Parameter(ParameterSetName = "SAS")] + [Parameter(ParameterSetName = "Key")] + [Parameter(ParameterSetName = "Token")] + [Parameter(ParameterSetName = "ManagedIdentity")] [ValidateNotNullOrEmpty()] public string TableName { get; set; } @@ -81,6 +82,10 @@ protected override void EndProcessing() if (!Enum.TryParse(ParameterSetName, out AzDataTableConnectionType connectionType)) WriteError(new ErrorRecord(new ArgumentException("Incorrect connection type!"), "ConnectionTypeError", ErrorCategory.InvalidType, connectionType)); + if (string.IsNullOrWhiteSpace(TableName)) { + WriteWarning("No table name was provided! This table context will not be able to operate on table data, only the storage account."); + } + // Output the AzDataTableContext to user for further operations WriteObject(new AzDataTableContext(TableName, connectionType, ConnectionString, StorageAccountName, StorageAccountKey, SharedAccessSignature, ClientId, Token)); diff --git a/source/AzBobbyTables.psd1 b/source/AzBobbyTables.psd1 index 872c537..c08826f 100644 --- a/source/AzBobbyTables.psd1 +++ b/source/AzBobbyTables.psd1 @@ -67,6 +67,7 @@ FunctionsToExport = @() CmdletsToExport = @( 'Add-AzDataTableEntity' 'Clear-AzDataTable' + 'Get-AzDataTable' 'Get-AzDataTableEntity' 'Remove-AzDataTableEntity' 'Update-AzDataTableEntity' diff --git a/tests/AzuriteIntegration.Tests.ps1 b/tests/AzuriteIntegration.Tests.ps1 index 43945d8..da79125 100644 --- a/tests/AzuriteIntegration.Tests.ps1 +++ b/tests/AzuriteIntegration.Tests.ps1 @@ -77,11 +77,24 @@ Describe 'Azurite Integration Tests' -Tag 'Integration' { $ConnectionString = 'UseDevelopmentStorage=true' } - It 'can create table' { + It 'can create table context with table name' { + { New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString } | Should -Not -Throw + } + + It 'can create table context without table name' { + { New-AzDataTableContext -ConnectionString $ConnectionString } | Should -Not -Throw + } + + It 'can create table with context containing table name' { $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString { $null = New-AzDataTable -Context $Context } | Should -Not -Throw } + It 'cannot create table with context missing table name' { + $Context = New-AzDataTableContext -ConnectionString $ConnectionString + { $null = New-AzDataTable -Context $Context } | Should -Throw + } + It 'can add data' { $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString $AddResult = Add-AzDataTableEntity -Context $Context -Entity $UsersHashtable @@ -178,6 +191,38 @@ Describe 'Azurite Integration Tests' -Tag 'Integration' { $ExpectedData = Get-ComparableHash ($UsersHashtable | Where-Object { $_['Id'] -eq $User.Id }) Get-ComparableHash $User | Should -Be $ExpectedData } + { Remove-AzDataTable -Context $Context } | Should -Not -Throw + } + + It 'can get all tables from storage account with context containing table name' { + $Context = New-AzDataTableContext -TableName "${TableName}1" -ConnectionString $ConnectionString + { $null = New-AzDataTable -Context $Context } | Should -Not -Throw + $Context = New-AzDataTableContext -TableName "${TableName}2" -ConnectionString $ConnectionString + { $null = New-AzDataTable -Context $Context } | Should -Not -Throw + $Tables = Get-AzDataTable -Context $Context + $Tables | Should -Contain "${TableName}1" + $Tables | Should -Contain "${TableName}2" + $Tables.Count | Should -BeExactly 2 + } + + It 'can get all tables from storage account with context missing table name' { + $Context = New-AzDataTableContext -ConnectionString $ConnectionString + $Tables = Get-AzDataTable -Context $Context + $Tables | Should -Contain "${TableName}1" + $Tables | Should -Contain "${TableName}2" + $Tables.Count | Should -BeExactly 2 + } + + It 'can get specific table with filter from storage account with context containing table name' { + $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString + $Table = Get-AzDataTable -Context $Context -Filter "TableName eq '${TableName}1'" + $Table | Should -BeExactly "${TableName}1" + } + + It 'can get specific table with filter from storage account with context missing table name' { + $Context = New-AzDataTableContext -ConnectionString $ConnectionString + $Table = Get-AzDataTable -Context $Context -Filter "TableName eq '${TableName}2'" + $Table | Should -BeExactly "${TableName}2" } AfterAll { diff --git a/tests/Get-AzDataTable.Tests.ps1 b/tests/Get-AzDataTable.Tests.ps1 new file mode 100644 index 0000000..c7e290a --- /dev/null +++ b/tests/Get-AzDataTable.Tests.ps1 @@ -0,0 +1,57 @@ +BeforeDiscovery { + # Get command from current test file name + $Command = Get-Command ((Split-Path $PSCommandPath -Leaf) -replace '.Tests.ps1') + $ParameterTestCases = @( + @{ + Command = $Command + Name = 'Context' + Type = 'PipeHow.AzBobbyTables.AzDataTableContext' + ParameterSets = @( + @{ Name = '__AllParameterSets'; Mandatory = $true } + ) + } + @{ + Command = $Command + Name = 'Filter' + Type = 'string' + ParameterSets = @( + @{ Name = '__AllParameterSets'; Mandatory = $false } + ) + } + ) +} + +Describe 'Get-AzDataTable' { + Context 'parameters' { + + It 'only has expected parameters' -TestCases @{ Command = $Command ; Parameters = $ParameterTestCases.Name } { + $Command.Parameters.GetEnumerator() | Where-Object { + $_.Key -notin [System.Management.Automation.Cmdlet]::CommonParameters -and + $_.Key -notin $Parameters + } | Should -BeNullOrEmpty + } + + It 'has parameter of type ' -TestCases $ParameterTestCases { + $Command | Should -HaveParameter $Name -Type $Type + } + + It 'has correct parameter sets for parameter ' -TestCases $ParameterTestCases { + $Parameter = $Command.Parameters[$Name] + $Parameter.ParameterSets.Keys | Should -BeExactly $ParameterSets.Name + } + + foreach ($ParameterTestCase in $ParameterTestCases) { + foreach ($ParameterSet in $ParameterTestCase.ParameterSets) { + It 'has parameter set to mandatory for parameter set ' -TestCases @{ + Command = $ParameterTestCase['Command'] + ParameterName = $ParameterTestCase['Name'] + Name = $ParameterSet['Name'] + Mandatory = $ParameterSet['Mandatory'] + } { + $Parameter = $Command.Parameters[$ParameterName] + $Parameter.ParameterSets[$Name].IsMandatory | Should -Be $Mandatory + } + } + } + } +} \ No newline at end of file diff --git a/tests/New-AzDataTableContext.Tests.ps1 b/tests/New-AzDataTableContext.Tests.ps1 index 5c18042..ac0d95f 100644 --- a/tests/New-AzDataTableContext.Tests.ps1 +++ b/tests/New-AzDataTableContext.Tests.ps1 @@ -7,11 +7,11 @@ BeforeDiscovery { Name = 'TableName' Type = 'string' ParameterSets = @( - @{ Name = 'ConnectionString'; Mandatory = $true } - @{ Name = 'SAS'; Mandatory = $true } - @{ Name = 'Key'; Mandatory = $true } - @{ Name = 'Token'; Mandatory = $true } - @{ Name = 'ManagedIdentity'; Mandatory = $true } + @{ Name = 'ConnectionString'; Mandatory = $false } + @{ Name = 'SAS'; Mandatory = $false } + @{ Name = 'Key'; Mandatory = $false } + @{ Name = 'Token'; Mandatory = $false } + @{ Name = 'ManagedIdentity'; Mandatory = $false } ) } @{