feat: DH-HIS Web Giao Ban Go v1.0.1 (Favicon, Exe icon, System Tray, Gitea auto-update)
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
"web-giao-ban-go/config"
|
||||
"web-giao-ban-go/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
poolMu sync.RWMutex
|
||||
pools = make(map[string]*sql.DB)
|
||||
)
|
||||
|
||||
func GetConnectionString(cfg *config.AppConfig, dbName string) string {
|
||||
if dbName == "" {
|
||||
dbName = cfg.Database.DefaultDB
|
||||
}
|
||||
pass := cfg.DecryptedDBPassword
|
||||
if pass == "" {
|
||||
pass, _ = config.Decrypt(cfg.Database.Password)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable connect_timeout=10 statement_timeout=15000",
|
||||
cfg.Database.Host,
|
||||
cfg.Database.Port,
|
||||
cfg.Database.User,
|
||||
pass,
|
||||
dbName,
|
||||
)
|
||||
}
|
||||
|
||||
func GetDB(dbName string) (*sql.DB, error) {
|
||||
cfg := config.Get()
|
||||
if dbName == "" {
|
||||
dbName = cfg.Database.DefaultDB
|
||||
}
|
||||
|
||||
poolMu.RLock()
|
||||
if conn, ok := pools[dbName]; ok {
|
||||
poolMu.RUnlock()
|
||||
return conn, nil
|
||||
}
|
||||
poolMu.RUnlock()
|
||||
|
||||
poolMu.Lock()
|
||||
defer poolMu.Unlock()
|
||||
|
||||
// Double check
|
||||
if conn, ok := pools[dbName]; ok {
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
connStr := GetConnectionString(cfg, dbName)
|
||||
conn, err := sql.Open("postgres", connStr)
|
||||
if err != nil {
|
||||
logger.Error("Lỗi kết nối PostgreSQL [%s]: %v", dbName, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn.SetMaxOpenConns(15)
|
||||
conn.SetMaxIdleConns(5)
|
||||
conn.SetConnMaxLifetime(15 * time.Minute)
|
||||
|
||||
if err := conn.Ping(); err != nil {
|
||||
logger.Error("Ping thất bại tới CSDL [%s]: %v", dbName, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pools[dbName] = conn
|
||||
logger.Info("Khởi tạo connection pool tới CSDL: %s", dbName)
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func CloseAll() {
|
||||
poolMu.Lock()
|
||||
defer poolMu.Unlock()
|
||||
for name, conn := range pools {
|
||||
_ = conn.Close()
|
||||
delete(pools, name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnection(host string, port int, user, pass, dbName string) error {
|
||||
connStr := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable connect_timeout=5",
|
||||
host, port, user, pass, dbName)
|
||||
testConn, err := sql.Open("postgres", connStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer testConn.Close()
|
||||
return testConn.Ping()
|
||||
}
|
||||
|
||||
func EnsureTable(dbName string) {
|
||||
conn, err := GetDB(dbName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
safeName := regexp.MustCompile(`[^a-zA-Z0-9]`).ReplaceAllString(dbName, "_")
|
||||
sqlCreate := fmt.Sprintf(`
|
||||
CREATE TABLE IF NOT EXISTS current.giaoban_ghichu (
|
||||
id SERIAL PRIMARY KEY,
|
||||
maba VARCHAR(50) NOT NULL,
|
||||
mabn VARCHAR(20) NOT NULL,
|
||||
loai_danhsach VARCHAR(20) NOT NULL,
|
||||
ghichu TEXT,
|
||||
ngay_capnhat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT unq_giaoban_item_%s UNIQUE(maba, loai_danhsach)
|
||||
);
|
||||
`, safeName)
|
||||
|
||||
_, _ = conn.Exec(sqlCreate)
|
||||
}
|
||||
|
||||
func CleanRTF(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
if !strings.HasPrefix(s, "{\\rtf") && !strings.Contains(s, "\\rtf") {
|
||||
return s
|
||||
}
|
||||
|
||||
cleaned := s
|
||||
// Remove {\*...} blocks
|
||||
re1 := regexp.MustCompile(`\{\\\*[^}]*\}`)
|
||||
cleaned = re1.ReplaceAllString(cleaned, "")
|
||||
|
||||
// Remove general {...} groups with tags
|
||||
re2 := regexp.MustCompile(`\{[^{}]*\}`)
|
||||
cleaned = re2.ReplaceAllString(cleaned, "")
|
||||
|
||||
// Remove RTF control words (\b, \par, \fs20...)
|
||||
re3 := regexp.MustCompile(`\\[a-zA-Z]+(-?\d+)? ?`)
|
||||
cleaned = re3.ReplaceAllString(cleaned, " ")
|
||||
|
||||
// Remove stray brackets and backslashes
|
||||
re4 := regexp.MustCompile(`[\\{}]`)
|
||||
cleaned = re4.ReplaceAllString(cleaned, "")
|
||||
|
||||
// Collapse multiple spaces
|
||||
re5 := regexp.MustCompile(`\s+`)
|
||||
cleaned = strings.TrimSpace(re5.ReplaceAllString(cleaned, " "))
|
||||
|
||||
if cleaned == "" {
|
||||
return "Có kết quả (Định dạng RTF)"
|
||||
}
|
||||
return cleaned
|
||||
}
|
||||
Reference in New Issue
Block a user