From c638f1162f9e71e176c3091a7efaaf2ec692dec2 Mon Sep 17 00:00:00 2001 From: Heinrich Apfelmus Date: Thu, 18 Jul 2024 19:34:23 +0200 Subject: [PATCH] Improve performance of `insertMany` with prepared statement --- .../src/Database/Table/SQLite/Simple/Exec.hs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/delta-table/src/Database/Table/SQLite/Simple/Exec.hs b/lib/delta-table/src/Database/Table/SQLite/Simple/Exec.hs index a5657b59912..17b41f892b3 100644 --- a/lib/delta-table/src/Database/Table/SQLite/Simple/Exec.hs +++ b/lib/delta-table/src/Database/Table/SQLite/Simple/Exec.hs @@ -134,8 +134,22 @@ selectWhere expr = queryNamed . Stmt.selectWhere expr insertOne :: IsTableSql t => Row t -> proxy t -> SqlM () insertOne row proxy = executeOne (Stmt.insertOne proxy) row +-- | Insert many rows into a database table. +-- +-- As an optimization, we use a single prepared SQL statement. insertMany :: IsTableSql t => [Row t] -> proxy t -> SqlM () -insertMany rows proxy = for_ rows (`insertOne` proxy) +insertMany rows proxy = + ReaderT $ \conn -> do + -- The 'query' string contains '?' which will be substituted + -- for the values in the row, but no named params. + let (query, _noBindings) = renderStmt $ Stmt.insertOne proxy + Sqlite.withStatement conn query $ \stmt -> + for_ rows $ \row -> + -- From : + -- Each call to sqlite3_bind() overrides + -- prior bindings on the same parameter. + Sqlite.withBind stmt row (Sqlite.nextRow stmt) + :: IO (Maybe [Bool]) -- dummy type, we expect 'Nothing' updateWhere :: IsTableSql t