Initial SQL-only 1C adapter baseline
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
param(
|
||||
[string]$Server = $env:ONEC_SQL_SERVER,
|
||||
[string]$Database = $env:ONEC_SQL_DATABASE,
|
||||
[string]$User = $env:ONEC_SQL_USER,
|
||||
[string]$Password = $env:ONEC_SQL_PASSWORD,
|
||||
[string]$SummaryPath,
|
||||
[string]$OutputPath
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
if (-not $Server) { throw "Server is required. Use -Server or ONEC_SQL_SERVER." }
|
||||
if (-not $Database) { throw "Database is required. Use -Database or ONEC_SQL_DATABASE." }
|
||||
if (-not $User) { throw "User is required. Use -User or ONEC_SQL_USER." }
|
||||
if (-not $Password) { throw "Password is required. Use -Password or ONEC_SQL_PASSWORD." }
|
||||
if (-not $SummaryPath) { throw "SummaryPath is required." }
|
||||
if (-not $OutputPath) { throw "OutputPath is required." }
|
||||
|
||||
$metadataFields = @(
|
||||
"attributes", "tabular_sections", "dimensions", "resources", "forms",
|
||||
"templates", "commands", "addressing_attributes", "accounting_flags",
|
||||
"columns", "enum_values", "integration_service_channels", "operations",
|
||||
"url_templates"
|
||||
"tabular_section_attributes"
|
||||
)
|
||||
|
||||
$summary = Get-Content -LiteralPath $SummaryPath -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
$checks = New-Object System.Collections.Generic.List[object]
|
||||
$tableChecks = New-Object System.Collections.Generic.List[object]
|
||||
|
||||
foreach ($row in $summary.outputs) {
|
||||
$report = Get-Content -LiteralPath $row.output -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
$tables = @($report.object_storage_routes | Where-Object { $_.route_kind -eq "table" -and $_.physical_name_candidate } | ForEach-Object { $_.physical_name_candidate })
|
||||
foreach ($field in $metadataFields) {
|
||||
if (-not ($report.PSObject.Properties.Name -contains $field)) { continue }
|
||||
foreach ($item in @($report.$field)) {
|
||||
$itemCandidateTables = $tables
|
||||
if ($item.PSObject.Properties.Name -contains "parent_physical_tables") {
|
||||
$parentTables = @($item.parent_physical_tables | Where-Object { $_.PSObject.Properties.Name -contains "table" -and $_.table } | ForEach-Object { $_.table })
|
||||
if ($parentTables.Count -gt 0) {
|
||||
$itemCandidateTables = $parentTables
|
||||
}
|
||||
}
|
||||
foreach ($column in @($item.physical_columns | Where-Object { $_.PSObject.Properties.Name -contains "column" -and $_.column })) {
|
||||
$checks.Add([pscustomobject]@{
|
||||
kind = $report.kind
|
||||
object_name = $report.identity.name
|
||||
object_guid = $report.identity.guid
|
||||
metadata_field = $field
|
||||
item_name = $item.name
|
||||
item_guid = $item.uuid
|
||||
value_type = if ($column.PSObject.Properties.Name -contains "value_type") { $column.value_type } elseif ($column.PSObject.Properties.Name -contains "value_types") { ($column.value_types -join ",") } else { $null }
|
||||
predicted_column = $column.column
|
||||
candidate_tables = $itemCandidateTables
|
||||
})
|
||||
}
|
||||
$physicalTables = @()
|
||||
if ($item.PSObject.Properties.Name -contains "physical_tables") {
|
||||
$physicalTables = @($item.physical_tables)
|
||||
}
|
||||
foreach ($tableCandidate in @($physicalTables | Where-Object { $_.PSObject.Properties.Name -contains "table" -and $_.table })) {
|
||||
$tableChecks.Add([pscustomobject]@{
|
||||
kind = $report.kind
|
||||
object_name = $report.identity.name
|
||||
object_guid = $report.identity.guid
|
||||
metadata_field = $field
|
||||
item_name = $item.name
|
||||
item_guid = $item.uuid
|
||||
predicted_table = $tableCandidate.table
|
||||
reason = $tableCandidate.reason
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$connectionString = "Server=$Server;Database=$Database;User ID=$User;Password=$Password;Encrypt=False;TrustServerCertificate=True;Application Name=Codex 1C Column Prediction Validation;"
|
||||
$connection = [System.Data.SqlClient.SqlConnection]::new($connectionString)
|
||||
|
||||
$results = New-Object System.Collections.Generic.List[object]
|
||||
$foundCount = 0
|
||||
|
||||
try {
|
||||
$connection.Open()
|
||||
$allTables = @(
|
||||
@($checks | ForEach-Object { $_.candidate_tables } | Where-Object { $_ })
|
||||
@($tableChecks | ForEach-Object { $_.predicted_table } | Where-Object { $_ })
|
||||
) | Select-Object -Unique
|
||||
$schemaLookup = @{}
|
||||
if ($allTables.Count -gt 0) {
|
||||
$command = $connection.CreateCommand()
|
||||
$command.CommandTimeout = 0
|
||||
$tableParams = @()
|
||||
for ($i = 0; $i -lt $allTables.Count; $i++) {
|
||||
$name = "@t$i"
|
||||
$tableParams += $name
|
||||
$null = $command.Parameters.Add($name, [System.Data.SqlDbType]::NVarChar, 128)
|
||||
$command.Parameters[$name].Value = $allTables[$i]
|
||||
}
|
||||
$command.CommandText = @"
|
||||
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, IS_NULLABLE
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME IN ($($tableParams -join ","))
|
||||
"@
|
||||
$reader = $command.ExecuteReader()
|
||||
try {
|
||||
while ($reader.Read()) {
|
||||
$item = [pscustomobject]@{
|
||||
table = [string]$reader.GetValue(0)
|
||||
column = [string]$reader.GetValue(1)
|
||||
data_type = [string]$reader.GetValue(2)
|
||||
max_length = if ($reader.IsDBNull(3)) { $null } else { $reader.GetValue(3) }
|
||||
precision = if ($reader.IsDBNull(4)) { $null } else { $reader.GetValue(4) }
|
||||
scale = if ($reader.IsDBNull(5)) { $null } else { $reader.GetValue(5) }
|
||||
nullable = [string]$reader.GetValue(6)
|
||||
}
|
||||
$key = "$($item.table)|$($item.column)"
|
||||
if (-not $schemaLookup.ContainsKey($key)) {
|
||||
$schemaLookup[$key] = New-Object System.Collections.Generic.List[object]
|
||||
}
|
||||
$schemaLookup[$key].Add($item)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ($reader -ne $null) {
|
||||
$reader.Close()
|
||||
$reader.Dispose()
|
||||
}
|
||||
if ($command -ne $null) { $command.Dispose() }
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($check in $checks) {
|
||||
$matches = New-Object System.Collections.Generic.List[object]
|
||||
foreach ($table in @($check.candidate_tables)) {
|
||||
$key = "$table|$($check.predicted_column)"
|
||||
if ($schemaLookup.ContainsKey($key)) {
|
||||
foreach ($match in $schemaLookup[$key]) {
|
||||
$matches.Add($match)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($matches.Count -gt 0) { $foundCount++ }
|
||||
$results.Add([pscustomobject]@{
|
||||
kind = $check.kind
|
||||
object_name = $check.object_name
|
||||
object_guid = $check.object_guid
|
||||
metadata_field = $check.metadata_field
|
||||
item_name = $check.item_name
|
||||
item_guid = $check.item_guid
|
||||
value_type = $check.value_type
|
||||
predicted_column = $check.predicted_column
|
||||
candidate_tables = $check.candidate_tables
|
||||
found = $matches.Count -gt 0
|
||||
matches = $matches
|
||||
})
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ($connection -ne $null) { $connection.Dispose() }
|
||||
}
|
||||
|
||||
$byKind = $results | Group-Object kind | ForEach-Object {
|
||||
[pscustomobject]@{
|
||||
kind = $_.Name
|
||||
predicted_count = $_.Count
|
||||
found_count = @($_.Group | Where-Object found).Count
|
||||
}
|
||||
}
|
||||
|
||||
$tableResults = New-Object System.Collections.Generic.List[object]
|
||||
$tableFoundCount = 0
|
||||
foreach ($check in $tableChecks) {
|
||||
$exists = $false
|
||||
foreach ($key in $schemaLookup.Keys) {
|
||||
if ($key.StartsWith("$($check.predicted_table)|")) {
|
||||
$exists = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($exists) { $tableFoundCount++ }
|
||||
$tableResults.Add([pscustomobject]@{
|
||||
kind = $check.kind
|
||||
object_name = $check.object_name
|
||||
object_guid = $check.object_guid
|
||||
metadata_field = $check.metadata_field
|
||||
item_name = $check.item_name
|
||||
item_guid = $check.item_guid
|
||||
predicted_table = $check.predicted_table
|
||||
reason = $check.reason
|
||||
found = $exists
|
||||
})
|
||||
}
|
||||
|
||||
$tableByKind = $tableResults | Group-Object kind | ForEach-Object {
|
||||
[pscustomobject]@{
|
||||
kind = $_.Name
|
||||
predicted_count = $_.Count
|
||||
found_count = @($_.Group | Where-Object found).Count
|
||||
}
|
||||
}
|
||||
|
||||
$report = [pscustomobject]@{
|
||||
schema = "onec_predicted_column_validation.v1"
|
||||
summary = $SummaryPath
|
||||
database = $Database
|
||||
predicted_count = $checks.Count
|
||||
found_count = $foundCount
|
||||
predicted_table_count = $tableChecks.Count
|
||||
found_table_count = $tableFoundCount
|
||||
by_kind = $byKind
|
||||
table_by_kind = $tableByKind
|
||||
results = $results
|
||||
table_results = $tableResults
|
||||
}
|
||||
|
||||
$resolvedOutput = [System.IO.Path]::GetFullPath($OutputPath)
|
||||
New-Item -ItemType Directory -Force -Path ([System.IO.Path]::GetDirectoryName($resolvedOutput)) | Out-Null
|
||||
$report | ConvertTo-Json -Depth 12 | Out-File -LiteralPath $resolvedOutput -Encoding UTF8
|
||||
$report | Select-Object schema, predicted_count, found_count, predicted_table_count, found_table_count | ConvertTo-Json -Compress
|
||||
Reference in New Issue
Block a user