-
Notifications
You must be signed in to change notification settings - Fork 298
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
Add schema support to Persistent (issue #93) #1561
base: master
Are you sure you want to change the base?
Conversation
Add new `entitySchema` field and refactor callsites of `entityDB` to use `getEntityDBName` instead
[INT-844] prepend schema to entity db name
…ntityDBName revert change to `getEntityDBName`
…tters-for-entitySchema add setters and getters for `entitySchema`
…b.com:curranosaurus/persistent into curran/update-entitySchema-to-its-own-newtype
…o-its-own-newtype Create newtype for schema name
…t-schema update sqlQQ test to consider a case with a schema
…s-migrations Use new entitySchema field for Postgres migrations
…sql-queries Start using table schema in queries with Postgres
import qualified PersistentTest | ||
import qualified PersistUniqueTest |
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.
Sorted imports due to stylish-haskell
.
, (==@) | ||
, (@/=) | ||
, (@==) | ||
) |
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.
Reformatted by stylish-haskell
.
import PersistentTestModels | ||
import qualified CodeGenTest | ||
import PersistTestPetType |
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.
Imports sorted by stylish-haskell
.
import qualified PersistentTest | ||
import qualified PersistUniqueTest |
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.
Imports sorted by stylish-haskell
.
import qualified PersistentTest | ||
import qualified PersistUniqueTest |
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.
Imports sorted by stylish-haskell
.
@@ -539,7 +541,7 @@ getCopyTable :: [EntityDef] | |||
-> EntityDef | |||
-> IO [(Bool, Text)] | |||
getCopyTable allDefs getter def = do |
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.
The changes to this function were non-trivial. A naive change to this function would allow identically named tables in different schemas to clobber each other when copying them into the temporary schema. So we do some manual namespacing by prefixing the table name with <schema>_
when copying it to the temporary schema.
@@ -470,6 +470,8 @@ migrate' allDefs getter val = do | |||
where | |||
def = val | |||
table = getEntityDBName def | |||
schema = getEntitySchema def | |||
sqliteMaster = maybe "sqlite_master" (\schema' -> escapeS schema' <> ".sqlite_master") schema |
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.
There is one copy of the sqlite_master
table in each schema, and it only contains information about the tables in its own schema.
, fcOnDelete = parseCascadeAction onDel | ||
} | ||
then Just $ | ||
let colSchema = |
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.
This is one of the most complex pieces of logic in the persistent-mysql
diff, it's worth scrutinizing whether this makes sense.
6b464fa
to
a4e8af3
Compare
I've run the test suites for the changed packages, and they all pass except for
|
@@ -37,6 +40,7 @@ runConn f = do | |||
db :: SqlPersistT (LoggingT (ResourceT IO)) a -> IO a | |||
db actions = do | |||
runResourceT $ runConn $ do | |||
rawSql @(Single Int64) ("attach 'animals.db' as animals") [] |
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.
This ensures that the tests referencing the animals
schema succeed.
Addresses #93 by adding schema support to Persistent. You specify a Persistent model's schema using syntax like
schema=foo
.I worked on this together with @benjonesy.
Design challenges and decisions
"Schema" means many things to many backends
In this PR, we use the word "schema" to refer to various devices that backends offer for namespacing tables.
Schemas may or may not exist
We considered designing this PR so that Persistent would create schemas for the user if they did not already exist. But we chose not to do that. This means that local development with Persistent using schemas will require some manual SQL migrations to create the schemas that the user wants. But for conventional use-cases, schema creation will be a rare event, so this is not very onerous for developers. Below are some issues one would have to solve to make Persistent automate schema creation for the developer:
Three-stage migrations
RIght now, the
CREATe TABLE
DDL statements are sorted to the top of the migration output, so that the (potentially recursive) foreign-key constraints are created only after all of the tables they reference exist. If we also wanted Persistent to ensure the existence of schemas, we would need to sort backend-appropriate versions ofCREATE SCHEMA
statements above theCREATe TABLE
statements.Granting permissions in MySQL
Before a connection can use a newly created database in MySQL, one must run a
GRANT
statement to give the current user the requisite DDL operations to runCREATe TABLE
statements. We would somehow need to make Persistent aware of theGRANT
statement required.File name and directory in SQLite
SQLite's invocation for creating a new database also specifies the file name and location for that database's
.db
file. Persistent would need to be opinionated about this directory scheme, or we would have to add a configuration option, if we wanted to support schema creation in SQLite.PR Template checklist
Before submitting your PR, check that you've:
@since
declarations to the Haddockstylish-haskell
on any changed files..editorconfig
file for details)After submitting your PR:
(unreleased)
on the Changelog