@@ -21,7 +21,7 @@ defmodule Sqlitex.Statement do
21
21
iex(6)> Sqlitex.Statement.exec(statement)
22
22
:ok
23
23
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 )
25
25
{:ok, [[id: 1, name: "hello"]]}
26
26
iex(9)> Sqlitex.close(db)
27
27
:ok
@@ -46,7 +46,7 @@ defmodule Sqlitex.Statement do
46
46
and store it separately in the `Statement` struct. Only the portion of the query
47
47
preceding the returning clause is passed to SQLite's prepare function.
48
48
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 `
50
50
the returning clause is parsed and the query is performed with the following
51
51
additional logic:
52
52
@@ -73,6 +73,8 @@ defmodule Sqlitex.Statement do
73
73
column_names: [ ] ,
74
74
column_types: [ ]
75
75
76
+ @ chunk_size 5000
77
+
76
78
alias Sqlitex.Config
77
79
78
80
@ doc """
@@ -170,35 +172,36 @@ defmodule Sqlitex.Statement do
170
172
## Parameters
171
173
172
174
* `statement` - The statement to run.
175
+ * `timeout` - The query timeout to be passed to esqlite.
173
176
* `into` - The collection to put the results into. Defaults to an empty list.
174
177
175
178
## Returns
176
179
177
180
* `{:ok, results}`
178
181
* `{:error, error}`
179
182
"""
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
182
185
{ :error , _ } = other -> other
183
186
raw_data ->
184
187
{ :ok , Row . from ( statement . column_types , statement . column_names , raw_data , into ) }
185
188
end
186
189
end
187
190
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 )
190
193
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 )
193
196
end
194
197
195
198
@ 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.
197
200
198
201
Returns the results otherwise.
199
202
"""
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
202
205
{ :ok , results } -> results
203
206
{ :error , reason } -> raise Sqlitex.Statement.FetchAllError , reason: reason
204
207
end
@@ -338,11 +341,11 @@ defmodule Sqlitex.Statement do
338
341
{ :error , :invalid_returning_clause }
339
342
end
340
343
341
- defp returning_query ( % __MODULE__ { database: db } = stmt ) do
344
+ defp returning_query ( % __MODULE__ { database: db } = stmt , timeout ) do
342
345
sp = "sp_#{ random_id ( ) } "
343
346
{ :ok , _ } = db_exec ( db , "SAVEPOINT #{ sp } " )
344
347
345
- case returning_query_in_savepoint ( sp , stmt ) do
348
+ case returning_query_in_savepoint ( sp , stmt , timeout ) do
346
349
{ :error , _ } = error ->
347
350
rollback ( db , sp )
348
351
error
@@ -354,7 +357,7 @@ defmodule Sqlitex.Statement do
354
357
355
358
defp returning_query_in_savepoint ( sp , % __MODULE__ { database: db ,
356
359
statement: statement ,
357
- returning: { table , cols , cmd , ref } } )
360
+ returning: { table , cols , cmd , ref } } , timeout )
358
361
do
359
362
temp_table = "t_#{ random_id ( ) } "
360
363
temp_fields = Enum . join ( cols , ", " )
@@ -371,7 +374,7 @@ defmodule Sqlitex.Statement do
371
374
372
375
with { :ok , _ } = db_exec ( db , "CREATE TEMP TABLE #{ temp_table } (#{ temp_fields } )" ) ,
373
376
{ :ok , _ } = db_exec ( db , trigger ) ,
374
- result = :esqlite3 . fetchall ( statement ) ,
377
+ result = :esqlite3 . fetchall ( statement , @ chunk_size , timeout ) ,
375
378
{ :ok , rows } = db_exec ( db , "SELECT #{ column_names } FROM #{ temp_table } " ) ,
376
379
{ :ok , _ } = db_exec ( db , "DROP TRIGGER IF EXISTS #{ trigger_name } " ) ,
377
380
{ :ok , _ } = db_exec ( db , "DROP TABLE IF EXISTS #{ temp_table } " )
0 commit comments