@@ -21,7 +21,7 @@ defmodule Sqlitex.Statement do
2121 iex(6)> Sqlitex.Statement.exec(statement)
2222 :ok
2323 iex(7)> {:ok, statement} = Sqlitex.Statement.prepare(db, "SELECT * FROM data;")
24- iex(8)> Sqlitex.Statement.fetch_all(statement)
24+ iex(8)> Sqlitex.Statement.fetch_all(statement, 1_000 )
2525 {:ok, [[id: 1, name: "hello"]]}
2626 iex(9)> Sqlitex.close(db)
2727 :ok
@@ -46,7 +46,7 @@ defmodule Sqlitex.Statement do
4646 and store it separately in the `Statement` struct. Only the portion of the query
4747 preceding the returning clause is passed to SQLite's prepare function.
4848
49- Later, when such a statement struct is passed to `fetch_all/2 ` or `fetch_all!/2 `
49+ Later, when such a statement struct is passed to `fetch_all/3 ` or `fetch_all!/3 `
5050 the returning clause is parsed and the query is performed with the following
5151 additional logic:
5252
@@ -73,6 +73,8 @@ defmodule Sqlitex.Statement do
7373 column_names: [ ] ,
7474 column_types: [ ]
7575
76+ @ chunk_size 5000
77+
7678 alias Sqlitex.Config
7779
7880 @ doc """
@@ -170,35 +172,36 @@ defmodule Sqlitex.Statement do
170172 ## Parameters
171173
172174 * `statement` - The statement to run.
175+ * `timeout` - The query timeout to be passed to esqlite.
173176 * `into` - The collection to put the results into. Defaults to an empty list.
174177
175178 ## Returns
176179
177180 * `{:ok, results}`
178181 * `{:error, error}`
179182 """
180- def fetch_all ( statement , into \\ [ ] ) do
181- case raw_fetch_all ( statement ) do
183+ def fetch_all ( statement , timeout , into \\ [ ] ) do
184+ case raw_fetch_all ( statement , timeout ) do
182185 { :error , _ } = other -> other
183186 raw_data ->
184187 { :ok , Row . from ( statement . column_types , statement . column_names , raw_data , into ) }
185188 end
186189 end
187190
188- defp raw_fetch_all ( % __MODULE__ { returning: nil , statement: statement } ) do
189- :esqlite3 . fetchall ( statement )
191+ defp raw_fetch_all ( % __MODULE__ { returning: nil , statement: statement } , timeout ) do
192+ :esqlite3 . fetchall ( statement , @ chunk_size , timeout )
190193 end
191- defp raw_fetch_all ( statement ) do
192- returning_query ( statement )
194+ defp raw_fetch_all ( statement , timeout ) do
195+ returning_query ( statement , timeout )
193196 end
194197
195198 @ doc """
196- Same as `fetch_all/2 ` but raises a Sqlitex.Statement.FetchAllError on error.
199+ Same as `fetch_all/3 ` but raises a Sqlitex.Statement.FetchAllError on error.
197200
198201 Returns the results otherwise.
199202 """
200- def fetch_all! ( statement , into \\ [ ] ) do
201- case fetch_all ( statement , into ) do
203+ def fetch_all! ( statement , timeout , into \\ [ ] ) do
204+ case fetch_all ( statement , timeout , into ) do
202205 { :ok , results } -> results
203206 { :error , reason } -> raise Sqlitex.Statement.FetchAllError , reason: reason
204207 end
@@ -338,11 +341,11 @@ defmodule Sqlitex.Statement do
338341 { :error , :invalid_returning_clause }
339342 end
340343
341- defp returning_query ( % __MODULE__ { database: db } = stmt ) do
344+ defp returning_query ( % __MODULE__ { database: db } = stmt , timeout ) do
342345 sp = "sp_#{ random_id ( ) } "
343346 { :ok , _ } = db_exec ( db , "SAVEPOINT #{ sp } " )
344347
345- case returning_query_in_savepoint ( sp , stmt ) do
348+ case returning_query_in_savepoint ( sp , stmt , timeout ) do
346349 { :error , _ } = error ->
347350 rollback ( db , sp )
348351 error
@@ -354,7 +357,7 @@ defmodule Sqlitex.Statement do
354357
355358 defp returning_query_in_savepoint ( sp , % __MODULE__ { database: db ,
356359 statement: statement ,
357- returning: { table , cols , cmd , ref } } )
360+ returning: { table , cols , cmd , ref } } , timeout )
358361 do
359362 temp_table = "t_#{ random_id ( ) } "
360363 temp_fields = Enum . join ( cols , ", " )
@@ -371,7 +374,7 @@ defmodule Sqlitex.Statement do
371374
372375 with { :ok , _ } = db_exec ( db , "CREATE TEMP TABLE #{ temp_table } (#{ temp_fields } )" ) ,
373376 { :ok , _ } = db_exec ( db , trigger ) ,
374- result = :esqlite3 . fetchall ( statement ) ,
377+ result = :esqlite3 . fetchall ( statement , @ chunk_size , timeout ) ,
375378 { :ok , rows } = db_exec ( db , "SELECT #{ column_names } FROM #{ temp_table } " ) ,
376379 { :ok , _ } = db_exec ( db , "DROP TRIGGER IF EXISTS #{ trigger_name } " ) ,
377380 { :ok , _ } = db_exec ( db , "DROP TABLE IF EXISTS #{ temp_table } " )
0 commit comments