-
Notifications
You must be signed in to change notification settings - Fork 302
Use backend-specific upsertBy #856
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
Use backend-specific upsertBy #856
Conversation
|
Tests currently fail with format errors: It seems to require a condition for every unique key in the |
|
@limick can you merge the latest master to rerun CI against the new test suite? I think we can get this in for 2.9.2 once tests are passing. |
|
I think you may have discovered a bug! The code in the Postgresql for upsertSql' :: EntityDef -> Text -> Text
upsertSql' ent updateVal = T.concat
[ "INSERT INTO "
, escape (entityDB ent)
, "("
, T.intercalate "," $ map (escape . fieldDB) $ entityFields ent
, ") VALUES ("
, T.intercalate "," $ map (const "?") (entityFields ent)
, ") ON CONFLICT ("
, T.intercalate "," $ concat $ map (\x -> map escape (map snd $ uniqueFields x)) (entityUniques ent)
, ") DO UPDATE SET "
, updateVal
, " WHERE "
, wher
, " RETURNING ??"
]
where
wher = T.intercalate " AND " $ map singleCondition $ entityUniques ent
singleCondition :: UniqueDef -> Text
singleCondition udef = T.intercalate " AND " (map singleClause $ map snd (uniqueFields udef))
singleClause :: DBName -> Text
singleClause field = escape (entityDB ent) <> "." <> (escape field) <> " =?"The So, I think we need to alter the # persistent/Database/Persist/Sql?Types/Internal.hs
# line 89
- , connUpsertSql :: Maybe (EntityDef -> Text -> Text)
+ , connUpsertSql :: Maybe (EntityDef -> NonEmpty UniqueDef -> Text -> Text)Then, in the |
|
Yes, the fact that we had a clause per unique condition was part of what I found confusing. |
|
Neither MySQL nor SQLite have |
|
Does this PR still have a purpose after the merged PR #895 from @parsonsmatt ? |
|
Yes, it still has a purpose because the aim is to use upsert where available, which is worth fixing and not fixed by anything else as far as I know. |
I implemented the changes as suggested by @parsonsmatt and the tests pass. |
parsonsmatt
left a comment
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.
Ah, crap, sorry, I started a review a long time ago but never actually finalized it.
| -- backends that support this functioanlity. If 'Nothing', rows will be | ||
| -- inserted one-at-a-time using 'connInsertSql'. | ||
| , connUpsertSql :: Maybe (EntityDef -> NonEmpty UniqueDef -> Text -> Text) | ||
| , connUpsertSql :: Maybe (EntityDef -> NonEmpty (HaskellName,DBName) -> Text -> Text) |
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 major-bump change since it's changing the type definition of a public datatype. Is this necessary?
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 think it's necessary, because I don't see a way to go from Unique record (which is the type of uniqueKey in Persist/Sql/Orphan/PersistUnique.hs) to its corresponding UniqueDef.
I'd be glad to be proven wrong.
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.
Hmmm. That's irritating.
Looks like we have this possible pathway:
- With a
PersistEntity ein scope, we can calllet uniqDefs = entityUniques (entityDef (Proxy @e)) :: [UniqueDef]. - Then we have
persistUniqueToFieldNames :: Unique record -> [(HaskellName, DBName)]. - We can do a lookup on the
[UniqueDef]to find the correspondinguniqueFields- egfind (\u -> uniqueFields u == persistUniqueToFieldNames uniq) uniqDefs
Not the most elegant solution, for sure, but it will work I think.
|
Going to get this merged in for a 2.11 release soon. |
This fixes #855, where
upsertByonly ever used the default implementation.Before submitting your PR, check that you've:
@sincedeclarations to the HaddockAfter submitting your PR: