modules/Azure/Discovery/Public/Save-CIEMAzureResourceRelationship.ps1

function Save-CIEMAzureResourceRelationship {
    [CmdletBinding(DefaultParameterSetName = 'ByProperties')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Upsert operation for bulk data')]
    param(
        [Parameter(Mandatory, ParameterSetName = 'ByProperties')]
        [string]$SourceId,

        [Parameter(Mandatory, ParameterSetName = 'ByProperties')]
        [string]$SourceType,

        [Parameter(Mandatory, ParameterSetName = 'ByProperties')]
        [string]$TargetId,

        [Parameter(Mandatory, ParameterSetName = 'ByProperties')]
        [string]$TargetType,

        [Parameter(Mandatory, ParameterSetName = 'ByProperties')]
        [string]$Relationship,

        [Parameter(Mandatory, ParameterSetName = 'ByProperties')]
        [string]$CollectedAt,

        [Parameter()]
        $Connection,

        [Parameter(Mandatory, ParameterSetName = 'InputObject', ValueFromPipeline)]
        [PSObject[]]$InputObject
    )

    begin {
        $items = [System.Collections.Generic.List[object]]::new()
    }

    process {
        if ($PSCmdlet.ParameterSetName -eq 'InputObject') {
            foreach ($item in $InputObject) {
                $items.Add([pscustomobject]@{
                    SourceId = $item.SourceId
                    SourceType = $item.SourceType
                    TargetId = $item.TargetId
                    TargetType = $item.TargetType
                    Relationship = $item.Relationship
                    CollectedAt = $item.CollectedAt
                })
            }
            return
        }

        $items.Add([pscustomobject]@{
            SourceId = $SourceId
            SourceType = $SourceType
            TargetId = $TargetId
            TargetType = $TargetType
            Relationship = $Relationship
            CollectedAt = $CollectedAt
        })
    }

    end {
        if ($items.Count -eq 0) {
            return
        }

        $columns = @('source_id', 'source_type', 'target_id', 'target_type', 'relationship', 'collected_at')
        for ($offset = 0; $offset -lt $items.Count; $offset += $script:CIEMSqlBatchSize) {
            $remaining = $items.Count - $offset
            $chunkSize = [Math]::Min($script:CIEMSqlBatchSize, $remaining)
            $rows = @()
            $parameters = @{}

            for ($rowIndex = 0; $rowIndex -lt $chunkSize; $rowIndex++) {
                $item = $items[$offset + $rowIndex]
                $suffix = $rowIndex + 1
                $rows += "(@source_id_$suffix, @source_type_$suffix, @target_id_$suffix, @target_type_$suffix, @relationship_$suffix, @collected_at_$suffix)"

                $parameters["source_id_$suffix"] = $item.SourceId
                $parameters["source_type_$suffix"] = $item.SourceType
                $parameters["target_id_$suffix"] = $item.TargetId
                $parameters["target_type_$suffix"] = $item.TargetType
                $parameters["relationship_$suffix"] = $item.Relationship
                $parameters["collected_at_$suffix"] = $item.CollectedAt
            }

            $sql = "INSERT OR REPLACE INTO azure_resource_relationships ($($columns -join ', ')) VALUES $($rows -join ', ')"
            if ($Connection) {
                Invoke-PSUSQLiteQuery -Connection $Connection -Query $sql -Parameters $parameters -AsNonQuery | Out-Null
            }
            else {
                Invoke-CIEMQuery -Query $sql -Parameters $parameters -AsNonQuery | Out-Null
            }
        }
    }
}