Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ghc-persistent-sqlite for 
openSUSE:Factory checked in at 2021-02-16 22:38:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-persistent-sqlite (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-persistent-sqlite.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-persistent-sqlite"

Tue Feb 16 22:38:55 2021 rev:5 rq:870876 version:2.11.1.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/ghc-persistent-sqlite/ghc-persistent-sqlite.changes  
    2020-12-22 11:44:17.153757485 +0100
+++ 
/work/SRC/openSUSE:Factory/.ghc-persistent-sqlite.new.28504/ghc-persistent-sqlite.changes
   2021-02-16 22:48:39.590566751 +0100
@@ -1,0 +2,11 @@
+Mon Feb  8 05:05:42 UTC 2021 - [email protected]
+
+- Update persistent-sqlite to version 2.11.1.0.
+  ##  2.11.1.0
+
+  * Add `checkForeignKeys` operation to verify no foreign key constraints are
+    violated by the database contents.
+  * Fix the migration for primary keys that was broken in 2.11.0.0
+    [#1184](https://github.com/yesodweb/persistent/issues/1184)
+
+-------------------------------------------------------------------

Old:
----
  persistent-sqlite-2.11.0.0.tar.gz

New:
----
  persistent-sqlite-2.11.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-persistent-sqlite.spec ++++++
--- /var/tmp/diff_new_pack.w70Fs5/_old  2021-02-16 22:48:40.278567289 +0100
+++ /var/tmp/diff_new_pack.w70Fs5/_new  2021-02-16 22:48:40.278567289 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-persistent-sqlite
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %global pkg_name persistent-sqlite
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        2.11.0.0
+Version:        2.11.1.0
 Release:        0
 Summary:        Backend for the persistent library using sqlite3
 License:        MIT
@@ -32,6 +32,7 @@
 BuildRequires:  ghc-containers-devel
 BuildRequires:  ghc-microlens-th-devel
 BuildRequires:  ghc-monad-logger-devel
+BuildRequires:  ghc-mtl-devel
 BuildRequires:  ghc-persistent-devel
 BuildRequires:  ghc-resource-pool-devel
 BuildRequires:  ghc-resourcet-devel
@@ -50,6 +51,7 @@
 BuildRequires:  ghc-exceptions-devel
 BuildRequires:  ghc-fast-logger-devel
 BuildRequires:  ghc-hspec-devel
+BuildRequires:  ghc-microlens-devel
 BuildRequires:  ghc-persistent-template-devel
 BuildRequires:  ghc-persistent-test-devel
 BuildRequires:  ghc-system-fileio-devel

++++++ persistent-sqlite-2.11.0.0.tar.gz -> persistent-sqlite-2.11.1.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/persistent-sqlite-2.11.0.0/ChangeLog.md 
new/persistent-sqlite-2.11.1.0/ChangeLog.md
--- old/persistent-sqlite-2.11.0.0/ChangeLog.md 2020-11-04 19:49:27.000000000 
+0100
+++ new/persistent-sqlite-2.11.1.0/ChangeLog.md 2021-02-05 22:39:24.000000000 
+0100
@@ -1,5 +1,12 @@
 # Changelog for persistent-sqlite
 
+##  2.11.1.0
+
+* Add `checkForeignKeys` operation to verify no foreign key constraints are
+  violated by the database contents.
+* Fix the migration for primary keys that was broken in 2.11.0.0
+  [#1184](https://github.com/yesodweb/persistent/issues/1184)
+
 ##  2.11.0.0
 
 * Foreign Key improvements [#1121] 
(https://github.com/yesodweb/persistent/pull/1121)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/persistent-sqlite-2.11.0.0/Database/Persist/Sqlite.hs 
new/persistent-sqlite-2.11.1.0/Database/Persist/Sqlite.hs
--- old/persistent-sqlite-2.11.0.0/Database/Persist/Sqlite.hs   2020-11-04 
19:28:13.000000000 +0100
+++ new/persistent-sqlite-2.11.1.0/Database/Persist/Sqlite.hs   2021-02-05 
22:39:24.000000000 +0100
@@ -36,6 +36,8 @@
     , mockMigration
     , retryOnBusy
     , waitForDatabase
+    , ForeignKeyViolation(..)
+    , checkForeignKeys
     , RawSqlite
     , persistentBackend
     , rawSqliteConnection
@@ -51,6 +53,8 @@
 import Control.Monad (forM_)
 import Control.Monad.IO.Unlift (MonadIO (..), MonadUnliftIO, askRunInIO, 
withRunInIO, withUnliftIO, unliftIO, withRunInIO)
 import Control.Monad.Logger (NoLoggingT, runNoLoggingT, MonadLogger, logWarn, 
runLoggingT)
+import Control.Monad.Reader (MonadReader)
+import Control.Monad.Trans.Resource (MonadResource)
 import Control.Monad.Trans.Reader (ReaderT, runReaderT, withReaderT)
 import Control.Monad.Trans.Writer (runWriterT)
 import Data.Acquire (Acquire, mkAcquire, with)
@@ -58,6 +62,7 @@
 import Data.Aeson
 import Data.Aeson.Types (modifyFailure)
 import Data.Conduit
+import qualified Data.Conduit.Combinators as C
 import qualified Data.Conduit.List as CL
 import qualified Data.HashMap.Lazy as HashMap
 import Data.Int (Int64)
@@ -487,7 +492,7 @@
 getCopyTable allDefs getter def = do
     stmt <- getter $ T.concat [ "PRAGMA table_info(", escape table, ")" ]
     oldCols' <- with (stmtQuery stmt []) (\src -> runConduit $ src .| getCols)
-    let oldCols = map DBName $ filter (/= "id") oldCols' -- need to update for 
table id attribute ?
+    let oldCols = map DBName oldCols'
     let newCols = filter (not . safeToRemove def) $ map cName cols
     let common = filter (`elem` oldCols) newCols
     return [ (False, tmpSql)
@@ -751,6 +756,44 @@
         <*> o .: "fkEnabled"
         <*> o .:? "extraPragmas" .!= []
 
+-- | Data type for reporting foreign key violations using 'checkForeignKeys'.
+--
+-- @since 2.11.1
+data ForeignKeyViolation = ForeignKeyViolation
+    { foreignKeyTable :: Text -- ^ The table of the violated constraint
+    , foreignKeyColumn :: Text -- ^ The column of the violated constraint
+    , foreignKeyRowId :: Int64 -- ^ The ROWID of the row with the violated 
foreign key constraint
+    } deriving (Eq, Ord, Show)
+
+-- | Outputs all (if any) the violated foreign key constraints in the database.
+--
+-- The main use is to validate that no foreign key constraints were
+-- broken/corrupted by anyone operating on the database with foreign keys
+-- disabled. See 'fkEnabled'.
+--
+-- @since 2.11.1
+checkForeignKeys
+    :: (MonadResource m, MonadReader env m, BackendCompatible SqlBackend env)
+    => ConduitM () ForeignKeyViolation m ()
+checkForeignKeys = rawQuery query [] .| C.mapM parse
+  where
+    parse l = case l of
+        [ PersistInt64 rowid , PersistText table , PersistText column ] ->
+            return ForeignKeyViolation
+                { foreignKeyTable = table
+                , foreignKeyColumn = column
+                , foreignKeyRowId = rowid
+                }
+        _ -> liftIO . E.throwIO . PersistMarshalError $ mconcat
+            [ "Unexpected result from foreign key check:\n", T.pack (show l) ]
+
+    query = "\
+\ SELECT origin.rowid, origin.\"table\", group_concat(foreignkeys.\"from\")\n\
+\ FROM pragma_foreign_key_check() AS origin\n\
+\ INNER JOIN pragma_foreign_key_list(origin.\"table\") AS foreignkeys\n\
+\ ON origin.fkid = foreignkeys.id AND origin.parent = foreignkeys.\"table\"\n\
+\ GROUP BY origin.rowid"
+
 -- | Like `withSqliteConnInfo`, but exposes the internal `Sqlite.Connection`.
 -- For power users who want to manually interact with SQLite's C API via
 -- internals exposed by "Database.Sqlite.Internal"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/persistent-sqlite-2.11.0.0/persistent-sqlite.cabal 
new/persistent-sqlite-2.11.1.0/persistent-sqlite.cabal
--- old/persistent-sqlite-2.11.0.0/persistent-sqlite.cabal      2020-11-02 
19:38:31.000000000 +0100
+++ new/persistent-sqlite-2.11.1.0/persistent-sqlite.cabal      2021-02-05 
22:39:24.000000000 +0100
@@ -1,5 +1,5 @@
 name:            persistent-sqlite
-version:         2.11.0.0
+version:         2.11.1.0
 license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <[email protected]>
@@ -51,6 +51,7 @@
                    , containers              >= 0.5
                    , microlens-th            >= 0.4.1.1
                    , monad-logger            >= 0.3.25
+                   , mtl
                    , resource-pool
                    , resourcet               >= 1.1.9
                    , text                    >= 1.2
@@ -123,11 +124,14 @@
                    , persistent-test
                    , bytestring
                    , containers
+                   , conduit
                    , exceptions
                    , fast-logger
                    , hspec >= 2.4
                    , HUnit
+                   , microlens
                    , monad-logger
+                   , mtl
                    , QuickCheck
                    , resourcet
                    , system-fileio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/persistent-sqlite-2.11.0.0/test/main.hs 
new/persistent-sqlite-2.11.1.0/test/main.hs
--- old/persistent-sqlite-2.11.0.0/test/main.hs 2020-11-04 19:28:13.000000000 
+0100
+++ new/persistent-sqlite-2.11.1.0/test/main.hs 2021-02-05 22:39:24.000000000 
+0100
@@ -1,5 +1,6 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE ExistentialQuantification #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -46,16 +47,21 @@
 import qualified UpsertTest
 import qualified LongIdentifierTest
 
-import Control.Exception (handle, IOException)
+import Control.Exception (handle, IOException, throwIO)
 import Control.Monad.Catch (catch)
 import Control.Monad.IO.Class (liftIO)
+import Control.Monad.Reader (MonadReader)
+import Control.Monad.Trans.Resource (MonadResource)
 import qualified Data.ByteString as BS
+import Data.Conduit ((.|), runConduit)
+import qualified Data.Conduit.List as CL
 import Data.Fixed
 import Data.IntMap (IntMap)
 import qualified Data.Text as T
 import Data.Time
 import Filesystem (removeFile)
 import Filesystem.Path.CurrentOS (fromText)
+import qualified Lens.Micro as Lens
 import Test.QuickCheck.Arbitrary (Arbitrary, arbitrary)
 import System.IO (hClose)
 import System.IO.Temp (withSystemTempFile)
@@ -88,20 +94,57 @@
 |]
 
 share [mkPersist sqlSettings, mkMigrate "compositeSetup"] [persistLowerCase|
-Simple
+SimpleComposite
     int Int
     text Text
     Primary text int
     deriving Show Eq
+
+SimpleCompositeReference
+    int Int
+    text Text
+    label Text
+    Foreign SimpleComposite fk_simple_composite text int
+    deriving Show Eq
 |]
 
 share [mkPersist sqlSettings, mkMigrate "compositeMigrateTest"] 
[persistLowerCase|
-Simple2 sql=simple
+SimpleComposite2 sql=simple_composite
     int Int
     text Text
-    bool Bool
+    new Int default=0
     Primary text int
     deriving Show Eq
+
+SimpleCompositeReference2 sql=simple_composite_reference
+    int Int
+    text Text
+    label Text
+    Foreign SimpleComposite2 fk_simple_composite text int
+    deriving Show Eq
+|]
+
+share [mkPersist sqlSettings, mkMigrate "idSetup"] [persistLowerCase|
+Simple
+    text Text
+    deriving Show Eq
+
+SimpleReference
+    simpleCompositeId SimpleId
+    text Text
+    deriving Show Eq
+|]
+
+share [mkPersist sqlSettings, mkMigrate "idMigrateTest"] [persistLowerCase|
+Simple2 sql=simple
+    text Text
+    int Int default=0
+    deriving Show Eq
+
+SimpleReference2 sql=simple_reference
+    simpleCompositeId Simple2Id
+    text Text
+    deriving Show Eq
 |]
 
 instance Arbitrary DataTypeTable where
@@ -247,6 +290,38 @@
         void $ runMigrationSilent compositeMigrateTest
         pure ()
 
+    it "test migrating sparse primary keys (issue #1184)" $ asIO $ 
withSystemTempFile "test564.sqlite3"$ \fp h -> do
+        hClose h
+        let connInfo = Lens.set fkEnabled False $ mkSqliteConnectionInfo 
(T.pack fp)
+        runSqliteInfo connInfo $ do
+            void $ runMigrationSilent idSetup
+            forM_ (map toSqlKey [1,3]) $ \key -> do
+                insertKey key (Simple "foo")
+                insert (SimpleReference key "test")
+
+            validateForeignKeys
+
+        runSqliteInfo connInfo $ do
+            void $ runMigrationSilent idMigrateTest
+            validateForeignKeys
+
+    it "test migrating sparse composite primary keys (issue #1184)" $ asIO $ 
withSystemTempFile "test564.sqlite3"$ \fp h -> do
+        hClose h
+        let connInfo = Lens.set fkEnabled False $ mkSqliteConnectionInfo 
(T.pack fp)
+
+        runSqliteInfo connInfo $ do
+            void $ runMigrationSilent compositeSetup
+            forM_ [(1,"foo"),(3,"bar")] $ \(intKey, strKey) -> do
+                let key = SimpleCompositeKey strKey intKey
+                insertKey key (SimpleComposite intKey strKey)
+                insert (SimpleCompositeReference intKey strKey "test")
+
+            validateForeignKeys
+
+        runSqliteInfo connInfo $ do
+            void $ runMigrationSilent compositeMigrateTest
+            validateForeignKeys
+
     it "afterException" $ asIO $ runSqliteInfo (mkSqliteConnectionInfo 
":memory:") $ do
         void $ runMigrationSilent testMigrate
         let catcher :: forall m. Monad m => SomeException -> m ()
@@ -255,3 +330,11 @@
         insert_ (Person "A" 1 Nothing) `catch` catcher
         insert_ $ Person "B" 0 Nothing
         return ()
+
+validateForeignKeys
+    :: (MonadResource m, MonadReader env m, BackendCompatible SqlBackend env)
+    => m ()
+validateForeignKeys = do
+    violations <- map (T.pack . show) <$> runConduit (checkForeignKeys .| 
CL.consume)
+    unless (null violations) . liftIO . throwIO $
+        PersistForeignConstraintUnmet (T.unlines violations)

Reply via email to