File size: 2,062 Bytes
edcf070
 
 
 
25eb4e0
edcf070
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9fc6937
 
 
 
 
25eb4e0
 
 
 
9fc6937
25eb4e0
 
 
 
 
edcf070
 
25eb4e0
edcf070
 
 
 
 
 
 
 
 
 
 
 
 
 
cb01565
 
 
 
edcf070
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package config

import (
	"log"
	"os"
	"strings"
	"time"

	"gorm.io/driver/postgres"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

var DB *gorm.DB

func ConnectDatabase() {
	dsn := GlobalConfig.DatabaseURL

	// Bersihkan skema psycopg dari Python jika ada
	if strings.HasPrefix(dsn, "postgresql+psycopg://") {
		dsn = strings.Replace(dsn, "postgresql+psycopg://", "postgres://", 1)
	} else if strings.HasPrefix(dsn, "postgresql://") {
		dsn = strings.Replace(dsn, "postgresql://", "postgres://", 1)
	}

	log.Printf("Connecting to database: %s", sanitizeDSN(dsn))

	logLevel := logger.Warn
	if strings.ToLower(os.Getenv("DEBUG")) == "true" || strings.ToLower(os.Getenv("GORM_LOG_LEVEL")) == "info" {
		logLevel = logger.Info
	}

	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags),
		logger.Config{
			SlowThreshold:             1500 * time.Millisecond, // Batas lambat 1.5 detik demi mengakomodasi latensi cross-region internet
			LogLevel:                  logLevel,
			IgnoreRecordNotFoundError: true,
			Colorful:                  true,
		},
	)

	var err error
	DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
		Logger: newLogger,
	})

	if err != nil {
		log.Fatalf("Gagal menghubungkan ke database: %v", err)
	}

	log.Println("Berhasil terhubung ke database!")

	// Konfigurasi connection pool
	sqlDB, err := DB.DB()
	if err != nil {
		log.Fatalf("Gagal mengambil instance SQL DB: %v", err)
	}

	// Atur batas pool yang efisien untuk mencegah kelelahan koneksi Supabase & latensi tinggi
	sqlDB.SetMaxIdleConns(4)
	sqlDB.SetMaxOpenConns(20)
	sqlDB.SetConnMaxIdleTime(10 * time.Minute)
	sqlDB.SetConnMaxLifetime(time.Hour)
}

func sanitizeDSN(dsn string) string {
	// Sembunyikan password dalam log demi alasan keamanan
	if strings.Contains(dsn, "@") {
		parts := strings.Split(dsn, "@")
		credentials := strings.Split(parts[0], "://")
		if len(credentials) == 2 {
			userPass := strings.Split(credentials[1], ":")
			if len(userPass) == 2 {
				return credentials[0] + "://" + userPass[0] + ":******@" + parts[1]
			}
		}
	}
	return dsn
}