@@ -28,6 +28,7 @@ defmodule Exqlite.Connection do
28
28
alias Exqlite.Query
29
29
alias Exqlite.Result
30
30
alias Exqlite.Sqlite3
31
+ require Logger
31
32
32
33
defstruct [
33
34
:db ,
@@ -128,6 +129,32 @@ defmodule Exqlite.Connection do
128
129
* `:soft_heap_limit` - The size limit in bytes for the heap limit.
129
130
* `:hard_heap_limit` - The size limit in bytes for the heap.
130
131
* `:custom_pragmas` - A list of custom pragmas to set on the connection, for example to configure extensions.
132
+ * `:load_extensions` - A list of paths identifying extensions to load. Defaults to `[]`.
133
+ The provided list will be merged with the global extensions list, set on `:exqlite, :load_extensions`.
134
+ Be aware that the path should handle pointing to a library compiled for the current architecture.
135
+ Example configuration:
136
+
137
+ ```
138
+ arch_dir =
139
+ System.cmd("uname", ["-sm"])
140
+ |> elem(0)
141
+ |> String.trim()
142
+ |> String.replace(" ", "-")
143
+ |> String.downcase() # => "darwin-arm64"
144
+
145
+ config :myapp, arch_dir: arch_dir
146
+
147
+ # global
148
+ config :exqlite, load_extensions: [ "./priv/sqlite/\# {arch_dir}/rotate" ]
149
+
150
+ # per connection in a Phoenix app
151
+ config :myapp, Myapp.Repo,
152
+ database: "path/to/db",
153
+ load_extensions: [
154
+ "./priv/sqlite/\# {arch_dir}/vector0",
155
+ "./priv/sqlite/\# {arch_dir}/vss0"
156
+ ]
157
+ ```
131
158
132
159
For more information about the options above, see [sqlite documentation][1]
133
160
@@ -460,6 +487,30 @@ defmodule Exqlite.Connection do
460
487
set_pragma ( db , "busy_timeout" , Pragma . busy_timeout ( options ) )
461
488
end
462
489
490
+ defp load_extensions ( db , options ) do
491
+ global_extensions = Application . get_env ( :exqlite , :load_extensions , [ ] )
492
+
493
+ extensions =
494
+ Keyword . get ( options , :load_extensions , [ ] )
495
+ |> Enum . concat ( global_extensions )
496
+ |> Enum . uniq ( )
497
+
498
+ do_load_extensions ( db , extensions )
499
+ end
500
+
501
+ defp do_load_extensions ( _db , [ ] ) , do: :ok
502
+
503
+ defp do_load_extensions ( db , extensions ) do
504
+ Sqlite3 . enable_load_extension ( db , true )
505
+
506
+ Enum . each ( extensions , fn extension ->
507
+ Logger . debug ( fn -> "Exqlite: loading extension `#{ extension } `" end )
508
+ Sqlite3 . execute ( db , "SELECT load_extension('#{ extension } ')" )
509
+ end )
510
+
511
+ Sqlite3 . enable_load_extension ( db , false )
512
+ end
513
+
463
514
defp do_connect ( database , options ) do
464
515
with { :ok , directory } <- resolve_directory ( database ) ,
465
516
:ok <- mkdir_p ( directory ) ,
@@ -480,7 +531,8 @@ defmodule Exqlite.Connection do
480
531
:ok <- set_busy_timeout ( db , options ) ,
481
532
:ok <- set_journal_size_limit ( db , options ) ,
482
533
:ok <- set_soft_heap_limit ( db , options ) ,
483
- :ok <- set_hard_heap_limit ( db , options ) do
534
+ :ok <- set_hard_heap_limit ( db , options ) ,
535
+ :ok <- load_extensions ( db , options ) do
484
536
state = % __MODULE__ {
485
537
db: db ,
486
538
directory: directory ,
0 commit comments