Remove message.owner_user_id field and implement db migrations
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package primary
|
||||
package db
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
"time"
|
||||
)
|
||||
@@ -12,5 +11,5 @@ type TxContext interface {
|
||||
Err() error
|
||||
Value(key any) any
|
||||
|
||||
GetOrCreateTransaction(db db.DatabaseImpl) (sq.Tx, error)
|
||||
GetOrCreateTransaction(db DatabaseImpl) (sq.Tx, error)
|
||||
}
|
@@ -13,17 +13,17 @@ type DatabaseImpl interface {
|
||||
BeginTx(ctx context.Context) (sq.Tx, error)
|
||||
Stop(ctx context.Context) error
|
||||
|
||||
ReadSchema(ctx context.Context) (int, error)
|
||||
ReadSchema(ctx TxContext) (int, error)
|
||||
|
||||
WriteMetaString(ctx context.Context, key string, value string) error
|
||||
WriteMetaInt(ctx context.Context, key string, value int64) error
|
||||
WriteMetaReal(ctx context.Context, key string, value float64) error
|
||||
WriteMetaBlob(ctx context.Context, key string, value []byte) error
|
||||
WriteMetaString(ctx TxContext, key string, value string) error
|
||||
WriteMetaInt(ctx TxContext, key string, value int64) error
|
||||
WriteMetaReal(ctx TxContext, key string, value float64) error
|
||||
WriteMetaBlob(ctx TxContext, key string, value []byte) error
|
||||
|
||||
ReadMetaString(ctx context.Context, key string) (*string, error)
|
||||
ReadMetaInt(ctx context.Context, key string) (*int64, error)
|
||||
ReadMetaReal(ctx context.Context, key string) (*float64, error)
|
||||
ReadMetaBlob(ctx context.Context, key string) (*[]byte, error)
|
||||
ReadMetaString(ctx TxContext, key string) (*string, error)
|
||||
ReadMetaInt(ctx TxContext, key string) (*int64, error)
|
||||
ReadMetaReal(ctx TxContext, key string) (*float64, error)
|
||||
ReadMetaBlob(ctx TxContext, key string) (*[]byte, error)
|
||||
|
||||
DeleteMeta(ctx context.Context, key string) error
|
||||
DeleteMeta(ctx TxContext, key string) error
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
server "blackforestbytes.com/simplecloudnotifier"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/dbtools"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/schema"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/simplectx"
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
@@ -63,77 +64,93 @@ func (db *Database) DB() sq.DB {
|
||||
return db.db
|
||||
}
|
||||
|
||||
func (db *Database) Migrate(ctx context.Context) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 24*time.Second)
|
||||
defer cancel()
|
||||
func (db *Database) Migrate(outerctx context.Context) error {
|
||||
innerctx, cancel := context.WithTimeout(outerctx, 24*time.Second)
|
||||
tctx := simplectx.CreateSimpleContext(innerctx, cancel)
|
||||
|
||||
currschema, err := db.ReadSchema(ctx)
|
||||
tx, err := tctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if tx.Status() == sq.TxStatusInitial || tx.Status() == sq.TxStatusActive {
|
||||
err = tx.Rollback()
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to rollback transaction")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
ppReInit := false
|
||||
|
||||
currschema, err := db.ReadSchema(tctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if currschema == 0 {
|
||||
schemastr := schema.LogsSchema[schema.LogsSchemaVersion].SQL
|
||||
schemahash := schema.LogsSchema[schema.LogsSchemaVersion].Hash
|
||||
|
||||
schemastr := schema.LogsSchema1
|
||||
|
||||
schemahash, err := sq.HashSqliteSchema(ctx, schemastr)
|
||||
_, err = tx.Exec(tctx, schemastr, sq.PP{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = db.db.Exec(ctx, schemastr, sq.PP{})
|
||||
err = db.WriteMetaInt(tctx, "schema", int64(schema.LogsSchemaVersion))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.WriteMetaInt(ctx, "schema", 1)
|
||||
err = db.WriteMetaString(tctx, "schema_hash", schemahash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.WriteMetaString(ctx, "schema_hash", schemahash)
|
||||
ppReInit = true
|
||||
|
||||
currschema = schema.LogsSchemaVersion
|
||||
}
|
||||
|
||||
if currschema == 1 {
|
||||
schemHashDB, err := sq.HashSqliteDatabase(tctx, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.pp.Init(ctx) // Re-Init
|
||||
schemaHashMeta, err := db.ReadMetaString(tctx, "schema_hash")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
} else if currschema == 1 {
|
||||
|
||||
schemHashDB, err := sq.HashSqliteDatabase(ctx, db.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schemaHashMeta, err := db.ReadMetaString(ctx, "schema_hash")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schemHashAsset := schema.LogsHash1
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if schemHashDB != langext.Coalesce(schemaHashMeta, "") || langext.Coalesce(schemaHashMeta, "") != schemHashAsset {
|
||||
if schemHashDB != langext.Coalesce(schemaHashMeta, "") || langext.Coalesce(schemaHashMeta, "") != schema.LogsSchema[currschema].Hash {
|
||||
log.Debug().Str("schemHashDB", schemHashDB).Msg("Schema (logs db)")
|
||||
log.Debug().Str("schemaHashMeta", langext.Coalesce(schemaHashMeta, "")).Msg("Schema (logs db)")
|
||||
log.Debug().Str("schemHashAsset", schemHashAsset).Msg("Schema (logs db)")
|
||||
log.Debug().Str("schemaHashAsset", schema.LogsSchema[currschema].Hash).Msg("Schema (logs db)")
|
||||
return errors.New("database schema does not match (logs db)")
|
||||
} else {
|
||||
log.Debug().Str("schemHash", schemHashDB).Msg("Verified Schema consistency (logs db)")
|
||||
}
|
||||
}
|
||||
|
||||
return nil // current
|
||||
} else {
|
||||
if currschema != schema.LogsSchemaVersion {
|
||||
return errors.New(fmt.Sprintf("Unknown DB schema: %d", currschema))
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ppReInit {
|
||||
log.Debug().Msg("Re-Init preprocessor")
|
||||
err = db.pp.Init(outerctx) // Re-Init
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) Ping(ctx context.Context) error {
|
||||
|
@@ -1,15 +1,19 @@
|
||||
package logs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"errors"
|
||||
"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 db.TxContext) (retval int, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r1, err := db.db.Query(ctx, "SELECT name FROM sqlite_master WHERE type = :typ AND name = :name", sq.PP{"typ": "table", "name": "meta"})
|
||||
r1, err := tx.Query(ctx, "SELECT name FROM sqlite_master WHERE type = :typ AND name = :name", sq.PP{"typ": "table", "name": "meta"})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -31,7 +35,7 @@ func (db *Database) ReadSchema(ctx context.Context) (retval int, reterr error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r2, err := db.db.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": "schema"})
|
||||
r2, err := tx.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": "schema"})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -62,8 +66,13 @@ func (db *Database) ReadSchema(ctx context.Context) (retval int, reterr error) {
|
||||
return dbschema, nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaString(ctx context.Context, key string, value string) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_txt) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_txt = :val", sq.PP{
|
||||
func (db *Database) WriteMetaString(ctx db.TxContext, key string, value string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_txt) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_txt = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -73,8 +82,13 @@ func (db *Database) WriteMetaString(ctx context.Context, key string, value strin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaInt(ctx context.Context, key string, value int64) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_int) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_int = :val", sq.PP{
|
||||
func (db *Database) WriteMetaInt(ctx db.TxContext, key string, value int64) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_int) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_int = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -84,8 +98,13 @@ func (db *Database) WriteMetaInt(ctx context.Context, key string, value int64) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaReal(ctx context.Context, key string, value float64) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_real) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_real = :val", sq.PP{
|
||||
func (db *Database) WriteMetaReal(ctx db.TxContext, key string, value float64) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_real) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_real = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -95,8 +114,13 @@ func (db *Database) WriteMetaReal(ctx context.Context, key string, value float64
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaBlob(ctx context.Context, key string, value []byte) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_blob) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_blob = :val", sq.PP{
|
||||
func (db *Database) WriteMetaBlob(ctx db.TxContext, key string, value []byte) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_blob) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_blob = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -106,8 +130,13 @@ func (db *Database) WriteMetaBlob(ctx context.Context, key string, value []byte)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaString(ctx context.Context, key string) (retval *string, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_txt FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaString(ctx db.TxContext, key string) (retval *string, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_txt FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,8 +166,13 @@ func (db *Database) ReadMetaString(ctx context.Context, key string) (retval *str
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaInt(ctx context.Context, key string) (retval *int64, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaInt(ctx db.TxContext, key string) (retval *int64, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -169,8 +203,13 @@ func (db *Database) ReadMetaInt(ctx context.Context, key string) (retval *int64,
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaReal(ctx context.Context, key string) (retval *float64, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_real FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaReal(ctx db.TxContext, key string) (retval *float64, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_real FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -201,8 +240,13 @@ func (db *Database) ReadMetaReal(ctx context.Context, key string) (retval *float
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaBlob(ctx context.Context, key string) (retval *[]byte, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_blob FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaBlob(ctx db.TxContext, key string) (retval *[]byte, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_blob FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -233,8 +277,13 @@ func (db *Database) ReadMetaBlob(ctx context.Context, key string) (retval *[]byt
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMeta(ctx context.Context, key string) error {
|
||||
_, err := db.db.Exec(ctx, "DELETE FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) DeleteMeta(ctx db.TxContext, key string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "DELETE FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package primary
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"database/sql"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (db *Database) GetChannelByName(ctx TxContext, userid models.UserID, chanName string) (*models.Channel, error) {
|
||||
func (db *Database) GetChannelByName(ctx db.TxContext, userid models.UserID, chanName string) (*models.Channel, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -32,7 +33,7 @@ func (db *Database) GetChannelByName(ctx TxContext, userid models.UserID, chanNa
|
||||
return &channel, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetChannelByID(ctx TxContext, chanid models.ChannelID) (*models.Channel, error) {
|
||||
func (db *Database) GetChannelByID(ctx db.TxContext, chanid models.ChannelID) (*models.Channel, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -56,7 +57,7 @@ func (db *Database) GetChannelByID(ctx TxContext, chanid models.ChannelID) (*mod
|
||||
return &channel, nil
|
||||
}
|
||||
|
||||
func (db *Database) CreateChannel(ctx TxContext, userid models.UserID, dispName string, intName string, subscribeKey string) (models.Channel, error) {
|
||||
func (db *Database) CreateChannel(ctx db.TxContext, userid models.UserID, dispName string, intName string, subscribeKey string) (models.Channel, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Channel{}, err
|
||||
@@ -81,7 +82,7 @@ func (db *Database) CreateChannel(ctx TxContext, userid models.UserID, dispName
|
||||
return entity.Model(), nil
|
||||
}
|
||||
|
||||
func (db *Database) ListChannelsByOwner(ctx TxContext, userid models.UserID, subUserID models.UserID) ([]models.ChannelWithSubscription, error) {
|
||||
func (db *Database) ListChannelsByOwner(ctx db.TxContext, userid models.UserID, subUserID models.UserID) ([]models.ChannelWithSubscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -105,7 +106,7 @@ func (db *Database) ListChannelsByOwner(ctx TxContext, userid models.UserID, sub
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) ListChannelsBySubscriber(ctx TxContext, userid models.UserID, confirmed *bool) ([]models.ChannelWithSubscription, error) {
|
||||
func (db *Database) ListChannelsBySubscriber(ctx db.TxContext, userid models.UserID, confirmed *bool) ([]models.ChannelWithSubscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -135,7 +136,7 @@ func (db *Database) ListChannelsBySubscriber(ctx TxContext, userid models.UserID
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) ListChannelsByAccess(ctx TxContext, userid models.UserID, confirmed *bool) ([]models.ChannelWithSubscription, error) {
|
||||
func (db *Database) ListChannelsByAccess(ctx db.TxContext, userid models.UserID, confirmed *bool) ([]models.ChannelWithSubscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -166,7 +167,7 @@ func (db *Database) ListChannelsByAccess(ctx TxContext, userid models.UserID, co
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetChannel(ctx TxContext, userid models.UserID, channelid models.ChannelID, enforceOwner bool) (models.ChannelWithSubscription, error) {
|
||||
func (db *Database) GetChannel(ctx db.TxContext, userid models.UserID, channelid models.ChannelID, enforceOwner bool) (models.ChannelWithSubscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.ChannelWithSubscription{}, err
|
||||
@@ -200,7 +201,7 @@ func (db *Database) GetChannel(ctx TxContext, userid models.UserID, channelid mo
|
||||
return channel, nil
|
||||
}
|
||||
|
||||
func (db *Database) IncChannelMessageCounter(ctx TxContext, channel *models.Channel) error {
|
||||
func (db *Database) IncChannelMessageCounter(ctx db.TxContext, channel *models.Channel) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -222,7 +223,7 @@ func (db *Database) IncChannelMessageCounter(ctx TxContext, channel *models.Chan
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateChannelSubscribeKey(ctx TxContext, channelid models.ChannelID, newkey string) error {
|
||||
func (db *Database) UpdateChannelSubscribeKey(ctx db.TxContext, channelid models.ChannelID, newkey string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -239,7 +240,7 @@ func (db *Database) UpdateChannelSubscribeKey(ctx TxContext, channelid models.Ch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateChannelDisplayName(ctx TxContext, channelid models.ChannelID, dispname string) error {
|
||||
func (db *Database) UpdateChannelDisplayName(ctx db.TxContext, channelid models.ChannelID, dispname string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -256,7 +257,7 @@ func (db *Database) UpdateChannelDisplayName(ctx TxContext, channelid models.Cha
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateChannelDescriptionName(ctx TxContext, channelid models.ChannelID, descname *string) error {
|
||||
func (db *Database) UpdateChannelDescriptionName(ctx db.TxContext, channelid models.ChannelID, descname *string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -1,12 +1,13 @@
|
||||
package primary
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (db *Database) CreateClient(ctx TxContext, userid models.UserID, ctype models.ClientType, fcmToken string, agentModel string, agentVersion string) (models.Client, error) {
|
||||
func (db *Database) CreateClient(ctx db.TxContext, userid models.UserID, ctype models.ClientType, fcmToken string, agentModel string, agentVersion string) (models.Client, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Client{}, err
|
||||
@@ -30,7 +31,7 @@ func (db *Database) CreateClient(ctx TxContext, userid models.UserID, ctype mode
|
||||
return entity.Model(), nil
|
||||
}
|
||||
|
||||
func (db *Database) ClearFCMTokens(ctx TxContext, fcmtoken string) error {
|
||||
func (db *Database) ClearFCMTokens(ctx db.TxContext, fcmtoken string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -44,7 +45,7 @@ func (db *Database) ClearFCMTokens(ctx TxContext, fcmtoken string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) ListClients(ctx TxContext, userid models.UserID) ([]models.Client, error) {
|
||||
func (db *Database) ListClients(ctx db.TxContext, userid models.UserID) ([]models.Client, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -63,7 +64,7 @@ func (db *Database) ListClients(ctx TxContext, userid models.UserID) ([]models.C
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetClient(ctx TxContext, userid models.UserID, clientid models.ClientID) (models.Client, error) {
|
||||
func (db *Database) GetClient(ctx db.TxContext, userid models.UserID, clientid models.ClientID) (models.Client, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Client{}, err
|
||||
@@ -85,7 +86,7 @@ func (db *Database) GetClient(ctx TxContext, userid models.UserID, clientid mode
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteClient(ctx TxContext, clientid models.ClientID) error {
|
||||
func (db *Database) DeleteClient(ctx db.TxContext, clientid models.ClientID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -99,7 +100,7 @@ func (db *Database) DeleteClient(ctx TxContext, clientid models.ClientID) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteClientsByFCM(ctx TxContext, fcmtoken string) error {
|
||||
func (db *Database) DeleteClientsByFCM(ctx db.TxContext, fcmtoken string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -113,7 +114,7 @@ func (db *Database) DeleteClientsByFCM(ctx TxContext, fcmtoken string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateClientFCMToken(ctx TxContext, clientid models.ClientID, fcmtoken string) error {
|
||||
func (db *Database) UpdateClientFCMToken(ctx db.TxContext, clientid models.ClientID, fcmtoken string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -130,7 +131,7 @@ func (db *Database) UpdateClientFCMToken(ctx TxContext, clientid models.ClientID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateClientAgentModel(ctx TxContext, clientid models.ClientID, agentModel string) error {
|
||||
func (db *Database) UpdateClientAgentModel(ctx db.TxContext, clientid models.ClientID, agentModel string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -147,7 +148,7 @@ func (db *Database) UpdateClientAgentModel(ctx TxContext, clientid models.Client
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateClientAgentVersion(ctx TxContext, clientid models.ClientID, agentVersion string) error {
|
||||
func (db *Database) UpdateClientAgentVersion(ctx db.TxContext, clientid models.ClientID, agentVersion string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package primary
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
)
|
||||
|
||||
func (db *Database) CreateCompatID(ctx TxContext, idtype string, newid string) (int64, error) {
|
||||
func (db *Database) CreateCompatID(ctx db.TxContext, idtype string, newid string) (int64, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -42,7 +43,7 @@ func (db *Database) CreateCompatID(ctx TxContext, idtype string, newid string) (
|
||||
return oldid, nil
|
||||
}
|
||||
|
||||
func (db *Database) ConvertCompatID(ctx TxContext, oldid int64, idtype string) (*string, error) {
|
||||
func (db *Database) ConvertCompatID(ctx db.TxContext, oldid int64, idtype string) (*string, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -72,7 +73,7 @@ func (db *Database) ConvertCompatID(ctx TxContext, oldid int64, idtype string) (
|
||||
return &newid, nil
|
||||
}
|
||||
|
||||
func (db *Database) ConvertToCompatID(ctx TxContext, newid string) (*int64, *string, error) {
|
||||
func (db *Database) ConvertToCompatID(ctx db.TxContext, newid string) (*int64, *string, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -100,7 +101,7 @@ func (db *Database) ConvertToCompatID(ctx TxContext, newid string) (*int64, *str
|
||||
return &oldid, &idtype, nil
|
||||
}
|
||||
|
||||
func (db *Database) ConvertToCompatIDOrCreate(ctx TxContext, idtype string, newid string) (int64, error) {
|
||||
func (db *Database) ConvertToCompatIDOrCreate(ctx db.TxContext, idtype string, newid string) (int64, error) {
|
||||
id1, _, err := db.ConvertToCompatID(ctx, newid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -116,7 +117,7 @@ func (db *Database) ConvertToCompatIDOrCreate(ctx TxContext, idtype string, newi
|
||||
return id2, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetAck(ctx TxContext, msgid models.MessageID) (bool, error) {
|
||||
func (db *Database) GetAck(ctx db.TxContext, msgid models.MessageID) (bool, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -139,7 +140,7 @@ func (db *Database) GetAck(ctx TxContext, msgid models.MessageID) (bool, error)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (db *Database) SetAck(ctx TxContext, userid models.UserID, msgid models.MessageID) error {
|
||||
func (db *Database) SetAck(ctx db.TxContext, userid models.UserID, msgid models.MessageID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -156,7 +157,7 @@ func (db *Database) SetAck(ctx TxContext, userid models.UserID, msgid models.Mes
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) IsCompatClient(ctx TxContext, clientid models.ClientID) (bool, error) {
|
||||
func (db *Database) IsCompatClient(ctx db.TxContext, clientid models.ClientID) (bool, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
server "blackforestbytes.com/simplecloudnotifier"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/dbtools"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/schema"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/simplectx"
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
@@ -63,81 +64,147 @@ func (db *Database) DB() sq.DB {
|
||||
return db.db
|
||||
}
|
||||
|
||||
func (db *Database) Migrate(ctx context.Context) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 24*time.Second)
|
||||
defer cancel()
|
||||
func (db *Database) Migrate(outerctx context.Context) error {
|
||||
innerctx, cancel := context.WithTimeout(outerctx, 24*time.Second)
|
||||
tctx := simplectx.CreateSimpleContext(innerctx, cancel)
|
||||
|
||||
currschema, err := db.ReadSchema(ctx)
|
||||
tx, err := tctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if tx.Status() == sq.TxStatusInitial || tx.Status() == sq.TxStatusActive {
|
||||
err = tx.Rollback()
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to rollback transaction")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
ppReInit := false
|
||||
|
||||
currschema, err := db.ReadSchema(tctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if currschema == 0 {
|
||||
schemastr := schema.PrimarySchema[schema.PrimarySchemaVersion].SQL
|
||||
schemahash := schema.PrimarySchema[schema.PrimarySchemaVersion].Hash
|
||||
|
||||
schemastr := schema.PrimarySchema3
|
||||
|
||||
schemahash, err := sq.HashSqliteSchema(ctx, schemastr)
|
||||
_, err = tx.Exec(tctx, schemastr, sq.PP{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = db.db.Exec(ctx, schemastr, sq.PP{})
|
||||
err = db.WriteMetaInt(tctx, "schema", int64(schema.PrimarySchemaVersion))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.WriteMetaInt(ctx, "schema", 3)
|
||||
err = db.WriteMetaString(tctx, "schema_hash", schemahash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.WriteMetaString(ctx, "schema_hash", schemahash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ppReInit = true
|
||||
|
||||
err = db.pp.Init(ctx) // Re-Init
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currschema = schema.PrimarySchemaVersion
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
} else if currschema == 1 {
|
||||
if currschema == 1 {
|
||||
return errors.New("cannot autom. upgrade schema 1")
|
||||
} else if currschema == 2 {
|
||||
}
|
||||
|
||||
if currschema == 2 {
|
||||
return errors.New("cannot autom. upgrade schema 2")
|
||||
} else if currschema == 3 {
|
||||
}
|
||||
|
||||
schemHashDB, err := sq.HashSqliteDatabase(ctx, db.db)
|
||||
if currschema == 3 {
|
||||
|
||||
schemaHashMeta, err := db.ReadMetaString(tctx, "schema_hash")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schemaHashMeta, err := db.ReadMetaString(ctx, "schema_hash")
|
||||
schemHashDB, err := sq.HashSqliteDatabase(tctx, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schemHashAsset := schema.PrimaryHash3
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if schemHashDB != langext.Coalesce(schemaHashMeta, "") || langext.Coalesce(schemaHashMeta, "") != schemHashAsset {
|
||||
if schemHashDB != langext.Coalesce(schemaHashMeta, "") || langext.Coalesce(schemaHashMeta, "") != schema.PrimarySchema[currschema].Hash {
|
||||
log.Debug().Str("schemHashDB", schemHashDB).Msg("Schema (primary db)")
|
||||
log.Debug().Str("schemaHashMeta", langext.Coalesce(schemaHashMeta, "")).Msg("Schema (primary db)")
|
||||
log.Debug().Str("schemHashAsset", schemHashAsset).Msg("Schema (primary db)")
|
||||
log.Debug().Str("schemaHashAsset", schema.PrimarySchema[currschema].Hash).Msg("Schema (primary db)")
|
||||
return errors.New("database schema does not match (primary db)")
|
||||
} else {
|
||||
log.Debug().Str("schemHash", schemHashDB).Msg("Verified Schema consistency (primary db)")
|
||||
}
|
||||
|
||||
return nil // current
|
||||
} else {
|
||||
log.Info().Int("currschema", currschema).Msg("Upgrade schema from 3 -> 4")
|
||||
|
||||
_, err = tx.Exec(tctx, schema.PrimaryMigration_3_4, sq.PP{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
currschema = 4
|
||||
|
||||
err = db.WriteMetaInt(tctx, "schema", int64(currschema))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.WriteMetaString(tctx, "schema_hash", schema.PrimarySchema[currschema].Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().Int("currschema", currschema).Msg("Upgrade schema from 3 -> 4 succesfuly")
|
||||
|
||||
ppReInit = true
|
||||
}
|
||||
|
||||
if currschema == 4 {
|
||||
|
||||
schemaHashMeta, err := db.ReadMetaString(tctx, "schema_hash")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schemHashDB, err := sq.HashSqliteDatabase(tctx, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if schemHashDB != langext.Coalesce(schemaHashMeta, "") || langext.Coalesce(schemaHashMeta, "") != schema.PrimarySchema[currschema].Hash {
|
||||
log.Debug().Str("schemHashDB", schemHashDB).Msg("Schema (primary db)")
|
||||
log.Debug().Str("schemaHashMeta", langext.Coalesce(schemaHashMeta, "")).Msg("Schema (primary db)")
|
||||
log.Debug().Str("schemaHashAsset", schema.PrimarySchema[currschema].Hash).Msg("Schema (primary db)")
|
||||
return errors.New("database schema does not match (primary db)")
|
||||
} else {
|
||||
log.Debug().Str("schemHash", schemHashDB).Msg("Verified Schema consistency (primary db)")
|
||||
}
|
||||
}
|
||||
|
||||
if currschema != schema.PrimarySchemaVersion {
|
||||
return errors.New(fmt.Sprintf("Unknown DB schema: %d", currschema))
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ppReInit {
|
||||
log.Debug().Msg("Re-Init preprocessor")
|
||||
err = db.pp.Init(outerctx) // Re-Init
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) Ping(ctx context.Context) error {
|
||||
|
@@ -2,13 +2,14 @@ package primary
|
||||
|
||||
import (
|
||||
scn "blackforestbytes.com/simplecloudnotifier"
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (db *Database) CreateRetryDelivery(ctx TxContext, client models.Client, msg models.Message) (models.Delivery, error) {
|
||||
func (db *Database) CreateRetryDelivery(ctx db.TxContext, client models.Client, msg models.Message) (models.Delivery, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Delivery{}, err
|
||||
@@ -38,7 +39,7 @@ func (db *Database) CreateRetryDelivery(ctx TxContext, client models.Client, msg
|
||||
return entity.Model(), nil
|
||||
}
|
||||
|
||||
func (db *Database) CreateSuccessDelivery(ctx TxContext, client models.Client, msg models.Message, fcmDelivID string) (models.Delivery, error) {
|
||||
func (db *Database) CreateSuccessDelivery(ctx db.TxContext, client models.Client, msg models.Message, fcmDelivID string) (models.Delivery, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Delivery{}, err
|
||||
@@ -67,7 +68,7 @@ func (db *Database) CreateSuccessDelivery(ctx TxContext, client models.Client, m
|
||||
return entity.Model(), nil
|
||||
}
|
||||
|
||||
func (db *Database) ListRetrieableDeliveries(ctx TxContext, pageSize int) ([]models.Delivery, error) {
|
||||
func (db *Database) ListRetrieableDeliveries(ctx db.TxContext, pageSize int) ([]models.Delivery, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -89,7 +90,7 @@ func (db *Database) ListRetrieableDeliveries(ctx TxContext, pageSize int) ([]mod
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) SetDeliverySuccess(ctx TxContext, delivery models.Delivery, fcmDelivID string) error {
|
||||
func (db *Database) SetDeliverySuccess(ctx db.TxContext, delivery models.Delivery, fcmDelivID string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -108,7 +109,7 @@ func (db *Database) SetDeliverySuccess(ctx TxContext, delivery models.Delivery,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) SetDeliveryFailed(ctx TxContext, delivery models.Delivery) error {
|
||||
func (db *Database) SetDeliveryFailed(ctx db.TxContext, delivery models.Delivery) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -127,7 +128,7 @@ func (db *Database) SetDeliveryFailed(ctx TxContext, delivery models.Delivery) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) SetDeliveryRetry(ctx TxContext, delivery models.Delivery) error {
|
||||
func (db *Database) SetDeliveryRetry(ctx db.TxContext, delivery models.Delivery) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -145,7 +146,7 @@ func (db *Database) SetDeliveryRetry(ctx TxContext, delivery models.Delivery) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) CancelPendingDeliveries(ctx TxContext, messageID models.MessageID) error {
|
||||
func (db *Database) CancelPendingDeliveries(ctx db.TxContext, messageID models.MessageID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package primary
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"database/sql"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func (db *Database) CreateKeyToken(ctx TxContext, name string, owner models.UserID, allChannels bool, channels []models.ChannelID, permissions models.TokenPermissionList, token string) (models.KeyToken, error) {
|
||||
func (db *Database) CreateKeyToken(ctx db.TxContext, name string, owner models.UserID, allChannels bool, channels []models.ChannelID, permissions models.TokenPermissionList, token string) (models.KeyToken, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.KeyToken{}, err
|
||||
@@ -36,7 +37,7 @@ func (db *Database) CreateKeyToken(ctx TxContext, name string, owner models.User
|
||||
return entity.Model(), nil
|
||||
}
|
||||
|
||||
func (db *Database) ListKeyTokens(ctx TxContext, ownerID models.UserID) ([]models.KeyToken, error) {
|
||||
func (db *Database) ListKeyTokens(ctx db.TxContext, ownerID models.UserID) ([]models.KeyToken, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -55,7 +56,7 @@ func (db *Database) ListKeyTokens(ctx TxContext, ownerID models.UserID) ([]model
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetKeyToken(ctx TxContext, userid models.UserID, keyTokenid models.KeyTokenID) (models.KeyToken, error) {
|
||||
func (db *Database) GetKeyToken(ctx db.TxContext, userid models.UserID, keyTokenid models.KeyTokenID) (models.KeyToken, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.KeyToken{}, err
|
||||
@@ -77,7 +78,7 @@ func (db *Database) GetKeyToken(ctx TxContext, userid models.UserID, keyTokenid
|
||||
return keyToken, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetKeyTokenByToken(ctx TxContext, key string) (*models.KeyToken, error) {
|
||||
func (db *Database) GetKeyTokenByToken(ctx db.TxContext, key string) (*models.KeyToken, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -99,7 +100,7 @@ func (db *Database) GetKeyTokenByToken(ctx TxContext, key string) (*models.KeyTo
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteKeyToken(ctx TxContext, keyTokenid models.KeyTokenID) error {
|
||||
func (db *Database) DeleteKeyToken(ctx db.TxContext, keyTokenid models.KeyTokenID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -113,7 +114,7 @@ func (db *Database) DeleteKeyToken(ctx TxContext, keyTokenid models.KeyTokenID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateKeyTokenName(ctx TxContext, keyTokenid models.KeyTokenID, name string) error {
|
||||
func (db *Database) UpdateKeyTokenName(ctx db.TxContext, keyTokenid models.KeyTokenID, name string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -130,7 +131,7 @@ func (db *Database) UpdateKeyTokenName(ctx TxContext, keyTokenid models.KeyToken
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateKeyTokenPermissions(ctx TxContext, keyTokenid models.KeyTokenID, perm models.TokenPermissionList) error {
|
||||
func (db *Database) UpdateKeyTokenPermissions(ctx db.TxContext, keyTokenid models.KeyTokenID, perm models.TokenPermissionList) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -147,7 +148,7 @@ func (db *Database) UpdateKeyTokenPermissions(ctx TxContext, keyTokenid models.K
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateKeyTokenAllChannels(ctx TxContext, keyTokenid models.KeyTokenID, allChannels bool) error {
|
||||
func (db *Database) UpdateKeyTokenAllChannels(ctx db.TxContext, keyTokenid models.KeyTokenID, allChannels bool) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -164,7 +165,7 @@ func (db *Database) UpdateKeyTokenAllChannels(ctx TxContext, keyTokenid models.K
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateKeyTokenChannels(ctx TxContext, keyTokenid models.KeyTokenID, channels []models.ChannelID) error {
|
||||
func (db *Database) UpdateKeyTokenChannels(ctx db.TxContext, keyTokenid models.KeyTokenID, channels []models.ChannelID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -181,7 +182,7 @@ func (db *Database) UpdateKeyTokenChannels(ctx TxContext, keyTokenid models.KeyT
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) IncKeyTokenMessageCounter(ctx TxContext, keyToken *models.KeyToken) error {
|
||||
func (db *Database) IncKeyTokenMessageCounter(ctx db.TxContext, keyToken *models.KeyToken) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -203,7 +204,7 @@ func (db *Database) IncKeyTokenMessageCounter(ctx TxContext, keyToken *models.Ke
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateKeyTokenLastUsed(ctx TxContext, keyTokenid models.KeyTokenID) error {
|
||||
func (db *Database) UpdateKeyTokenLastUsed(ctx db.TxContext, keyTokenid models.KeyTokenID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package primary
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
ct "blackforestbytes.com/simplecloudnotifier/db/cursortoken"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"database/sql"
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func (db *Database) GetMessageByUserMessageID(ctx TxContext, usrMsgId string) (*models.Message, error) {
|
||||
func (db *Database) GetMessageByUserMessageID(ctx db.TxContext, usrMsgId string) (*models.Message, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -31,7 +32,7 @@ func (db *Database) GetMessageByUserMessageID(ctx TxContext, usrMsgId string) (*
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetMessage(ctx TxContext, scnMessageID models.MessageID, allowDeleted bool) (models.Message, error) {
|
||||
func (db *Database) GetMessage(ctx db.TxContext, scnMessageID models.MessageID, allowDeleted bool) (models.Message, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Message{}, err
|
||||
@@ -57,7 +58,7 @@ func (db *Database) GetMessage(ctx TxContext, scnMessageID models.MessageID, all
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (db *Database) CreateMessage(ctx TxContext, senderUserID models.UserID, channel models.Channel, timestampSend *time.Time, title string, content *string, priority int, userMsgId *string, senderIP string, senderName *string, usedKeyID models.KeyTokenID) (models.Message, error) {
|
||||
func (db *Database) CreateMessage(ctx db.TxContext, senderUserID models.UserID, channel models.Channel, timestampSend *time.Time, title string, content *string, priority int, userMsgId *string, senderIP string, senderName *string, usedKeyID models.KeyTokenID) (models.Message, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Message{}, err
|
||||
@@ -66,7 +67,6 @@ func (db *Database) CreateMessage(ctx TxContext, senderUserID models.UserID, cha
|
||||
entity := models.MessageDB{
|
||||
MessageID: models.NewMessageID(),
|
||||
SenderUserID: senderUserID,
|
||||
OwnerUserID: channel.OwnerUserID,
|
||||
ChannelInternalName: channel.InternalName,
|
||||
ChannelID: channel.ChannelID,
|
||||
SenderIP: senderIP,
|
||||
@@ -89,7 +89,7 @@ func (db *Database) CreateMessage(ctx TxContext, senderUserID models.UserID, cha
|
||||
return entity.Model(), nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMessage(ctx TxContext, messageID models.MessageID) error {
|
||||
func (db *Database) DeleteMessage(ctx db.TxContext, messageID models.MessageID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -103,7 +103,7 @@ func (db *Database) DeleteMessage(ctx TxContext, messageID models.MessageID) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) ListMessages(ctx TxContext, filter models.MessageFilter, pageSize *int, inTok ct.CursorToken) ([]models.Message, ct.CursorToken, error) {
|
||||
func (db *Database) ListMessages(ctx db.TxContext, filter models.MessageFilter, pageSize *int, inTok ct.CursorToken) ([]models.Message, ct.CursorToken, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, ct.CursorToken{}, err
|
||||
@@ -151,7 +151,7 @@ func (db *Database) ListMessages(ctx TxContext, filter models.MessageFilter, pag
|
||||
}
|
||||
}
|
||||
|
||||
func (db *Database) CountMessages(ctx TxContext, filter models.MessageFilter) (int64, error) {
|
||||
func (db *Database) CountMessages(ctx db.TxContext, filter models.MessageFilter) (int64, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@@ -1,15 +1,19 @@
|
||||
package primary
|
||||
|
||||
import (
|
||||
"context"
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"errors"
|
||||
"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 db.TxContext) (retval int, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r1, err := db.db.Query(ctx, "SELECT name FROM sqlite_master WHERE type = :typ AND name = :name", sq.PP{"typ": "table", "name": "meta"})
|
||||
r1, err := tx.Query(ctx, "SELECT name FROM sqlite_master WHERE type = :typ AND name = :name", sq.PP{"typ": "table", "name": "meta"})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -31,7 +35,7 @@ func (db *Database) ReadSchema(ctx context.Context) (retval int, reterr error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r2, err := db.db.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": "schema"})
|
||||
r2, err := tx.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": "schema"})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -62,8 +66,13 @@ func (db *Database) ReadSchema(ctx context.Context) (retval int, reterr error) {
|
||||
return dbschema, nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaString(ctx context.Context, key string, value string) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_txt) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_txt = :val", sq.PP{
|
||||
func (db *Database) WriteMetaString(ctx db.TxContext, key string, value string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_txt) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_txt = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -73,8 +82,13 @@ func (db *Database) WriteMetaString(ctx context.Context, key string, value strin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaInt(ctx context.Context, key string, value int64) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_int) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_int = :val", sq.PP{
|
||||
func (db *Database) WriteMetaInt(ctx db.TxContext, key string, value int64) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_int) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_int = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -84,8 +98,13 @@ func (db *Database) WriteMetaInt(ctx context.Context, key string, value int64) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaReal(ctx context.Context, key string, value float64) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_real) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_real = :val", sq.PP{
|
||||
func (db *Database) WriteMetaReal(ctx db.TxContext, key string, value float64) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_real) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_real = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -95,8 +114,13 @@ func (db *Database) WriteMetaReal(ctx context.Context, key string, value float64
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaBlob(ctx context.Context, key string, value []byte) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_blob) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_blob = :val", sq.PP{
|
||||
func (db *Database) WriteMetaBlob(ctx db.TxContext, key string, value []byte) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_blob) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_blob = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -106,8 +130,13 @@ func (db *Database) WriteMetaBlob(ctx context.Context, key string, value []byte)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaString(ctx context.Context, key string) (retval *string, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_txt FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaString(ctx db.TxContext, key string) (retval *string, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_txt FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,8 +166,13 @@ func (db *Database) ReadMetaString(ctx context.Context, key string) (retval *str
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaInt(ctx context.Context, key string) (retval *int64, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaInt(ctx db.TxContext, key string) (retval *int64, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -169,8 +203,13 @@ func (db *Database) ReadMetaInt(ctx context.Context, key string) (retval *int64,
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaReal(ctx context.Context, key string) (retval *float64, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_real FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaReal(ctx db.TxContext, key string) (retval *float64, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_real FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -201,8 +240,13 @@ func (db *Database) ReadMetaReal(ctx context.Context, key string) (retval *float
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaBlob(ctx context.Context, key string) (retval *[]byte, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_blob FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaBlob(ctx db.TxContext, key string) (retval *[]byte, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_blob FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -233,8 +277,13 @@ func (db *Database) ReadMetaBlob(ctx context.Context, key string) (retval *[]byt
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMeta(ctx context.Context, key string) error {
|
||||
_, err := db.db.Exec(ctx, "DELETE FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) DeleteMeta(ctx db.TxContext, key string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "DELETE FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package primary
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"database/sql"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (db *Database) CreateSubscription(ctx TxContext, subscriberUID models.UserID, channel models.Channel, confirmed bool) (models.Subscription, error) {
|
||||
func (db *Database) CreateSubscription(ctx db.TxContext, subscriberUID models.UserID, channel models.Channel, confirmed bool) (models.Subscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Subscription{}, err
|
||||
@@ -31,7 +32,7 @@ func (db *Database) CreateSubscription(ctx TxContext, subscriberUID models.UserI
|
||||
return entity.Model(), nil
|
||||
}
|
||||
|
||||
func (db *Database) ListSubscriptionsByChannel(ctx TxContext, channelID models.ChannelID) ([]models.Subscription, error) {
|
||||
func (db *Database) ListSubscriptionsByChannel(ctx db.TxContext, channelID models.ChannelID) ([]models.Subscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -52,7 +53,7 @@ func (db *Database) ListSubscriptionsByChannel(ctx TxContext, channelID models.C
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) ListSubscriptionsByChannelOwner(ctx TxContext, ownerUserID models.UserID, confirmed *bool) ([]models.Subscription, error) {
|
||||
func (db *Database) ListSubscriptionsByChannelOwner(ctx db.TxContext, ownerUserID models.UserID, confirmed *bool) ([]models.Subscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -80,7 +81,7 @@ func (db *Database) ListSubscriptionsByChannelOwner(ctx TxContext, ownerUserID m
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) ListSubscriptionsBySubscriber(ctx TxContext, subscriberUserID models.UserID, confirmed *bool) ([]models.Subscription, error) {
|
||||
func (db *Database) ListSubscriptionsBySubscriber(ctx db.TxContext, subscriberUserID models.UserID, confirmed *bool) ([]models.Subscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -108,7 +109,7 @@ func (db *Database) ListSubscriptionsBySubscriber(ctx TxContext, subscriberUserI
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetSubscription(ctx TxContext, subid models.SubscriptionID) (models.Subscription, error) {
|
||||
func (db *Database) GetSubscription(ctx db.TxContext, subid models.SubscriptionID) (models.Subscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.Subscription{}, err
|
||||
@@ -127,7 +128,7 @@ func (db *Database) GetSubscription(ctx TxContext, subid models.SubscriptionID)
|
||||
return sub, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetSubscriptionBySubscriber(ctx TxContext, subscriberId models.UserID, channelId models.ChannelID) (*models.Subscription, error) {
|
||||
func (db *Database) GetSubscriptionBySubscriber(ctx db.TxContext, subscriberId models.UserID, channelId models.ChannelID) (*models.Subscription, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -152,7 +153,7 @@ func (db *Database) GetSubscriptionBySubscriber(ctx TxContext, subscriberId mode
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteSubscription(ctx TxContext, subid models.SubscriptionID) error {
|
||||
func (db *Database) DeleteSubscription(ctx db.TxContext, subid models.SubscriptionID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -166,7 +167,7 @@ func (db *Database) DeleteSubscription(ctx TxContext, subid models.SubscriptionI
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateSubscriptionConfirmed(ctx TxContext, subscriptionID models.SubscriptionID, confirmed bool) error {
|
||||
func (db *Database) UpdateSubscriptionConfirmed(ctx db.TxContext, subscriptionID models.SubscriptionID, confirmed bool) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -2,13 +2,14 @@ package primary
|
||||
|
||||
import (
|
||||
scn "blackforestbytes.com/simplecloudnotifier"
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"blackforestbytes.com/simplecloudnotifier/models"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (db *Database) CreateUser(ctx TxContext, protoken *string, username *string) (models.User, error) {
|
||||
func (db *Database) CreateUser(ctx db.TxContext, protoken *string, username *string) (models.User, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.User{}, err
|
||||
@@ -35,7 +36,7 @@ func (db *Database) CreateUser(ctx TxContext, protoken *string, username *string
|
||||
return entity.Model(), nil
|
||||
}
|
||||
|
||||
func (db *Database) ClearProTokens(ctx TxContext, protoken string) error {
|
||||
func (db *Database) ClearProTokens(ctx db.TxContext, protoken string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -49,7 +50,7 @@ func (db *Database) ClearProTokens(ctx TxContext, protoken string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) GetUser(ctx TxContext, userid models.UserID) (models.User, error) {
|
||||
func (db *Database) GetUser(ctx db.TxContext, userid models.UserID) (models.User, error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return models.User{}, err
|
||||
@@ -68,7 +69,7 @@ func (db *Database) GetUser(ctx TxContext, userid models.UserID) (models.User, e
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateUserUsername(ctx TxContext, userid models.UserID, username *string) error {
|
||||
func (db *Database) UpdateUserUsername(ctx db.TxContext, userid models.UserID, username *string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -85,7 +86,7 @@ func (db *Database) UpdateUserUsername(ctx TxContext, userid models.UserID, user
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateUserProToken(ctx TxContext, userid models.UserID, protoken *string) error {
|
||||
func (db *Database) UpdateUserProToken(ctx db.TxContext, userid models.UserID, protoken *string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -103,7 +104,7 @@ func (db *Database) UpdateUserProToken(ctx TxContext, userid models.UserID, prot
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) IncUserMessageCounter(ctx TxContext, user *models.User) error {
|
||||
func (db *Database) IncUserMessageCounter(ctx db.TxContext, user *models.User) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -132,7 +133,7 @@ func (db *Database) IncUserMessageCounter(ctx TxContext, user *models.User) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateUserLastRead(ctx TxContext, userid models.UserID) error {
|
||||
func (db *Database) UpdateUserLastRead(ctx db.TxContext, userid models.UserID) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
server "blackforestbytes.com/simplecloudnotifier"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/dbtools"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/schema"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/simplectx"
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
@@ -63,77 +64,98 @@ func (db *Database) DB() sq.DB {
|
||||
return db.db
|
||||
}
|
||||
|
||||
func (db *Database) Migrate(ctx context.Context) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 24*time.Second)
|
||||
defer cancel()
|
||||
func (db *Database) Migrate(outerctx context.Context) error {
|
||||
innerctx, cancel := context.WithTimeout(outerctx, 24*time.Second)
|
||||
tctx := simplectx.CreateSimpleContext(innerctx, cancel)
|
||||
|
||||
currschema, err := db.ReadSchema(ctx)
|
||||
tx, err := tctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if tx.Status() == sq.TxStatusInitial || tx.Status() == sq.TxStatusActive {
|
||||
err = tx.Rollback()
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to rollback transaction")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
ppReInit := false
|
||||
|
||||
currschema, err := db.ReadSchema(tctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if currschema == 0 {
|
||||
schemastr := schema.RequestsSchema[schema.RequestsSchemaVersion].SQL
|
||||
schemahash := schema.RequestsSchema[schema.RequestsSchemaVersion].Hash
|
||||
|
||||
schemastr := schema.RequestsSchema1
|
||||
|
||||
schemahash, err := sq.HashSqliteSchema(ctx, schemastr)
|
||||
schemahash, err := sq.HashSqliteSchema(tctx, schemastr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = db.db.Exec(ctx, schemastr, sq.PP{})
|
||||
_, err = tx.Exec(tctx, schemastr, sq.PP{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.WriteMetaInt(ctx, "schema", 1)
|
||||
err = db.WriteMetaInt(tctx, "schema", int64(schema.RequestsSchemaVersion))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.WriteMetaString(ctx, "schema_hash", schemahash)
|
||||
err = db.WriteMetaString(tctx, "schema_hash", schemahash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.pp.Init(ctx) // Re-Init
|
||||
ppReInit = true
|
||||
|
||||
currschema = schema.LogsSchemaVersion
|
||||
}
|
||||
|
||||
if currschema == 1 {
|
||||
schemHashDB, err := sq.HashSqliteDatabase(tctx, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
} else if currschema == 1 {
|
||||
|
||||
schemHashDB, err := sq.HashSqliteDatabase(ctx, db.db)
|
||||
schemaHashMeta, err := db.ReadMetaString(tctx, "schema_hash")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schemaHashMeta, err := db.ReadMetaString(ctx, "schema_hash")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schemHashAsset := schema.RequestsHash1
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if schemHashDB != langext.Coalesce(schemaHashMeta, "") || langext.Coalesce(schemaHashMeta, "") != schemHashAsset {
|
||||
if schemHashDB != langext.Coalesce(schemaHashMeta, "") || langext.Coalesce(schemaHashMeta, "") != schema.RequestsSchema[currschema].Hash {
|
||||
log.Debug().Str("schemHashDB", schemHashDB).Msg("Schema (requests db)")
|
||||
log.Debug().Str("schemaHashMeta", langext.Coalesce(schemaHashMeta, "")).Msg("Schema (requests db)")
|
||||
log.Debug().Str("schemHashAsset", schemHashAsset).Msg("Schema (requests db)")
|
||||
log.Debug().Str("schemaHashAsset", schema.RequestsSchema[currschema].Hash).Msg("Schema (requests db)")
|
||||
return errors.New("database schema does not match (requests db)")
|
||||
} else {
|
||||
log.Debug().Str("schemHash", schemHashDB).Msg("Verified Schema consistency (requests db)")
|
||||
}
|
||||
}
|
||||
|
||||
return nil // current
|
||||
} else {
|
||||
if currschema != schema.RequestsSchemaVersion {
|
||||
return errors.New(fmt.Sprintf("Unknown DB schema: %d", currschema))
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ppReInit {
|
||||
log.Debug().Msg("Re-Init preprocessor")
|
||||
err = db.pp.Init(outerctx) // Re-Init
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) Ping(ctx context.Context) error {
|
||||
|
@@ -1,15 +1,19 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"errors"
|
||||
"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 db.TxContext) (retval int, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r1, err := db.db.Query(ctx, "SELECT name FROM sqlite_master WHERE type = :typ AND name = :name", sq.PP{"typ": "table", "name": "meta"})
|
||||
r1, err := tx.Query(ctx, "SELECT name FROM sqlite_master WHERE type = :typ AND name = :name", sq.PP{"typ": "table", "name": "meta"})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -31,7 +35,7 @@ func (db *Database) ReadSchema(ctx context.Context) (retval int, reterr error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r2, err := db.db.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": "schema"})
|
||||
r2, err := tx.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": "schema"})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -62,8 +66,13 @@ func (db *Database) ReadSchema(ctx context.Context) (retval int, reterr error) {
|
||||
return dbschema, nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaString(ctx context.Context, key string, value string) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_txt) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_txt = :val", sq.PP{
|
||||
func (db *Database) WriteMetaString(ctx db.TxContext, key string, value string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_txt) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_txt = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -73,8 +82,13 @@ func (db *Database) WriteMetaString(ctx context.Context, key string, value strin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaInt(ctx context.Context, key string, value int64) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_int) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_int = :val", sq.PP{
|
||||
func (db *Database) WriteMetaInt(ctx db.TxContext, key string, value int64) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_int) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_int = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -84,8 +98,13 @@ func (db *Database) WriteMetaInt(ctx context.Context, key string, value int64) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaReal(ctx context.Context, key string, value float64) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_real) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_real = :val", sq.PP{
|
||||
func (db *Database) WriteMetaReal(ctx db.TxContext, key string, value float64) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_real) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_real = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -95,8 +114,13 @@ func (db *Database) WriteMetaReal(ctx context.Context, key string, value float64
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaBlob(ctx context.Context, key string, value []byte) error {
|
||||
_, err := db.db.Exec(ctx, "INSERT INTO meta (meta_key, value_blob) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_blob = :val", sq.PP{
|
||||
func (db *Database) WriteMetaBlob(ctx db.TxContext, key string, value []byte) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO meta (meta_key, value_blob) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_blob = :val", sq.PP{
|
||||
"key": key,
|
||||
"val": value,
|
||||
})
|
||||
@@ -106,8 +130,13 @@ func (db *Database) WriteMetaBlob(ctx context.Context, key string, value []byte)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaString(ctx context.Context, key string) (retval *string, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_txt FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaString(ctx db.TxContext, key string) (retval *string, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_txt FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,8 +166,13 @@ func (db *Database) ReadMetaString(ctx context.Context, key string) (retval *str
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaInt(ctx context.Context, key string) (retval *int64, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaInt(ctx db.TxContext, key string) (retval *int64, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_int FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -169,8 +203,13 @@ func (db *Database) ReadMetaInt(ctx context.Context, key string) (retval *int64,
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaReal(ctx context.Context, key string) (retval *float64, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_real FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaReal(ctx db.TxContext, key string) (retval *float64, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_real FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -201,8 +240,13 @@ func (db *Database) ReadMetaReal(ctx context.Context, key string) (retval *float
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaBlob(ctx context.Context, key string) (retval *[]byte, reterr error) {
|
||||
r2, err := db.db.Query(ctx, "SELECT value_blob FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) ReadMetaBlob(ctx db.TxContext, key string) (retval *[]byte, reterr error) {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r2, err := tx.Query(ctx, "SELECT value_blob FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -233,8 +277,13 @@ func (db *Database) ReadMetaBlob(ctx context.Context, key string) (retval *[]byt
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMeta(ctx context.Context, key string) error {
|
||||
_, err := db.db.Exec(ctx, "DELETE FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
func (db *Database) DeleteMeta(ctx db.TxContext, key string) error {
|
||||
tx, err := ctx.GetOrCreateTransaction(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "DELETE FROM meta WHERE meta_key = :key", sq.PP{"key": key})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -2,27 +2,52 @@ package schema
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed primary_1.ddl
|
||||
var PrimarySchema1 string
|
||||
type Def struct {
|
||||
SQL string
|
||||
Hash string
|
||||
}
|
||||
|
||||
const PrimaryHash1 = "f2b2847f32681a7178e405553beea4a324034915a0c5a5dc70b3c6abbcc852f2"
|
||||
//go:embed primary_1.ddl
|
||||
var primarySchema1 string
|
||||
|
||||
//go:embed primary_2.ddl
|
||||
var PrimarySchema2 string
|
||||
|
||||
const PrimaryHash2 = "07ed1449114416ed043084a30e0722a5f97bf172161338d2f7106a8dfd387d0a"
|
||||
var primarySchema2 string
|
||||
|
||||
//go:embed primary_3.ddl
|
||||
var PrimarySchema3 string
|
||||
var primarySchema3 string
|
||||
|
||||
const PrimaryHash3 = "65c2125ad0e12d02490cf2275f0067ef3c62a8522edf9a35ee8aa3f3c09b12e8"
|
||||
//go:embed primary_4.ddl
|
||||
var primarySchema4 string
|
||||
|
||||
//go:embed primary_migration_3_4.ddl
|
||||
var PrimaryMigration_3_4 string
|
||||
|
||||
//go:embed requests_1.ddl
|
||||
var RequestsSchema1 string
|
||||
|
||||
const RequestsHash1 = "ebb0a5748b605e8215437413b738279670190ca8159b6227cfc2aa13418b41e9"
|
||||
var requestsSchema1 string
|
||||
|
||||
//go:embed logs_1.ddl
|
||||
var LogsSchema1 string
|
||||
var logsSchema1 string
|
||||
|
||||
const LogsHash1 = "65fba477c04095effc3a8e1bb79fe7547b8e52e983f776f156266eddc4f201d7"
|
||||
var PrimarySchema = map[int]Def{
|
||||
0: {"", ""},
|
||||
1: {primarySchema1, "f2b2847f32681a7178e405553beea4a324034915a0c5a5dc70b3c6abbcc852f2"},
|
||||
2: {primarySchema2, "07ed1449114416ed043084a30e0722a5f97bf172161338d2f7106a8dfd387d0a"},
|
||||
3: {primarySchema3, "65c2125ad0e12d02490cf2275f0067ef3c62a8522edf9a35ee8aa3f3c09b12e8"},
|
||||
4: {primarySchema4, "cb022156ab0e7aea39dd0c985428c43cae7d60e41ca8e9e5a84c774b3019d2ca"},
|
||||
}
|
||||
|
||||
var PrimarySchemaVersion = 4
|
||||
|
||||
var RequestsSchema = map[int]Def{
|
||||
0: {"", ""},
|
||||
1: {requestsSchema1, "ebb0a5748b605e8215437413b738279670190ca8159b6227cfc2aa13418b41e9"},
|
||||
}
|
||||
|
||||
var RequestsSchemaVersion = 1
|
||||
|
||||
var LogsSchema = map[int]Def{
|
||||
0: {"", ""},
|
||||
1: {logsSchema1, "65fba477c04095effc3a8e1bb79fe7547b8e52e983f776f156266eddc4f201d7"},
|
||||
}
|
||||
|
||||
var LogsSchemaVersion = 1
|
||||
|
233
scnserver/db/schema/primary_4.ddl
Normal file
233
scnserver/db/schema/primary_4.ddl
Normal file
@@ -0,0 +1,233 @@
|
||||
CREATE TABLE users
|
||||
(
|
||||
user_id TEXT NOT NULL,
|
||||
|
||||
username TEXT NULL DEFAULT NULL,
|
||||
|
||||
timestamp_created INTEGER NOT NULL,
|
||||
timestamp_lastread INTEGER NULL DEFAULT NULL,
|
||||
timestamp_lastsent INTEGER NULL DEFAULT NULL,
|
||||
|
||||
messages_sent INTEGER NOT NULL DEFAULT '0',
|
||||
|
||||
quota_used INTEGER NOT NULL DEFAULT '0',
|
||||
quota_used_day TEXT NULL DEFAULT NULL,
|
||||
|
||||
is_pro INTEGER CHECK(is_pro IN (0, 1)) NOT NULL DEFAULT 0,
|
||||
pro_token TEXT NULL DEFAULT NULL,
|
||||
|
||||
PRIMARY KEY (user_id)
|
||||
) STRICT;
|
||||
CREATE UNIQUE INDEX "idx_users_protoken" ON users (pro_token) WHERE pro_token IS NOT NULL;
|
||||
|
||||
|
||||
CREATE TABLE keytokens
|
||||
(
|
||||
keytoken_id TEXT NOT NULL,
|
||||
|
||||
timestamp_created INTEGER NOT NULL,
|
||||
timestamp_lastused INTEGER NULL DEFAULT NULL,
|
||||
|
||||
name TEXT NOT NULL,
|
||||
|
||||
owner_user_id TEXT NOT NULL,
|
||||
|
||||
all_channels INTEGER CHECK(all_channels IN (0, 1)) NOT NULL,
|
||||
channels TEXT NOT NULL,
|
||||
token TEXT NOT NULL,
|
||||
permissions TEXT NOT NULL,
|
||||
|
||||
messages_sent INTEGER NOT NULL DEFAULT '0',
|
||||
|
||||
PRIMARY KEY (keytoken_id)
|
||||
) STRICT;
|
||||
CREATE UNIQUE INDEX "idx_keytokens_token" ON keytokens (token);
|
||||
|
||||
|
||||
CREATE TABLE clients
|
||||
(
|
||||
client_id TEXT NOT NULL,
|
||||
|
||||
user_id TEXT NOT NULL,
|
||||
type TEXT CHECK(type IN ('ANDROID', 'IOS')) NOT NULL,
|
||||
fcm_token TEXT NOT NULL,
|
||||
|
||||
timestamp_created INTEGER NOT NULL,
|
||||
|
||||
agent_model TEXT NOT NULL,
|
||||
agent_version TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (client_id)
|
||||
) STRICT;
|
||||
CREATE INDEX "idx_clients_userid" ON clients (user_id);
|
||||
CREATE UNIQUE INDEX "idx_clients_fcmtoken" ON clients (fcm_token);
|
||||
|
||||
|
||||
CREATE TABLE channels
|
||||
(
|
||||
channel_id TEXT NOT NULL,
|
||||
|
||||
owner_user_id TEXT NOT NULL,
|
||||
|
||||
internal_name TEXT NOT NULL,
|
||||
display_name TEXT NOT NULL,
|
||||
description_name TEXT NULL,
|
||||
|
||||
subscribe_key TEXT NOT NULL,
|
||||
|
||||
timestamp_created INTEGER NOT NULL,
|
||||
timestamp_lastsent INTEGER NULL DEFAULT NULL,
|
||||
|
||||
messages_sent INTEGER NOT NULL DEFAULT '0',
|
||||
|
||||
PRIMARY KEY (channel_id)
|
||||
) STRICT;
|
||||
CREATE UNIQUE INDEX "idx_channels_identity" ON channels (owner_user_id, internal_name);
|
||||
|
||||
CREATE TABLE subscriptions
|
||||
(
|
||||
subscription_id TEXT NOT NULL,
|
||||
|
||||
subscriber_user_id TEXT NOT NULL,
|
||||
channel_owner_user_id TEXT NOT NULL,
|
||||
channel_internal_name TEXT NOT NULL,
|
||||
channel_id TEXT NOT NULL,
|
||||
|
||||
timestamp_created INTEGER NOT NULL,
|
||||
|
||||
confirmed INTEGER CHECK(confirmed IN (0, 1)) NOT NULL,
|
||||
|
||||
PRIMARY KEY (subscription_id)
|
||||
) STRICT;
|
||||
CREATE UNIQUE INDEX "idx_subscriptions_ref" ON subscriptions (subscriber_user_id, channel_owner_user_id, channel_internal_name);
|
||||
CREATE INDEX "idx_subscriptions_chan" ON subscriptions (channel_id);
|
||||
CREATE INDEX "idx_subscriptions_subuser" ON subscriptions (subscriber_user_id);
|
||||
CREATE INDEX "idx_subscriptions_ownuser" ON subscriptions (channel_owner_user_id);
|
||||
CREATE INDEX "idx_subscriptions_tsc" ON subscriptions (timestamp_created);
|
||||
CREATE INDEX "idx_subscriptions_conf" ON subscriptions (confirmed);
|
||||
|
||||
|
||||
CREATE TABLE messages
|
||||
(
|
||||
message_id TEXT NOT NULL,
|
||||
sender_user_id TEXT NOT NULL,
|
||||
channel_internal_name TEXT NOT NULL,
|
||||
channel_id TEXT NOT NULL,
|
||||
sender_ip TEXT NOT NULL,
|
||||
sender_name TEXT NULL,
|
||||
|
||||
timestamp_real INTEGER NOT NULL,
|
||||
timestamp_client INTEGER NULL,
|
||||
|
||||
title TEXT NOT NULL,
|
||||
content TEXT NULL,
|
||||
priority INTEGER CHECK(priority IN (0, 1, 2)) NOT NULL,
|
||||
usr_message_id TEXT NULL,
|
||||
|
||||
used_key_id TEXT NOT NULL,
|
||||
|
||||
deleted INTEGER CHECK(deleted IN (0, 1)) NOT NULL DEFAULT '0',
|
||||
|
||||
PRIMARY KEY (message_id)
|
||||
) STRICT;
|
||||
CREATE INDEX "idx_messages_channel" ON messages (channel_internal_name COLLATE BINARY);
|
||||
CREATE INDEX "idx_messages_channel_nc" ON messages (channel_internal_name COLLATE NOCASE);
|
||||
CREATE UNIQUE INDEX "idx_messages_idempotency" ON messages (sender_user_id, usr_message_id COLLATE BINARY);
|
||||
CREATE INDEX "idx_messages_senderip" ON messages (sender_ip COLLATE BINARY);
|
||||
CREATE INDEX "idx_messages_sendername" ON messages (sender_name COLLATE BINARY);
|
||||
CREATE INDEX "idx_messages_sendername_nc" ON messages (sender_name COLLATE NOCASE);
|
||||
CREATE INDEX "idx_messages_title" ON messages (title COLLATE BINARY);
|
||||
CREATE INDEX "idx_messages_title_nc" ON messages (title COLLATE NOCASE);
|
||||
CREATE INDEX "idx_messages_usedkey" ON messages (sender_user_id, used_key_id);
|
||||
CREATE INDEX "idx_messages_deleted" ON messages (deleted);
|
||||
|
||||
|
||||
CREATE VIRTUAL TABLE messages_fts USING fts5
|
||||
(
|
||||
channel_internal_name,
|
||||
sender_name,
|
||||
title,
|
||||
content,
|
||||
|
||||
tokenize = unicode61,
|
||||
content = 'messages',
|
||||
content_rowid = 'rowid'
|
||||
);
|
||||
|
||||
CREATE TRIGGER fts_insert AFTER INSERT ON messages BEGIN
|
||||
INSERT INTO messages_fts (rowid, channel_internal_name, sender_name, title, content) VALUES (new.rowid, new.channel_internal_name, new.sender_name, new.title, new.content);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER fts_update AFTER UPDATE ON messages BEGIN
|
||||
INSERT INTO messages_fts (messages_fts, rowid, channel_internal_name, sender_name, title, content) VALUES ('delete', old.rowid, old.channel_internal_name, old.sender_name, old.title, old.content);
|
||||
INSERT INTO messages_fts ( rowid, channel_internal_name, sender_name, title, content) VALUES ( new.rowid, new.channel_internal_name, new.sender_name, new.title, new.content);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER fts_delete AFTER DELETE ON messages BEGIN
|
||||
INSERT INTO messages_fts (messages_fts, rowid, channel_internal_name, sender_name, title, content) VALUES ('delete', old.rowid, old.channel_internal_name, old.sender_name, old.title, old.content);
|
||||
END;
|
||||
|
||||
|
||||
CREATE TABLE deliveries
|
||||
(
|
||||
delivery_id TEXT NOT NULL,
|
||||
|
||||
message_id TEXT NOT NULL,
|
||||
receiver_user_id TEXT NOT NULL,
|
||||
receiver_client_id TEXT NOT NULL,
|
||||
|
||||
timestamp_created INTEGER NOT NULL,
|
||||
timestamp_finalized INTEGER NULL,
|
||||
|
||||
|
||||
status TEXT CHECK(status IN ('RETRY','SUCCESS','FAILED')) NOT NULL,
|
||||
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||
next_delivery TEXT NULL DEFAULT NULL,
|
||||
|
||||
fcm_message_id TEXT NULL,
|
||||
|
||||
PRIMARY KEY (delivery_id)
|
||||
) STRICT;
|
||||
CREATE INDEX "idx_deliveries_receiver" ON deliveries (message_id, receiver_client_id);
|
||||
|
||||
|
||||
CREATE TABLE compat_ids
|
||||
(
|
||||
old INTEGER NOT NULL,
|
||||
new TEXT NOT NULL,
|
||||
type TEXT NOT NULL
|
||||
) STRICT;
|
||||
CREATE UNIQUE INDEX "idx_compatids_new" ON compat_ids (new);
|
||||
CREATE UNIQUE INDEX "idx_compatids_old" ON compat_ids (old, type);
|
||||
|
||||
|
||||
CREATE TABLE compat_acks
|
||||
(
|
||||
user_id TEXT NOT NULL,
|
||||
message_id TEXT NOT NULL
|
||||
) STRICT;
|
||||
CREATE INDEX "idx_compatacks_userid" ON compat_acks (user_id);
|
||||
CREATE UNIQUE INDEX "idx_compatacks_messageid" ON compat_acks (message_id);
|
||||
CREATE UNIQUE INDEX "idx_compatacks_userid_messageid" ON compat_acks (user_id, message_id);
|
||||
|
||||
|
||||
CREATE TABLE compat_clients
|
||||
(
|
||||
client_id TEXT NOT NULL
|
||||
) STRICT;
|
||||
CREATE UNIQUE INDEX "idx_compatclient_clientid" ON compat_clients (client_id);
|
||||
|
||||
|
||||
CREATE TABLE `meta`
|
||||
(
|
||||
meta_key TEXT NOT NULL,
|
||||
value_int INTEGER NULL,
|
||||
value_txt TEXT NULL,
|
||||
value_real REAL NULL,
|
||||
value_blob BLOB NULL,
|
||||
|
||||
PRIMARY KEY (meta_key)
|
||||
) STRICT;
|
||||
|
||||
|
||||
INSERT INTO meta (meta_key, value_int) VALUES ('schema', 3)
|
20
scnserver/db/schema/primary_migration_3_4.ddl
Normal file
20
scnserver/db/schema/primary_migration_3_4.ddl
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
DROP INDEX idx_messages_owner_channel;
|
||||
|
||||
|
||||
DROP INDEX idx_messages_owner_channel_nc;
|
||||
|
||||
|
||||
DROP INDEX idx_messages_idempotency;
|
||||
CREATE UNIQUE INDEX "idx_messages_idempotency" ON messages (sender_user_id, usr_message_id COLLATE BINARY);
|
||||
|
||||
|
||||
DROP INDEX idx_messages_usedkey;
|
||||
CREATE INDEX "idx_messages_usedkey" ON messages (sender_user_id, used_key_id);
|
||||
|
||||
|
||||
ALTER TABLE messages DROP COLUMN owner_user_id;
|
||||
|
||||
|
||||
|
||||
|
97
scnserver/db/simplectx/simplecontext.go
Normal file
97
scnserver/db/simplectx/simplecontext.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package simplectx
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db"
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SimpleContext struct {
|
||||
inner context.Context
|
||||
cancelFunc context.CancelFunc
|
||||
cancelled bool
|
||||
transaction sq.Tx
|
||||
}
|
||||
|
||||
func CreateSimpleContext(innerCtx context.Context, cancelFn context.CancelFunc) *SimpleContext {
|
||||
return &SimpleContext{
|
||||
inner: innerCtx,
|
||||
cancelFunc: cancelFn,
|
||||
cancelled: false,
|
||||
transaction: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *SimpleContext) Deadline() (deadline time.Time, ok bool) {
|
||||
return sc.inner.Deadline()
|
||||
}
|
||||
|
||||
func (sc *SimpleContext) Done() <-chan struct{} {
|
||||
return sc.inner.Done()
|
||||
}
|
||||
|
||||
func (sc *SimpleContext) Err() error {
|
||||
return sc.inner.Err()
|
||||
}
|
||||
|
||||
func (sc *SimpleContext) Value(key any) any {
|
||||
return sc.inner.Value(key)
|
||||
}
|
||||
|
||||
func (sc *SimpleContext) Cancel() {
|
||||
sc.cancelled = true
|
||||
if sc.transaction != nil {
|
||||
log.Error().Msg("Rollback transaction")
|
||||
err := sc.transaction.Rollback()
|
||||
if err != nil {
|
||||
panic("failed to rollback transaction: " + err.Error())
|
||||
}
|
||||
sc.transaction = nil
|
||||
}
|
||||
if sc.cancelFunc != nil {
|
||||
sc.cancelFunc()
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *SimpleContext) GetOrCreateTransaction(db db.DatabaseImpl) (sq.Tx, error) {
|
||||
if sc.cancelled {
|
||||
return nil, errors.New("context cancelled")
|
||||
}
|
||||
if sc.transaction != nil {
|
||||
return sc.transaction, nil
|
||||
}
|
||||
tx, err := db.BeginTx(sc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sc.transaction = tx
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
func (sc *SimpleContext) CommitTransaction() error {
|
||||
if sc.transaction == nil {
|
||||
return nil
|
||||
}
|
||||
err := sc.transaction.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sc.transaction = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *SimpleContext) RollbackTransaction() {
|
||||
if sc.transaction == nil {
|
||||
return
|
||||
}
|
||||
err := sc.transaction.Rollback()
|
||||
if err != nil {
|
||||
log.Err(err).Stack().Msg("Failed to rollback transaction")
|
||||
panic(err)
|
||||
}
|
||||
sc.transaction = nil
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user