diff --git a/appservice/appservice.go b/appservice/appservice.go index 594b537c4..e356f68ee 100644 --- a/appservice/appservice.go +++ b/appservice/appservice.go @@ -48,7 +48,7 @@ func NewInternalAPI( rsAPI roomserverAPI.RoomserverInternalAPI, ) appserviceAPI.AppServiceQueryAPI { // Create a connection to the appservice postgres DB - appserviceDB, err := storage.NewDatabase(string(base.Cfg.AppServiceAPI.Database), base.Cfg.AppServiceAPI.DatabaseOptions) + appserviceDB, err := storage.NewDatabase(&base.Cfg.AppServiceAPI.Database) if err != nil { logrus.WithError(err).Panicf("failed to connect to appservice db") } diff --git a/appservice/storage/postgres/storage.go b/appservice/storage/postgres/storage.go index 03f331d64..9fda87ae9 100644 --- a/appservice/storage/postgres/storage.go +++ b/appservice/storage/postgres/storage.go @@ -21,6 +21,7 @@ import ( // Import postgres database driver _ "github.com/lib/pq" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/gomatrixserverlib" ) @@ -34,10 +35,10 @@ type Database struct { } // NewDatabase opens a new database -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) { var result Database var err error - if result.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil { + if result.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } if err = result.prepare(); err != nil { diff --git a/appservice/storage/sqlite3/storage.go b/appservice/storage/sqlite3/storage.go index cb55c8d94..59af9016d 100644 --- a/appservice/storage/sqlite3/storage.go +++ b/appservice/storage/sqlite3/storage.go @@ -20,6 +20,7 @@ import ( "database/sql" // Import SQLite database driver + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/gomatrixserverlib" _ "github.com/mattn/go-sqlite3" @@ -34,14 +35,10 @@ type Database struct { } // NewDatabase opens a new database -func NewDatabase(dataSourceName string) (*Database, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) { var result Database var err error - cs, err := sqlutil.ParseFileURI(dataSourceName) - if err != nil { - return nil, err - } - if result.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil { + if result.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } if err = result.prepare(); err != nil { diff --git a/appservice/storage/storage.go b/appservice/storage/storage.go index c848d15d7..e2d7e4e54 100644 --- a/appservice/storage/storage.go +++ b/appservice/storage/storage.go @@ -17,26 +17,22 @@ package storage import ( - "net/url" + "fmt" "github.com/matrix-org/dendrite/appservice/storage/postgres" "github.com/matrix-org/dendrite/appservice/storage/sqlite3" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" ) // NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme) // and sets DB connection parameters -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.NewDatabase(dataSourceName, dbProperties) - } - switch uri.Scheme { - case "postgres": - return postgres.NewDatabase(dataSourceName, dbProperties) - case "file": - return sqlite3.NewDatabase(dataSourceName) +func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.NewDatabase(dbProperties) default: - return postgres.NewDatabase(dataSourceName, dbProperties) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/appservice/storage/storage_wasm.go b/appservice/storage/storage_wasm.go index 1d6c4b4a9..7eb7da26e 100644 --- a/appservice/storage/storage_wasm.go +++ b/appservice/storage/storage_wasm.go @@ -16,26 +16,18 @@ package storage import ( "fmt" - "net/url" "github.com/matrix-org/dendrite/appservice/storage/sqlite3" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" ) -func NewDatabase( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam -) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") - case "file": - return sqlite3.NewDatabase(dataSourceName) +func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/build/gobind/monolith.go b/build/gobind/monolith.go index b4585fe6b..e1380e4d3 100644 --- a/build/gobind/monolith.go +++ b/build/gobind/monolith.go @@ -92,15 +92,15 @@ func (m *DendriteMonolith) Start() { cfg.Global.Kafka.Topics.OutputTypingEvent = "typingServerOutput" cfg.Global.Kafka.Topics.OutputSendToDeviceEvent = "sendToDeviceOutput" cfg.Global.Kafka.Database = config.DataSource(fmt.Sprintf("file:%s/dendrite-naffka.db", m.StorageDirectory)) - cfg.UserAPI.AccountDatabase = config.DataSource(fmt.Sprintf("file:%s/dendrite-account.db", m.StorageDirectory)) - cfg.UserAPI.DeviceDatabase = config.DataSource(fmt.Sprintf("file:%s/dendrite-device.db", m.StorageDirectory)) - cfg.MediaAPI.Database = config.DataSource(fmt.Sprintf("file:%s/dendrite-mediaapi.db", m.StorageDirectory)) - cfg.SyncAPI.Database = config.DataSource(fmt.Sprintf("file:%s/dendrite-syncapi.db", m.StorageDirectory)) - cfg.RoomServer.Database = config.DataSource(fmt.Sprintf("file:%s/dendrite-roomserver.db", m.StorageDirectory)) - cfg.ServerKeyAPI.Database = config.DataSource(fmt.Sprintf("file:%s/dendrite-serverkey.db", m.StorageDirectory)) - cfg.FederationSender.Database = config.DataSource(fmt.Sprintf("file:%s/dendrite-federationsender.db", m.StorageDirectory)) - cfg.AppServiceAPI.Database = config.DataSource(fmt.Sprintf("file:%s/dendrite-appservice.db", m.StorageDirectory)) - cfg.CurrentStateServer.Database = config.DataSource(fmt.Sprintf("file:%s/dendrite-currentstate.db", m.StorageDirectory)) + cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-account.db", m.StorageDirectory)) + cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-device.db", m.StorageDirectory)) + cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-mediaapi.db", m.StorageDirectory)) + cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-syncapi.db", m.StorageDirectory)) + cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-roomserver.db", m.StorageDirectory)) + cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-serverkey.db", m.StorageDirectory)) + cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-federationsender.db", m.StorageDirectory)) + cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-appservice.db", m.StorageDirectory)) + cfg.CurrentStateServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-currentstate.db", m.StorageDirectory)) cfg.MediaAPI.BasePath = config.Path(fmt.Sprintf("%s/tmp", m.StorageDirectory)) cfg.MediaAPI.AbsBasePath = config.Path(fmt.Sprintf("%s/tmp", m.StorageDirectory)) cfg.FederationSender.FederationMaxRetries = 6 diff --git a/cmd/create-account/main.go b/cmd/create-account/main.go index ff022ec3c..73e223d61 100644 --- a/cmd/create-account/main.go +++ b/cmd/create-account/main.go @@ -20,6 +20,7 @@ import ( "fmt" "os" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/userapi/storage/accounts" "github.com/matrix-org/dendrite/userapi/storage/devices" "github.com/matrix-org/gomatrixserverlib" @@ -63,7 +64,9 @@ func main() { serverName := gomatrixserverlib.ServerName(*serverNameStr) - accountDB, err := accounts.NewDatabase(*database, nil, serverName) + accountDB, err := accounts.NewDatabase(&config.DatabaseOptions{ + ConnectionString: config.DataSource(*database), + }, serverName) if err != nil { fmt.Println(err.Error()) os.Exit(1) @@ -75,7 +78,9 @@ func main() { os.Exit(1) } - deviceDB, err := devices.NewDatabase(*database, nil, serverName) + deviceDB, err := devices.NewDatabase(&config.DatabaseOptions{ + ConnectionString: config.DataSource(*database), + }, serverName) if err != nil { fmt.Println(err.Error()) os.Exit(1) diff --git a/cmd/dendrite-demo-libp2p/main.go b/cmd/dendrite-demo-libp2p/main.go index d1f00c078..31e2f87fa 100644 --- a/cmd/dendrite-demo-libp2p/main.go +++ b/cmd/dendrite-demo-libp2p/main.go @@ -123,17 +123,17 @@ func main() { cfg.Global.Kafka.Topics.OutputSendToDeviceEvent = "sendToDeviceOutput" cfg.Global.Kafka.Topics.OutputKeyChangeEvent = "keyChangeOutput" cfg.FederationSender.FederationMaxRetries = 6 - cfg.UserAPI.AccountDatabase = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName)) - cfg.UserAPI.DeviceDatabase = config.DataSource(fmt.Sprintf("file:%s-device.db", *instanceName)) - cfg.MediaAPI.Database = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName)) - cfg.SyncAPI.Database = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName)) - cfg.RoomServer.Database = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName)) - cfg.ServerKeyAPI.Database = config.DataSource(fmt.Sprintf("file:%s-serverkey.db", *instanceName)) - cfg.FederationSender.Database = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName)) - cfg.AppServiceAPI.Database = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName)) - cfg.CurrentStateServer.Database = config.DataSource(fmt.Sprintf("file:%s-currentstate.db", *instanceName)) - cfg.Global.Kafka.Database = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName)) - cfg.KeyServer.Database = config.DataSource(fmt.Sprintf("file:%s-e2ekey.db", *instanceName)) + cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName)) + cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-device.db", *instanceName)) + cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName)) + cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName)) + cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName)) + cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-serverkey.db", *instanceName)) + cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName)) + cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName)) + cfg.CurrentStateServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-currentstate.db", *instanceName)) + cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName)) + cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-e2ekey.db", *instanceName)) if err = cfg.Derive(); err != nil { panic(err) } diff --git a/cmd/dendrite-demo-yggdrasil/main.go b/cmd/dendrite-demo-yggdrasil/main.go index d9cb8956b..1ab2f7b43 100644 --- a/cmd/dendrite-demo-yggdrasil/main.go +++ b/cmd/dendrite-demo-yggdrasil/main.go @@ -79,17 +79,17 @@ func main() { cfg.Global.Kafka.Topics.OutputSendToDeviceEvent = "sendToDeviceOutput" cfg.Global.Kafka.Topics.OutputKeyChangeEvent = "keyChangeOutput" cfg.FederationSender.FederationMaxRetries = 6 - cfg.UserAPI.AccountDatabase = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName)) - cfg.UserAPI.DeviceDatabase = config.DataSource(fmt.Sprintf("file:%s-device.db", *instanceName)) - cfg.MediaAPI.Database = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName)) - cfg.SyncAPI.Database = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName)) - cfg.RoomServer.Database = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName)) - cfg.ServerKeyAPI.Database = config.DataSource(fmt.Sprintf("file:%s-serverkey.db", *instanceName)) - cfg.FederationSender.Database = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName)) - cfg.AppServiceAPI.Database = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName)) - cfg.CurrentStateServer.Database = config.DataSource(fmt.Sprintf("file:%s-currentstate.db", *instanceName)) - cfg.Global.Kafka.Database = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName)) - cfg.KeyServer.Database = config.DataSource(fmt.Sprintf("file:%s-e2ekey.db", *instanceName)) + cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName)) + cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-device.db", *instanceName)) + cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName)) + cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName)) + cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName)) + cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-serverkey.db", *instanceName)) + cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName)) + cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName)) + cfg.CurrentStateServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-currentstate.db", *instanceName)) + cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName)) + cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-e2ekey.db", *instanceName)) if err = cfg.Derive(); err != nil { panic(err) } diff --git a/cmd/dendritejs/main.go b/cmd/dendritejs/main.go index 38b090be4..c9f2f181e 100644 --- a/cmd/dendritejs/main.go +++ b/cmd/dendritejs/main.go @@ -162,18 +162,18 @@ func createP2PNode(privKey ed25519.PrivateKey) (serverName string, node *go_http func main() { cfg := &config.Dendrite{} cfg.Defaults() - cfg.UserAPI.AccountDatabase = "file:/idb/dendritejs_account.db" - cfg.AppServiceAPI.Database = "file:/idb/dendritejs_appservice.db" - cfg.UserAPI.DeviceDatabase = "file:/idb/dendritejs_device.db" - cfg.FederationSender.Database = "file:/idb/dendritejs_fedsender.db" - cfg.MediaAPI.Database = "file:/idb/dendritejs_mediaapi.db" - cfg.RoomServer.Database = "file:/idb/dendritejs_roomserver.db" - cfg.ServerKeyAPI.Database = "file:/idb/dendritejs_serverkey.db" - cfg.SyncAPI.Database = "file:/idb/dendritejs_syncapi.db" - cfg.CurrentStateServer.Database = "file:/idb/dendritejs_currentstate.db" - cfg.KeyServer.Database = "file:/idb/dendritejs_e2ekey.db" + cfg.UserAPI.AccountDatabase.ConnectionString = "file:/idb/dendritejs_account.db" + cfg.AppServiceAPI.Database.ConnectionString = "file:/idb/dendritejs_appservice.db" + cfg.UserAPI.DeviceDatabase.ConnectionString = "file:/idb/dendritejs_device.db" + cfg.FederationSender.Database.ConnectionString = "file:/idb/dendritejs_fedsender.db" + cfg.MediaAPI.Database.ConnectionString = "file:/idb/dendritejs_mediaapi.db" + cfg.RoomServer.Database.ConnectionString = "file:/idb/dendritejs_roomserver.db" + cfg.ServerKeyAPI.Database.ConnectionString = "file:/idb/dendritejs_serverkey.db" + cfg.SyncAPI.Database.ConnectionString = "file:/idb/dendritejs_syncapi.db" + cfg.CurrentStateServer.Database.ConnectionString = "file:/idb/dendritejs_currentstate.db" + cfg.KeyServer.Database.ConnectionString = "file:/idb/dendritejs_e2ekey.db" cfg.Global.Kafka.UseNaffka = true - cfg.Global.Kafka.Database = "file:/idb/dendritejs_naffka.db" + cfg.Global.Kafka.Database.ConnectionString = "file:/idb/dendritejs_naffka.db" cfg.Global.Kafka.Topics.OutputTypingEvent = "output_typing_event" cfg.Global.Kafka.Topics.OutputSendToDeviceEvent = "output_send_to_device_event" cfg.Global.Kafka.Topics.OutputClientData = "output_client_data" diff --git a/currentstateserver/currentstateserver.go b/currentstateserver/currentstateserver.go index 8c9d5bc9c..8e985e84c 100644 --- a/currentstateserver/currentstateserver.go +++ b/currentstateserver/currentstateserver.go @@ -35,7 +35,7 @@ func AddInternalRoutes(router *mux.Router, intAPI api.CurrentStateInternalAPI) { // NewInternalAPI returns a concrete implementation of the internal API. Callers // can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes. func NewInternalAPI(cfg *config.CurrentStateServer, consumer sarama.Consumer) api.CurrentStateInternalAPI { - csDB, err := storage.NewDatabase(string(cfg.Database), cfg.DatabaseOptions) + csDB, err := storage.NewDatabase(&cfg.Database) if err != nil { logrus.WithError(err).Panicf("failed to open database") } diff --git a/currentstateserver/currentstateserver_test.go b/currentstateserver/currentstateserver_test.go index 12d599a2f..42751b2e3 100644 --- a/currentstateserver/currentstateserver_test.go +++ b/currentstateserver/currentstateserver_test.go @@ -97,8 +97,8 @@ func MustMakeInternalAPI(t *testing.T) (api.CurrentStateInternalAPI, sarama.Sync cfg.Defaults() cfg.Global.ServerName = "kaer.morhen" cfg.Global.Kafka.Topics.OutputRoomEvent = config.Topic(kafkaTopic) - cfg.CurrentStateServer.Database = config.DataSource("file::memory:") - db, err := sqlutil.Open(sqlutil.SQLiteDriverName(), "file::memory:", nil) + cfg.CurrentStateServer.Database.ConnectionString = config.DataSource("file::memory:") + db, err := sqlutil.Open(&cfg.CurrentStateServer.Database) if err != nil { t.Fatalf("Failed to open naffka database: %s", err) } diff --git a/currentstateserver/storage/postgres/storage.go b/currentstateserver/storage/postgres/storage.go index f8edb94e6..0cd7e5553 100644 --- a/currentstateserver/storage/postgres/storage.go +++ b/currentstateserver/storage/postgres/storage.go @@ -4,6 +4,7 @@ import ( "database/sql" "github.com/matrix-org/dendrite/currentstateserver/storage/shared" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" ) @@ -14,10 +15,10 @@ type Database struct { } // NewDatabase creates a new sync server database -func NewDatabase(dbDataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) { var d Database var err error - if d.db, err = sqlutil.Open("postgres", dbDataSourceName, dbProperties); err != nil { + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } if err = d.PartitionOffsetStatements.Prepare(d.db, "currentstate"); err != nil { diff --git a/currentstateserver/storage/sqlite3/storage.go b/currentstateserver/storage/sqlite3/storage.go index 6975e40ba..4454c9ed7 100644 --- a/currentstateserver/storage/sqlite3/storage.go +++ b/currentstateserver/storage/sqlite3/storage.go @@ -4,6 +4,7 @@ import ( "database/sql" "github.com/matrix-org/dendrite/currentstateserver/storage/shared" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" ) @@ -15,13 +16,10 @@ type Database struct { // NewDatabase creates a new sync server database // nolint: gocyclo -func NewDatabase(dataSourceName string) (*Database, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) { var d Database - cs, err := sqlutil.ParseFileURI(dataSourceName) - if err != nil { - return nil, err - } - if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil { + var err error + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } if err = d.PartitionOffsetStatements.Prepare(d.db, "currentstate"); err != nil { diff --git a/currentstateserver/storage/storage.go b/currentstateserver/storage/storage.go index ad04cf414..e0707def4 100644 --- a/currentstateserver/storage/storage.go +++ b/currentstateserver/storage/storage.go @@ -17,25 +17,21 @@ package storage import ( - "net/url" + "fmt" "github.com/matrix-org/dendrite/currentstateserver/storage/postgres" "github.com/matrix-org/dendrite/currentstateserver/storage/sqlite3" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" ) // NewDatabase opens a database connection. -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.NewDatabase(dataSourceName, dbProperties) - } - switch uri.Scheme { - case "postgres": - return postgres.NewDatabase(dataSourceName, dbProperties) - case "file": - return sqlite3.NewDatabase(dataSourceName) +func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.NewDatabase(dbProperties) default: - return postgres.NewDatabase(dataSourceName, dbProperties) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/currentstateserver/storage/storage_wasm.go b/currentstateserver/storage/storage_wasm.go index aa46c44df..46a5abd64 100644 --- a/currentstateserver/storage/storage_wasm.go +++ b/currentstateserver/storage/storage_wasm.go @@ -16,27 +16,19 @@ package storage import ( "fmt" - "net/url" "github.com/matrix-org/dendrite/currentstateserver/storage/sqlite3" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" ) // NewDatabase opens a database connection. -func NewDatabase( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam -) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") - case "file": - return sqlite3.NewDatabase(dataSourceName) +func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/federationapi/federationapi_test.go b/federationapi/federationapi_test.go index 01c204ed3..a19c36c60 100644 --- a/federationapi/federationapi_test.go +++ b/federationapi/federationapi_test.go @@ -26,7 +26,7 @@ func TestRoomsV3URLEscapeDoNot404(t *testing.T) { cfg.Global.PrivateKey = privKey cfg.Global.Kafka.UseNaffka = true cfg.Global.Kafka.Database = "file::memory:" - cfg.FederationSender.Database = "file::memory:" + cfg.FederationSender.Database.ConnectionString = config.DataSource("file::memory:") base := setup.NewBaseDendrite(cfg, "Test", false) keyRing := &test.NopJSONVerifier{} fsAPI := base.FederationSenderHTTPClient() diff --git a/federationsender/federationsender.go b/federationsender/federationsender.go index 4f69c793a..68999e30f 100644 --- a/federationsender/federationsender.go +++ b/federationsender/federationsender.go @@ -45,7 +45,7 @@ func NewInternalAPI( ) api.FederationSenderInternalAPI { cfg := &base.Cfg.FederationSender - federationSenderDB, err := storage.NewDatabase(string(cfg.Database), cfg.DatabaseOptions) + federationSenderDB, err := storage.NewDatabase(&cfg.Database) if err != nil { logrus.WithError(err).Panic("failed to connect to federation sender db") } diff --git a/federationsender/storage/postgres/storage.go b/federationsender/storage/postgres/storage.go index a3094bda2..b65ff0b6d 100644 --- a/federationsender/storage/postgres/storage.go +++ b/federationsender/storage/postgres/storage.go @@ -19,6 +19,7 @@ import ( "database/sql" "github.com/matrix-org/dendrite/federationsender/storage/shared" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" ) @@ -30,10 +31,10 @@ type Database struct { } // NewDatabase opens a new database -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) { var d Database var err error - if d.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil { + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } joinedHosts, err := NewPostgresJoinedHostsTable(d.db) diff --git a/federationsender/storage/sqlite3/storage.go b/federationsender/storage/sqlite3/storage.go index c303d0940..41b91871e 100644 --- a/federationsender/storage/sqlite3/storage.go +++ b/federationsender/storage/sqlite3/storage.go @@ -21,6 +21,7 @@ import ( _ "github.com/mattn/go-sqlite3" "github.com/matrix-org/dendrite/federationsender/storage/shared" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" ) @@ -32,14 +33,10 @@ type Database struct { } // NewDatabase opens a new database -func NewDatabase(dataSourceName string) (*Database, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) { var d Database var err error - cs, err := sqlutil.ParseFileURI(dataSourceName) - if err != nil { - return nil, err - } - if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil { + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } joinedHosts, err := NewSQLiteJoinedHostsTable(d.db) diff --git a/federationsender/storage/storage.go b/federationsender/storage/storage.go index d37360056..1380fefd1 100644 --- a/federationsender/storage/storage.go +++ b/federationsender/storage/storage.go @@ -17,25 +17,21 @@ package storage import ( - "net/url" + "fmt" "github.com/matrix-org/dendrite/federationsender/storage/postgres" "github.com/matrix-org/dendrite/federationsender/storage/sqlite3" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" ) // NewDatabase opens a new database -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.NewDatabase(dataSourceName, dbProperties) - } - switch uri.Scheme { - case "file": - return sqlite3.NewDatabase(dataSourceName) - case "postgres": - return postgres.NewDatabase(dataSourceName, dbProperties) +func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.NewDatabase(dbProperties) default: - return postgres.NewDatabase(dataSourceName, dbProperties) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/federationsender/storage/storage_wasm.go b/federationsender/storage/storage_wasm.go index e5c8f293b..459329e97 100644 --- a/federationsender/storage/storage_wasm.go +++ b/federationsender/storage/storage_wasm.go @@ -16,27 +16,19 @@ package storage import ( "fmt" - "net/url" "github.com/matrix-org/dendrite/federationsender/storage/sqlite3" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" ) // NewDatabase opens a new database -func NewDatabase( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam -) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "file": - return sqlite3.NewDatabase(dataSourceName) - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") +func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/internal/config/config.go b/internal/config/config.go index a059981b9..0c1f058b6 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -131,6 +131,16 @@ type Path string // A DataSource for opening a postgresql database using lib/pq. type DataSource string +func (d DataSource) IsSQLite() bool { + return strings.HasPrefix(string(d), "file:") +} + +func (d DataSource) IsPostgres() bool { + // commented line may not always be true? + // return strings.HasPrefix(string(d), "postgres:") + return !d.IsSQLite() +} + // A Topic in kafka. type Topic string diff --git a/internal/config/config_appservice.go b/internal/config/config_appservice.go index 51a40c3cd..9ffc4f4dc 100644 --- a/internal/config/config_appservice.go +++ b/internal/config/config_appservice.go @@ -32,8 +32,7 @@ type AppServiceAPI struct { Listen Address `yaml:"listen"` Bind Address `yaml:"bind"` - Database DataSource `yaml:"database"` - DatabaseOptions DatabaseOptions `yaml:"database_options"` + Database DatabaseOptions `yaml:"database"` ConfigFiles []string `yaml:"config_files"` } @@ -41,14 +40,14 @@ type AppServiceAPI struct { func (c *AppServiceAPI) Defaults() { c.Listen = "localhost:7777" c.Bind = "localhost:7777" - c.Database = "file:appservice.db" - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = "file:appservice.db" } func (c *AppServiceAPI) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "app_service_api.listen", string(c.Listen)) checkNotEmpty(configErrs, "app_service_api.bind", string(c.Bind)) - checkNotEmpty(configErrs, "app_service_api.database", string(c.Database)) + checkNotEmpty(configErrs, "app_service_api.database.connection_string", string(c.Database.ConnectionString)) } // ApplicationServiceNamespace is the namespace that a specific application diff --git a/internal/config/config_currentstate.go b/internal/config/config_currentstate.go index 2f32848ae..8c6f61dd0 100644 --- a/internal/config/config_currentstate.go +++ b/internal/config/config_currentstate.go @@ -8,19 +8,18 @@ type CurrentStateServer struct { // The CurrentState database stores the current state of all rooms. // It is accessed by the CurrentStateServer. - Database DataSource `yaml:"database"` - DatabaseOptions DatabaseOptions `yaml:"database_options"` + Database DatabaseOptions `yaml:"database"` } func (c *CurrentStateServer) Defaults() { c.Listen = "localhost:7782" c.Bind = "localhost:7782" - c.Database = "file:currentstate.db" - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = "file:currentstate.db" } func (c *CurrentStateServer) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "current_state_server.listen", string(c.Listen)) checkNotEmpty(configErrs, "current_state_server.bind", string(c.Bind)) - checkNotEmpty(configErrs, "current_state_server.database", string(c.Database)) + checkNotEmpty(configErrs, "current_state_server.database.connection_string", string(c.Database.ConnectionString)) } diff --git a/internal/config/config_federationsender.go b/internal/config/config_federationsender.go index dff76d63c..d42c83f64 100644 --- a/internal/config/config_federationsender.go +++ b/internal/config/config_federationsender.go @@ -8,8 +8,7 @@ type FederationSender struct { // The FederationSender database stores information used by the FederationSender // It is only accessed by the FederationSender. - Database DataSource `yaml:"database"` - DatabaseOptions DatabaseOptions `yaml:"database_options"` + Database DatabaseOptions `yaml:"database"` // Federation failure threshold. How many consecutive failures that we should // tolerate when sending federation requests to a specific server. The backoff @@ -23,8 +22,8 @@ type FederationSender struct { func (c *FederationSender) Defaults() { c.Listen = "localhost:7775" c.Bind = "localhost:7775" - c.Database = "file:federationsender.db" - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = "file:federationsender.db" c.FederationMaxRetries = 16 @@ -34,7 +33,7 @@ func (c *FederationSender) Defaults() { func (c *FederationSender) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "federation_sender.listen", string(c.Listen)) checkNotEmpty(configErrs, "federation_sender.bind", string(c.Bind)) - checkNotEmpty(configErrs, "federation_sender.database", string(c.Database)) + checkNotEmpty(configErrs, "federation_sender.database.connection_string", string(c.Database.ConnectionString)) } // The config for setting a proxy to use for server->server requests diff --git a/internal/config/config_global.go b/internal/config/config_global.go index 83a31faa4..9890fb8ab 100644 --- a/internal/config/config_global.go +++ b/internal/config/config_global.go @@ -69,8 +69,7 @@ type Kafka struct { // components as separate servers. UseNaffka bool `yaml:"use_naffka"` // The Naffka database is used internally by the naffka library, if used. - Database DataSource `yaml:"naffka_database"` - DatabaseOptions DatabaseOptions `yaml:"naffka_database_options"` + Database DatabaseOptions `yaml:"naffka_database"` // The names of the topics to use when reading and writing from kafka. Topics struct { // Topic for roomserver/api.OutputRoomEvent events. @@ -88,8 +87,8 @@ type Kafka struct { func (c *Kafka) Defaults() { c.UseNaffka = true - c.Database = DataSource("file:naffka.db") - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = DataSource("file:naffka.db") c.Topics.OutputRoomEvent = "OutputRoomEventTopic" c.Topics.OutputClientData = "OutputClientDataTopic" c.Topics.OutputTypingEvent = "OutputTypingEventTopic" @@ -105,7 +104,7 @@ func (c *Kafka) Verify(configErrs *configErrors) { configErrs.Add(fmt.Sprintf("naffka can only be used in a monolithic server")) } */ - checkNotEmpty(configErrs, "global.kafka.database", string(c.Database)) + checkNotEmpty(configErrs, "global.kafka.database.connection_string", string(c.Database.ConnectionString)) } else { // If we aren't using naffka then we need to have at least one kafka // server to talk to. @@ -141,12 +140,14 @@ func (c *Metrics) Verify(configErrs *configErrors) { } type DatabaseOptions struct { + // The connection string, file:filename.db or postgres://server.... + ConnectionString DataSource `yaml:"connection_string"` // Maximum open connections to the DB (0 = use default, negative means unlimited) - MaxOpenConnections int `yaml:"database_max_open_conns"` + MaxOpenConnections int `yaml:"max_open_conns"` // Maximum idle connections to the DB (0 = use default, negative means unlimited) - MaxIdleConnections int `yaml:"database_max_idle_conns"` + MaxIdleConnections int `yaml:"max_idle_conns"` // maximum amount of time (in seconds) a connection may be reused (<= 0 means unlimited) - ConnMaxLifetimeSeconds int `yaml:"database_conn_max_lifetime"` + ConnMaxLifetimeSeconds int `yaml:"conn_max_lifetime"` } func (c *DatabaseOptions) Defaults() { diff --git a/internal/config/config_keyserver.go b/internal/config/config_keyserver.go index 1920e77c5..68f53d57f 100644 --- a/internal/config/config_keyserver.go +++ b/internal/config/config_keyserver.go @@ -6,19 +6,18 @@ type KeyServer struct { Listen Address `yaml:"listen"` Bind Address `yaml:"bind"` - Database DataSource `yaml:"database"` - DatabaseOptions DatabaseOptions `yaml:"database_options"` + Database DatabaseOptions `yaml:"database"` } func (c *KeyServer) Defaults() { c.Listen = "localhost:7779" c.Bind = "localhost:7779" - c.Database = "file:keyserver.db" - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = "file:keyserver.db" } func (c *KeyServer) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "key_server.listen", string(c.Listen)) checkNotEmpty(configErrs, "key_server.bind", string(c.Bind)) - checkNotEmpty(configErrs, "key_server.database", string(c.Database)) + checkNotEmpty(configErrs, "key_server.database.connection_string", string(c.Database.ConnectionString)) } diff --git a/internal/config/config_mediaapi.go b/internal/config/config_mediaapi.go index 0d35e7001..d1631fd64 100644 --- a/internal/config/config_mediaapi.go +++ b/internal/config/config_mediaapi.go @@ -12,8 +12,7 @@ type MediaAPI struct { // The MediaAPI database stores information about files uploaded and downloaded // by local users. It is only accessed by the MediaAPI. - Database DataSource `yaml:"database"` - DatabaseOptions DatabaseOptions `yaml:"database_options"` + Database DatabaseOptions `yaml:"database"` // The base path to where the media files will be stored. May be relative or absolute. BasePath Path `yaml:"base_path"` @@ -39,8 +38,8 @@ type MediaAPI struct { func (c *MediaAPI) Defaults() { c.Listen = "localhost:7774" c.Bind = "localhost:7774" - c.Database = "file:mediaapi.db" - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = "file:mediaapi.db" defaultMaxFileSizeBytes := FileSizeBytes(10485760) c.MaxFileSizeBytes = &defaultMaxFileSizeBytes @@ -50,7 +49,7 @@ func (c *MediaAPI) Defaults() { func (c *MediaAPI) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "media_api.listen", string(c.Listen)) checkNotEmpty(configErrs, "media_api.bind", string(c.Bind)) - checkNotEmpty(configErrs, "media_api.database", string(c.Database)) + checkNotEmpty(configErrs, "media_api.database.connection_string", string(c.Database.ConnectionString)) checkNotEmpty(configErrs, "media_api.base_path", string(c.BasePath)) checkPositive(configErrs, "media_api.max_file_size_bytes", int64(*c.MaxFileSizeBytes)) diff --git a/internal/config/config_roomserver.go b/internal/config/config_roomserver.go index 33a212554..9587af663 100644 --- a/internal/config/config_roomserver.go +++ b/internal/config/config_roomserver.go @@ -6,19 +6,18 @@ type RoomServer struct { Listen Address `yaml:"listen"` Bind Address `yaml:"bind"` - Database DataSource `yaml:"database"` - DatabaseOptions DatabaseOptions `yaml:"database_options"` + Database DatabaseOptions `yaml:"database"` } func (c *RoomServer) Defaults() { c.Listen = "localhost:7770" c.Bind = "localhost:7770" - c.Database = "file:roomserver.db" - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = "file:roomserver.db" } func (c *RoomServer) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "room_server.listen", string(c.Listen)) checkNotEmpty(configErrs, "room_server.bind", string(c.Bind)) - checkNotEmpty(configErrs, "room_server.database", string(c.Database)) + checkNotEmpty(configErrs, "room_server.database.connection_string", string(c.Database.ConnectionString)) } diff --git a/internal/config/config_serverkey.go b/internal/config/config_serverkey.go index e22660d4a..8722c7185 100644 --- a/internal/config/config_serverkey.go +++ b/internal/config/config_serverkey.go @@ -8,8 +8,7 @@ type ServerKeyAPI struct { // The ServerKey database caches the public keys of remote servers. // It may be accessed by the FederationAPI, the ClientAPI, and the MediaAPI. - Database DataSource `yaml:"database"` - DatabaseOptions DatabaseOptions `yaml:"database_options"` + Database DatabaseOptions `yaml:"database"` // Perspective keyservers, to use as a backup when direct key fetch // requests don't succeed @@ -19,12 +18,12 @@ type ServerKeyAPI struct { func (c *ServerKeyAPI) Defaults() { c.Listen = "localhost:7780" c.Bind = "localhost:7780" - c.Database = "file:serverkeyapi.db" - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = "file:serverkeyapi.db" } func (c *ServerKeyAPI) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "server_key_api.listen", string(c.Listen)) checkNotEmpty(configErrs, "server_key_api.bind", string(c.Bind)) - checkNotEmpty(configErrs, "server_key_api.database", string(c.Database)) + checkNotEmpty(configErrs, "server_key_api.database.connection_string", string(c.Database.ConnectionString)) } diff --git a/internal/config/config_syncapi.go b/internal/config/config_syncapi.go index 687bf6043..c0b174f02 100644 --- a/internal/config/config_syncapi.go +++ b/internal/config/config_syncapi.go @@ -6,19 +6,18 @@ type SyncAPI struct { Listen Address `yaml:"listen"` Bind Address `yaml:"bind"` - Database DataSource `yaml:"database"` - DatabaseOptions DatabaseOptions `yaml:"database_options"` + Database DatabaseOptions `yaml:"database"` } func (c *SyncAPI) Defaults() { c.Listen = "localhost:7773" c.Bind = "localhost:7773" - c.Database = "file:syncapi.db" - c.DatabaseOptions.Defaults() + c.Database.Defaults() + c.Database.ConnectionString = "file:syncapi.db" } func (c *SyncAPI) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "sync_api.listen", string(c.Listen)) checkNotEmpty(configErrs, "sync_api.bind", string(c.Bind)) - checkNotEmpty(configErrs, "sync_api.database", string(c.Database)) + checkNotEmpty(configErrs, "sync_api.database", string(c.Database.ConnectionString)) } diff --git a/internal/config/config_userapi.go b/internal/config/config_userapi.go index 2c1c4ff8e..24bc27e29 100644 --- a/internal/config/config_userapi.go +++ b/internal/config/config_userapi.go @@ -8,26 +8,24 @@ type UserAPI struct { // The Account database stores the login details and account information // for local users. It is accessed by the UserAPI. - AccountDatabase DataSource `yaml:"account_database"` - AccountDatabaseOptions DatabaseOptions `yaml:"account_database_options"` + AccountDatabase DatabaseOptions `yaml:"account_database"` // The Device database stores session information for the devices of logged // in local users. It is accessed by the UserAPI. - DeviceDatabase DataSource `yaml:"device_database"` - DeviceDatabaseOptions DatabaseOptions `yaml:"device_database_options"` + DeviceDatabase DatabaseOptions `yaml:"device_database"` } func (c *UserAPI) Defaults() { c.Listen = "localhost:7781" c.Bind = "localhost:7781" - c.AccountDatabase = "file:userapi_accounts.db" - c.DeviceDatabase = "file:userapi_devices.db" - c.AccountDatabaseOptions.Defaults() - c.DeviceDatabaseOptions.Defaults() + c.AccountDatabase.Defaults() + c.DeviceDatabase.Defaults() + c.AccountDatabase.ConnectionString = "file:userapi_accounts.db" + c.DeviceDatabase.ConnectionString = "file:userapi_devices.db" } func (c *UserAPI) Verify(configErrs *configErrors) { checkNotEmpty(configErrs, "user_api.listen", string(c.Listen)) checkNotEmpty(configErrs, "user_api.bind", string(c.Bind)) - checkNotEmpty(configErrs, "user_api.account_database", string(c.AccountDatabase)) - checkNotEmpty(configErrs, "user_api.device_database", string(c.DeviceDatabase)) + checkNotEmpty(configErrs, "user_api.account_database.connection_string", string(c.AccountDatabase.ConnectionString)) + checkNotEmpty(configErrs, "user_api.device_database.connection_string", string(c.DeviceDatabase.ConnectionString)) } diff --git a/internal/setup/base.go b/internal/setup/base.go index a47330b54..c5a7a8a85 100644 --- a/internal/setup/base.go +++ b/internal/setup/base.go @@ -15,7 +15,6 @@ package setup import ( - "database/sql" "fmt" "io" "net/http" @@ -228,7 +227,7 @@ func (b *BaseDendrite) KeyServerHTTPClient() keyserverAPI.KeyInternalAPI { // CreateDeviceDB creates a new instance of the device database. Should only be // called once per component. func (b *BaseDendrite) CreateDeviceDB() devices.Database { - db, err := devices.NewDatabase(string(b.Cfg.UserAPI.DeviceDatabase), &b.Cfg.UserAPI.DeviceDatabaseOptions, b.Cfg.Global.ServerName) + db, err := devices.NewDatabase(&b.Cfg.UserAPI.DeviceDatabase, b.Cfg.Global.ServerName) if err != nil { logrus.WithError(err).Panicf("failed to connect to devices db") } @@ -239,7 +238,7 @@ func (b *BaseDendrite) CreateDeviceDB() devices.Database { // CreateAccountsDB creates a new instance of the accounts database. Should only // be called once per component. func (b *BaseDendrite) CreateAccountsDB() accounts.Database { - db, err := accounts.NewDatabase(string(b.Cfg.UserAPI.AccountDatabase), &b.Cfg.UserAPI.AccountDatabaseOptions, b.Cfg.Global.ServerName) + db, err := accounts.NewDatabase(&b.Cfg.UserAPI.AccountDatabase, b.Cfg.Global.ServerName) if err != nil { logrus.WithError(err).Panicf("failed to connect to accounts db") } @@ -307,36 +306,26 @@ func setupKafka(cfg *config.Dendrite) (sarama.Consumer, sarama.SyncProducer) { // setupNaffka creates kafka consumer/producer pair from the config. func setupNaffka(cfg *config.Dendrite) (sarama.Consumer, sarama.SyncProducer) { - var err error - var db *sql.DB var naffkaDB *naffka.DatabaseImpl - uri, err := url.Parse(string(cfg.Global.Kafka.Database)) - if err != nil || uri.Scheme == "file" { - var cs string - cs, err = sqlutil.ParseFileURI(string(cfg.Global.Kafka.Database)) - if err != nil { - logrus.WithError(err).Panic("Failed to parse naffka database file URI") - } - db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil) - if err != nil { - logrus.WithError(err).Panic("Failed to open naffka database") - } + db, err := sqlutil.Open(&cfg.Global.Kafka.Database) + if err != nil { + logrus.WithError(err).Panic("Failed to open naffka database") + } + switch { + case cfg.Global.Kafka.Database.ConnectionString.IsSQLite(): naffkaDB, err = naffka.NewSqliteDatabase(db) if err != nil { logrus.WithError(err).Panic("Failed to setup naffka database") } - } else { - db, err = sqlutil.Open("postgres", string(cfg.Global.Kafka.Database), nil) - if err != nil { - logrus.WithError(err).Panic("Failed to open naffka database") - } - + case cfg.Global.Kafka.Database.ConnectionString.IsPostgres(): naffkaDB, err = naffka.NewPostgresqlDatabase(db) if err != nil { logrus.WithError(err).Panic("Failed to setup naffka database") } + default: + panic("unknown naffka database type") } if naffkaDB == nil { diff --git a/internal/sqlutil/sql.go b/internal/sqlutil/sql.go index 2ec6ce291..95467c636 100644 --- a/internal/sqlutil/sql.go +++ b/internal/sqlutil/sql.go @@ -19,7 +19,6 @@ import ( "errors" "fmt" "runtime" - "time" "go.uber.org/atomic" ) @@ -107,13 +106,6 @@ func SQLiteDriverName() string { return "sqlite3" } -// DbProperties functions return properties used by database/sql/DB -type DbProperties interface { - MaxIdleConns() int - MaxOpenConns() int - ConnMaxLifetime() time.Duration -} - // TransactionWriter allows queuing database writes so that you don't // contend on database locks in, e.g. SQLite. Only one task will run // at a time on a given TransactionWriter. diff --git a/internal/sqlutil/trace.go b/internal/sqlutil/trace.go index f6644d591..fbd983bec 100644 --- a/internal/sqlutil/trace.go +++ b/internal/sqlutil/trace.go @@ -25,6 +25,7 @@ import ( "strings" "time" + "github.com/matrix-org/dendrite/internal/config" "github.com/ngrok/sqlmw" "github.com/sirupsen/logrus" ) @@ -77,7 +78,22 @@ func (in *traceInterceptor) RowsNext(c context.Context, rows driver.Rows, dest [ // Open opens a database specified by its database driver name and a driver-specific data source name, // usually consisting of at least a database name and connection information. Includes tracing driver // if DENDRITE_TRACE_SQL=1 -func Open(driverName, dsn string, dbProperties DbProperties) (*sql.DB, error) { +func Open(dbProperties *config.DatabaseOptions) (*sql.DB, error) { + var err error + var driverName, dsn string + switch { + case dbProperties.ConnectionString.IsSQLite(): + driverName = SQLiteDriverName() + dsn, err = ParseFileURI(dbProperties.ConnectionString) + if err != nil { + return nil, fmt.Errorf("ParseFileURI: %w", err) + } + case dbProperties.ConnectionString.IsPostgres(): + driverName = "postgres" + dsn = string(dbProperties.ConnectionString) + default: + return nil, fmt.Errorf("invalid database connection string %q", dbProperties.ConnectionString) + } if tracingEnabled { // install the wrapped driver driverName += "-trace" @@ -86,11 +102,11 @@ func Open(driverName, dsn string, dbProperties DbProperties) (*sql.DB, error) { if err != nil { return nil, err } - if driverName != SQLiteDriverName() && dbProperties != nil { + if driverName != SQLiteDriverName() { logrus.WithFields(logrus.Fields{ - "MaxOpenConns": dbProperties.MaxOpenConns(), - "MaxIdleConns": dbProperties.MaxIdleConns(), - "ConnMaxLifetime": dbProperties.ConnMaxLifetime(), + "MaxOpenConns": dbProperties.MaxOpenConns, + "MaxIdleConns": dbProperties.MaxIdleConns, + "ConnMaxLifetime": dbProperties.ConnMaxLifetime, "dataSourceName": regexp.MustCompile(`://[^@]*@`).ReplaceAllLiteralString(dsn, "://"), }).Debug("Setting DB connection limits") db.SetMaxOpenConns(dbProperties.MaxOpenConns()) diff --git a/internal/sqlutil/uri.go b/internal/sqlutil/uri.go index 703258e6c..e2c825d9d 100644 --- a/internal/sqlutil/uri.go +++ b/internal/sqlutil/uri.go @@ -15,14 +15,20 @@ package sqlutil import ( + "errors" "fmt" "net/url" + + "github.com/matrix-org/dendrite/internal/config" ) // ParseFileURI returns the filepath in the given file: URI. Specifically, this will handle // both relative (file:foo.db) and absolute (file:///path/to/foo) paths. -func ParseFileURI(dataSourceName string) (string, error) { - uri, err := url.Parse(dataSourceName) +func ParseFileURI(dataSourceName config.DataSource) (string, error) { + if !dataSourceName.IsSQLite() { + return "", errors.New("ParseFileURI expects SQLite connection string") + } + uri, err := url.Parse(string(dataSourceName)) if err != nil { return "", err } diff --git a/internal/test/config.go b/internal/test/config.go index 09396e9fa..43a5d1ff6 100644 --- a/internal/test/config.go +++ b/internal/test/config.go @@ -86,16 +86,16 @@ func MakeConfig(configDir, kafkaURI, database, host string, startPort int) (*con // Using the same database for every schema currently works because // the table names are globally unique. But we might not want to // rely on that in the future. - cfg.AppServiceAPI.Database = config.DataSource(database) - cfg.CurrentStateServer.Database = config.DataSource(database) - cfg.FederationSender.Database = config.DataSource(database) - cfg.KeyServer.Database = config.DataSource(database) - cfg.MediaAPI.Database = config.DataSource(database) - cfg.RoomServer.Database = config.DataSource(database) - cfg.ServerKeyAPI.Database = config.DataSource(database) - cfg.SyncAPI.Database = config.DataSource(database) - cfg.UserAPI.AccountDatabase = config.DataSource(database) - cfg.UserAPI.DeviceDatabase = config.DataSource(database) + cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(database) + cfg.CurrentStateServer.Database.ConnectionString = config.DataSource(database) + cfg.FederationSender.Database.ConnectionString = config.DataSource(database) + cfg.KeyServer.Database.ConnectionString = config.DataSource(database) + cfg.MediaAPI.Database.ConnectionString = config.DataSource(database) + cfg.RoomServer.Database.ConnectionString = config.DataSource(database) + cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource(database) + cfg.SyncAPI.Database.ConnectionString = config.DataSource(database) + cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(database) + cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(database) cfg.AppServiceAPI.Listen = assignAddress() cfg.CurrentStateServer.Listen = assignAddress() diff --git a/keyserver/keyserver.go b/keyserver/keyserver.go index 2f1bfb016..4416768bf 100644 --- a/keyserver/keyserver.go +++ b/keyserver/keyserver.go @@ -39,7 +39,7 @@ func AddInternalRoutes(router *mux.Router, intAPI api.KeyInternalAPI) { func NewInternalAPI( cfg *config.KeyServer, fedClient *gomatrixserverlib.FederationClient, userAPI userapi.UserInternalAPI, producer sarama.SyncProducer, ) api.KeyInternalAPI { - db, err := storage.NewDatabase(string(cfg.Database), cfg.DatabaseOptions) + db, err := storage.NewDatabase(&cfg.Database) if err != nil { logrus.WithError(err).Panicf("failed to connect to key server database") } diff --git a/keyserver/storage/postgres/storage.go b/keyserver/storage/postgres/storage.go index 4f3217b65..db569518e 100644 --- a/keyserver/storage/postgres/storage.go +++ b/keyserver/storage/postgres/storage.go @@ -15,14 +15,15 @@ package postgres import ( + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/keyserver/storage/shared" ) // NewDatabase creates a new sync server database -func NewDatabase(dbDataSourceName string, dbProperties sqlutil.DbProperties) (*shared.Database, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*shared.Database, error) { var err error - db, err := sqlutil.Open("postgres", dbDataSourceName, dbProperties) + db, err := sqlutil.Open(dbProperties) if err != nil { return nil, err } diff --git a/keyserver/storage/sqlite3/storage.go b/keyserver/storage/sqlite3/storage.go index f3566ef5c..6f87f4e1b 100644 --- a/keyserver/storage/sqlite3/storage.go +++ b/keyserver/storage/sqlite3/storage.go @@ -15,17 +15,13 @@ package sqlite3 import ( + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/keyserver/storage/shared" ) -func NewDatabase(dataSourceName string) (*shared.Database, error) { - var err error - cs, err := sqlutil.ParseFileURI(dataSourceName) - if err != nil { - return nil, err - } - db, err := sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil) +func NewDatabase(dbProperties *config.DatabaseOptions) (*shared.Database, error) { + db, err := sqlutil.Open(dbProperties) if err != nil { return nil, err } diff --git a/keyserver/storage/storage.go b/keyserver/storage/storage.go index ffcead701..e1deaf93d 100644 --- a/keyserver/storage/storage.go +++ b/keyserver/storage/storage.go @@ -17,26 +17,22 @@ package storage import ( - "net/url" + "fmt" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/keyserver/storage/postgres" "github.com/matrix-org/dendrite/keyserver/storage/sqlite3" ) // NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme) // and sets postgres connection parameters -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.NewDatabase(dataSourceName, dbProperties) - } - switch uri.Scheme { - case "postgres": - return postgres.NewDatabase(dataSourceName, dbProperties) - case "file": - return sqlite3.NewDatabase(dataSourceName) +func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.NewDatabase(dbProperties) default: - return postgres.NewDatabase(dataSourceName, dbProperties) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/keyserver/storage/storage_wasm.go b/keyserver/storage/storage_wasm.go index 233e5d295..792cd4a59 100644 --- a/keyserver/storage/storage_wasm.go +++ b/keyserver/storage/storage_wasm.go @@ -16,26 +16,18 @@ package storage import ( "fmt" - "net/url" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/keyserver/storage/sqlite3" ) -func NewDatabase( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam -) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") - case "file": - return sqlite3.NewDatabase(dataSourceName) +func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/mediaapi/mediaapi.go b/mediaapi/mediaapi.go index 79f5e8ab7..1c14559f5 100644 --- a/mediaapi/mediaapi.go +++ b/mediaapi/mediaapi.go @@ -30,7 +30,7 @@ func AddPublicRoutes( userAPI userapi.UserInternalAPI, client *gomatrixserverlib.Client, ) { - mediaDB, err := storage.Open(string(cfg.Database), cfg.DatabaseOptions) + mediaDB, err := storage.Open(&cfg.Database) if err != nil { logrus.WithError(err).Panicf("failed to connect to media db") } diff --git a/mediaapi/storage/postgres/storage.go b/mediaapi/storage/postgres/storage.go index e45e08416..756913d35 100644 --- a/mediaapi/storage/postgres/storage.go +++ b/mediaapi/storage/postgres/storage.go @@ -21,6 +21,7 @@ import ( // Import the postgres database driver. _ "github.com/lib/pq" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/mediaapi/types" "github.com/matrix-org/gomatrixserverlib" @@ -33,10 +34,10 @@ type Database struct { } // Open opens a postgres database. -func Open(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) { +func Open(dbProperties *config.DatabaseOptions) (*Database, error) { var d Database var err error - if d.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil { + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } if err = d.statements.prepare(d.db); err != nil { diff --git a/mediaapi/storage/sqlite3/storage.go b/mediaapi/storage/sqlite3/storage.go index 010c0a66e..a1e7fec7d 100644 --- a/mediaapi/storage/sqlite3/storage.go +++ b/mediaapi/storage/sqlite3/storage.go @@ -20,6 +20,7 @@ import ( "database/sql" // Import the postgres database driver. + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/mediaapi/types" "github.com/matrix-org/gomatrixserverlib" @@ -33,14 +34,10 @@ type Database struct { } // Open opens a postgres database. -func Open(dataSourceName string) (*Database, error) { +func Open(dbProperties *config.DatabaseOptions) (*Database, error) { var d Database var err error - cs, err := sqlutil.ParseFileURI(dataSourceName) - if err != nil { - return nil, err - } - if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil { + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } if err = d.statements.prepare(d.db); err != nil { diff --git a/mediaapi/storage/storage.go b/mediaapi/storage/storage.go index 5ff114db6..829d47b36 100644 --- a/mediaapi/storage/storage.go +++ b/mediaapi/storage/storage.go @@ -17,25 +17,21 @@ package storage import ( - "net/url" + "fmt" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/mediaapi/storage/postgres" "github.com/matrix-org/dendrite/mediaapi/storage/sqlite3" ) // Open opens a postgres database. -func Open(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.Open(dataSourceName, dbProperties) - } - switch uri.Scheme { - case "postgres": - return postgres.Open(dataSourceName, dbProperties) - case "file": - return sqlite3.Open(dataSourceName) +func Open(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.Open(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.Open(dbProperties) default: - return postgres.Open(dataSourceName, dbProperties) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/mediaapi/storage/storage_wasm.go b/mediaapi/storage/storage_wasm.go index a672271f9..6b5de681b 100644 --- a/mediaapi/storage/storage_wasm.go +++ b/mediaapi/storage/storage_wasm.go @@ -16,27 +16,19 @@ package storage import ( "fmt" - "net/url" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/mediaapi/storage/sqlite3" ) // Open opens a postgres database. -func Open( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam -) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") - case "file": - return sqlite3.Open(dataSourceName) +func Open(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.Open(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/roomserver/roomserver.go b/roomserver/roomserver.go index 250b46993..1c226085e 100644 --- a/roomserver/roomserver.go +++ b/roomserver/roomserver.go @@ -41,7 +41,7 @@ func NewInternalAPI( ) api.RoomserverInternalAPI { cfg := &base.Cfg.RoomServer - roomserverDB, err := storage.Open(string(cfg.Database), cfg.DatabaseOptions) + roomserverDB, err := storage.Open(&cfg.Database) if err != nil { logrus.WithError(err).Panicf("failed to connect to room server db") } diff --git a/roomserver/roomserver_test.go b/roomserver/roomserver_test.go index d04a5f707..d11c63b28 100644 --- a/roomserver/roomserver_test.go +++ b/roomserver/roomserver_test.go @@ -98,7 +98,7 @@ func mustSendEvents(t *testing.T, ver gomatrixserverlib.RoomVersion, events []js cfg.Defaults() cfg.Global.ServerName = testOrigin cfg.Global.Kafka.UseNaffka = true - cfg.RoomServer.Database = roomserverDBFileURI + cfg.RoomServer.Database.ConnectionString = config.DataSource(roomserverDBFileURI) dp := &dummyProducer{ topic: string(cfg.Global.Kafka.Topics.OutputRoomEvent), } diff --git a/roomserver/storage/postgres/storage.go b/roomserver/storage/postgres/storage.go index c4f30f041..52ff479ba 100644 --- a/roomserver/storage/postgres/storage.go +++ b/roomserver/storage/postgres/storage.go @@ -18,6 +18,7 @@ package postgres import ( "database/sql" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" // Import the postgres database driver. @@ -32,11 +33,11 @@ type Database struct { // Open a postgres database. // nolint: gocyclo -func Open(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) { +func Open(dbProperties *config.DatabaseOptions) (*Database, error) { var d Database var db *sql.DB var err error - if db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil { + if db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } eventStateKeys, err := NewPostgresEventStateKeysTable(db) diff --git a/roomserver/storage/sqlite3/storage.go b/roomserver/storage/sqlite3/storage.go index 11781ce06..048de1928 100644 --- a/roomserver/storage/sqlite3/storage.go +++ b/roomserver/storage/sqlite3/storage.go @@ -19,6 +19,7 @@ import ( "context" "database/sql" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/roomserver/storage/shared" "github.com/matrix-org/dendrite/roomserver/storage/tables" @@ -44,13 +45,10 @@ type Database struct { // Open a sqlite database. // nolint: gocyclo -func Open(dataSourceName string) (*Database, error) { +func Open(dbProperties *config.DatabaseOptions) (*Database, error) { var d Database - cs, err := sqlutil.ParseFileURI(dataSourceName) - if err != nil { - return nil, err - } - if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil { + var err error + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } //d.db.Exec("PRAGMA journal_mode=WAL;") diff --git a/roomserver/storage/storage.go b/roomserver/storage/storage.go index d7367e4c7..c6561fdc5 100644 --- a/roomserver/storage/storage.go +++ b/roomserver/storage/storage.go @@ -17,25 +17,21 @@ package storage import ( - "net/url" + "fmt" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/roomserver/storage/postgres" "github.com/matrix-org/dendrite/roomserver/storage/sqlite3" ) // Open opens a database connection. -func Open(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.Open(dataSourceName, dbProperties) - } - switch uri.Scheme { - case "postgres": - return postgres.Open(dataSourceName, dbProperties) - case "file": - return sqlite3.Open(dataSourceName) +func Open(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.Open(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.Open(dbProperties) default: - return postgres.Open(dataSourceName, dbProperties) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/roomserver/storage/storage_wasm.go b/roomserver/storage/storage_wasm.go index 78405b20e..43367f361 100644 --- a/roomserver/storage/storage_wasm.go +++ b/roomserver/storage/storage_wasm.go @@ -16,27 +16,19 @@ package storage import ( "fmt" - "net/url" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/roomserver/storage/sqlite3" ) // NewPublicRoomsServerDatabase opens a database connection. -func Open( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam -) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") - case "file": - return sqlite3.Open(dataSourceName) +func Open(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.Open(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/serverkeyapi/serverkeyapi.go b/serverkeyapi/serverkeyapi.go index 2919bc75f..fbaaefadd 100644 --- a/serverkeyapi/serverkeyapi.go +++ b/serverkeyapi/serverkeyapi.go @@ -30,8 +30,7 @@ func NewInternalAPI( caches *caching.Caches, ) api.ServerKeyInternalAPI { innerDB, err := storage.NewDatabase( - string(cfg.Database), - cfg.DatabaseOptions, + &cfg.Database, cfg.Matrix.ServerName, cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey), cfg.Matrix.KeyID, diff --git a/serverkeyapi/serverkeyapi_test.go b/serverkeyapi/serverkeyapi_test.go index 88fa70f85..b8c462c7b 100644 --- a/serverkeyapi/serverkeyapi_test.go +++ b/serverkeyapi/serverkeyapi_test.go @@ -76,7 +76,7 @@ func TestMain(m *testing.M) { cfg.Global.PrivateKey = testPriv cfg.Global.KeyID = serverKeyID cfg.Global.KeyValidityPeriod = s.validity - cfg.ServerKeyAPI.Database = config.DataSource("file::memory:") + cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource("file::memory:") s.config = &cfg.ServerKeyAPI s.fedconfig = &cfg.FederationAPI diff --git a/serverkeyapi/storage/keydb.go b/serverkeyapi/storage/keydb.go index c28c4de1e..3d3a0c303 100644 --- a/serverkeyapi/storage/keydb.go +++ b/serverkeyapi/storage/keydb.go @@ -17,11 +17,11 @@ package storage import ( - "net/url" + "fmt" "golang.org/x/crypto/ed25519" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/serverkeyapi/storage/postgres" "github.com/matrix-org/dendrite/serverkeyapi/storage/sqlite3" "github.com/matrix-org/gomatrixserverlib" @@ -29,22 +29,17 @@ import ( // NewDatabase opens a database connection. func NewDatabase( - dataSourceName string, - dbProperties sqlutil.DbProperties, + dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, serverKey ed25519.PublicKey, serverKeyID gomatrixserverlib.KeyID, ) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.NewDatabase(dataSourceName, dbProperties, serverName, serverKey, serverKeyID) - } - switch uri.Scheme { - case "postgres": - return postgres.NewDatabase(dataSourceName, dbProperties, serverName, serverKey, serverKeyID) - case "file": - return sqlite3.NewDatabase(dataSourceName, serverName, serverKey, serverKeyID) + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties, serverName, serverKey, serverKeyID) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.NewDatabase(dbProperties, serverName, serverKey, serverKeyID) default: - return postgres.NewDatabase(dataSourceName, dbProperties, serverName, serverKey, serverKeyID) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/serverkeyapi/storage/postgres/keydb.go b/serverkeyapi/storage/postgres/keydb.go index aaa4409be..634440859 100644 --- a/serverkeyapi/storage/postgres/keydb.go +++ b/serverkeyapi/storage/postgres/keydb.go @@ -20,6 +20,7 @@ import ( "golang.org/x/crypto/ed25519" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/gomatrixserverlib" ) @@ -35,13 +36,12 @@ type Database struct { // It prepares all the SQL statements that it will use. // Returns an error if there was a problem talking to the database. func NewDatabase( - dataSourceName string, - dbProperties sqlutil.DbProperties, + dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, serverKey ed25519.PublicKey, serverKeyID gomatrixserverlib.KeyID, ) (*Database, error) { - db, err := sqlutil.Open("postgres", dataSourceName, dbProperties) + db, err := sqlutil.Open(dbProperties) if err != nil { return nil, err } diff --git a/serverkeyapi/storage/sqlite3/keydb.go b/serverkeyapi/storage/sqlite3/keydb.go index dc72b79eb..5174ece15 100644 --- a/serverkeyapi/storage/sqlite3/keydb.go +++ b/serverkeyapi/storage/sqlite3/keydb.go @@ -20,6 +20,7 @@ import ( "golang.org/x/crypto/ed25519" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/gomatrixserverlib" @@ -37,16 +38,12 @@ type Database struct { // It prepares all the SQL statements that it will use. // Returns an error if there was a problem talking to the database. func NewDatabase( - dataSourceName string, + dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, serverKey ed25519.PublicKey, serverKeyID gomatrixserverlib.KeyID, ) (*Database, error) { - cs, err := sqlutil.ParseFileURI(dataSourceName) - if err != nil { - return nil, err - } - db, err := sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil) + db, err := sqlutil.Open(dbProperties) if err != nil { return nil, err } diff --git a/syncapi/storage/postgres/syncserver.go b/syncapi/storage/postgres/syncserver.go index 10c1b37c7..26ef082f5 100644 --- a/syncapi/storage/postgres/syncserver.go +++ b/syncapi/storage/postgres/syncserver.go @@ -21,6 +21,7 @@ import ( // Import the postgres database driver. _ "github.com/lib/pq" "github.com/matrix-org/dendrite/eduserver/cache" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/syncapi/storage/shared" ) @@ -34,10 +35,10 @@ type SyncServerDatasource struct { } // NewDatabase creates a new sync server database -func NewDatabase(dbDataSourceName string, dbProperties sqlutil.DbProperties) (*SyncServerDatasource, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*SyncServerDatasource, error) { var d SyncServerDatasource var err error - if d.db, err = sqlutil.Open("postgres", dbDataSourceName, dbProperties); err != nil { + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } if err = d.PartitionOffsetStatements.Prepare(d.db, "syncapi"); err != nil { diff --git a/syncapi/storage/sqlite3/syncserver.go b/syncapi/storage/sqlite3/syncserver.go index c85db5a4f..9564a23aa 100644 --- a/syncapi/storage/sqlite3/syncserver.go +++ b/syncapi/storage/sqlite3/syncserver.go @@ -22,6 +22,7 @@ import ( _ "github.com/mattn/go-sqlite3" "github.com/matrix-org/dendrite/eduserver/cache" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/syncapi/storage/shared" ) @@ -37,13 +38,10 @@ type SyncServerDatasource struct { // NewDatabase creates a new sync server database // nolint: gocyclo -func NewDatabase(dataSourceName string) (*SyncServerDatasource, error) { +func NewDatabase(dbProperties *config.DatabaseOptions) (*SyncServerDatasource, error) { var d SyncServerDatasource - cs, err := sqlutil.ParseFileURI(dataSourceName) - if err != nil { - return nil, err - } - if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil { + var err error + if d.db, err = sqlutil.Open(dbProperties); err != nil { return nil, err } if err = d.prepare(); err != nil { diff --git a/syncapi/storage/storage.go b/syncapi/storage/storage.go index ea69da3bc..c16dcd810 100644 --- a/syncapi/storage/storage.go +++ b/syncapi/storage/storage.go @@ -17,25 +17,21 @@ package storage import ( - "net/url" + "fmt" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/syncapi/storage/postgres" "github.com/matrix-org/dendrite/syncapi/storage/sqlite3" ) // NewSyncServerDatasource opens a database connection. -func NewSyncServerDatasource(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.NewDatabase(dataSourceName, dbProperties) - } - switch uri.Scheme { - case "postgres": - return postgres.NewDatabase(dataSourceName, dbProperties) - case "file": - return sqlite3.NewDatabase(dataSourceName) +func NewSyncServerDatasource(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.NewDatabase(dbProperties) default: - return postgres.NewDatabase(dataSourceName, dbProperties) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/syncapi/storage/storage_test.go b/syncapi/storage/storage_test.go index 474d3222b..6756778d9 100644 --- a/syncapi/storage/storage_test.go +++ b/syncapi/storage/storage_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/syncapi/storage" "github.com/matrix-org/dendrite/syncapi/storage/sqlite3" "github.com/matrix-org/dendrite/syncapi/types" @@ -59,7 +60,9 @@ func MustCreateDatabase(t *testing.T) storage.Database { t.Fatalf("tried to delete stale test database but failed: %s", err) } } - db, err := sqlite3.NewDatabase(fmt.Sprintf("file:%s", dbname)) + db, err := sqlite3.NewDatabase(&config.DatabaseOptions{ + ConnectionString: config.DataSource(fmt.Sprintf("file:%s", dbname)), + }) if err != nil { t.Fatalf("NewSyncServerDatasource returned %s", err) } diff --git a/syncapi/storage/storage_wasm.go b/syncapi/storage/storage_wasm.go index 0886b8c21..43b7bbead 100644 --- a/syncapi/storage/storage_wasm.go +++ b/syncapi/storage/storage_wasm.go @@ -16,27 +16,19 @@ package storage import ( "fmt" - "net/url" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/syncapi/storage/sqlite3" ) // NewPublicRoomsServerDatabase opens a database connection. -func NewSyncServerDatasource( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam -) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") - case "file": - return sqlite3.NewDatabase(dataSourceName) +func NewSyncServerDatasource(dbProperties *config.DatabaseOptions) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/syncapi/syncapi.go b/syncapi/syncapi.go index a7a4add02..88530a31c 100644 --- a/syncapi/syncapi.go +++ b/syncapi/syncapi.go @@ -42,7 +42,7 @@ func AddPublicRoutes( federation *gomatrixserverlib.FederationClient, cfg *config.SyncAPI, ) { - syncDB, err := storage.NewSyncServerDatasource(string(cfg.Database), cfg.DatabaseOptions) + syncDB, err := storage.NewSyncServerDatasource(&cfg.Database) if err != nil { logrus.WithError(err).Panicf("failed to connect to sync db") } diff --git a/userapi/storage/accounts/postgres/storage.go b/userapi/storage/accounts/postgres/storage.go index f56fb6d81..9653c019c 100644 --- a/userapi/storage/accounts/postgres/storage.go +++ b/userapi/storage/accounts/postgres/storage.go @@ -22,6 +22,7 @@ import ( "strconv" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" @@ -43,10 +44,9 @@ type Database struct { } // NewDatabase creates a new accounts and profiles database -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serverName gomatrixserverlib.ServerName) (*Database, error) { - var db *sql.DB - var err error - if db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil { +func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (*Database, error) { + db, err := sqlutil.Open(dbProperties) + if err != nil { return nil, err } partitions := sqlutil.PartitionOffsetStatements{} diff --git a/userapi/storage/accounts/sqlite3/storage.go b/userapi/storage/accounts/sqlite3/storage.go index 722390148..4d2c5e51d 100644 --- a/userapi/storage/accounts/sqlite3/storage.go +++ b/userapi/storage/accounts/sqlite3/storage.go @@ -23,6 +23,7 @@ import ( "sync" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" @@ -47,16 +48,11 @@ type Database struct { } // NewDatabase creates a new accounts and profiles database -func NewDatabase(dataSourceName string, serverName gomatrixserverlib.ServerName) (*Database, error) { - var db *sql.DB - var err error - cs, err := sqlutil.ParseFileURI(dataSourceName) +func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (*Database, error) { + db, err := sqlutil.Open(dbProperties) if err != nil { return nil, err } - if db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil { - return nil, err - } partitions := sqlutil.PartitionOffsetStatements{} if err = partitions.Prepare(db, "account"); err != nil { return nil, err diff --git a/userapi/storage/accounts/storage.go b/userapi/storage/accounts/storage.go index 87f626bf9..57d5f7039 100644 --- a/userapi/storage/accounts/storage.go +++ b/userapi/storage/accounts/storage.go @@ -17,9 +17,9 @@ package accounts import ( - "net/url" + "fmt" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/userapi/storage/accounts/postgres" "github.com/matrix-org/dendrite/userapi/storage/accounts/sqlite3" "github.com/matrix-org/gomatrixserverlib" @@ -27,17 +27,13 @@ import ( // NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme) // and sets postgres connection parameters -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serverName gomatrixserverlib.ServerName) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.NewDatabase(dataSourceName, dbProperties, serverName) - } - switch uri.Scheme { - case "postgres": - return postgres.NewDatabase(dataSourceName, dbProperties, serverName) - case "file": - return sqlite3.NewDatabase(dataSourceName, serverName) +func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties, serverName) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.NewDatabase(dbProperties, serverName) default: - return postgres.NewDatabase(dataSourceName, dbProperties, serverName) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/userapi/storage/accounts/storage_wasm.go b/userapi/storage/accounts/storage_wasm.go index 692567059..ade32b68f 100644 --- a/userapi/storage/accounts/storage_wasm.go +++ b/userapi/storage/accounts/storage_wasm.go @@ -16,28 +16,22 @@ package accounts import ( "fmt" - "net/url" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/userapi/storage/accounts/sqlite3" "github.com/matrix-org/gomatrixserverlib" ) func NewDatabase( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam + dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, ) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") - case "file": - return sqlite3.NewDatabase(dataSourceName, serverName) + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties, serverName) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/userapi/storage/devices/postgres/storage.go b/userapi/storage/devices/postgres/storage.go index 6ac802bb1..4a7c7f975 100644 --- a/userapi/storage/devices/postgres/storage.go +++ b/userapi/storage/devices/postgres/storage.go @@ -20,6 +20,7 @@ import ( "database/sql" "encoding/base64" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" @@ -35,10 +36,9 @@ type Database struct { } // NewDatabase creates a new device database -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serverName gomatrixserverlib.ServerName) (*Database, error) { - var db *sql.DB - var err error - if db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil { +func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (*Database, error) { + db, err := sqlutil.Open(dbProperties) + if err != nil { return nil, err } d := devicesStatements{} diff --git a/userapi/storage/devices/sqlite3/storage.go b/userapi/storage/devices/sqlite3/storage.go index b9f08ca11..1f2b59f30 100644 --- a/userapi/storage/devices/sqlite3/storage.go +++ b/userapi/storage/devices/sqlite3/storage.go @@ -20,6 +20,7 @@ import ( "database/sql" "encoding/base64" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" @@ -37,16 +38,11 @@ type Database struct { } // NewDatabase creates a new device database -func NewDatabase(dataSourceName string, serverName gomatrixserverlib.ServerName) (*Database, error) { - var db *sql.DB - var err error - cs, err := sqlutil.ParseFileURI(dataSourceName) +func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (*Database, error) { + db, err := sqlutil.Open(dbProperties) if err != nil { return nil, err } - if db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil { - return nil, err - } d := devicesStatements{} if err = d.prepare(db, serverName); err != nil { return nil, err diff --git a/userapi/storage/devices/storage.go b/userapi/storage/devices/storage.go index e094d202a..1bd73a9fb 100644 --- a/userapi/storage/devices/storage.go +++ b/userapi/storage/devices/storage.go @@ -17,9 +17,9 @@ package devices import ( - "net/url" + "fmt" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/userapi/storage/devices/postgres" "github.com/matrix-org/dendrite/userapi/storage/devices/sqlite3" "github.com/matrix-org/gomatrixserverlib" @@ -27,17 +27,13 @@ import ( // NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme) // and sets postgres connection parameters -func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serverName gomatrixserverlib.ServerName) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return postgres.NewDatabase(dataSourceName, dbProperties, serverName) - } - switch uri.Scheme { - case "postgres": - return postgres.NewDatabase(dataSourceName, dbProperties, serverName) - case "file": - return sqlite3.NewDatabase(dataSourceName, serverName) +func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (Database, error) { + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties, serverName) + case dbProperties.ConnectionString.IsPostgres(): + return postgres.NewDatabase(dbProperties, serverName) default: - return postgres.NewDatabase(dataSourceName, dbProperties, serverName) + return nil, fmt.Errorf("unexpected database type") } } diff --git a/userapi/storage/devices/storage_wasm.go b/userapi/storage/devices/storage_wasm.go index a5a515eff..e966c37f3 100644 --- a/userapi/storage/devices/storage_wasm.go +++ b/userapi/storage/devices/storage_wasm.go @@ -16,28 +16,22 @@ package devices import ( "fmt" - "net/url" - "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/userapi/storage/devices/sqlite3" "github.com/matrix-org/gomatrixserverlib" ) func NewDatabase( - dataSourceName string, - dbProperties sqlutil.DbProperties, // nolint:unparam + dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName, ) (Database, error) { - uri, err := url.Parse(dataSourceName) - if err != nil { - return nil, fmt.Errorf("Cannot use postgres implementation") - } - switch uri.Scheme { - case "postgres": - return nil, fmt.Errorf("Cannot use postgres implementation") - case "file": - return sqlite3.NewDatabase(dataSourceName, serverName) + switch { + case dbProperties.ConnectionString.IsSQLite(): + return sqlite3.NewDatabase(dbProperties, serverName) + case dbProperties.ConnectionString.IsPostgres(): + return nil, fmt.Errorf("can't use Postgres implementation") default: - return nil, fmt.Errorf("Cannot use postgres implementation") + return nil, fmt.Errorf("unexpected database type") } } diff --git a/userapi/userapi_test.go b/userapi/userapi_test.go index 163b10ec7..b971964af 100644 --- a/userapi/userapi_test.go +++ b/userapi/userapi_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/gorilla/mux" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/httputil" "github.com/matrix-org/dendrite/internal/test" "github.com/matrix-org/dendrite/userapi" @@ -23,11 +24,15 @@ const ( ) func MustMakeInternalAPI(t *testing.T) (api.UserInternalAPI, accounts.Database, devices.Database) { - accountDB, err := accounts.NewDatabase("file::memory:", nil, serverName) + accountDB, err := accounts.NewDatabase(&config.DatabaseOptions{ + ConnectionString: "file::memory:", + }, serverName) if err != nil { t.Fatalf("failed to create account DB: %s", err) } - deviceDB, err := devices.NewDatabase("file::memory:", nil, serverName) + deviceDB, err := devices.NewDatabase(&config.DatabaseOptions{ + ConnectionString: "file::memory:", + }, serverName) if err != nil { t.Fatalf("failed to create device DB: %s", err) }