@@ -3,12 +3,13 @@ defmodule Exqlite do
3
3
SQLite3 driver for Elixir.
4
4
"""
5
5
6
- alias Exqlite . { Nif , Error }
6
+ alias Exqlite . { Nif , SQLiteError , UsageError }
7
7
8
8
@ type conn :: reference ( )
9
9
@ type stmt :: reference ( )
10
10
@ type bind_arg :: atom | binary | number | { :blob , binary }
11
11
@ type returned_row :: [ number | binary | nil ]
12
+ @ type error :: SQLiteError . t ( ) | UsageError . t ( )
12
13
13
14
# https://www.sqlite.org/c3ref/c_open_autoproxy.html
14
15
open_flag_mappings = [
@@ -57,7 +58,7 @@ defmodule Exqlite do
57
58
See https://www.sqlite.org/c3ref/c_open_autoproxy.html for more options.
58
59
59
60
"""
60
- @ spec open ( String . t ( ) , [ open_flag ] ) :: { :ok , conn } | { :error , Error . t ( ) }
61
+ @ spec open ( String . t ( ) , [ open_flag ] ) :: { :ok , conn } | { :error , error }
61
62
def open ( path , flags \\ @ default_open_flags ) do
62
63
path = String . to_charlist ( path )
63
64
@@ -72,13 +73,13 @@ defmodule Exqlite do
72
73
@ doc """
73
74
Closes the database and releases any underlying resources.
74
75
"""
75
- @ spec close ( conn ) :: :ok | { :error , Error . t ( ) }
76
+ @ spec close ( conn ) :: :ok | { :error , error }
76
77
def close ( conn ) , do: wrap_error ( Nif . close ( conn ) )
77
78
78
79
@ doc """
79
80
Executes an sql script. Multiple stanzas can be passed at once.
80
81
"""
81
- @ spec execute ( conn , iodata ) :: :ok | { :error , Error . t ( ) }
82
+ @ spec execute ( conn , iodata ) :: :ok | { :error , error }
82
83
def execute ( conn , sql ) , do: wrap_error ( Nif . execute ( conn , sql ) )
83
84
84
85
@ doc """
@@ -88,38 +89,38 @@ defmodule Exqlite do
88
89
89
90
See: https://sqlite.org/c3ref/changes.html
90
91
"""
91
- @ spec changes ( conn ) :: { :ok , non_neg_integer } | { :error , Error . t ( ) }
92
+ @ spec changes ( conn ) :: { :ok , non_neg_integer } | { :error , error }
92
93
def changes ( conn ) , do: wrap_error ( Nif . changes ( conn ) )
93
94
94
95
@ doc """
95
96
Prepares an SQL statement.
96
97
"""
97
- @ spec prepare ( conn , iodata ) :: { :ok , stmt } | { :error , Error . t ( ) }
98
+ @ spec prepare ( conn , iodata ) :: { :ok , stmt } | { :error , error }
98
99
def prepare ( conn , sql ) , do: wrap_error ( Nif . prepare ( conn , sql ) )
99
100
100
101
@ doc """
101
102
Binds values to a prepared SQL statement.
102
103
"""
103
- @ spec bind ( conn , stmt , [ bind_arg ] ) :: :ok | { :error , Error . t ( ) }
104
+ @ spec bind ( conn , stmt , [ bind_arg ] ) :: :ok | { :error , error }
104
105
def bind ( conn , stmt , args ) , do: wrap_error ( Nif . bind ( conn , stmt , args ) )
105
106
106
107
@ doc """
107
108
Reads the column names returned by a prepared SQL statement.
108
109
"""
109
- @ spec columns ( conn , stmt ) :: { :ok , [ String . t ( ) ] } | { :error , Error . t ( ) }
110
+ @ spec columns ( conn , stmt ) :: { :ok , [ String . t ( ) ] } | { :error , error }
110
111
def columns ( conn , stmt ) , do: wrap_error ( Nif . columns ( conn , stmt ) )
111
112
112
113
@ doc """
113
114
Performs a single step through a prepared SQL statement.
114
115
"""
115
- @ spec step ( conn , stmt ) :: { :row , returned_row } | :done | { :error , Error . t ( ) }
116
+ @ spec step ( conn , stmt ) :: { :row , returned_row } | :done | { :error , error }
116
117
def step ( conn , stmt ) , do: wrap_error ( Nif . step ( conn , stmt ) )
117
118
118
119
@ doc """
119
120
Performs multiple steps through a prepared SQL statement in a single NIF call.
120
121
"""
121
122
@ spec multi_step ( conn , stmt , pos_integer ) ::
122
- { :rows , [ returned_row ] } | { :done , [ returned_row ] } | { :error , Error . t ( ) }
123
+ { :rows , [ returned_row ] } | { :done , [ returned_row ] } | { :error , error }
123
124
def multi_step ( conn , stmt , max_rows ) do
124
125
case Nif . multi_step ( conn , stmt , max_rows ) do
125
126
{ :rows , rows } -> { :rows , :lists . reverse ( rows ) }
@@ -131,20 +132,20 @@ defmodule Exqlite do
131
132
@ doc """
132
133
Reads the last inserted ROWID from the connection.
133
134
"""
134
- @ spec last_insert_rowid ( conn ) :: { :ok , integer } | { :error , Error . t ( ) }
135
+ @ spec last_insert_rowid ( conn ) :: { :ok , integer } | { :error , error }
135
136
def last_insert_rowid ( conn ) , do: wrap_error ( Nif . last_insert_rowid ( conn ) )
136
137
137
138
@ doc """
138
139
Reads the transactions status of the connection.
139
140
"""
140
- @ spec transaction_status ( conn ) :: { :ok , :idle | :transaction } | { :error , Error . t ( ) }
141
+ @ spec transaction_status ( conn ) :: { :ok , :idle | :transaction } | { :error , error }
141
142
def transaction_status ( conn ) , do: wrap_error ( Nif . transaction_status ( conn ) )
142
143
143
144
@ doc """
144
145
Fetches all rows from a prepared statement in batches of `max_rows` per NIF call.
145
146
"""
146
147
@ spec fetch_all ( conn , stmt , pos_integer ) ::
147
- { :ok , [ returned_row ] } | { :error , Error . t ( ) }
148
+ { :ok , [ returned_row ] } | { :error , error }
148
149
def fetch_all ( conn , stmt , max_rows \\ 50 ) when is_reference ( stmt ) do
149
150
{ :ok , try_fetch_all ( conn , stmt , max_rows ) }
150
151
catch
@@ -162,7 +163,7 @@ defmodule Exqlite do
162
163
# TODO document once the write counterpart is ready
163
164
@ doc false
164
165
@ spec prepare_fetch_all ( conn , iodata , [ bind_arg ] , pos_integer ) ::
165
- { :ok , [ returned_row ] } | { :error , Error . t ( ) }
166
+ { :ok , [ returned_row ] } | { :error , error }
166
167
def prepare_fetch_all ( conn , sql , args \\ [ ] , max_rows \\ 50 ) do
167
168
with { :ok , stmt } <- prepare ( conn , sql ) do
168
169
try do
@@ -178,7 +179,7 @@ defmodule Exqlite do
178
179
@ doc """
179
180
Serialize the contents of the database to a binary.
180
181
"""
181
- @ spec serialize ( conn , String . t ( ) ) :: { :ok , binary } | { :error , Error . t ( ) }
182
+ @ spec serialize ( conn , String . t ( ) ) :: { :ok , binary } | { :error , error }
182
183
def serialize ( conn , database \\ "main" ) do
183
184
wrap_error ( Nif . serialize ( conn , to_charlist ( database ) ) )
184
185
end
@@ -187,7 +188,7 @@ defmodule Exqlite do
187
188
Disconnect from database and then reopen as an in-memory database based on
188
189
the serialized binary.
189
190
"""
190
- @ spec deserialize ( conn , String . t ( ) , binary ) :: :ok | { :error , Error . t ( ) }
191
+ @ spec deserialize ( conn , String . t ( ) , binary ) :: :ok | { :error , error }
191
192
def deserialize ( conn , database \\ "main" , serialized ) do
192
193
wrap_error ( Nif . deserialize ( conn , to_charlist ( database ) , serialized ) )
193
194
end
@@ -203,19 +204,19 @@ defmodule Exqlite do
203
204
204
205
If you are operating on limited memory capacity systems, definitely call this.
205
206
"""
206
- @ spec release ( stmt ) :: :ok | { :error , Error . t ( ) }
207
+ @ spec release ( stmt ) :: :ok | { :error , error }
207
208
def release ( stmt ) , do: wrap_error ( Nif . release ( stmt ) )
208
209
209
210
@ doc """
210
211
Allow loading native extensions.
211
212
"""
212
- @ spec enable_load_extension ( conn ) :: :ok | { :error , Error . t ( ) }
213
+ @ spec enable_load_extension ( conn ) :: :ok | { :error , error }
213
214
def enable_load_extension ( conn ) , do: wrap_error ( Nif . enable_load_extension ( conn , 1 ) )
214
215
215
216
@ doc """
216
217
Forbid loading native extensions.
217
218
"""
218
- @ spec disable_load_extension ( conn ) :: :ok | { :error , Error . t ( ) }
219
+ @ spec disable_load_extension ( conn ) :: :ok | { :error , error }
219
220
def disable_load_extension ( conn ) , do: wrap_error ( Nif . enable_load_extension ( conn , 0 ) )
220
221
221
222
@ doc """
@@ -242,7 +243,7 @@ defmodule Exqlite do
242
243
hook set for connection A will not receive the update, but the hook for
243
244
connection B will receive the update.
244
245
"""
245
- @ spec set_update_hook ( conn , pid ) :: :ok | { :error , Error . t ( ) }
246
+ @ spec set_update_hook ( conn , pid ) :: :ok | { :error , error }
246
247
def set_update_hook ( conn , pid ) , do: wrap_error ( Nif . set_update_hook ( conn , pid ) )
247
248
248
249
@ doc """
@@ -264,13 +265,17 @@ defmodule Exqlite do
264
265
If this function is called multiple times, only the last pid will
265
266
receive the notifications
266
267
"""
267
- @ spec set_log_hook ( pid ) :: :ok | { :error , Error . t ( ) }
268
+ @ spec set_log_hook ( pid ) :: :ok | { :error , error }
268
269
def set_log_hook ( pid ) , do: wrap_error ( Nif . set_log_hook ( pid ) )
269
270
270
271
# TODO sql / statement
271
272
@ compile inline: [ wrap_error: 1 ]
272
- defp wrap_error ( { :error , reason } ) do
273
- { :error , Error . exception ( message: reason ) }
273
+ defp wrap_error ( { :error , reason } ) when is_binary ( reason ) do
274
+ { :error , UsageError . exception ( message: reason ) }
275
+ end
276
+
277
+ defp wrap_error ( { :error , error } ) when is_list ( error ) do
278
+ { :error , SQLiteError . exception ( error ) }
274
279
end
275
280
276
281
defp wrap_error ( success ) , do: success
0 commit comments