1
1
{-# OPTIONS_GHC -fno-warn-orphans #-}
2
2
{-# LANGUAGE BangPatterns #-}
3
- {-# LANGUAGE CPP #-}
4
3
{-# LANGUAGE DataKinds #-}
5
4
{-# LANGUAGE InstanceSigs #-}
6
5
{-# LANGUAGE UndecidableInstances #-}
@@ -72,6 +71,7 @@ import Data.ByteString.Builder (toLazyByteString)
72
71
import qualified Data.ByteString.Char8 as BS
73
72
import qualified Data.ByteString.Lazy.Char8 as BL
74
73
import qualified Data.DList as D
74
+ import Data.Hashable (hash )
75
75
import Data.Int
76
76
import Data.Maybe (mapMaybe )
77
77
import Data.Proxy (Proxy (.. ))
@@ -82,21 +82,13 @@ import qualified Data.Text.Encoding as T (decodeUtf8)
82
82
import qualified Data.Text.Lazy as TL
83
83
import qualified Data.Text.Lazy.Encoding as TL (decodeUtf8 )
84
84
import Data.Time ( LocalTime , UTCTime , Day
85
- , ZonedTime , utc , utcToLocalTime )
85
+ , ZonedTime , utc , utcToLocalTime , getCurrentTime )
86
86
import Data.Typeable (cast )
87
87
import Data.Word
88
88
import GHC.TypeLits
89
89
90
90
import Network.URI
91
91
92
- #ifdef UNIX
93
- import System.Posix.Process (getProcessID )
94
- #elif defined(WINDOWS)
95
- import System.Win32.Process (getCurrentProcessId )
96
- #else
97
- #error Need either POSIX or Win32 API for MonadBeamInsertReturning
98
- #endif
99
-
100
92
import Text.Read (readMaybe )
101
93
102
94
-- | The SQLite backend. Used to parameterize 'MonadBeam' and 'FromBackendRow'
@@ -388,34 +380,34 @@ runInsertReturningList SqlInsertNoRows = pure []
388
380
runInsertReturningList (SqlInsert tblSettings insertStmt_@ (SqliteInsertSyntax nm _ _ _)) =
389
381
do (logger, conn) <- SqliteM ask
390
382
SqliteM . liftIO $ do
391
-
392
- #ifdef UNIX
393
- processId <- fromString . show <$> getProcessID
394
- #elif defined(WINDOWS)
395
- processId <- fromString . show <$> getCurrentProcessId
396
- #else
397
- #error Need either POSIX or Win32 API for MonadBeamInsertReturning
398
- #endif
383
+
384
+ -- We create a pseudo-random savepoint identification that can be referenced
385
+ -- throughout this operation. -- This used to be based on the process ID
386
+ -- (e.g. `System.Posix.Process.getProcessID` for UNIX),
387
+ -- but using timestamps is more portable; see #738
388
+ --
389
+ -- Note that `hash` can return negative numbers, hence the use of `abs`.
390
+ savepointId <- fromString . show . abs . hash <$> getCurrentTime
399
391
400
392
let tableNameTxt = T. decodeUtf8 (BL. toStrict (sqliteRenderSyntaxScript (fromSqliteTableName nm)))
401
393
402
394
startSavepoint =
403
- execute_ conn (Query (" SAVEPOINT insert_savepoint_" <> processId ))
395
+ execute_ conn (Query (" SAVEPOINT insert_savepoint_" <> savepointId ))
404
396
rollbackToSavepoint =
405
- execute_ conn (Query (" ROLLBACK TRANSACTION TO SAVEPOINT insert_savepoint_" <> processId ))
397
+ execute_ conn (Query (" ROLLBACK TRANSACTION TO SAVEPOINT insert_savepoint_" <> savepointId ))
406
398
releaseSavepoint =
407
- execute_ conn (Query (" RELEASE SAVEPOINT insert_savepoint_" <> processId ))
399
+ execute_ conn (Query (" RELEASE SAVEPOINT insert_savepoint_" <> savepointId ))
408
400
409
401
createInsertedValuesTable =
410
- execute_ conn (Query (" CREATE TEMPORARY TABLE inserted_values_" <> processId <> " AS SELECT * FROM " <> tableNameTxt <> " LIMIT 0" ))
402
+ execute_ conn (Query (" CREATE TEMPORARY TABLE inserted_values_" <> savepointId <> " AS SELECT * FROM " <> tableNameTxt <> " LIMIT 0" ))
411
403
dropInsertedValuesTable =
412
- execute_ conn (Query (" DROP TABLE inserted_values_" <> processId ))
404
+ execute_ conn (Query (" DROP TABLE inserted_values_" <> savepointId ))
413
405
414
406
createInsertTrigger =
415
- execute_ conn (Query (" CREATE TEMPORARY TRIGGER insert_trigger_" <> processId <> " AFTER INSERT ON " <> tableNameTxt <> " BEGIN " <>
416
- " INSERT INTO inserted_values_" <> processId <> " SELECT * FROM " <> tableNameTxt <> " WHERE ROWID=last_insert_rowid(); END" ))
407
+ execute_ conn (Query (" CREATE TEMPORARY TRIGGER insert_trigger_" <> savepointId <> " AFTER INSERT ON " <> tableNameTxt <> " BEGIN " <>
408
+ " INSERT INTO inserted_values_" <> savepointId <> " SELECT * FROM " <> tableNameTxt <> " WHERE ROWID=last_insert_rowid(); END" ))
417
409
dropInsertTrigger =
418
- execute_ conn (Query (" DROP TRIGGER insert_trigger_" <> processId ))
410
+ execute_ conn (Query (" DROP TRIGGER insert_trigger_" <> savepointId ))
419
411
420
412
421
413
mask $ \ restore -> do
@@ -430,7 +422,7 @@ runInsertReturningList (SqlInsert tblSettings insertStmt_@(SqliteInsertSyntax nm
430
422
allBeamValues (\ (Columnar' projField) -> quotedIdentifier (_fieldName projField)) $
431
423
tblSettings
432
424
433
- fmap (\ (BeamSqliteRow r) -> r) <$> query_ conn (Query (" SELECT " <> columns <> " FROM inserted_values_" <> processId ))
425
+ fmap (\ (BeamSqliteRow r) -> r) <$> query_ conn (Query (" SELECT " <> columns <> " FROM inserted_values_" <> savepointId ))
434
426
releaseSavepoint
435
427
return x
436
428
0 commit comments