Move sq + ParseDurShortString() to goext and change conf values by env

This commit is contained in:
Mike Schwörer 2022-12-07 23:32:58 +01:00
parent 8db0fa37db
commit 0cae24a612
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
22 changed files with 170 additions and 226 deletions

View File

@ -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()))
}
}
}

View File

@ -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"
) )

View File

@ -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"
) )

View File

@ -1,7 +1,7 @@
package db package db
import ( import (
"blackforestbytes.com/simplecloudnotifier/sq" "gogs.mikescher.com/BlackForestBytes/goext/sq"
"time" "time"
) )

View File

@ -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))
}

View File

@ -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"
) )

View File

@ -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"
) )

View File

@ -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) {

View File

@ -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"
) )

View File

@ -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"
) )

View File

@ -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
}

View File

@ -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
) )

View File

@ -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=

View File

@ -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"
) )

View File

@ -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"
) )

View File

@ -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
}

View File

@ -1,3 +0,0 @@
package sq
type PP map[string]any

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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": {

View File

@ -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