Files
folium/dbx/postgres.go
Snowykami b0d224dc64 feat: add logging and collector implementations
- Introduced `hertzx` package with `NewHertz` function for server initialization.
- Implemented `logx` package with various log collectors: Console, Loki, Elasticsearch, and Prometheus.
- Added `Logger` struct to manage logging levels and collectors.
- Created environment variable loading functionality in `osx` package to support configuration.
- Enhanced logging capabilities with structured log entries and asynchronous collection.
2025-11-01 13:20:02 +08:00

71 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package dbx
import (
"context"
"fmt"
"strings"
"time"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func GetPostgresDB(cfg *DBConfig, dbName string) *gorm.DB {
db, err := getPostgresInstance(cfg, dbName)
if err != nil {
panic("failed to connect to Postgres database: " + err.Error())
}
return db
}
func getPostgresInstance(cfg *DBConfig, dbName string) (*gorm.DB, error) {
targetDSN := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
cfg.Host, cfg.Port, cfg.User, cfg.Password, dbName, cfg.Sslmode)
// 先尝试直接连接目标库
if db, err := gorm.Open(postgres.Open(targetDSN), &gorm.Config{}); err == nil {
return db, nil
}
// 连接 admin DBpostgres
adminDSN := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=postgres sslmode=%s",
cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.Sslmode)
adminDB, err := gorm.Open(postgres.Open(adminDSN), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("connect admin postgres failed: %w", err)
}
// 确保关闭底层连接
if sqlDB, e := adminDB.DB(); e == nil {
defer sqlDB.Close()
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 检查是否存在
var count int64
if err := adminDB.WithContext(ctx).Raw("SELECT count(*) FROM pg_database WHERE datname = ?", dbName).Scan(&count).Error; err != nil {
return nil, fmt.Errorf("check database existence failed: %w", err)
}
if count == 0 {
ident := escapePostgresIdentifier(dbName)
createSQL := fmt.Sprintf("CREATE DATABASE %s", ident)
if err := adminDB.WithContext(ctx).Exec(createSQL).Error; err != nil {
return nil, fmt.Errorf("create database %s failed: %w", dbName, err)
}
}
// 尝试连接目标数据库
db2, err := gorm.Open(postgres.Open(targetDSN), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("connect target after create failed: %w", err)
}
return db2, nil
}
// 辅助:安全转义 Postgres 标识符(用双引号并把 " 替换为 ""
func escapePostgresIdentifier(s string) string {
s = strings.ReplaceAll(s, `"`, `""`)
return `"` + s + `"`
}