diff options
author | Grail Finder <wohilas@gmail.com> | 2025-03-29 11:12:53 +0300 |
---|---|---|
committer | Grail Finder <wohilas@gmail.com> | 2025-03-29 11:12:53 +0300 |
commit | 3921db6166e2da895257496bb76dd115556699d3 (patch) | |
tree | 1be4f739121761085f69cb7706c60dbbe98a93e9 /internal/database/sql/main.go |
init
Diffstat (limited to 'internal/database/sql/main.go')
-rw-r--r-- | internal/database/sql/main.go | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/internal/database/sql/main.go b/internal/database/sql/main.go new file mode 100644 index 0000000..5a523f6 --- /dev/null +++ b/internal/database/sql/main.go @@ -0,0 +1,88 @@ +package database + +import ( + "os" + "time" + + "log/slog" + + "github.com/jmoiron/sqlx" + _ "github.com/mattn/go-sqlite3" + "github.com/pkg/errors" +) + +var ( + log = slog.New(slog.NewJSONHandler(os.Stdout, nil)) + dbDriver = "sqlite3" +) + +type DB struct { + Conn *sqlx.DB + URI string +} + +func (d *DB) CloseAll() error { + for _, conn := range []*sqlx.DB{d.Conn} { + if err := closeConn(conn); err != nil { + return err + } + } + return nil +} + +func closeConn(conn *sqlx.DB) error { + return conn.Close() +} + +func Init(DBURI string) (*DB, error) { + var result DB + var err error + result.Conn, err = openDBConnection(DBURI, dbDriver) + if err != nil { + return nil, err + } + result.URI = DBURI + if err := testConnection(result.Conn); err != nil { + return nil, err + } + return &result, nil +} + +func openDBConnection(dbURI, driver string) (*sqlx.DB, error) { + conn, err := sqlx.Open(driver, dbURI) + if err != nil { + return nil, err + } + return conn, nil +} + +func testConnection(conn *sqlx.DB) error { + err := conn.Ping() + if err != nil { + return errors.Wrap(err, "can't ping database") + } + return nil +} + +func (d *DB) PingRoutine(interval time.Duration) { + ticker := time.NewTicker(interval) + done := make(chan bool) + for { + select { + case <-done: + return + case t := <-ticker.C: + if err := testConnection(d.Conn); err != nil { + log.Error("failed to ping postrges db", "error", err, "ping_at", t) + // reconnect + if err := closeConn(d.Conn); err != nil { + log.Error("failed to close db connection", "error", err, "ping_at", t) + } + d.Conn, err = openDBConnection(d.URI, dbDriver) + if err != nil { + log.Error("failed to reconnect", "error", err, "ping_at", t) + } + } + } + } +} |