Fix format detection: check file content for PGDMP signature, not just extension
This commit is contained in:
@ -1,6 +1,9 @@
|
|||||||
package restore
|
package restore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"compress/gzip"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,7 +21,7 @@ const (
|
|||||||
FormatUnknown ArchiveFormat = "Unknown"
|
FormatUnknown ArchiveFormat = "Unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DetectArchiveFormat detects the format of a backup archive from its filename
|
// DetectArchiveFormat detects the format of a backup archive from its filename and content
|
||||||
func DetectArchiveFormat(filename string) ArchiveFormat {
|
func DetectArchiveFormat(filename string) ArchiveFormat {
|
||||||
lower := strings.ToLower(filename)
|
lower := strings.ToLower(filename)
|
||||||
|
|
||||||
@ -27,11 +30,24 @@ func DetectArchiveFormat(filename string) ArchiveFormat {
|
|||||||
return FormatClusterTarGz
|
return FormatClusterTarGz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for compressed formats
|
// For .dump files, check if they're actually custom format or SQL text
|
||||||
if strings.HasSuffix(lower, ".dump.gz") {
|
if strings.HasSuffix(lower, ".dump.gz") {
|
||||||
return FormatPostgreSQLDumpGz
|
if isCustomFormat(filename, true) {
|
||||||
|
return FormatPostgreSQLDumpGz
|
||||||
|
}
|
||||||
|
// If not custom format, treat as SQL
|
||||||
|
return FormatPostgreSQLSQLGz
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(lower, ".dump") {
|
||||||
|
if isCustomFormat(filename, false) {
|
||||||
|
return FormatPostgreSQLDump
|
||||||
|
}
|
||||||
|
// If not custom format, treat as SQL
|
||||||
|
return FormatPostgreSQLSQL
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for compressed SQL formats
|
||||||
if strings.HasSuffix(lower, ".sql.gz") {
|
if strings.HasSuffix(lower, ".sql.gz") {
|
||||||
// Determine if MySQL or PostgreSQL based on naming convention
|
// Determine if MySQL or PostgreSQL based on naming convention
|
||||||
if strings.Contains(lower, "mysql") || strings.Contains(lower, "mariadb") {
|
if strings.Contains(lower, "mysql") || strings.Contains(lower, "mariadb") {
|
||||||
@ -40,11 +56,7 @@ func DetectArchiveFormat(filename string) ArchiveFormat {
|
|||||||
return FormatPostgreSQLSQLGz
|
return FormatPostgreSQLSQLGz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for uncompressed formats
|
// Check for uncompressed SQL formats
|
||||||
if strings.HasSuffix(lower, ".dump") {
|
|
||||||
return FormatPostgreSQLDump
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasSuffix(lower, ".sql") {
|
if strings.HasSuffix(lower, ".sql") {
|
||||||
// Determine if MySQL or PostgreSQL based on naming convention
|
// Determine if MySQL or PostgreSQL based on naming convention
|
||||||
if strings.Contains(lower, "mysql") || strings.Contains(lower, "mariadb") {
|
if strings.Contains(lower, "mysql") || strings.Contains(lower, "mariadb") {
|
||||||
@ -60,6 +72,36 @@ func DetectArchiveFormat(filename string) ArchiveFormat {
|
|||||||
return FormatUnknown
|
return FormatUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isCustomFormat checks if a file is PostgreSQL custom format (has PGDMP signature)
|
||||||
|
func isCustomFormat(filename string, compressed bool) bool {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
var reader io.Reader = file
|
||||||
|
|
||||||
|
// Handle compression
|
||||||
|
if compressed {
|
||||||
|
gz, err := gzip.NewReader(file)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer gz.Close()
|
||||||
|
reader = gz
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read first 5 bytes to check for PGDMP signature
|
||||||
|
buffer := make([]byte, 5)
|
||||||
|
n, err := reader.Read(buffer)
|
||||||
|
if err != nil || n < 5 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(buffer) == "PGDMP"
|
||||||
|
}
|
||||||
|
|
||||||
// IsCompressed returns true if the archive format is compressed
|
// IsCompressed returns true if the archive format is compressed
|
||||||
func (f ArchiveFormat) IsCompressed() bool {
|
func (f ArchiveFormat) IsCompressed() bool {
|
||||||
return f == FormatPostgreSQLDumpGz ||
|
return f == FormatPostgreSQLDumpGz ||
|
||||||
|
|||||||
Reference in New Issue
Block a user