@@ -69,22 +69,24 @@ defmodule EctoSQLite3Extras do
69
69
@ doc """
70
70
Run the query specified by its slug atom and get (or print) the result.
71
71
"""
72
- @ spec query ( module ( ) , repo ( ) , keyword ( ) ) :: any ( )
73
- def query ( module_name , repo , opts \\ [ ] ) do
74
- query_module = Map . fetch! ( queries ( repo ) , module_name )
72
+ @ spec query ( atom ( ) , repo ( ) , keyword ( ) ) :: any ( )
73
+ def query ( query_name , repo , opts \\ [ ] ) do
74
+ query_module = Map . fetch! ( queries ( repo ) , query_name )
75
75
sql_query = query_module . query ( Keyword . get ( opts , :args , [ ] ) )
76
76
query_opts = Keyword . get ( opts , :query_opts , log: false )
77
77
format_name = Keyword . get ( opts , :format , :ascii )
78
78
79
79
repo
80
- |> query! ( sql_query , query_opts )
80
+ |> run_query ( sql_query , query_opts )
81
+ |> unwrap ( )
81
82
|> preformat ( )
82
83
|> format ( format_name , query_module . info )
83
84
end
84
85
85
86
# run query on a remote node
86
- defp query! ( { repo , node } , query , query_opts ) do
87
- case :rpc . call ( node , repo , :query! , [ query , [ ] , query_opts ] ) do
87
+ @ spec run_query ( repo ( ) , String . t ( ) , keyword ( ) ) :: { :ok , map ( ) } | { :error , Exception . t ( ) }
88
+ defp run_query ( { repo , node } , query , query_opts ) do
89
+ case :rpc . call ( node , repo , :query , [ query , [ ] , query_opts ] ) do
88
90
{ :badrpc , { :EXIT , { :undef , _ } } } ->
89
91
raise "repository is not defined on remote node"
90
92
@@ -97,11 +99,20 @@ defmodule EctoSQLite3Extras do
97
99
end
98
100
99
101
# run query on the current node
100
- defp query! ( repo , query , query_opts ) do
101
- repo . query! ( query , [ ] , query_opts )
102
+ defp run_query ( repo , query , query_opts ) do
103
+ repo . query ( query , [ ] , query_opts )
102
104
end
103
105
106
+ @ spec unwrap ( { :ok , map ( ) } | { :error , Exception . t ( ) } ) :: map ( )
107
+ defp unwrap ( { :ok , result } ) , do: result
108
+
109
+ defp unwrap ( { :error , % { message: "no such table: sqlite_sequence" } } ) ,
110
+ do: % { rows: [ ] , num_rows: 0 , columns: [ "table_name" , "sequence_number" ] }
111
+
112
+ defp unwrap ( { :error , err } ) , do: raise ( err )
113
+
104
114
# format summary tables based on the name in the first row
115
+ @ spec preformat ( map ( ) ) :: map ( )
105
116
defp preformat ( % { columns: [ _ , _ ] , rows: rows } = result ) do
106
117
rows = rows |> Enum . map ( & format_row / 1 )
107
118
Map . replace! ( result , :rows , rows )
@@ -111,6 +122,7 @@ defmodule EctoSQLite3Extras do
111
122
result
112
123
end
113
124
125
+ @ spec format ( map ( ) , atom ( ) , map ( ) ) :: any ( )
114
126
defp format ( result , :raw , _info ) , do: result
115
127
defp format ( % { rows: [ ] } , :ascii , _info ) , do: "No results"
116
128
@@ -124,6 +136,7 @@ defmodule EctoSQLite3Extras do
124
136
|> IO . puts ( )
125
137
end
126
138
139
+ @ spec format_row ( list ( list ( ) ) , list ( atom ( ) ) ) :: any ( )
127
140
defp format_row ( values , types ) do
128
141
Enum . zip ( values , types ) |> Enum . map ( & format_value / 1 )
129
142
end
@@ -136,10 +149,13 @@ defmodule EctoSQLite3Extras do
136
149
end
137
150
end
138
151
152
+ @ spec format_value ( { any ( ) , atom ( ) } ) :: String . t ( )
139
153
defp format_value ( { integer , :bytes } ) when is_integer ( integer ) , do: format_bytes ( integer )
140
154
defp format_value ( { binary , _ } ) when is_binary ( binary ) , do: binary
141
155
defp format_value ( { other , _ } ) , do: inspect ( other )
142
156
157
+ # format integer bytes value as a human-readable string
158
+ @ spec format_bytes ( integer ( ) ) :: String . t ( )
143
159
defp format_bytes ( bytes ) do
144
160
cond do
145
161
bytes >= memory_unit ( :TB ) -> format_bytes ( bytes , :TB )
@@ -150,11 +166,14 @@ defmodule EctoSQLite3Extras do
150
166
end
151
167
end
152
168
169
+ @ spec format_bytes ( integer ( ) , atom ( ) ) :: String . t ( )
153
170
defp format_bytes ( bytes , unit ) do
154
171
value = bytes / memory_unit ( unit )
155
172
"#{ :erlang . float_to_binary ( value , decimals: 1 ) } #{ unit } "
156
173
end
157
174
175
+ # get number of bytes for the given memory unit atom
176
+ @ spec memory_unit ( atom ( ) ) :: integer ( )
158
177
defp memory_unit ( :TB ) , do: 1024 * 1024 * 1024 * 1024
159
178
defp memory_unit ( :GB ) , do: 1024 * 1024 * 1024
160
179
defp memory_unit ( :MB ) , do: 1024 * 1024
0 commit comments