diff --git a/changelog.md b/changelog.md index 7fb7592..fdecf6d 100644 --- a/changelog.md +++ b/changelog.md @@ -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 ======== diff --git a/esqueleto.cabal b/esqueleto.cabal index 4882743..7dcb29c 100644 --- a/esqueleto.cabal +++ b/esqueleto.cabal @@ -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. . diff --git a/src/Database/Esqueleto/Internal/Internal.hs b/src/Database/Esqueleto/Internal/Internal.hs index 1559f5d..1a8b717 100644 --- a/src/Database/Esqueleto/Internal/Internal.hs +++ b/src/Database/Esqueleto/Internal/Internal.hs @@ -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 diff --git a/test/Common/Test.hs b/test/Common/Test.hs index 1ae2059..820c21e 100644 --- a/test/Common/Test.hs +++ b/test/Common/Test.hs @@ -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 ()