mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-15 12:27:59 +00:00
25dc7bfe72
# Which Problems Are Solved Cache implementation using a PGX connection pool. # How the Problems Are Solved Defines a new schema `cache` in the zitadel database. A table for string keys and a table for objects is defined. For postgreSQL, tables are unlogged and partitioned by cache name for performance. Cockroach does not have unlogged tables and partitioning is an enterprise feature that uses alternative syntax combined with sharding. Regular tables are used here. # Additional Changes - `postgres.Config` can return a pxg pool. See following discussion # Additional Context - Part of https://github.com/zitadel/zitadel/issues/8648 - Closes https://github.com/zitadel/zitadel/issues/8647 --------- Co-authored-by: Silvan <silvan.reusser@gmail.com>
95 lines
1.7 KiB
Go
95 lines
1.7 KiB
Go
package dialect
|
|
|
|
import (
|
|
"database/sql"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type Dialect struct {
|
|
Matcher Matcher
|
|
Config Connector
|
|
IsDefault bool
|
|
}
|
|
|
|
var (
|
|
dialects []*Dialect
|
|
defaultDialect *Dialect
|
|
dialectsMu sync.Mutex
|
|
)
|
|
|
|
type Matcher interface {
|
|
MatchName(string) bool
|
|
Decode([]interface{}) (Connector, error)
|
|
}
|
|
|
|
const (
|
|
QueryAppName = "zitadel_queries"
|
|
EventstorePusherAppName = "zitadel_es_pusher"
|
|
ProjectionSpoolerAppName = "zitadel_projection_spooler"
|
|
defaultAppName = "zitadel"
|
|
)
|
|
|
|
// DBPurpose is what the resulting connection pool is used for.
|
|
type DBPurpose int
|
|
|
|
const (
|
|
DBPurposeQuery DBPurpose = iota
|
|
DBPurposeEventPusher
|
|
DBPurposeProjectionSpooler
|
|
)
|
|
|
|
func (p DBPurpose) AppName() string {
|
|
switch p {
|
|
case DBPurposeQuery:
|
|
return QueryAppName
|
|
case DBPurposeEventPusher:
|
|
return EventstorePusherAppName
|
|
case DBPurposeProjectionSpooler:
|
|
return ProjectionSpoolerAppName
|
|
default:
|
|
return defaultAppName
|
|
}
|
|
}
|
|
|
|
type Connector interface {
|
|
Connect(useAdmin bool, pusherRatio, spoolerRatio float64, purpose DBPurpose) (*sql.DB, *pgxpool.Pool, error)
|
|
Password() string
|
|
Database
|
|
}
|
|
|
|
type Database interface {
|
|
DatabaseName() string
|
|
Username() string
|
|
Type() string
|
|
Timetravel(time.Duration) string
|
|
}
|
|
|
|
func Register(matcher Matcher, config Connector, isDefault bool) {
|
|
dialectsMu.Lock()
|
|
defer dialectsMu.Unlock()
|
|
|
|
d := &Dialect{Matcher: matcher, Config: config}
|
|
|
|
if isDefault {
|
|
defaultDialect = d
|
|
return
|
|
}
|
|
|
|
dialects = append(dialects, d)
|
|
}
|
|
|
|
func SelectByConfig(config map[string]interface{}) *Dialect {
|
|
for key := range config {
|
|
for _, d := range dialects {
|
|
if d.Matcher.MatchName(key) {
|
|
return d
|
|
}
|
|
}
|
|
}
|
|
|
|
return defaultDialect
|
|
}
|