-
Notifications
You must be signed in to change notification settings - Fork 297
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
WIP: Schema support #1466
base: master
Are you sure you want to change the base?
WIP: Schema support #1466
Conversation
dbc038e
to
166bdf9
Compare
At this stage the schema support is added to Sqlite and PostgreSQL backend. There is a simple test that passes for these backends too. |
@arrowd Currently, we have a hardcode |
I'm not sure what function you're talking about. I did adapt |
@arrowd Sorry, you are right. Your PR will be able to solve my current problem. Can you tell me when the PR will be ready? I hope it can be merged soon. |
At the moment this PR lacks 2 things:
Once this is done a review from Persistent developers would be required, which may take some time. |
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 a fantastic start! Apologies for the delayed review.
With the current change set, this is a minor bump to persistent
, which will require new lower bounds on persistent-sqlite
and persistent-postgresql
to take advantage of the feature.
, entitySchema :: !(Maybe Text) | ||
-- ^ The schema name of the database table. |
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.
Let's make another newtype SchemaNameDB
for this - will make it easier to disambiguate what is and isn't a schema vs any other bit of text
@@ -34,6 +34,7 @@ data Column = Column | |||
-- | This value specifies how a field references another table. | |||
-- | |||
-- @since 2.11.0.0 | |||
-- TODO: what about schema name there? |
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 does seem important to resolve. Unfortunately, the ColumnReference
type is exposed, meaning that we will incur a major version bump if we modify it.
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.
Since ColumnReference
isn't supported yet, this addition will fail for things that need to use it - which is specifying foreign key relationships in migrations. I suspect that a test that works on this schema would fail:
mkPersist sqlSettings [persistLowerCase|
Foo schema=foo_schema
name Int
Bar
foo FooId
|]
let mbRefdef = find (\ent -> getEntityDBSchema ent == getEntityDBSchema edef | ||
&& getEntityDBName ent == crTableName colRef) | ||
defs | ||
(schema, _) = schemaNamePair edef | ||
in case mbRefdef of | ||
Just refdef | ||
| Just _oldName /= fmap fieldDB (getEntityIdField edef) | ||
-> | ||
[AddReference | ||
(crTableName colRef) | ||
(schema, crTableName colRef) |
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.
Oh, nice, you handle this appropriately here. Well done.
@@ -731,6 +738,7 @@ mayDefault def = case def of | |||
Just d -> " DEFAULT " <> d | |||
|
|||
type SafeToRemove = Bool | |||
type SchemaEntityName = (Text, EntityNameDB) |
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.
I'd prefer to see a newtype
or a data
with named fields to make this more explicit
schemaNamePair' :: Maybe Text -> EntityNameDB -> SchemaEntityName | ||
schemaNamePair' mbSchema entName = case mbSchema of | ||
Nothing -> ("", entName) | ||
Just "main" -> ("", entName) | ||
Just "temp" -> ("temp", entName) | ||
Just schema -> ("", EntityNameDB $ (schema <> "_") <> unEntityNameDB entName) |
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.
Intriguing - so sqlite only has two schema, main
and temp
? And we mimic that by using schema_table_name
? I'd be inclined to use __
(two underscore) to make the distinction more clear - that way you can see foo__bar_baz
and know that foo
is the supposed schema, rather than foo_bar_baz
potentially being either BarBaz schema=foo
or FooBarBaz
(no schema).
schemaNamePair :: EntityDef -> SchemaEntityName | ||
schemaNamePair ent = schemaNamePair' (getEntityDBSchema ent) (getEntityDBName ent) | ||
|
||
schemaNamePair' :: Maybe Text -> EntityNameDB -> SchemaEntityName | ||
schemaNamePair' mbSchema entName = case mbSchema of | ||
Nothing -> ("", entName) | ||
Just "public" -> ("", entName) | ||
Just schema -> (schema, entName) |
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.
Uses of this function case on ""
and treat it differently - I think that's a good reason to keep this as a Maybe Text
instead of a Text
.
I'm also curious about treating "public"
differently here - can you explain why we don't just keep the public
prefix? Presumably, the user must have specified that - ie Foo schema=public
- and I'm hesitant to override a user choice.
Thanks for the review. Currently I'm swamped with daily work, so I will not be able to address your comments and move this work forward. I'm hoping to get more free time in the second half of June. |
This is a first take on #1454
It adds
entitySchema
field and teach sqlite backend to use it.I'm a bit worried that I had to import Internal modules, so I decided to ask for early feedback.