Alexey Kim 8 bulan lalu
induk
melakukan
7ab7dbd8ec
5 mengubah file dengan 121 tambahan dan 24 penghapusan
  1. 2 1
      config/config.go
  2. 0 9
      config/database.go
  3. 93 0
      database/clickhouse.go
  4. 12 0
      database/compression.go
  5. 14 14
      database/config.go

+ 2 - 1
config/config.go

@@ -2,6 +2,7 @@ package config
 
 import (
 	"fmt"
+	"git.beejay.kim/Craft/Api/database"
 	"time"
 )
 
@@ -9,7 +10,7 @@ type Configuration struct {
 	Timeout int    `yaml:"timeout"`
 	Issuer  string `yaml:"issuer"`
 
-	Database Databases `yaml:"database"`
+	Database database.Config `yaml:"database"`
 }
 
 func (c Configuration) Invalidate() error {

+ 0 - 9
config/database.go

@@ -1,9 +0,0 @@
-package config
-
-type Databases struct {
-	Clickhouse *ClickhouseConfig `json:"clickhouse" yaml:"clickhouse"`
-}
-
-func (db Databases) Invalidate() error {
-	return Invalidate(db)
-}

+ 93 - 0
database/clickhouse.go

@@ -0,0 +1,93 @@
+package database
+
+import (
+	"context"
+	"crypto/tls"
+	"fmt"
+	"github.com/ClickHouse/clickhouse-go/v2"
+	"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
+	"sync"
+	"time"
+)
+
+type _ch struct {
+	Database[driver.Rows, driver.Batch]
+
+	config *configCH
+	conn   clickhouse.Conn
+}
+
+//goland:noinspection GoUnusedExportedFunction
+func NewClickhouse(cfg *Config, debug bool) (Database[driver.Rows, driver.Batch], error) {
+	if cfg == nil || cfg.Clickhouse == nil {
+		return nil, fmt.Errorf("illegal state: `*config.ClickhouseConfig` is nil")
+	}
+
+	var tlcConfig *tls.Config
+	if cfg.Clickhouse.Params.Secure {
+		tlcConfig = &tls.Config{
+			InsecureSkipVerify: true,
+		}
+	}
+
+	session, err := clickhouse.Open(&clickhouse.Options{
+		Protocol: clickhouse.Native,
+		TLS:      tlcConfig,
+		Addr: []string{
+			fmt.Sprintf("%s:%d", cfg.Clickhouse.Host, cfg.Clickhouse.Port),
+		},
+		Auth: clickhouse.Auth{
+			Database: cfg.Clickhouse.Database,
+			Username: cfg.Clickhouse.Username,
+			Password: cfg.Clickhouse.Password,
+		},
+		Debug: debug,
+		Compression: &clickhouse.Compression{
+			Method: cfg.Clickhouse.Params.CompressionMethod(),
+		},
+		DialTimeout: time.Duration(cfg.Clickhouse.Params.Timeout) * time.Second,
+		ReadTimeout: time.Duration(cfg.Clickhouse.Params.ReadTimeout) * time.Second,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	s := &_ch{
+		config: cfg.Clickhouse,
+		conn:   session,
+	}
+
+	if err = s.Ping(context.TODO()); err != nil {
+		return nil, err
+	}
+
+	return s, nil
+}
+
+func (db *_ch) String() string {
+	return "clickhouse"
+}
+
+func (db *_ch) Close() error {
+	var wg sync.WaitGroup
+	wg.Add(1)
+
+	go func() {
+		defer wg.Done()
+
+		if db.conn != nil {
+			_ = db.conn.Close()
+		}
+	}()
+
+	wg.Wait()
+	return nil
+}
+
+func (db *_ch) Ping(ctx context.Context) error {
+	return db.conn.Ping(ctx)
+}
+
+func (db *_ch) Query(ctx context.Context, query string, args ...any) (driver.Rows, error) {
+	return db.conn.Query(ctx, query, args...)
+}

+ 12 - 0
database/compression.go

@@ -0,0 +1,12 @@
+package database
+
+import "github.com/ClickHouse/clickhouse-go/v2"
+
+var compressionCH = map[string]clickhouse.CompressionMethod{
+	"none":    clickhouse.CompressionNone,
+	"zstd":    clickhouse.CompressionZSTD,
+	"lz4":     clickhouse.CompressionLZ4,
+	"gzip":    clickhouse.CompressionGZIP,
+	"deflate": clickhouse.CompressionDeflate,
+	"br":      clickhouse.CompressionBrotli,
+}

+ 14 - 14
config/clickhouse.go → database/config.go

@@ -1,21 +1,21 @@
-package config
+package database
 
 import (
 	"fmt"
+	"git.beejay.kim/Craft/Api/config"
 	"github.com/ClickHouse/clickhouse-go/v2"
 	"strings"
 )
 
-var compressionMap = map[string]clickhouse.CompressionMethod{
-	"none":    clickhouse.CompressionNone,
-	"zstd":    clickhouse.CompressionZSTD,
-	"lz4":     clickhouse.CompressionLZ4,
-	"gzip":    clickhouse.CompressionGZIP,
-	"deflate": clickhouse.CompressionDeflate,
-	"br":      clickhouse.CompressionBrotli,
+type Config struct {
+	Clickhouse *configCH `yaml:"clickhouse"`
 }
 
-type ClickhouseConfig struct {
+func (cfg Config) Invalidate() error {
+	return config.Invalidate(cfg)
+}
+
+type configCH struct {
 	Username string `json:"username" yaml:"username"`
 	Password string `json:"password" yaml:"password"`
 	Host     string `json:"host" yaml:"host"`
@@ -32,7 +32,7 @@ type params struct {
 	WriteTimeout int    `json:"write_timeout" yaml:"write-timeout"`
 }
 
-func (c ClickhouseConfig) Invalidate() error {
+func (c configCH) Invalidate() error {
 	if strings.TrimSpace(c.Username) == "" {
 		c.Username = "default"
 	}
@@ -49,7 +49,7 @@ func (c ClickhouseConfig) Invalidate() error {
 		return fmt.Errorf("`clickhouse.database` must not be an empty string")
 	}
 
-	return Invalidate(c)
+	return config.Invalidate(c)
 }
 
 func (p params) Invalidate() error {
@@ -57,7 +57,7 @@ func (p params) Invalidate() error {
 		p.Compress = "lz4"
 	}
 
-	if _, ok := compressionMap[p.Compress]; !ok {
+	if _, ok := compressionCH[p.Compress]; !ok {
 		return fmt.Errorf("illegal `clickhouse.params.compress`")
 	}
 
@@ -73,9 +73,9 @@ func (p params) Invalidate() error {
 		return fmt.Errorf("`clickhouse.params.write-timeout` must not be at least 1")
 	}
 
-	return Invalidate(p)
+	return config.Invalidate(p)
 }
 
 func (p params) CompressionMethod() clickhouse.CompressionMethod {
-	return compressionMap[p.Compress]
+	return compressionCH[p.Compress]
 }