mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-02-04 16:54:26 +00:00
Some checks failed
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in -26m26s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in -25m56s
Build , Vet Test, and Lint / Lint Code (push) Failing after -26m11s
Build , Vet Test, and Lint / Build (push) Successful in -26m18s
Tests / Unit Tests (push) Successful in -26m35s
Tests / Integration Tests (push) Failing after -26m49s
107 lines
3.5 KiB
Go
107 lines
3.5 KiB
Go
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"strings"
|
|
|
|
"github.com/uptrace/bun/dialect/mssqldialect"
|
|
"github.com/uptrace/bun/dialect/pgdialect"
|
|
"github.com/uptrace/bun/dialect/sqlitedialect"
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/driver/sqlserver"
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/bitechdev/ResolveSpec/pkg/logger"
|
|
)
|
|
|
|
// PostgreSQL identifier length limit (63 bytes + null terminator = 64 bytes total)
|
|
const postgresIdentifierLimit = 63
|
|
|
|
// checkAliasLength checks if a preload relation path will generate aliases that exceed PostgreSQL's limit
|
|
// Returns true if the alias is likely to be truncated
|
|
func checkAliasLength(relation string) bool {
|
|
// Bun generates aliases like: parentalias__childalias__columnname
|
|
// For nested preloads, it uses the pattern: relation1__relation2__relation3__columnname
|
|
parts := strings.Split(relation, ".")
|
|
if len(parts) <= 1 {
|
|
return false // Single level relations are fine
|
|
}
|
|
|
|
// Calculate the actual alias prefix length that Bun will generate
|
|
// Bun uses double underscores (__) between each relation level
|
|
// and converts the relation names to lowercase with underscores
|
|
aliasPrefix := strings.ToLower(strings.Join(parts, "__"))
|
|
aliasPrefixLen := len(aliasPrefix)
|
|
|
|
// We need to add 2 more underscores for the column name separator plus column name length
|
|
// Column names in the error were things like "rid_mastertype_hubtype" (23 chars)
|
|
// To be safe, assume the longest column name could be around 35 chars
|
|
maxColumnNameLen := 35
|
|
estimatedMaxLen := aliasPrefixLen + 2 + maxColumnNameLen
|
|
|
|
// Check if this would exceed PostgreSQL's identifier limit
|
|
if estimatedMaxLen > postgresIdentifierLimit {
|
|
logger.Warn("Preload relation '%s' will generate aliases up to %d chars (prefix: %d + column: %d), exceeding PostgreSQL's %d char limit",
|
|
relation, estimatedMaxLen, aliasPrefixLen, maxColumnNameLen, postgresIdentifierLimit)
|
|
return true
|
|
}
|
|
|
|
// Also check if just the prefix is getting close (within 15 chars of limit)
|
|
// This gives room for column names
|
|
if aliasPrefixLen > (postgresIdentifierLimit - 15) {
|
|
logger.Warn("Preload relation '%s' has alias prefix of %d chars, which may cause truncation with longer column names (limit: %d)",
|
|
relation, aliasPrefixLen, postgresIdentifierLimit)
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// parseTableName splits a table name that may contain schema into separate schema and table
|
|
// For example: "public.users" -> ("public", "users")
|
|
//
|
|
// "users" -> ("", "users")
|
|
func parseTableName(fullTableName string) (schema, table string) {
|
|
if idx := strings.LastIndex(fullTableName, "."); idx != -1 {
|
|
return fullTableName[:idx], fullTableName[idx+1:]
|
|
}
|
|
return "", fullTableName
|
|
}
|
|
|
|
// GetPostgresDialect returns a Bun PostgreSQL dialect
|
|
func GetPostgresDialect() *pgdialect.Dialect {
|
|
return pgdialect.New()
|
|
}
|
|
|
|
// GetSQLiteDialect returns a Bun SQLite dialect
|
|
func GetSQLiteDialect() *sqlitedialect.Dialect {
|
|
return sqlitedialect.New()
|
|
}
|
|
|
|
// GetMSSQLDialect returns a Bun MSSQL dialect
|
|
func GetMSSQLDialect() *mssqldialect.Dialect {
|
|
return mssqldialect.New()
|
|
}
|
|
|
|
// GetPostgresDialector returns a GORM PostgreSQL dialector
|
|
func GetPostgresDialector(db *sql.DB) gorm.Dialector {
|
|
return postgres.New(postgres.Config{
|
|
Conn: db,
|
|
})
|
|
}
|
|
|
|
// GetSQLiteDialector returns a GORM SQLite dialector
|
|
func GetSQLiteDialector(db *sql.DB) gorm.Dialector {
|
|
return sqlite.Dialector{
|
|
Conn: db,
|
|
}
|
|
}
|
|
|
|
// GetMSSQLDialector returns a GORM MSSQL dialector
|
|
func GetMSSQLDialector(db *sql.DB) gorm.Dialector {
|
|
return sqlserver.New(sqlserver.Config{
|
|
Conn: db,
|
|
})
|
|
}
|