Update (^.) to fix natural key handling (#177)

* Update (^.) to only treat natural keys with more than one component as ECompositeKey. Fixes #176.

* Update article metadata test to ensure the correct response was being returned instead of just check if an exception was thrown

* Add article metadata to cleanDB before deleting all articles to fix foreign key constraint errors

* Bump version number and add changelog entry
This commit is contained in:
Ben Levy 2020-03-22 10:30:45 -05:00 committed by GitHub
parent 951bb21c1b
commit 9a762e9f20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 5 deletions

View File

@ -1,3 +1,9 @@
3.3.2
========
- @belevy
- [#177](https://github.com/bitemyapp/esqueleto/pull/177) Fix natural key handling in (^.)
3.3.1.1 3.3.1.1
======== ========

View File

@ -1,7 +1,7 @@
cabal-version: 1.12 cabal-version: 1.12
name: esqueleto name: esqueleto
version: 3.3.1.1 version: 3.3.2
synopsis: Type-safe EDSL for SQL queries on persistent backends. synopsis: Type-safe EDSL for SQL queries on persistent backends.
description: @esqueleto@ is a bare bones, type-safe EDSL for SQL queries that works with unmodified @persistent@ SQL backends. Its language closely resembles SQL, so you don't have to learn new concepts, just new syntax, and it's fairly easy to predict the generated SQL and optimize it for your backend. Most kinds of errors committed when writing SQL are caught as compile-time errors---although it is possible to write type-checked @esqueleto@ queries that fail at runtime. description: @esqueleto@ is a bare bones, type-safe EDSL for SQL queries that works with unmodified @persistent@ SQL backends. Its language closely resembles SQL, so you don't have to learn new concepts, just new syntax, and it's fairly easy to predict the generated SQL and optimize it for your backend. Most kinds of errors committed when writing SQL are caught as compile-time errors---although it is possible to write type-checked @esqueleto@ queries that fail at runtime.
. .

View File

@ -522,10 +522,17 @@ subSelectUnsafe = sub SELECT
-> EntityField val typ -> EntityField val typ
-> SqlExpr (Value typ) -> SqlExpr (Value typ)
EEntity ident ^. field EEntity ident ^. field
| isComposite = ECompositeKey $ \info -> dot info <$> compositeFields pdef | isIdField field = idFieldValue
| otherwise = ERaw Never $ \info -> (dot info $ persistFieldDef field, []) | otherwise = ERaw Never $ \info -> (dot info $ persistFieldDef field, [])
where where
isComposite = isIdField field && hasCompositeKey ed idFieldValue =
case entityKeyFields ed of
idField:[] ->
ERaw Never $ \info -> (dot info idField, [])
idFields ->
ECompositeKey $ \info -> dot info <$> idFields
dot info x = useIdent info ident <> "." <> fromDBName info (fieldDB x) dot info x = useIdent info ident <> "." <> fromDBName info (fieldDB x)
ed = entityDef $ getEntityVal (Proxy :: Proxy (SqlExpr (Entity val))) ed = entityDef $ getEntityVal (Proxy :: Proxy (SqlExpr (Entity val)))
Just pdef = entityPrimary ed Just pdef = entityPrimary ed

View File

@ -165,6 +165,10 @@ share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
frontcoverNumber Int frontcoverNumber Int
Foreign Frontcover fkfrontcover frontcoverNumber Foreign Frontcover fkfrontcover frontcoverNumber
deriving Eq Show deriving Eq Show
ArticleMetadata
articleId ArticleId
Primary articleId
deriving Eq Show
Tag Tag
name String maxlen=100 name String maxlen=100
Primary name Primary name
@ -753,7 +757,16 @@ testSelectJoin run = do
liftIO $ do liftIO $ do
retFc `shouldBe` fc retFc `shouldBe` fc
fcPk `shouldBe` thePk fcPk `shouldBe` thePk
it "allows using a primary key that is itself a key of another table" $
run $ do
let number = 101
insert_ $ Frontcover number ""
articleId <- insert $ Article "title" number
articleMetaE <- insert' (ArticleMetadata articleId)
result <- select . from $ \articleMetadata -> do
where_ $ (articleMetadata ^. ArticleMetadataId) ==. (val ((ArticleMetadataKey articleId)))
pure articleMetadata
liftIO $ [articleMetaE] `shouldBe` result
it "works with a ForeignKey to a non-id primary key returning both entities" $ it "works with a ForeignKey to a non-id primary key returning both entities" $
run $ do run $ do
let fc = Frontcover number "" let fc = Frontcover number ""
@ -2332,6 +2345,7 @@ cleanDB = do
delete $ from $ \(_ :: SqlExpr (Entity CcList)) -> return () delete $ from $ \(_ :: SqlExpr (Entity CcList)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity ArticleTag)) -> return () delete $ from $ \(_ :: SqlExpr (Entity ArticleTag)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity ArticleMetadata)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity Article)) -> return () delete $ from $ \(_ :: SqlExpr (Entity Article)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity Article2)) -> return () delete $ from $ \(_ :: SqlExpr (Entity Article2)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity Tag)) -> return () delete $ from $ \(_ :: SqlExpr (Entity Tag)) -> return ()