-
-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create scaffolding for adding Postgres support #171
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds about right so far. I take it that the current (It's written in the PR description 👍)Postgres
module is a copy of the SQLite
at the moment?
New work completed
Current Issues
Work still to be done
|
I agree that the full alternative is somewhat a stretch, and that sounds good. To not confuse people though, I'd still suggest to hide the
No; because in-memory database using the InMemory Nothing ->
("file::kupo:?mode=memory&cache=shared", openFlags) What's not obvious here is that the file name is
This cannot conflict with a live running instance because users cannot actually provide an
It should be possible by using the |
How so ? |
Add 'postgres' flag to: 1. `make` targets: 1. `make configure` 1. `make /dist/bin/kupo` 1. kupo.cabal: 1. Conditionally include the Postgres module vs the SQLite module 1. Add `cpp-options: -Dpostgres` 1. Kupo.App.Database: import Postgres or SQLite module depending on flag Also add additional files to `make clean` to cause the project to be recompiled after `clean`
Previously, creating a SQLite DB file, creating read-only and read-write connection pools, and gatekeeping connection types (e.g., `ReadWrite`) against the Kupo instance type (e.g., read only replica) was exposed by the `SQLite` module and performed in `Kupo`. Now, those functions are encapsulated within the DB-specific modules to allow unique implementations. For instance, PostgreSQL does not have a DB file and does not need separate pools for read-only and read-write connections.
Use a single data structure, `databaseLocation`, to describe either a work directory or in-memory when compiled for SQLite or a remote URL when compiled for PostgreSQL. This provides strong type safety but comes at the cost of having to include a argument parser in the DB modules, which is not really where it belongs. Alternatively, conditional compilation could be added to the argument parsing module, but that also seems out of place. Ultimately, including all 3 alternatives in `databaseLocation` and validating at runtime may be a cleaner solution, despite the loss of type safety.
This reverts commit 2701b34.
Add a command line option to specify a remote URL as DB location instead of work directory or in memory. This was added as another sum type to the existing option to prevent additional conditional compilation and avoid the need to conditionally compile the option parser. This comes at the expense of type safety, as each DB module throws a runtime error if an incompatible DB Location is provided. Trace logging of the max concurrency configuration was kept in `Kupo` rather than the DB modules due to a cyclical dependency between `App/Configuration`, `SQLite`/`Postgres`, and `App/Database`.
Add a command line option to specify a remote URL as DB location instead of work directory or in memory. This was added as another sum type to the existing option to prevent additional conditional compilation and avoid the need to conditionally compile the option parser. This comes at the expense of type safety, as each DB module throws a runtime error if an incompatible DB Location is provided. Trace logging of the max concurrency configuration was kept in `Kupo` rather than the DB modules due to a cyclical dependency between `App/Configuration`, `SQLite`/`Postgres`, and `App/Database`.
Clean whole build directory so cabal actually rebuilds the binary, and include the postgres flag in configure stage
longestRollback | ||
dbFile | ||
(action InstallIndexesIfNotExist) | ||
(withDatabaseBlocking dbPool) ReadOnly (action InstallIndexesIfNotExist) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes slightly alter the behavior. Before, the main background connection will not actually be part of the pool; mostly because there's no need: this connection never goes back to the pool; it's a long running connection that persists the entire life of the application.
It's not a big deal though as it will only consume one reader connection when setup as a read-only replica. It makes things easier down the line.
We cannot just use 'InMemory' for tests as this creates a shared in-memory database (each test therefore conflicting with one another). This is why the 'DatabaseFile' allows for passing an extra path to the InMemory variant. Not that having both 'DatabaseFile' and 'DatabaseLocation' feels somewhat redundant and just adds confusion overall. We shall perhaps consider getting rid of one.
Ideally, we should just not create any resource pool when in read-only mode. But the impact on the API is sufficiently annoying to not be worth it. So we still create a read/write pool which simply remains idle for the entire application lifetime. Yet we must ensure that the pool size is >= 1, otherwise it crashes at runtime. Yet, we don't want to report any writer capabilities in log.
Including `newDBPoolFromFile` in the external API of `App/Database` creates issues for the Postgres module, which does not have any notion of a DB file. Instead, we add a `FilePath` to `Configuration.InMemory` but do not expose ability to provide a filepath to the command line. This allows us to provide a filepath for testing purposes but does allow the user to supply one, all while maintaining good abstraction boundaries.
Due to an issue with CPP, multiline string literals had to be replaced with concatenated single line literals. `internal` was used instead of `hidden` to hide the options from the long help text as well as the short help.
Merging this already as we've got a few things to do on top which might conflict; so to save everyone time, let's bring new changes as new PRs :) |
Add 'postgres' flag and dummy Postgres module
Add 'postgres' flag to:
make
targets:make configure
make /dist/bin/kupo
cpp-options: -Dpostgres
Also add additional files to
make clean
to cause the project to be recompiled afterclean