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
========

View File

@ -1,7 +1,7 @@
cabal-version: 1.12
name: esqueleto
version: 3.3.1.1
version: 3.3.2
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.
.

View File

@ -522,10 +522,17 @@ subSelectUnsafe = sub SELECT
-> EntityField val typ
-> SqlExpr (Value typ)
EEntity ident ^. field
| isComposite = ECompositeKey $ \info -> dot info <$> compositeFields pdef
| otherwise = ERaw Never $ \info -> (dot info $ persistFieldDef field, [])
| isIdField field = idFieldValue
| otherwise = ERaw Never $ \info -> (dot info $ persistFieldDef field, [])
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)
ed = entityDef $ getEntityVal (Proxy :: Proxy (SqlExpr (Entity val)))
Just pdef = entityPrimary ed

View File

@ -165,6 +165,10 @@ share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
frontcoverNumber Int
Foreign Frontcover fkfrontcover frontcoverNumber
deriving Eq Show
ArticleMetadata
articleId ArticleId
Primary articleId
deriving Eq Show
Tag
name String maxlen=100
Primary name
@ -753,7 +757,16 @@ testSelectJoin run = do
liftIO $ do
retFc `shouldBe` fc
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" $
run $ do
let fc = Frontcover number ""
@ -2332,6 +2345,7 @@ cleanDB = do
delete $ from $ \(_ :: SqlExpr (Entity CcList)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity ArticleTag)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity ArticleMetadata)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity Article)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity Article2)) -> return ()
delete $ from $ \(_ :: SqlExpr (Entity Tag)) -> return ()