diff --git a/.all-contributorsrc b/.all-contributorsrc
index d6101a9da1..dee87b2a16 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -240,6 +240,15 @@
"contributions": [
"design"
]
+ },
+ {
+ "login": "dstotijn",
+ "name": "David Stotijn",
+ "avatar_url": "https://avatars.githubusercontent.com/u/983924?v=4",
+ "profile": "https://v0x.nl",
+ "contributions": [
+ "code"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 54568e9798..5d2ada11ac 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -6,7 +6,7 @@ monorepo:
builds:
- main: ./cmd/flipt/.
ldflags:
- - -s -w -X main.version={{ .Version }} -X main.commit={{ .Commit }} -X main.date={{ .Date }} -X main.analyticsKey={{ .Env.ANALYTICS_KEY }}
+ - -s -w -X main.version={{ .PrefixedTag }} -X main.commit={{ .Commit }} -X main.date={{ .Date }} -X main.analyticsKey={{ .Env.ANALYTICS_KEY }}
- -linkmode external -extldflags -static
goos:
- linux
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd57b4c59f..42fba1e7cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,24 @@
This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [v1.23.1](https://github.com/flipt-io/flipt/releases/tag/v1.23.1) - 2023-06-15
+
+### Added
+
+- Ability to configure use of prepared statements (for enabling PGBouncer) (#1750)
+- `telemetry`: track storage type and experimental features (#1745)
+
+### Changed
+
+- Dependency updates
+
+### Fixed
+
+- `storage/sql`: set binary_parameters=yes for lib/pq when prepared statements disabled (#1753)
+- UI: input bg / text in darkmode (#1752)
+- count rules was not taking flagKey into account (#1738)
+- tag prefix for build info/release links (#1757)
+
## [v1.23.0](https://github.com/flipt-io/flipt/releases/tag/v1.23.0) - 2023-06-12
### Added
diff --git a/README.md b/README.md
index 3116c533f9..52851f55a0 100644
--- a/README.md
+++ b/README.md
@@ -316,6 +316,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Darin McLain 💻 |
Adam Weiss 💡 |
Yuval Goihberg 🎨 |
+ David Stotijn 💻 |
diff --git a/cmd/flipt/server.go b/cmd/flipt/server.go
index e6a15d804f..c20f0ae93b 100644
--- a/cmd/flipt/server.go
+++ b/cmd/flipt/server.go
@@ -25,15 +25,19 @@ func fliptServer(logger *zap.Logger, cfg *config.Config) (*server.Server, func()
return nil, nil, fmt.Errorf("opening db: %w", err)
}
+ logger.Debug("constructing builder", zap.Bool("prepared_statements", cfg.Database.PreparedStatementsEnabled))
+
+ builder := sql.BuilderFor(db, driver, cfg.Database.PreparedStatementsEnabled)
+
var store storage.Store
switch driver {
case sql.SQLite:
- store = sqlite.NewStore(db, logger)
+ store = sqlite.NewStore(db, builder, logger)
case sql.Postgres, sql.CockroachDB:
- store = postgres.NewStore(db, logger)
+ store = postgres.NewStore(db, builder, logger)
case sql.MySQL:
- store = mysql.NewStore(db, logger)
+ store = mysql.NewStore(db, builder, logger)
}
return server.New(logger, store), func() { _ = db.Close() }, nil
diff --git a/config/flipt.schema.cue b/config/flipt.schema.cue
index 8e5be8dea6..f0da6d312c 100644
--- a/config/flipt.schema.cue
+++ b/config/flipt.schema.cue
@@ -101,6 +101,7 @@ import "strings"
max_idle_conn?: int | *2
max_open_conn?: int
conn_max_lifetime?: int
+ prepared_statements_enabled?: boolean | *true
}
_#lower: ["debug", "error", "fatal", "info", "panic", "trace", "warn"]
diff --git a/config/flipt.schema.json b/config/flipt.schema.json
index b23c33e189..f3cde86083 100644
--- a/config/flipt.schema.json
+++ b/config/flipt.schema.json
@@ -325,6 +325,9 @@
},
"conn_max_lifetime": {
"type": "integer"
+ },
+ "prepared_statements_enabled": {
+ "type": "boolean"
}
},
"required": [],
diff --git a/internal/cmd/auth.go b/internal/cmd/auth.go
index 7f933fb13f..bc6d600b6c 100644
--- a/internal/cmd/auth.go
+++ b/internal/cmd/auth.go
@@ -20,7 +20,6 @@ import (
"go.flipt.io/flipt/internal/storage/auth/memory"
authsql "go.flipt.io/flipt/internal/storage/auth/sql"
oplocksql "go.flipt.io/flipt/internal/storage/oplock/sql"
- fliptsql "go.flipt.io/flipt/internal/storage/sql"
rpcauth "go.flipt.io/flipt/rpc/flipt/auth"
"go.uber.org/zap"
"google.golang.org/grpc"
@@ -43,18 +42,17 @@ func authenticationGRPC(
}, nil, func(ctx context.Context) error { return nil }, nil
}
- db, driver, shutdown, err := getDB(ctx, logger, cfg, forceMigrate)
+ _, builder, driver, shutdown, err := getDB(ctx, logger, cfg, forceMigrate)
if err != nil {
return nil, nil, nil, err
}
var (
- authCfg = cfg.Authentication
- sqlBuilder = fliptsql.BuilderFor(db, driver)
- store = authsql.NewStore(driver, sqlBuilder, logger)
- oplock = oplocksql.New(logger, driver, sqlBuilder)
- public = public.NewServer(logger, authCfg)
- register = grpcRegisterers{
+ authCfg = cfg.Authentication
+ store = authsql.NewStore(driver, builder, logger)
+ oplock = oplocksql.New(logger, driver, builder)
+ public = public.NewServer(logger, authCfg)
+ register = grpcRegisterers{
public,
auth.NewServer(logger, store, auth.WithAuditLoggingEnabled(cfg.Audit.Enabled())),
}
diff --git a/internal/cmd/grpc.go b/internal/cmd/grpc.go
index dc214ef535..9f6598fbeb 100644
--- a/internal/cmd/grpc.go
+++ b/internal/cmd/grpc.go
@@ -10,6 +10,7 @@ import (
"sync"
"time"
+ sq "github.com/Masterminds/squirrel"
"go.flipt.io/flipt/internal/config"
"go.flipt.io/flipt/internal/containers"
"go.flipt.io/flipt/internal/info"
@@ -116,7 +117,7 @@ func NewGRPCServer(
switch cfg.Storage.Type {
case "", config.DatabaseStorageType:
- db, driver, shutdown, err := getDB(ctx, logger, cfg, forceMigrate)
+ db, builder, driver, shutdown, err := getDB(ctx, logger, cfg, forceMigrate)
if err != nil {
return nil, err
}
@@ -125,11 +126,11 @@ func NewGRPCServer(
switch driver {
case fliptsql.SQLite:
- store = sqlite.NewStore(db, logger)
+ store = sqlite.NewStore(db, builder, logger)
case fliptsql.Postgres, fliptsql.CockroachDB:
- store = postgres.NewStore(db, logger)
+ store = postgres.NewStore(db, builder, logger)
case fliptsql.MySQL:
- store = mysql.NewStore(db, logger)
+ store = mysql.NewStore(db, builder, logger)
default:
return nil, fmt.Errorf("unsupported driver: %s", driver)
}
@@ -390,14 +391,15 @@ func (s *GRPCServer) onShutdown(fn errFunc) {
}
var (
- once sync.Once
- db *sql.DB
- driver fliptsql.Driver
- dbFunc errFunc = func(context.Context) error { return nil }
- dbErr error
+ once sync.Once
+ db *sql.DB
+ builder sq.StatementBuilderType
+ driver fliptsql.Driver
+ dbFunc errFunc = func(context.Context) error { return nil }
+ dbErr error
)
-func getDB(ctx context.Context, logger *zap.Logger, cfg *config.Config, forceMigrate bool) (*sql.DB, fliptsql.Driver, errFunc, error) {
+func getDB(ctx context.Context, logger *zap.Logger, cfg *config.Config, forceMigrate bool) (*sql.DB, sq.StatementBuilderType, fliptsql.Driver, errFunc, error) {
once.Do(func() {
migrator, err := fliptsql.NewMigrator(*cfg, logger)
if err != nil {
@@ -419,6 +421,10 @@ func getDB(ctx context.Context, logger *zap.Logger, cfg *config.Config, forceMig
return
}
+ logger.Debug("constructing builder", zap.Bool("prepared_statements", cfg.Database.PreparedStatementsEnabled))
+
+ builder = fliptsql.BuilderFor(db, driver, cfg.Database.PreparedStatementsEnabled)
+
dbFunc = func(context.Context) error {
return db.Close()
}
@@ -432,5 +438,5 @@ func getDB(ctx context.Context, logger *zap.Logger, cfg *config.Config, forceMig
}
})
- return db, driver, dbFunc, dbErr
+ return db, builder, driver, dbFunc, dbErr
}
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index 0a56e62a79..9bc1908d7d 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -261,8 +261,9 @@ func defaultConfig() *Config {
},
Database: DatabaseConfig{
- URL: "file:/var/opt/flipt/flipt.db",
- MaxIdleConn: 2,
+ URL: "file:/var/opt/flipt/flipt.db",
+ MaxIdleConn: 2,
+ PreparedStatementsEnabled: true,
},
Meta: MetaConfig{
@@ -419,13 +420,14 @@ func TestLoad(t *testing.T) {
expected: func() *Config {
cfg := defaultConfig()
cfg.Database = DatabaseConfig{
- Protocol: DatabaseMySQL,
- Host: "localhost",
- Port: 3306,
- User: "flipt",
- Password: "s3cr3t!",
- Name: "flipt",
- MaxIdleConn: 2,
+ Protocol: DatabaseMySQL,
+ Host: "localhost",
+ Port: 3306,
+ User: "flipt",
+ Password: "s3cr3t!",
+ Name: "flipt",
+ MaxIdleConn: 2,
+ PreparedStatementsEnabled: true,
}
return cfg
},
@@ -591,10 +593,11 @@ func TestLoad(t *testing.T) {
Type: StorageType("database"),
}
cfg.Database = DatabaseConfig{
- URL: "postgres://postgres@localhost:5432/flipt?sslmode=disable",
- MaxIdleConn: 10,
- MaxOpenConn: 50,
- ConnMaxLifetime: 30 * time.Minute,
+ URL: "postgres://postgres@localhost:5432/flipt?sslmode=disable",
+ MaxIdleConn: 10,
+ MaxOpenConn: 50,
+ ConnMaxLifetime: 30 * time.Minute,
+ PreparedStatementsEnabled: true,
}
cfg.Meta = MetaConfig{
CheckForUpdates: false,
diff --git a/internal/config/database.go b/internal/config/database.go
index fdcb59b61b..db44603967 100644
--- a/internal/config/database.go
+++ b/internal/config/database.go
@@ -27,16 +27,17 @@ const (
//
// Flipt currently supports SQLite, Postgres and MySQL backends.
type DatabaseConfig struct {
- URL string `json:"url,omitempty" mapstructure:"url"`
- MaxIdleConn int `json:"maxIdleConn,omitempty" mapstructure:"max_idle_conn"`
- MaxOpenConn int `json:"maxOpenConn,omitempty" mapstructure:"max_open_conn"`
- ConnMaxLifetime time.Duration `json:"connMaxLifetime,omitempty" mapstructure:"conn_max_lifetime"`
- Name string `json:"name,omitempty" mapstructure:"name"`
- User string `json:"user,omitempty" mapstructure:"user"`
- Password string `json:"password,omitempty" mapstructure:"password"`
- Host string `json:"host,omitempty" mapstructure:"host"`
- Port int `json:"port,omitempty" mapstructure:"port"`
- Protocol DatabaseProtocol `json:"protocol,omitempty" mapstructure:"protocol"`
+ URL string `json:"url,omitempty" mapstructure:"url"`
+ MaxIdleConn int `json:"maxIdleConn,omitempty" mapstructure:"max_idle_conn"`
+ MaxOpenConn int `json:"maxOpenConn,omitempty" mapstructure:"max_open_conn"`
+ ConnMaxLifetime time.Duration `json:"connMaxLifetime,omitempty" mapstructure:"conn_max_lifetime"`
+ Name string `json:"name,omitempty" mapstructure:"name"`
+ User string `json:"user,omitempty" mapstructure:"user"`
+ Password string `json:"password,omitempty" mapstructure:"password"`
+ Host string `json:"host,omitempty" mapstructure:"host"`
+ Port int `json:"port,omitempty" mapstructure:"port"`
+ Protocol DatabaseProtocol `json:"protocol,omitempty" mapstructure:"protocol"`
+ PreparedStatementsEnabled bool `json:"preparedStatementsEnabled,omitempty" mapstructure:"prepared_statements_enabled"`
}
func (c *DatabaseConfig) setDefaults(v *viper.Viper) {
@@ -54,6 +55,8 @@ func (c *DatabaseConfig) setDefaults(v *viper.Viper) {
if setDefaultURL {
v.SetDefault("db.url", "file:/var/opt/flipt/flipt.db")
}
+
+ v.SetDefault("db.prepared_statements_enabled", true)
}
func (c *DatabaseConfig) deprecations(v *viper.Viper) []deprecation {
diff --git a/internal/storage/auth/sql/store_test.go b/internal/storage/auth/sql/store_test.go
index a1b3eddcdd..0faf8a71da 100644
--- a/internal/storage/auth/sql/store_test.go
+++ b/internal/storage/auth/sql/store_test.go
@@ -359,7 +359,7 @@ func newTestStore(t *testing.T, seed ...authentication) func(...Option) *Store {
storeFn = func(opts ...Option) *Store {
return NewStore(
db.Driver,
- storagesql.BuilderFor(db.DB, db.Driver),
+ storagesql.BuilderFor(db.DB, db.Driver, true),
logger,
opts...,
)
diff --git a/internal/storage/oplock/sql/sql_test.go b/internal/storage/oplock/sql/sql_test.go
index 3ed7defe02..cf1d24bd0e 100644
--- a/internal/storage/oplock/sql/sql_test.go
+++ b/internal/storage/oplock/sql/sql_test.go
@@ -21,6 +21,6 @@ func Test_Harness(t *testing.T) {
New(
logger,
db.Driver,
- storagesql.BuilderFor(db.DB, db.Driver),
+ storagesql.BuilderFor(db.DB, db.Driver, true),
))
}
diff --git a/internal/storage/sql/db.go b/internal/storage/sql/db.go
index a716e8a253..72c63f961e 100644
--- a/internal/storage/sql/db.go
+++ b/internal/storage/sql/db.go
@@ -39,8 +39,13 @@ func Open(cfg config.Config, opts ...Option) (*sql.DB, Driver, error) {
// BuilderFor returns a squirrel statement builder which decorates
// the provided sql.DB configured for the provided driver.
-func BuilderFor(db *sql.DB, driver Driver) sq.StatementBuilderType {
- builder := sq.StatementBuilder.RunWith(sq.NewStmtCacher(db))
+func BuilderFor(db *sql.DB, driver Driver, preparedStatementsEnabled bool) sq.StatementBuilderType {
+ var brdb sq.BaseRunner = db
+ if preparedStatementsEnabled {
+ brdb = sq.NewStmtCacher(db)
+ }
+
+ builder := sq.StatementBuilder.RunWith(brdb)
if driver == Postgres || driver == CockroachDB {
builder = builder.PlaceholderFormat(sq.Dollar)
}
@@ -203,36 +208,32 @@ func parse(cfg config.Config, opts Options) (Driver, *dburl.URL, error) {
return 0, nil, fmt.Errorf("unknown database driver for: %q", url.Driver)
}
+ v := url.Query()
switch driver {
case Postgres, CockroachDB:
if opts.sslDisabled {
- v := url.Query()
v.Set("sslmode", "disable")
- url.RawQuery = v.Encode()
- // we need to re-parse since we modified the query params
- url, err = dburl.Parse(url.URL.String())
+ }
+
+ // see: https://github.com/lib/pq/issues/389
+ if !cfg.Database.PreparedStatementsEnabled {
+ v.Set("binary_parameters", "yes")
}
case MySQL:
- v := url.Query()
v.Set("multiStatements", "true")
v.Set("parseTime", "true")
if !opts.migrate {
v.Set("sql_mode", "ANSI")
}
- url.RawQuery = v.Encode()
- // we need to re-parse since we modified the query params
- url, err = dburl.Parse(url.URL.String())
-
case SQLite:
- v := url.Query()
v.Set("cache", "shared")
v.Set("mode", "rwc")
v.Set("_fk", "true")
- url.RawQuery = v.Encode()
-
- // we need to re-parse since we modified the query params
- url, err = dburl.Parse(url.URL.String())
}
+ url.RawQuery = v.Encode()
+ // we need to re-parse since we modified the query params
+ url, err = dburl.Parse(url.URL.String())
+
return driver, url, err
}
diff --git a/internal/storage/sql/db_internal_test.go b/internal/storage/sql/db_internal_test.go
index 037754b981..66fdcf1f2c 100644
--- a/internal/storage/sql/db_internal_test.go
+++ b/internal/storage/sql/db_internal_test.go
@@ -34,13 +34,22 @@ func TestParse(t *testing.T) {
driver: SQLite,
dsn: "flipt.db?_fk=true&cache=shared&mode=rwc",
},
+ {
+ name: "postgres url prepared statements enabled",
+ cfg: config.DatabaseConfig{
+ URL: "postgres://postgres@localhost:5432/flipt?sslmode=disable",
+ PreparedStatementsEnabled: true,
+ },
+ driver: Postgres,
+ dsn: "dbname=flipt host=localhost port=5432 sslmode=disable user=postgres",
+ },
{
name: "postgres url",
cfg: config.DatabaseConfig{
URL: "postgres://postgres@localhost:5432/flipt?sslmode=disable",
},
driver: Postgres,
- dsn: "dbname=flipt host=localhost port=5432 sslmode=disable user=postgres",
+ dsn: "binary_parameters=yes dbname=flipt host=localhost port=5432 sslmode=disable user=postgres",
},
{
name: "postgres no disable sslmode",
@@ -48,7 +57,7 @@ func TestParse(t *testing.T) {
URL: "postgres://postgres@localhost:5432/flipt",
},
driver: Postgres,
- dsn: "dbname=flipt host=localhost port=5432 user=postgres",
+ dsn: "binary_parameters=yes dbname=flipt host=localhost port=5432 user=postgres",
},
{
name: "postgres disable sslmode via opts",
@@ -61,7 +70,7 @@ func TestParse(t *testing.T) {
},
options: []Option{WithSSLDisabled},
driver: Postgres,
- dsn: "dbname=flipt host=localhost port=5432 sslmode=disable user=postgres",
+ dsn: "binary_parameters=yes dbname=flipt host=localhost port=5432 sslmode=disable user=postgres",
},
{
name: "postgres no port",
@@ -72,7 +81,7 @@ func TestParse(t *testing.T) {
User: "postgres",
},
driver: Postgres,
- dsn: "dbname=flipt host=localhost user=postgres",
+ dsn: "binary_parameters=yes dbname=flipt host=localhost user=postgres",
},
{
name: "postgres no password",
@@ -84,7 +93,7 @@ func TestParse(t *testing.T) {
User: "postgres",
},
driver: Postgres,
- dsn: "dbname=flipt host=localhost port=5432 user=postgres",
+ dsn: "binary_parameters=yes dbname=flipt host=localhost port=5432 user=postgres",
},
{
name: "postgres with password",
@@ -97,7 +106,7 @@ func TestParse(t *testing.T) {
Password: "foo",
},
driver: Postgres,
- dsn: "dbname=flipt host=localhost password=foo port=5432 user=postgres",
+ dsn: "binary_parameters=yes dbname=flipt host=localhost password=foo port=5432 user=postgres",
},
{
name: "mysql url",
@@ -159,13 +168,22 @@ func TestParse(t *testing.T) {
driver: MySQL,
dsn: "mysql:foo@tcp(localhost:3306)/flipt?multiStatements=true&parseTime=true&sql_mode=ANSI",
},
+ {
+ name: "cockroachdb url prepared statements enabled",
+ cfg: config.DatabaseConfig{
+ URL: "cockroachdb://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ PreparedStatementsEnabled: true,
+ },
+ driver: CockroachDB,
+ dsn: "postgres://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ },
{
name: "cockroachdb url",
cfg: config.DatabaseConfig{
URL: "cockroachdb://cockroachdb@localhost:26257/flipt?sslmode=disable",
},
driver: CockroachDB,
- dsn: "postgres://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ dsn: "postgres://cockroachdb@localhost:26257/flipt?binary_parameters=yes&sslmode=disable",
},
{
name: "cockroachdb url alternative (cockroach://",
@@ -173,7 +191,7 @@ func TestParse(t *testing.T) {
URL: "cockroach://cockroachdb@localhost:26257/flipt?sslmode=disable",
},
driver: CockroachDB,
- dsn: "postgres://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ dsn: "postgres://cockroachdb@localhost:26257/flipt?binary_parameters=yes&sslmode=disable",
},
{
name: "cockroachdb url alternative (crdb://",
@@ -181,7 +199,7 @@ func TestParse(t *testing.T) {
URL: "crdb://cockroachdb@localhost:26257/flipt?sslmode=disable",
},
driver: CockroachDB,
- dsn: "postgres://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ dsn: "postgres://cockroachdb@localhost:26257/flipt?binary_parameters=yes&sslmode=disable",
},
{
name: "cockroachdb default disable sslmode",
@@ -191,7 +209,7 @@ func TestParse(t *testing.T) {
URL: "cockroachdb://cockroachdb@localhost:26257/flipt",
},
driver: CockroachDB,
- dsn: "postgres://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ dsn: "postgres://cockroachdb@localhost:26257/flipt?binary_parameters=yes&sslmode=disable",
},
{
name: "cockroachdb disable sslmode via opts",
@@ -206,7 +224,7 @@ func TestParse(t *testing.T) {
WithSSLDisabled,
},
driver: CockroachDB,
- dsn: "postgres://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ dsn: "postgres://cockroachdb@localhost:26257/flipt?binary_parameters=yes&sslmode=disable",
},
{
name: "cockroachdb no port",
@@ -217,7 +235,7 @@ func TestParse(t *testing.T) {
User: "cockroachdb",
},
driver: CockroachDB,
- dsn: "postgres://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ dsn: "postgres://cockroachdb@localhost:26257/flipt?binary_parameters=yes&sslmode=disable",
},
{
name: "cockroachdb no password",
@@ -229,7 +247,7 @@ func TestParse(t *testing.T) {
User: "cockroachdb",
},
driver: CockroachDB,
- dsn: "postgres://cockroachdb@localhost:26257/flipt?sslmode=disable",
+ dsn: "postgres://cockroachdb@localhost:26257/flipt?binary_parameters=yes&sslmode=disable",
},
{
name: "cockroachdb with password",
@@ -242,7 +260,7 @@ func TestParse(t *testing.T) {
Password: "foo",
},
driver: CockroachDB,
- dsn: "postgres://cockroachdb:foo@localhost:26257/flipt?sslmode=disable",
+ dsn: "postgres://cockroachdb:foo@localhost:26257/flipt?binary_parameters=yes&sslmode=disable",
},
{
name: "invalid url",
diff --git a/internal/storage/sql/db_test.go b/internal/storage/sql/db_test.go
index 943be09786..84c8e0eea6 100644
--- a/internal/storage/sql/db_test.go
+++ b/internal/storage/sql/db_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"time"
+ sq "github.com/Masterminds/squirrel"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
@@ -134,15 +135,17 @@ func (s *DBTestSuite) SetupSuite() {
s.db = db
+ builder := sq.StatementBuilder.RunWith(sq.NewStmtCacher(db.DB))
+
var store storage.Store
switch db.Driver {
case fliptsql.SQLite:
- store = sqlite.NewStore(db.DB, logger)
+ store = sqlite.NewStore(db.DB, builder, logger)
case fliptsql.Postgres, fliptsql.CockroachDB:
- store = postgres.NewStore(db.DB, logger)
+ store = postgres.NewStore(db.DB, builder, logger)
case fliptsql.MySQL:
- store = mysql.NewStore(db.DB, logger)
+ store = mysql.NewStore(db.DB, builder, logger)
}
namespace := randomString(6)
diff --git a/internal/storage/sql/mysql/mysql.go b/internal/storage/sql/mysql/mysql.go
index bce01fb581..a99d010920 100644
--- a/internal/storage/sql/mysql/mysql.go
+++ b/internal/storage/sql/mysql/mysql.go
@@ -22,9 +22,7 @@ const (
var _ storage.Store = &Store{}
-func NewStore(db *sql.DB, logger *zap.Logger) *Store {
- builder := sq.StatementBuilder.RunWith(sq.NewStmtCacher(db))
-
+func NewStore(db *sql.DB, builder sq.StatementBuilderType, logger *zap.Logger) *Store {
return &Store{
Store: common.NewStore(db, builder, logger),
}
diff --git a/internal/storage/sql/postgres/postgres.go b/internal/storage/sql/postgres/postgres.go
index c2a0b28cfd..0d856fc29e 100644
--- a/internal/storage/sql/postgres/postgres.go
+++ b/internal/storage/sql/postgres/postgres.go
@@ -22,11 +22,9 @@ const (
var _ storage.Store = &Store{}
-func NewStore(db *sql.DB, logger *zap.Logger) *Store {
- builder := sq.StatementBuilder.PlaceholderFormat(sq.Dollar).RunWith(sq.NewStmtCacher(db))
-
+func NewStore(db *sql.DB, builder sq.StatementBuilderType, logger *zap.Logger) *Store {
return &Store{
- Store: common.NewStore(db, builder, logger),
+ Store: common.NewStore(db, builder.PlaceholderFormat(sq.Dollar), logger),
}
}
diff --git a/internal/storage/sql/sqlite/sqlite.go b/internal/storage/sql/sqlite/sqlite.go
index ce27262608..79f6c10492 100644
--- a/internal/storage/sql/sqlite/sqlite.go
+++ b/internal/storage/sql/sqlite/sqlite.go
@@ -18,9 +18,7 @@ import (
var _ storage.Store = &Store{}
// NewStore creates a new sqlite.Store
-func NewStore(db *sql.DB, logger *zap.Logger) *Store {
- builder := sq.StatementBuilder.RunWith(sq.NewStmtCacher(db))
-
+func NewStore(db *sql.DB, builder sq.StatementBuilderType, logger *zap.Logger) *Store {
return &Store{
Store: common.NewStore(db, builder, logger),
}
diff --git a/ui/package-lock.json b/ui/package-lock.json
index d6133e6356..e3dc78db22 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -22,7 +22,7 @@
"buffer": "^6.0.3",
"date-fns": "^2.30.0",
"dotenv": "^16.1.4",
- "formik": "^2.4.1",
+ "formik": "^2.4.2",
"highlight.js": "^11.8.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
@@ -31,7 +31,7 @@
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
"react-redux": "^8.0.7",
- "react-router-dom": "^6.12.1",
+ "react-router-dom": "^6.13.0",
"swr": "^2.1.5",
"uuid": "^9.0.0",
"yup": "^0.32.11"
@@ -7030,9 +7030,9 @@
}
},
"node_modules/formik": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.1.tgz",
- "integrity": "sha512-ajOB9EmFhXb4PACTlaooVEn7PLtLtBJEZ8fPs+wFZjL5KSGwgAoU+n9DHN8JcqNKcXkloEYYtn1lxrLav18ecQ==",
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.2.tgz",
+ "integrity": "sha512-C6nx0hifW2uENP3M6HpPmnAE6HFWCcd8/sqBZEOHZY6lpHJ5qehsfAy43ktpFLEmkBmhiZDei726utcUB9leqg==",
"funding": [
{
"type": "individual",
@@ -7046,17 +7046,12 @@
"lodash-es": "^4.17.21",
"react-fast-compare": "^2.0.1",
"tiny-warning": "^1.0.2",
- "tslib": "^1.10.0"
+ "tslib": "^2.0.0"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
- "node_modules/formik/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
"node_modules/fraction.js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@@ -10899,9 +10894,9 @@
}
},
"node_modules/react-router": {
- "version": "6.12.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.12.1.tgz",
- "integrity": "sha512-evd/GrKJOeOypD0JB9e1r7pQh2gWCsTbUfq059Wm1AFT/K2MNZuDo19lFtAgIhlBrp0MmpgpqtvZC7LPAs7vSw==",
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.13.0.tgz",
+ "integrity": "sha512-Si6KnfEnJw7gUQkNa70dlpI1bul46FuSxX5t5WwlUBxE25DAz2BjVkwaK8Y2s242bQrZPXCpmwLPtIO5pv4tXg==",
"dependencies": {
"@remix-run/router": "1.6.3"
},
@@ -10913,12 +10908,12 @@
}
},
"node_modules/react-router-dom": {
- "version": "6.12.1",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.12.1.tgz",
- "integrity": "sha512-POIZN9UDKWwEDga054LvYr2KnK8V+0HR4Ny4Bwv8V7/FZCPxJgsCjYxXGxqxzHs7VBxMKZfgvtKhafuJkJSPGA==",
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.13.0.tgz",
+ "integrity": "sha512-6Nqoqd7fgwxxVGdbiMHTpDHCYPq62d7Wk1Of7B82vH7ZPwwsRaIa22zRZKPPg413R5REVNiyuQPKDG1bubcOFA==",
"dependencies": {
"@remix-run/router": "1.6.3",
- "react-router": "6.12.1"
+ "react-router": "6.13.0"
},
"engines": {
"node": ">=14"
@@ -17260,9 +17255,9 @@
}
},
"formik": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.1.tgz",
- "integrity": "sha512-ajOB9EmFhXb4PACTlaooVEn7PLtLtBJEZ8fPs+wFZjL5KSGwgAoU+n9DHN8JcqNKcXkloEYYtn1lxrLav18ecQ==",
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.2.tgz",
+ "integrity": "sha512-C6nx0hifW2uENP3M6HpPmnAE6HFWCcd8/sqBZEOHZY6lpHJ5qehsfAy43ktpFLEmkBmhiZDei726utcUB9leqg==",
"requires": {
"deepmerge": "^2.1.1",
"hoist-non-react-statics": "^3.3.0",
@@ -17270,14 +17265,7 @@
"lodash-es": "^4.17.21",
"react-fast-compare": "^2.0.1",
"tiny-warning": "^1.0.2",
- "tslib": "^1.10.0"
- },
- "dependencies": {
- "tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- }
+ "tslib": "^2.0.0"
}
},
"fraction.js": {
@@ -19949,20 +19937,20 @@
"dev": true
},
"react-router": {
- "version": "6.12.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.12.1.tgz",
- "integrity": "sha512-evd/GrKJOeOypD0JB9e1r7pQh2gWCsTbUfq059Wm1AFT/K2MNZuDo19lFtAgIhlBrp0MmpgpqtvZC7LPAs7vSw==",
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.13.0.tgz",
+ "integrity": "sha512-Si6KnfEnJw7gUQkNa70dlpI1bul46FuSxX5t5WwlUBxE25DAz2BjVkwaK8Y2s242bQrZPXCpmwLPtIO5pv4tXg==",
"requires": {
"@remix-run/router": "1.6.3"
}
},
"react-router-dom": {
- "version": "6.12.1",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.12.1.tgz",
- "integrity": "sha512-POIZN9UDKWwEDga054LvYr2KnK8V+0HR4Ny4Bwv8V7/FZCPxJgsCjYxXGxqxzHs7VBxMKZfgvtKhafuJkJSPGA==",
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.13.0.tgz",
+ "integrity": "sha512-6Nqoqd7fgwxxVGdbiMHTpDHCYPq62d7Wk1Of7B82vH7ZPwwsRaIa22zRZKPPg413R5REVNiyuQPKDG1bubcOFA==",
"requires": {
"@remix-run/router": "1.6.3",
- "react-router": "6.12.1"
+ "react-router": "6.13.0"
}
},
"react-side-effect": {
diff --git a/ui/package.json b/ui/package.json
index 39be78d56d..dc049188cb 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -26,7 +26,7 @@
"buffer": "^6.0.3",
"date-fns": "^2.30.0",
"dotenv": "^16.1.4",
- "formik": "^2.4.1",
+ "formik": "^2.4.2",
"highlight.js": "^11.8.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
@@ -35,7 +35,7 @@
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
"react-redux": "^8.0.7",
- "react-router-dom": "^6.12.1",
+ "react-router-dom": "^6.13.0",
"swr": "^2.1.5",
"uuid": "^9.0.0",
"yup": "^0.32.11"
diff --git a/ui/src/components/Footer.tsx b/ui/src/components/Footer.tsx
index 428cc78469..391c30b408 100644
--- a/ui/src/components/Footer.tsx
+++ b/ui/src/components/Footer.tsx
@@ -13,7 +13,7 @@ export default function Footer() {
const ref = () => {
if (info?.isRelease && info?.version) {
- return `v${info.version}`;
+ return info.version;
}
if (info?.commit) {
return info.commit.substring(0, 7);