|
- param(
- [Parameter(Mandatory = $true)][string]$Path,
- [string]$ConfigPath = (Join-Path (Split-Path -Parent $PSScriptRoot) 'config.ini')
- )
-
- $ErrorActionPreference = 'Stop'
- . (Join-Path $PSScriptRoot 'template-common.ps1')
- $context = Get-MailContext -ConfigPath $ConfigPath
- $limits = Get-TemplateLimits $context
- $sourcePath = [System.IO.Path]::GetFullPath($Path)
- if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) { throw "Template not found: $sourcePath" }
- if (-not $sourcePath.StartsWith($limits.Root + [System.IO.Path]::DirectorySeparatorChar,
- [StringComparison]::OrdinalIgnoreCase)) { throw 'Template must be inside TEMPLATE_ROOT' }
- $templateName = [System.IO.Path]::GetFileNameWithoutExtension($sourcePath)
- if ($templateName.Length -gt 200) { throw 'Template file name is too long' }
- $document = Read-SafeTemplate $sourcePath
- $images = Get-TemplateImages $document $sourcePath $limits
- $html = $document.OuterXml
- $htmlBytes = [System.Text.Encoding]::UTF8.GetBytes($html)
- $total = $htmlBytes.Length
- foreach ($image in $images) { $total += $image.Bytes.Length }
- if ($total -gt $limits.MessageLimit) { throw 'Template and images exceed TEMPLATE_MESSAGE_MAX_BYTES' }
- $connection = Open-MailDatabase $context
- $transaction = $null
- try {
- $transaction = $connection.BeginTransaction()
- $next = $connection.CreateCommand()
- $next.Transaction = $transaction
- $next.CommandText = 'SELECT MAX([VersionNumber]) FROM [TemplateVersion] WHERE [TemplateName]=?'
- Add-TextParameter $next 'name' 200 $templateName
- $maximum = $next.ExecuteScalar()
- $version = if ($maximum -is [DBNull]) { 1 } else { [int]$maximum + 1 }
- $insert = $connection.CreateCommand()
- $insert.Transaction = $transaction
- $insert.CommandText = 'INSERT INTO [TemplateVersion] ([TemplateName],[VersionNumber],[HtmlContent],[ContentHash],[ImportedAtUtc],[ValidationStatus]) VALUES (?,?,?,?,?,?)'
- Add-TextParameter $insert 'name' 200 $templateName
- $null = $insert.Parameters.Add('version', [System.Data.OleDb.OleDbType]::Integer)
- $insert.Parameters[1].Value = $version
- $null = $insert.Parameters.Add('html', [System.Data.OleDb.OleDbType]::LongVarWChar)
- $insert.Parameters[2].Value = $html
- Add-TextParameter $insert 'hash' 64 (Get-HashHex $htmlBytes)
- $null = $insert.Parameters.Add('imported', [System.Data.OleDb.OleDbType]::Date)
- $insert.Parameters[4].Value = [DateTime]::UtcNow
- Add-TextParameter $insert 'status' 30 'validated'
- $null = $insert.ExecuteNonQuery()
- $identity = $connection.CreateCommand()
- $identity.Transaction = $transaction
- $identity.CommandText = 'SELECT @@IDENTITY'
- $templateId = [int]$identity.ExecuteScalar()
- foreach ($image in $images) {
- $command = $connection.CreateCommand()
- $command.Transaction = $transaction
- $command.CommandText = 'INSERT INTO [TemplateImage] ([TemplateVersionId],[OriginalRelativePath],[ContentType],[ContentHash],[SnapshotBytes],[ContentId]) VALUES (?,?,?,?,?,?)'
- $null = $command.Parameters.Add('template', [System.Data.OleDb.OleDbType]::Integer)
- $command.Parameters[0].Value = $templateId
- Add-TextParameter $command 'path' 255 $image.Path
- Add-TextParameter $command 'type' 40 $image.Type
- Add-TextParameter $command 'hash' 64 $image.Hash
- $null = $command.Parameters.Add('bytes', [System.Data.OleDb.OleDbType]::LongVarBinary, $image.Bytes.Length)
- $command.Parameters[4].Value = $image.Bytes
- Add-TextParameter $command 'cid' 200 $image.Cid
- $null = $command.ExecuteNonQuery()
- }
- $transaction.Commit()
- $transaction = $null
- Write-Output "Imported template ID $templateId, version $version, $($images.Count) inline image(s)."
- }
- catch {
- if ($transaction) { $transaction.Rollback() }
- throw
- }
- finally { $connection.Dispose() }
|