-
Notifications
You must be signed in to change notification settings - Fork 3
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
Rudimentary support for enum types #118
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.
First and foremost: thank you for tackling this. It's a tricky feature, that is indeed lacking from this library.
I am somewhat not inclined to approve as is, on several basis.
1°) The PR does too many unrelated things, though I fully support dropping the stylish-haskell and I support the refactoring of database definition.
2°) The lack of support for enum update seems precarious (particularly when it comes to migrations).
Though I understand reluctancy to add
ALTER TYPE xxx ADD VALUE 'newvalue'
I would advocate adding at least support for
ALTER TYPE xxx RENAME TO yyy
which would be invaluable when migrating enums.
checkDatabaseWithReport | ||
options | ||
DatabaseDefinitions | ||
{ dbExtensions = _ -- We currently don't check extensions |
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 no "we", here since this is a public library. If this is not supported, this shouldn't be listed.
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 can get rid of the comment or rephrase it, but I'd rather add extension checking than splitting DatabaseDefinitions
into two different types with difference of one field being present/absent if this is really necessary for approval.
Especially considering that listing installed extensions is as easy as select extname::text from pg_catalog.pg_extension
. We already perform the check during migration.
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.
Fair enough. Please get rid of the comment then.
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.
Just wondering whether I should do the actual checking, but it's yet another unrelated thing, which you already complained about.
unless (resultHasErrors report) $ | ||
tell =<< lift (checkInitialSetups tables) | ||
where | ||
checkInitialSetups :: [Table] -> m ValidationResult |
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.
If ghc lets you do it (and it should), it might be a good opportunity to remove the intermediary signatures here, I think this is clear enough as it is.
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 essentially just moved code, so I didn't made any changes that were not necessary. But I can do that.
I didn't introduce anything that wasn't needed at the moment, especially given that you can write raw queries in the migrations anyway. |
|
That's because you haven't had to do enough rollback in your life, lucky man that you are ! Joking aside, it's also a way to make reviewing easier. On your second point, I think rename is the safest option (based on experience). In the meantime, ok for using RawSQL. |
I'm confused about what you mean by "rename is the safest option". It's one of two operations for managing enums, they are meant to do different thing. |
Renaming used to be a very common way to update enums before |
Well, apparently there's a hacky way to modify an existing enum type. The PR looks alright to me. However, I'm still not sure if we want "proper" enums, specially since they aren't perfect and What's more, we already support serialization of enum Haskell types to readable values on the DB side via EnumAsTextEncoding, which "just works" (see |
"Enum '" | ||
<> enumName | ||
<> "' has same values, but differs in order (database:" | ||
<+> T.pack (show dbValues) |
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.
Can you use just <>
here (or mconcat) and add spaces where necessary? It's a bit confusing to read with different operators.
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.
Sure, I only used <+>
because it was already used in similar messages elsewhere.
, dbDomains = domains | ||
, dbTables = tables | ||
} = execWriterT $ do | ||
(_, report) <- W.listen $ 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.
I don't particularly like usage of Writer here, but can't think of anything better.
I did use it, but the storage type for that is |
Okay, but then you're renaming the entire type, not just one of the enum values. It's a different thing. And how does it achieve correct mapping between the old and new enums? |
I know, but is this really an issue? |
@marco44 any thoughts about simply using a text column instead of enum? |
Both have their advantages Enum is more compact and it enforces what's in the list efficiently. But you have this limitation on removing an element from the list. And as it's just a number in disguise, the stats collection is faster and more accurate. Text stores any string, but check constraints to enforce the content are a pain: it takes more resources to enforce, and needs a very slow & resource heavy recheck each time you change your mind about the content of the list. Indexes (btrees) are also faster on enums, of course... as it's much easier to sort (we're doing unicode collations…) and more compact |
@zlondrej Ok, if you think enum is better than text in your case, considered potential cons and found them not problematic, let's merge this. |
migrateDatabase
andcheckDatabase
into aDatabaseDefinitions
record type,as it was getting confusing with 5 list parameters.
stylish-haskell
configuration file, since we format moved tofourmolu
.