-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
factory.go
122 lines (94 loc) · 2.85 KB
/
factory.go
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package sql
import (
"context"
"database/sql"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/cjlapao/common-go/execution_context"
"github.com/cjlapao/common-go/log"
)
type sqlDatabase struct {
context context.Context
defaultTimeout time.Duration
factory *SqlFactory
db *sql.DB
}
func (db *sqlDatabase) Close() error {
return db.db.Close()
}
func (db *sqlDatabase) Query(query string, args ...any) (*sql.Rows, error) {
return db.db.Query(query, args...)
}
func (db *sqlDatabase) QueryContext(query string, args ...any) (*sql.Rows, error) {
return db.db.QueryContext(db.context, query, args...)
}
func (db *sqlDatabase) QueryRow(query string, args ...any) *sql.Row {
return db.db.QueryRow(query, args...)
}
func (db *sqlDatabase) QueryRowContext(query string, args ...any) *sql.Row {
return db.db.QueryRowContext(db.context, query, args...)
}
func (db *sqlDatabase) ExecContext(query string, args ...any) (sql.Result, error) {
return db.db.ExecContext(db.context, query, args...)
}
type SqlFactory struct {
Context *execution_context.Context
Database *sqlDatabase
Timeout time.Duration
DatabaseContext *SqlDatabaseContext
Logger *log.Logger
}
func NewFactory(connectionString string) *SqlFactory {
factory := SqlFactory{
DatabaseContext: &SqlDatabaseContext{},
Context: execution_context.Get(),
Logger: log.Get(),
Timeout: time.Second * 30,
}
connStrBuilder := SqlConnectionString{}
if err := connStrBuilder.Parse(connectionString); err != nil {
return nil
}
factory.DatabaseContext.ConnectionString = &connStrBuilder
return &factory
}
func (f *SqlFactory) WithDatabase(databaseName string) *SqlFactory {
f.DatabaseContext.ConnectionString.Database = databaseName
return f
}
func (f *SqlFactory) WithTimeout(seconds int) *SqlFactory {
f.Timeout = time.Duration(seconds * int(time.Second))
return f
}
func (f *SqlFactory) Ping() error {
dbConn, err := sql.Open("mysql", f.DatabaseContext.ConnectionString.ConnectionString())
if err != nil {
f.Logger.Exception(err, "error getting connection to the database")
return err
}
defer dbConn.Close()
if err := dbConn.Ping(); err != nil {
f.Logger.Exception(err, "error pinging the server")
return err
}
f.Logger.Info("Ping successfully")
return nil
}
func Named(name string, value any) sql.NamedArg {
return sql.Named(name, value)
}
func (f *SqlFactory) Connect() *sqlDatabase {
dbConn, err := sql.Open("mysql", f.DatabaseContext.ConnectionString.ConnectionString())
if err != nil {
f.Logger.Exception(err, "error getting connection to the database")
return nil
}
f.Database = &sqlDatabase{
factory: f,
context: context.Background(),
defaultTimeout: f.Timeout,
db: dbConn,
}
f.Logger.Debug("Database connection created successfully")
return f.Database
}