@@ -42,18 +42,26 @@ module Simplex.Messaging.Agent.Store.SQLite
4242 )
4343where
4444
45+ import Control.Concurrent.MVar
46+ import Control.Concurrent.STM
47+ import Control.Exception (bracketOnError , onException , throwIO )
4548import Control.Monad
4649import Data.ByteArray (ScrubbedBytes )
4750import qualified Data.ByteArray as BA
51+ import qualified Data.ByteString as B
4852import Data.Functor (($>) )
4953import Data.IORef
5054import Data.Maybe (fromMaybe )
55+ import Data.Int (Int64 )
5156import Data.Text (Text )
5257import qualified Data.Text as T
5358import Database.SQLite.Simple (Query (.. ))
5459import qualified Database.SQLite.Simple as SQL
5560import Database.SQLite.Simple.QQ (sql )
61+ import Database.SQLite3 (FuncArgs , FuncContext , funcArgInt64 , funcResultBlob )
5662import qualified Database.SQLite3 as SQLite3
63+ import Database.SQLite3.Direct (createAggregate )
64+ import Simplex.MemberRelations.MemberRelations (MemberRelation (.. ), fromRelationInt , setRelations )
5765import Simplex.Messaging.Agent.Store.Migrations (DBMigrate (.. ), sharedMigrateSchema )
5866import qualified Simplex.Messaging.Agent.Store.SQLite.Migrations as Migrations
5967import Simplex.Messaging.Agent.Store.SQLite.Common
@@ -62,9 +70,6 @@ import Simplex.Messaging.Agent.Store.Shared (Migration (..), MigrationConfig (..
6270import Simplex.Messaging.Util (ifM , safeDecodeUtf8 )
6371import System.Directory (copyFile , createDirectoryIfMissing , doesFileExist )
6472import System.FilePath (takeDirectory , takeFileName , (</>) )
65- import UnliftIO.Exception (bracketOnError , onException )
66- import UnliftIO.MVar
67- import UnliftIO.STM
6873
6974-- * SQLite Store implementation
7075
@@ -109,16 +114,31 @@ connectDB path key track = do
109114 pure db
110115 where
111116 prepare db = do
112- let exec = SQLite3. exec $ SQL. connectionHandle $ DB. conn db
113- unless (BA. null key) . exec $ " PRAGMA key = " <> keyString key <> " ;"
114- exec . fromQuery $
117+ let db' = SQL. connectionHandle $ DB. conn db
118+ unless (BA. null key) . SQLite3. exec db' $ " PRAGMA key = " <> keyString key <> " ;"
119+ SQLite3. exec db' . fromQuery $
115120 [sql |
116121 PRAGMA busy_timeout = 100;
117122 PRAGMA foreign_keys = ON;
118123 -- PRAGMA trusted_schema = OFF;
119124 PRAGMA secure_delete = ON;
120125 PRAGMA auto_vacuum = FULL;
121126 |]
127+ createAggregate db' " build_relations_vector" (Just 2 ) [] buildRelationsVectorStep buildRelationsVectorFinal
128+ >>= either (throwIO . userError . show ) pure
129+
130+ -- | Step function for build_relations_vector aggregate.
131+ -- Accumulates (idx, relation) pairs.
132+ buildRelationsVectorStep :: FuncContext -> FuncArgs -> [(Int64 , MemberRelation )] -> IO [(Int64 , MemberRelation )]
133+ buildRelationsVectorStep _ args acc = do
134+ idx <- funcArgInt64 args 0
135+ relation <- fromRelationInt . fromIntegral <$> funcArgInt64 args 1
136+ pure $ (idx, relation) : acc
137+
138+ -- | Final function for build_relations_vector aggregate.
139+ -- Builds the vector from accumulated pairs using setRelations.
140+ buildRelationsVectorFinal :: FuncContext -> [(Int64 , MemberRelation )] -> IO ()
141+ buildRelationsVectorFinal ctx acc = funcResultBlob ctx $ setRelations acc B. empty
122142
123143closeDBStore :: DBStore -> IO ()
124144closeDBStore st@ DBStore {dbClosed} =
0 commit comments