1
+ defimpl DBConnection.Query , for: BitString do
2
+ def parse ( query , _opts ) , do: query
3
+
4
+ def describe ( query , _opts ) , do: query
5
+
6
+ def encode ( _query , params , _opts ) , do: Enum . into ( params , % { } )
7
+
8
+ def decode ( _query , params , _opts ) , do: params
9
+ end
10
+
1
11
defmodule Arangox.Connection do
2
12
@ moduledoc false
3
13
@@ -22,6 +32,7 @@ defmodule Arangox.Connection do
22
32
username: binary ,
23
33
password: binary ,
24
34
headers: Arangox . headers ( ) ,
35
+ disconnect_on_error_codes: [ integer ] ,
25
36
read_only?: boolean ,
26
37
cursors: map
27
38
}
@@ -38,6 +49,7 @@ defmodule Arangox.Connection do
38
49
username: "root" ,
39
50
password: "" ,
40
51
headers: % { } ,
52
+ disconnect_on_error_codes: [ 401 , 405 , 503 , 505 ] ,
41
53
read_only?: false ,
42
54
cursors: % { }
43
55
]
@@ -238,117 +250,111 @@ defmodule Arangox.Connection do
238
250
|> Keyword . get ( :properties , [ ] )
239
251
|> Enum . into ( % { collections: collections } )
240
252
241
- with (
242
- { :ok , % Response { status: 201 } = response , state } <-
243
- % Request {
244
- method: :post ,
245
- path: Path . join ( @ path_trx , "begin" ) ,
246
- body: body
247
- }
248
- |> merge_headers ( state . headers )
249
- |> maybe_prepend_database ( state )
250
- |> maybe_encode_body ( state )
251
- |> Client . request ( state ) ,
252
- % Response { body: % { "result" => % { "id" => id } } } = response <-
253
- maybe_decode_body ( response , state )
254
- ) do
255
- { :ok , response , put_header ( state , { @ header_trx_id , id } ) }
256
- else
257
- { :ok , % Response { } , state } ->
253
+ request = % Request {
254
+ method: :post ,
255
+ path: Path . join ( @ path_trx , "begin" ) ,
256
+ body: body
257
+ }
258
+
259
+ case handle_execute ( nil , request , opts , state ) do
260
+ { :ok , _request , % Response { status: 201 , body: % { "result" => % { "id" => id } } } = response ,
261
+ state } ->
262
+ { :ok , response , put_header ( state , { @ header_trx_id , id } ) }
263
+
264
+ { :ok , _request , % Response { } , state } ->
258
265
{ :error , state }
259
266
260
- { :error , :noproc , state } ->
261
- { :disconnect , exception ( state , "connection lost" ) , state }
267
+ { :error , _exception , state } ->
268
+ { :error , state }
262
269
263
- { :error , _reason , state } ->
270
+ { :disconnect , _exception , state } ->
264
271
{ :error , state }
265
272
end
266
273
end
267
274
268
275
@ impl true
269
- def handle_status ( _opts , % __MODULE__ { } = state ) do
276
+ def handle_status ( opts , % __MODULE__ { } = state ) do
270
277
with (
271
- { id , headers } when is_binary ( id ) <- Map . pop ( state . headers , @ header_trx_id ) ,
272
- { :ok , % Response { status: 200 } , state } <-
273
- % Request {
274
- method: :get ,
275
- path: Path . join ( @ path_trx , id )
276
- }
277
- |> merge_headers ( headers )
278
- |> maybe_prepend_database ( state )
279
- |> Client . request ( state )
278
+ { id , _headers } when is_binary ( id ) <-
279
+ Map . pop ( state . headers , @ header_trx_id ) ,
280
+ { :ok , _request , % Response { status: 200 } , state } <-
281
+ handle_execute (
282
+ nil ,
283
+ % Request { method: :get , path: Path . join ( @ path_trx , id ) } ,
284
+ opts ,
285
+ state
286
+ )
280
287
) do
281
288
{ :transaction , state }
282
289
else
283
290
{ nil , _headers } ->
284
291
{ :idle , state }
285
292
286
- { :ok , % Response { status: _status } , state } ->
293
+ { :ok , _request , % Response { } , state } ->
287
294
{ :error , state }
288
295
289
- { :error , :noproc , state } ->
290
- { :disconnect , exception ( state , "connection lost" ) , state }
291
-
292
- { :error , _reason , state } ->
296
+ { :error , _exception , state } ->
293
297
{ :error , state }
298
+
299
+ { :disconnect , exception , state } ->
300
+ { :disconnect , exception , state }
294
301
end
295
302
end
296
303
297
304
@ impl true
298
- def handle_commit ( _opts , % __MODULE__ { } = state ) do
305
+ def handle_commit ( opts , % __MODULE__ { } = state ) do
299
306
with (
300
- { id , headers } when is_binary ( id ) <- Map . pop ( state . headers , @ header_trx_id ) ,
301
- { :ok , % Response { status: 200 } = response , state } <-
302
- % Request {
303
- method: :put ,
304
- path: Path . join ( @ path_trx , id )
305
- }
306
- |> merge_headers ( headers )
307
- |> maybe_prepend_database ( state )
308
- |> Client . request ( state )
307
+ { id , headers } when is_binary ( id ) <-
308
+ Map . pop ( state . headers , @ header_trx_id ) ,
309
+ { :ok , _request , % Response { status: 200 } = response , state } <-
310
+ handle_execute (
311
+ nil ,
312
+ % Request { method: :put , path: Path . join ( @ path_trx , id ) } ,
313
+ opts ,
314
+ % { state | headers: headers }
315
+ )
309
316
) do
310
- { :ok , maybe_decode_body ( response , state ) , % { state | headers: headers } }
317
+ { :ok , response , state }
311
318
else
312
319
{ nil , _headers } ->
313
320
{ :idle , state }
314
321
315
- { :ok , % Response { status: _status } , state } ->
322
+ { :ok , _request , % Response { } , state } ->
316
323
{ :error , state }
317
324
318
- { :error , :noproc , state } ->
319
- { :disconnect , exception ( state , "connection lost" ) , state }
320
-
321
- { :error , _reason , state } ->
325
+ { :error , _exception , state } ->
322
326
{ :error , state }
327
+
328
+ { :disconnect , exception , state } ->
329
+ { :disconnect , exception , state }
323
330
end
324
331
end
325
332
326
333
@ impl true
327
- def handle_rollback ( _opts , % __MODULE__ { } = state ) do
334
+ def handle_rollback ( opts , % __MODULE__ { } = state ) do
328
335
with (
329
336
{ id , headers } when is_binary ( id ) <- Map . pop ( state . headers , @ header_trx_id ) ,
330
- { :ok , % Response { status: 200 } = response , state } <-
331
- % Request {
332
- method: :delete ,
333
- path: Path . join ( @ path_trx , id )
334
- }
335
- |> merge_headers ( headers )
336
- |> maybe_prepend_database ( state )
337
- |> Client . request ( state )
337
+ { :ok , _request , % Response { status: 200 } = response , state } <-
338
+ handle_execute (
339
+ nil ,
340
+ % Request { method: :put , path: Path . join ( @ path_trx , id ) } ,
341
+ opts ,
342
+ % { state | headers: headers }
343
+ )
338
344
) do
339
- { :ok , maybe_decode_body ( response , state ) , % { state | headers: headers } }
345
+ { :ok , response , state }
340
346
else
341
347
{ nil , _headers } ->
342
348
{ :idle , state }
343
349
344
- { :ok , % Response { status: _status } , state } ->
350
+ { :ok , _request , % Response { } , state } ->
345
351
{ :error , state }
346
352
347
- { :error , :noproc , state } ->
348
- { :disconnect , exception ( state , "connection lost" ) , state }
349
-
350
- { :error , _reason , state } ->
353
+ { :error , _exception , state } ->
351
354
{ :error , state }
355
+
356
+ { :disconnect , exception , state } ->
357
+ { :disconnect , exception , state }
352
358
end
353
359
end
354
360
@@ -429,41 +435,14 @@ defmodule Arangox.Connection do
429
435
end
430
436
end
431
437
432
- # Execution callbacks
433
-
434
- defmacrop exec_case ( condition , do: body ) do
435
- { :case , [ ] , [ condition , [ do: exec_cases_before ( ) ++ body ++ exec_cases_after ( ) ] ] }
436
- end
437
-
438
- def exec_cases_before do
439
- quote do
440
- { :ok , % Response { status: 505 } = response , state } ->
441
- { :disconnect , exception ( state , response ) , state }
442
-
443
- { :ok , % Response { status: 503 } = response , state } ->
444
- { :disconnect , exception ( state , response ) , state }
445
-
446
- { :ok , % Response { status: 405 } = response , state } ->
447
- { :disconnect , exception ( state , response ) , state }
448
-
449
- { :ok , % Response { status: 401 } = response , state } ->
450
- { :disconnect , exception ( state , response ) , state }
451
-
452
- { :ok , % Response { status: status } = response , state } when status in 400 .. 599 ->
453
- { :error , exception ( state , response ) , state }
454
- end
455
- end
456
-
457
- def exec_cases_after do
458
- quote do
459
- { :error , :noproc , state } ->
460
- { :disconnect , exception ( state , "connection lost" ) , state }
461
-
462
- { :error , % _ { } = reason , state } ->
463
- { :error , reason , state }
438
+ @ impl true
439
+ def ping ( % __MODULE__ { } = state ) do
440
+ case handle_execute ( nil , @ request_ping , [ ] , state ) do
441
+ { :ok , _request , % Response { } , state } ->
442
+ { :ok , state }
464
443
465
- { :error , reason , state } ->
466
- { :error , exception ( state , reason ) , state }
444
+ { call , exception , state } when call in [ :error , :disconnect ] ->
445
+ { :disconnect , exception , state }
467
446
end
468
447
end
469
448
@@ -475,21 +454,26 @@ defmodule Arangox.Connection do
475
454
|> maybe_prepend_database ( state )
476
455
|> maybe_encode_body ( state )
477
456
478
- exec_case Client . request ( request , state ) do
457
+ case Client . request ( request , state ) do
458
+ { :ok , % Response { status: status } = response , state } when status in 400 .. 599 ->
459
+ { disc_or_err ( status , state . disconnect_on_error_codes ) , exception ( state , response ) , state }
460
+
479
461
{ :ok , response , state } ->
480
462
{ :ok , sanitize_headers ( request ) , maybe_decode_body ( response , state ) , state }
463
+
464
+ { :error , :noproc , state } ->
465
+ { :disconnect , exception ( state , "connection lost" ) , state }
466
+
467
+ { :error , % _ { } = reason , state } ->
468
+ { :error , reason , state }
469
+
470
+ { :error , reason , state } ->
471
+ { :error , exception ( state , reason ) , state }
481
472
end
482
473
end
483
474
484
- @ impl true
485
- def ping ( % __MODULE__ { } = state ) do
486
- @ request_ping
487
- |> merge_headers ( state . headers )
488
- |> Client . request ( state )
489
- |> exec_case do
490
- { :ok , % Response { } , state } ->
491
- { :ok , state }
492
- end
475
+ defp disc_or_err ( status , codes ) do
476
+ if status in codes , do: :disconnect , else: :error
493
477
end
494
478
495
479
# Unsupported callbacks
0 commit comments