Move sq + ParseDurShortString() to goext and change conf values by env
This commit is contained in:
parent
8db0fa37db
commit
0cae24a612
124
server/config.go
124
server/config.go
@ -4,34 +4,37 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Namespace string
|
Namespace string
|
||||||
BaseURL string
|
BaseURL string `env:"SCN_URL"`
|
||||||
GinDebug bool
|
GinDebug bool `env:"SCN_GINDEBUG"`
|
||||||
LogLevel zerolog.Level
|
LogLevel zerolog.Level `env:"SCN_LOGLEVEL"`
|
||||||
ServerIP string
|
ServerIP string `env:"SCN_IP"`
|
||||||
ServerPort string
|
ServerPort string `env:"SCN_PORT"`
|
||||||
DBFile string
|
DBFile string `env:"SCN_DB_FILE"`
|
||||||
DBJournal string
|
DBJournal string `env:"SCN_DB_JOURNAL"`
|
||||||
DBTimeout time.Duration
|
DBTimeout time.Duration `env:"SCN_DB_TIMEOUT"`
|
||||||
DBMaxOpenConns int
|
DBMaxOpenConns int `env:"SCN_DB_MAXOPENCONNECTIONS"`
|
||||||
DBMaxIdleConns int
|
DBMaxIdleConns int `env:"SCN_DB_MAXIDLECONNECTIONS"`
|
||||||
DBConnMaxLifetime time.Duration
|
DBConnMaxLifetime time.Duration `env:"SCN_DB_CONNEXTIONMAXLIFETIME"`
|
||||||
DBConnMaxIdleTime time.Duration
|
DBConnMaxIdleTime time.Duration `env:"SCN_DB_CONNEXTIONMAXIDLETIME"`
|
||||||
DBCheckForeignKeys bool
|
DBCheckForeignKeys bool `env:"SCN_DB_CHECKFOREIGNKEYS"`
|
||||||
RequestTimeout time.Duration
|
RequestTimeout time.Duration `env:"SCN_REQUEST_TIMEOUT"`
|
||||||
ReturnRawErrors bool
|
ReturnRawErrors bool `env:"SCN_ERROR_RETURN"`
|
||||||
DummyFirebase bool
|
DummyFirebase bool `env:"SCN_DUMMY_FB"`
|
||||||
|
DummyGoogleAPI bool `env:"SCN_DUMMY_GOOG"`
|
||||||
FirebaseTokenURI string
|
FirebaseTokenURI string
|
||||||
FirebaseProjectID string
|
FirebaseProjectID string
|
||||||
FirebasePrivKeyID string
|
FirebasePrivKeyID string
|
||||||
FirebaseClientMail string
|
FirebaseClientMail string
|
||||||
FirebasePrivateKey string
|
FirebasePrivateKey string
|
||||||
DummyGoogleAPI bool
|
|
||||||
GoogleAPITokenURI string
|
GoogleAPITokenURI string
|
||||||
GoogleAPIPrivKeyID string
|
GoogleAPIPrivKeyID string
|
||||||
GoogleAPIClientMail string
|
GoogleAPIClientMail string
|
||||||
@ -181,7 +184,7 @@ var configStag = func() Config {
|
|||||||
var configProd = func() Config {
|
var configProd = func() Config {
|
||||||
return Config{
|
return Config{
|
||||||
Namespace: "production",
|
Namespace: "production",
|
||||||
BaseURL: confEnv("BASE_URL"),
|
BaseURL: confEnv("SCN_URL"),
|
||||||
GinDebug: false,
|
GinDebug: false,
|
||||||
LogLevel: zerolog.InfoLevel,
|
LogLevel: zerolog.InfoLevel,
|
||||||
ServerIP: "0.0.0.0",
|
ServerIP: "0.0.0.0",
|
||||||
@ -198,17 +201,17 @@ var configProd = func() Config {
|
|||||||
ReturnRawErrors: false,
|
ReturnRawErrors: false,
|
||||||
DummyFirebase: false,
|
DummyFirebase: false,
|
||||||
FirebaseTokenURI: "https://oauth2.googleapis.com/token",
|
FirebaseTokenURI: "https://oauth2.googleapis.com/token",
|
||||||
FirebaseProjectID: confEnv("FB_PROJECTID"),
|
FirebaseProjectID: confEnv("SCN_FB_PROJECTID"),
|
||||||
FirebasePrivKeyID: confEnv("FB_PRIVATEKEYID"),
|
FirebasePrivKeyID: confEnv("SCN_FB_PRIVATEKEYID"),
|
||||||
FirebaseClientMail: confEnv("FB_CLIENTEMAIL"),
|
FirebaseClientMail: confEnv("SCN_FB_CLIENTEMAIL"),
|
||||||
FirebasePrivateKey: confEnv("FB_PRIVATEKEY"),
|
FirebasePrivateKey: confEnv("SCN_FB_PRIVATEKEY"),
|
||||||
DummyGoogleAPI: false,
|
DummyGoogleAPI: false,
|
||||||
GoogleAPITokenURI: "https://oauth2.googleapis.com/token",
|
GoogleAPITokenURI: "https://oauth2.googleapis.com/token",
|
||||||
GoogleAPIPrivKeyID: confEnv("GOOG_PRIVATEKEYID"),
|
GoogleAPIPrivKeyID: confEnv("SCN_GOOG_PRIVATEKEYID"),
|
||||||
GoogleAPIClientMail: confEnv("GOOG_CLIENTEMAIL"),
|
GoogleAPIClientMail: confEnv("SCN_GOOG_CLIENTEMAIL"),
|
||||||
GoogleAPIPrivateKey: confEnv("GOOG_PRIVATEKEY"),
|
GoogleAPIPrivateKey: confEnv("SCN_GOOG_PRIVATEKEY"),
|
||||||
GooglePackageName: confEnv("GOOG_PACKAGENAME"),
|
GooglePackageName: confEnv("SCN_GOOG_PACKAGENAME"),
|
||||||
GoogleProProductID: confEnv("GOOG_PROPRODUCTID"),
|
GoogleProProductID: confEnv("SCN_GOOG_PROPRODUCTID"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,10 +225,12 @@ var allConfig = map[string]func() Config{
|
|||||||
|
|
||||||
func getConfig(ns string) (Config, bool) {
|
func getConfig(ns string) (Config, bool) {
|
||||||
if ns == "" {
|
if ns == "" {
|
||||||
return configLocHost(), true
|
ns = "local-host"
|
||||||
}
|
}
|
||||||
if c, ok := allConfig[ns]; ok {
|
if cfn, ok := allConfig[ns]; ok {
|
||||||
return c(), true
|
c := cfn()
|
||||||
|
parseConfOverride(&c)
|
||||||
|
return c, true
|
||||||
}
|
}
|
||||||
return Config{}, false
|
return Config{}, false
|
||||||
}
|
}
|
||||||
@ -249,3 +254,62 @@ func init() {
|
|||||||
|
|
||||||
Conf = cfg
|
Conf = cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseConfOverride(c *Config) {
|
||||||
|
|
||||||
|
rval := reflect.ValueOf(c).Elem()
|
||||||
|
rtyp := rval.Type()
|
||||||
|
|
||||||
|
for i := 0; i < rtyp.NumField(); i++ {
|
||||||
|
|
||||||
|
rsfield := rtyp.Field(i)
|
||||||
|
rvfield := rval.Field(i)
|
||||||
|
|
||||||
|
envkey := rsfield.Tag.Get("env")
|
||||||
|
if envkey == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
envval, efound := os.LookupEnv(envkey)
|
||||||
|
if !efound {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if rvfield.Kind() == reflect.String {
|
||||||
|
|
||||||
|
rvfield.Set(reflect.ValueOf(envval))
|
||||||
|
|
||||||
|
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", envkey, envval)
|
||||||
|
|
||||||
|
} else if rvfield.Type() == reflect.TypeOf(zerolog.Level(0)) {
|
||||||
|
|
||||||
|
envint, err := strconv.ParseInt(envval, 10, 8)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Failed to parse env-config variable '%s' to int (value := '%s')", envkey, envval))
|
||||||
|
}
|
||||||
|
if envint < -1 || envint > 7 {
|
||||||
|
panic(fmt.Sprintf("Failed to parse zerolog-level (invalid number: %d)", envint))
|
||||||
|
}
|
||||||
|
|
||||||
|
lvl := zerolog.Level(envint)
|
||||||
|
|
||||||
|
rvfield.Set(reflect.ValueOf(lvl))
|
||||||
|
|
||||||
|
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", envkey, lvl.String())
|
||||||
|
|
||||||
|
} else if rvfield.Type() == reflect.TypeOf(time.Duration(0)) {
|
||||||
|
|
||||||
|
dur, err := timeext.ParseDurationShortString(envval)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Failed to parse env-config variable '%s' to duration (value := '%s')", envkey, envval))
|
||||||
|
}
|
||||||
|
|
||||||
|
rvfield.Set(reflect.ValueOf(dur))
|
||||||
|
|
||||||
|
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", envkey, dur.String())
|
||||||
|
|
||||||
|
} else {
|
||||||
|
panic(fmt.Sprintf("Unknown kind/type in config: [ %s | %s ]", rvfield.Kind().String(), rvfield.Type().String()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,8 +2,8 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,14 +3,15 @@ package db
|
|||||||
import (
|
import (
|
||||||
server "blackforestbytes.com/simplecloudnotifier"
|
server "blackforestbytes.com/simplecloudnotifier"
|
||||||
"blackforestbytes.com/simplecloudnotifier/db/schema"
|
"blackforestbytes.com/simplecloudnotifier/db/schema"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,7 +34,11 @@ func NewDatabase(conf server.Config) (*Database, error) {
|
|||||||
|
|
||||||
qqdb := sq.NewDB(xdb)
|
qqdb := sq.NewDB(xdb)
|
||||||
|
|
||||||
return &Database{qqdb}, nil
|
scndb := &Database{qqdb}
|
||||||
|
|
||||||
|
qqdb.SetListener(scndb)
|
||||||
|
|
||||||
|
return scndb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) Migrate(ctx context.Context) error {
|
func (db *Database) Migrate(ctx context.Context) error {
|
||||||
@ -74,3 +79,35 @@ func (db *Database) Ping(ctx context.Context) error {
|
|||||||
func (db *Database) BeginTx(ctx context.Context) (sq.Tx, error) {
|
func (db *Database) BeginTx(ctx context.Context) (sq.Tx, error) {
|
||||||
return db.db.BeginTransaction(ctx, sql.LevelDefault)
|
return db.db.BeginTransaction(ctx, sql.LevelDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *Database) OnQuery(txID *uint16, sql string, _ *sq.PP) {
|
||||||
|
if txID == nil {
|
||||||
|
log.Debug().Msg(fmt.Sprintf("[SQL-QUERY] %s", fmtSQLPrint(sql)))
|
||||||
|
} else {
|
||||||
|
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-QUERY] %s", *txID, fmtSQLPrint(sql)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) OnExec(txID *uint16, sql string, _ *sq.PP) {
|
||||||
|
if txID == nil {
|
||||||
|
log.Debug().Msg(fmt.Sprintf("[SQL-EXEC] %s", fmtSQLPrint(sql)))
|
||||||
|
} else {
|
||||||
|
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-EXEC] %s", *txID, fmtSQLPrint(sql)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) OnPing() {
|
||||||
|
log.Debug().Msg("[SQL-PING]")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) OnTxBegin(txid uint16) {
|
||||||
|
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-START]", txid))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) OnTxCommit(txid uint16) {
|
||||||
|
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-COMMIT]", txid))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) OnTxRollback(txid uint16) {
|
||||||
|
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-ROLLBACK]", txid))
|
||||||
|
}
|
||||||
|
@ -3,8 +3,8 @@ package db
|
|||||||
import (
|
import (
|
||||||
scn "blackforestbytes.com/simplecloudnotifier"
|
scn "blackforestbytes.com/simplecloudnotifier"
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ package db
|
|||||||
import (
|
import (
|
||||||
"blackforestbytes.com/simplecloudnotifier/db/cursortoken"
|
"blackforestbytes.com/simplecloudnotifier/db/cursortoken"
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db *Database) ReadSchema(ctx context.Context) (retval int, reterr error) {
|
func (db *Database) ReadSchema(ctx context.Context) (retval int, reterr error) {
|
||||||
|
@ -2,8 +2,8 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ package db
|
|||||||
import (
|
import (
|
||||||
scn "blackforestbytes.com/simplecloudnotifier"
|
scn "blackforestbytes.com/simplecloudnotifier"
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,3 +24,14 @@ func time2DBOpt(t *time.Time) *int64 {
|
|||||||
}
|
}
|
||||||
return langext.Ptr(t.UnixMilli())
|
return langext.Ptr(t.UnixMilli())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fmtSQLPrint(sql string) string {
|
||||||
|
if strings.Contains(sql, ";") {
|
||||||
|
return "(...multi...)"
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = strings.ReplaceAll(sql, "\r", "")
|
||||||
|
sql = strings.ReplaceAll(sql, "\n", " ")
|
||||||
|
|
||||||
|
return sql
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@ require (
|
|||||||
github.com/mattn/go-sqlite3 v1.14.16
|
github.com/mattn/go-sqlite3 v1.14.16
|
||||||
github.com/rs/zerolog v1.28.0
|
github.com/rs/zerolog v1.28.0
|
||||||
github.com/swaggo/swag v1.8.7
|
github.com/swaggo/swag v1.8.7
|
||||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.27
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.31
|
||||||
github.com/jmoiron/sqlx v1.3.5
|
github.com/jmoiron/sqlx v1.3.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
|
|||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/blockloop/scan v1.3.0 h1:p8xnajpGA3d/V6o23IBFdQ764+JnNJ+PQj+OwT+rkdg=
|
|
||||||
github.com/blockloop/scan v1.3.0/go.mod h1:qd+3w68+o7m5Xhj9X5SlJH2rbFyK8w0WT47Rkuer010=
|
|
||||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -33,6 +31,7 @@ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/j
|
|||||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||||
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
|
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
|
||||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
|
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
|
||||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
@ -58,6 +57,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
|
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
@ -67,7 +67,6 @@ github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZb
|
|||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
@ -99,8 +98,8 @@ github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9e
|
|||||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.27 h1:Psjv/EGFI2smJoRv+1yUccmms8szmLIN0r1th9JQcik=
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.31 h1:DC2RZe7/tSDDbPRbjDcYa+BLRlY0SgLTAkI2DPw5WJQ=
|
||||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.27/go.mod h1:TMBOjo3FRFh/GiTT0z3nwLmgcFJB87oSF2VMs4XUCTQ=
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.31/go.mod h1:/u9JtMwCP68ix4R9BJ/MT0Lm+QScmqIoyYZFKBGzv9g=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||||
|
@ -4,11 +4,11 @@ import (
|
|||||||
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
||||||
"blackforestbytes.com/simplecloudnotifier/common/ginresp"
|
"blackforestbytes.com/simplecloudnotifier/common/ginresp"
|
||||||
"blackforestbytes.com/simplecloudnotifier/db"
|
"blackforestbytes.com/simplecloudnotifier/db"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ package logic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blackforestbytes.com/simplecloudnotifier/db"
|
"blackforestbytes.com/simplecloudnotifier/db"
|
||||||
"blackforestbytes.com/simplecloudnotifier/sq"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
package sq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DB interface {
|
|
||||||
Exec(ctx context.Context, sql string, prep PP) (sql.Result, error)
|
|
||||||
Query(ctx context.Context, sql string, prep PP) (*sqlx.Rows, error)
|
|
||||||
Ping(ctx context.Context) error
|
|
||||||
BeginTransaction(ctx context.Context, iso sql.IsolationLevel) (Tx, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type database struct {
|
|
||||||
db *sqlx.DB
|
|
||||||
txctr uint16
|
|
||||||
lock sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDB(db *sqlx.DB) DB {
|
|
||||||
return &database{
|
|
||||||
db: db,
|
|
||||||
txctr: 0,
|
|
||||||
lock: sync.Mutex{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *database) Exec(ctx context.Context, sql string, prep PP) (sql.Result, error) {
|
|
||||||
log.Debug().Msg(fmt.Sprintf("[SQL-EXEC] %s", fmtSQLPrint(sql)))
|
|
||||||
|
|
||||||
res, err := db.db.NamedExecContext(ctx, sql, prep)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *database) Query(ctx context.Context, sql string, prep PP) (*sqlx.Rows, error) {
|
|
||||||
log.Debug().Msg(fmt.Sprintf("[SQL-QUERY] %s", fmtSQLPrint(sql)))
|
|
||||||
|
|
||||||
rows, err := db.db.NamedQueryContext(ctx, sql, prep)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return rows, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *database) Ping(ctx context.Context) error {
|
|
||||||
log.Debug().Msg("[SQL-PING]")
|
|
||||||
|
|
||||||
err := db.db.PingContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *database) BeginTransaction(ctx context.Context, iso sql.IsolationLevel) (Tx, error) {
|
|
||||||
db.lock.Lock()
|
|
||||||
txid := db.txctr
|
|
||||||
db.txctr += 1 // with overflow !
|
|
||||||
db.lock.Unlock()
|
|
||||||
|
|
||||||
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-START]", txid))
|
|
||||||
|
|
||||||
xtx, err := db.db.BeginTxx(ctx, &sql.TxOptions{Isolation: iso})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewTransaction(xtx, txid), nil
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
package sq
|
|
||||||
|
|
||||||
type PP map[string]any
|
|
@ -1,12 +0,0 @@
|
|||||||
package sq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Queryable interface {
|
|
||||||
Exec(ctx context.Context, sql string, prep PP) (sql.Result, error)
|
|
||||||
Query(ctx context.Context, sql string, prep PP) (*sqlx.Rows, error)
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package sq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Tx interface {
|
|
||||||
Rollback() error
|
|
||||||
Commit() error
|
|
||||||
Exec(ctx context.Context, sql string, prep PP) (sql.Result, error)
|
|
||||||
Query(ctx context.Context, sql string, prep PP) (*sqlx.Rows, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type transaction struct {
|
|
||||||
tx *sqlx.Tx
|
|
||||||
id uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTransaction(xtx *sqlx.Tx, txid uint16) Tx {
|
|
||||||
return &transaction{
|
|
||||||
tx: xtx,
|
|
||||||
id: txid,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *transaction) Rollback() error {
|
|
||||||
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-ROLLBACK]", tx.id))
|
|
||||||
|
|
||||||
return tx.tx.Rollback()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *transaction) Commit() error {
|
|
||||||
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-COMMIT]", tx.id))
|
|
||||||
|
|
||||||
return tx.tx.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *transaction) Exec(ctx context.Context, sql string, prep PP) (sql.Result, error) {
|
|
||||||
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-EXEC] %s", tx.id, fmtSQLPrint(sql)))
|
|
||||||
|
|
||||||
res, err := tx.tx.NamedExecContext(ctx, sql, prep)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *transaction) Query(ctx context.Context, sql string, prep PP) (*sqlx.Rows, error) {
|
|
||||||
log.Debug().Msg(fmt.Sprintf("[SQL-TX<%d>-QUERY] %s", tx.id, fmtSQLPrint(sql)))
|
|
||||||
|
|
||||||
rows, err := sqlx.NamedQueryContext(ctx, tx.tx, sql, prep)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return rows, nil
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package sq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func fmtSQLPrint(sql string) string {
|
|
||||||
if strings.Contains(sql, ";") {
|
|
||||||
return "(...multi...)"
|
|
||||||
}
|
|
||||||
|
|
||||||
sql = strings.ReplaceAll(sql, "\r", "")
|
|
||||||
sql = strings.ReplaceAll(sql, "\n", " ")
|
|
||||||
|
|
||||||
return sql
|
|
||||||
}
|
|
@ -2800,7 +2800,7 @@
|
|||||||
"timestamp_created": {
|
"timestamp_created": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"timestamp_last_sent": {
|
"timestamp_lastsent": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2957,10 +2957,10 @@
|
|||||||
"timestamp_created": {
|
"timestamp_created": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"timestamp_last_read": {
|
"timestamp_lastread": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"timestamp_last_sent": {
|
"timestamp_lastsent": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"user_id": {
|
"user_id": {
|
||||||
@ -3007,10 +3007,10 @@
|
|||||||
"timestamp_created": {
|
"timestamp_created": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"timestamp_last_read": {
|
"timestamp_lastread": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"timestamp_last_sent": {
|
"timestamp_lastsent": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"user_id": {
|
"user_id": {
|
||||||
|
@ -347,7 +347,7 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
timestamp_created:
|
timestamp_created:
|
||||||
type: string
|
type: string
|
||||||
timestamp_last_sent:
|
timestamp_lastsent:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
models.ClientJSON:
|
models.ClientJSON:
|
||||||
@ -450,9 +450,9 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
timestamp_created:
|
timestamp_created:
|
||||||
type: string
|
type: string
|
||||||
timestamp_last_read:
|
timestamp_lastread:
|
||||||
type: string
|
type: string
|
||||||
timestamp_last_sent:
|
timestamp_lastsent:
|
||||||
type: string
|
type: string
|
||||||
user_id:
|
user_id:
|
||||||
type: integer
|
type: integer
|
||||||
@ -483,9 +483,9 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
timestamp_created:
|
timestamp_created:
|
||||||
type: string
|
type: string
|
||||||
timestamp_last_read:
|
timestamp_lastread:
|
||||||
type: string
|
type: string
|
||||||
timestamp_last_sent:
|
timestamp_lastsent:
|
||||||
type: string
|
type: string
|
||||||
user_id:
|
user_id:
|
||||||
type: integer
|
type: integer
|
||||||
|
Loading…
Reference in New Issue
Block a user