Initial SQL-only 1C adapter baseline
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
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,
|
||||
[ValidateSet("Config", "ConfigSave", "ConfigCAS", "ConfigCASSave", "Params")]
|
||||
[string]$Table = "Params",
|
||||
[string]$OutputPath = $env:ONEC_SQL_EXPORT_PATH,
|
||||
[string[]]$FileName,
|
||||
[int]$Limit = 0,
|
||||
[int]$CommandTimeoutSeconds = 0
|
||||
)
|
||||
|
||||
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 $OutputPath) { throw "OutputPath is required. Use -OutputPath or ONEC_SQL_EXPORT_PATH." }
|
||||
|
||||
$resolvedOutput = [System.IO.Path]::GetFullPath($OutputPath)
|
||||
New-Item -ItemType Directory -Force -Path $resolvedOutput | Out-Null
|
||||
|
||||
$connectionString = "Server=$Server;Database=$Database;User ID=$User;Password=$Password;Encrypt=False;TrustServerCertificate=True;Application Name=Codex 1C SQL File Export;"
|
||||
$connection = [System.Data.SqlClient.SqlConnection]::new($connectionString)
|
||||
$command = $connection.CreateCommand()
|
||||
$command.CommandTimeout = $CommandTimeoutSeconds
|
||||
|
||||
$where = ""
|
||||
if ($FileName -and $FileName.Count -gt 0) {
|
||||
$placeholders = @()
|
||||
for ($i = 0; $i -lt $FileName.Count; $i++) {
|
||||
$name = "@file$i"
|
||||
$placeholders += $name
|
||||
$null = $command.Parameters.Add($name, [System.Data.SqlDbType]::NVarChar, 512)
|
||||
$command.Parameters[$name].Value = $FileName[$i]
|
||||
}
|
||||
$where = "WHERE FileName IN ($($placeholders -join ', '))"
|
||||
}
|
||||
|
||||
$top = ""
|
||||
if ($Limit -gt 0 -and -not $where) {
|
||||
$top = "TOP ($Limit)"
|
||||
}
|
||||
|
||||
$command.CommandText = "SELECT $top FileName, PartNo, BinaryData FROM dbo.[$Table] $where ORDER BY FileName, PartNo"
|
||||
|
||||
$fileCount = 0
|
||||
$chunkCount = 0
|
||||
$byteCount = [int64]0
|
||||
$currentName = $null
|
||||
$currentStream = $null
|
||||
$manifest = @()
|
||||
|
||||
function Close-CurrentStream {
|
||||
if ($script:currentStream -ne $null) {
|
||||
$script:currentStream.Dispose()
|
||||
$script:currentStream = $null
|
||||
$script:fileCount++
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$connection.Open()
|
||||
$reader = $command.ExecuteReader([System.Data.CommandBehavior]::SequentialAccess)
|
||||
try {
|
||||
while ($reader.Read()) {
|
||||
$file = [string]$reader.GetValue(0)
|
||||
if ([System.IO.Path]::GetFileName($file) -ne $file) {
|
||||
throw "Unsafe FileName value from SQL: $file"
|
||||
}
|
||||
|
||||
if ($currentName -ne $file) {
|
||||
Close-CurrentStream
|
||||
$currentName = $file
|
||||
$target = Join-Path $resolvedOutput $file
|
||||
$currentStream = [System.IO.File]::Open($target, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::None)
|
||||
$manifest += [pscustomobject]@{ file_name = $file; path = $target }
|
||||
}
|
||||
|
||||
$buffer = [byte[]]$reader.GetValue(2)
|
||||
$currentStream.Write($buffer, 0, $buffer.Length)
|
||||
$chunkCount++
|
||||
$byteCount += $buffer.Length
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ($reader -ne $null) { $reader.Dispose() }
|
||||
Close-CurrentStream
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ($connection -ne $null) { $connection.Dispose() }
|
||||
}
|
||||
|
||||
$result = [pscustomobject]@{
|
||||
table = $Table
|
||||
output_path = $resolvedOutput
|
||||
files = $fileCount
|
||||
chunks = $chunkCount
|
||||
bytes = $byteCount
|
||||
exported = $manifest
|
||||
}
|
||||
|
||||
$result | ConvertTo-Json -Depth 5
|
||||
Reference in New Issue
Block a user