1
1
defmodule GraphQL.Relay.Connection.List do
2
2
@ prefix "arrayconnection:"
3
3
4
- def resolve ( data ) do
5
- resolve ( data , % { } )
6
- end
4
+ def resolve ( data ) , do: resolve ( data , % { } )
7
5
def resolve ( data , args ) do
8
6
resolve_slice ( data , args , % {
9
7
slice_start: 0 ,
@@ -13,34 +11,40 @@ defmodule GraphQL.Relay.Connection.List do
13
11
14
12
def resolve_slice ( records , args , meta ) do
15
13
before = args [ :before ]
14
+ # `after` is a keyword http://elixir-lang.org/docs/master/elixir/Kernel.SpecialForms.html#try/1
16
15
a_after = args [ :after ]
17
16
first = args [ :first ]
18
17
last = args [ :last ]
19
18
slice_start = meta [ :slice_start ] || 0
20
19
list_length = meta [ :list_length ] || length ( records )
21
20
slice_end = slice_start + length ( records )
22
- before_offset = get_offset_with_default ( before , list_length )
23
- after_offset = get_offset_with_default ( a_after , - 1 )
21
+ before_offset = cursor_to_offset ( before , list_length )
22
+ after_offset = cursor_to_offset ( a_after , - 1 )
24
23
start_offset = Enum . max ( [ slice_start - 1 , after_offset , - 1 ] ) + 1
25
24
end_offset = Enum . min ( [ slice_end , before_offset , list_length ] )
26
25
27
- if first do
28
- end_offset = Enum . min ( [ end_offset , start_offset + first ] )
26
+ end_offset = if first do
27
+ Enum . min ( [ end_offset , start_offset + first ] )
28
+ else
29
+ end_offset
29
30
end
30
31
31
- if last do
32
- start_offset = Enum . max ( [ start_offset , end_offset - last ] )
32
+ start_offset = if last do
33
+ Enum . max ( [ start_offset , end_offset - last ] )
34
+ else
35
+ start_offset
33
36
end
34
37
35
38
from_slice = Enum . max ( [ start_offset - slice_start , 0 ] )
36
39
to_slice = length ( records ) - ( slice_end - end_offset ) - 1
37
40
slice = case first do
38
41
0 -> [ ]
39
- _ ->
40
- Enum . slice ( records , from_slice .. to_slice )
42
+ _ -> Enum . slice ( records , from_slice .. to_slice )
41
43
end
42
44
43
- { edges , _count } = Enum . map_reduce ( slice , 0 , fn ( record , acc ) -> { % { cursor: offset_to_cursor ( start_offset + acc ) , node: record } , acc + 1 } end )
45
+ { edges , _count } = Enum . map_reduce ( slice , 0 , fn ( record , acc ) ->
46
+ { % { cursor: offset_to_cursor ( start_offset + acc ) , node: record } , acc + 1 }
47
+ end )
44
48
45
49
first_edge = List . first ( edges )
46
50
last_edge = List . last ( edges )
@@ -50,42 +54,31 @@ defmodule GraphQL.Relay.Connection.List do
50
54
% {
51
55
edges: edges ,
52
56
pageInfo: % {
53
- startCursor: first_edge && Map . get ( first_edge , :cursor ) || nil ,
54
- endCursor: last_edge && Map . get ( last_edge , :cursor ) || nil ,
57
+ startCursor: first_edge && Map . get ( first_edge , :cursor ) ,
58
+ endCursor: last_edge && Map . get ( last_edge , :cursor ) ,
55
59
hasPreviousPage: last && ( start_offset > lower_bound ) || false ,
56
60
hasNextPage: first && ( end_offset < upper_bound ) || false
57
61
}
58
62
}
59
63
end
60
64
61
- def get_offset_with_default ( cursor , default_offset ) do
62
- unless cursor do
63
- default_offset
64
- else
65
- offset = cursor_to_offset ( cursor )
66
- offset || default_offset
67
- end
68
- end
69
-
70
- def cursor_to_offset ( cursor ) do
65
+ def cursor_to_offset ( nil , default ) , do: default
66
+ def cursor_to_offset ( cursor , default ) do
71
67
case Base . decode64 ( cursor ) do
72
68
{ :ok , decoded_cursor } ->
73
69
{ int , _ } = Integer . parse ( String . slice ( decoded_cursor , String . length ( @ prefix ) .. String . length ( decoded_cursor ) ) )
74
70
int
75
71
:error ->
76
- nil
72
+ default
77
73
end
78
74
end
79
75
80
76
def cursor_for_object_in_connection ( data , object ) do
81
77
offset = Enum . find_index ( data , fn ( obj ) -> object == obj end )
82
- unless offset do
83
- nil
84
- else
85
- offset_to_cursor ( offset )
86
- end
78
+ offset_to_cursor ( offset )
87
79
end
88
80
81
+ def offset_to_cursor ( nil ) , do: nil
89
82
def offset_to_cursor ( offset ) do
90
83
Base . encode64 ( "#{ @ prefix } #{ offset } " )
91
84
end
0 commit comments