changed
CHANGELOG.md
|
@@ -1,3 +1,7 @@
|
1
|
+ # v0.2.8
|
2
|
+ * Bug Fixes
|
3
|
+ * Fixed issue where tail would time out queries randomly
|
4
|
+
|
1
5
|
# v0.2.7
|
2
6
|
* Enhancements
|
3
7
|
* Added ability to pass socket options to connect.
|
changed
hex_metadata.config
|
@@ -21,4 +21,4 @@
|
21
21
|
[{<<"app">>,<<"timex">>},
|
22
22
|
{<<"optional">>,nil},
|
23
23
|
{<<"requirement">>,<<"~> 0.13">>}]}]}.
|
24
|
- {<<"version">>,<<"0.2.7">>}.
|
24
|
+ {<<"version">>,<<"0.2.8">>}.
|
changed
lib/tds/connection.ex
|
@@ -86,12 +86,12 @@ defmodule Tds.Connection do
|
86
86
|
ireq: nil,
|
87
87
|
opts: nil,
|
88
88
|
state: :ready,
|
89
|
- tail: "",
|
89
|
+ tail: "", #only has non-empty value when waiting for more data
|
90
90
|
queue: :queue.new,
|
91
91
|
attn_timer: nil,
|
92
92
|
statement: nil,
|
93
|
- pak_header: "",
|
94
|
- pak_data: "",
|
93
|
+ pak_header: "", #current tds packet header
|
94
|
+ pak_data: "", #current tds message holding previous tds packets, #TODO should probably rename this
|
95
95
|
env: %{trans: <<0x00>>}}}
|
96
96
|
end
|
97
97
|
|
|
@@ -170,8 +170,6 @@ defmodule Tds.Connection do
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
173
|
-
|
174
|
-
|
175
173
|
def handle_info({:DOWN, ref, :process, _, _}, s) do
|
176
174
|
case :queue.out(s.queue) do
|
177
175
|
{{:value, {_,_,^ref}}, _queue} ->
|
|
@@ -270,45 +268,61 @@ defmodule Tds.Connection do
|
270
268
|
defp command(:attn, s) do
|
271
269
|
timeout = s.opts[:timeout] || @timeout
|
272
270
|
attn_timer_ref = :erlang.start_timer(timeout, self(), :command)
|
273
|
- Protocol.send_attn(%{s |attn_timer: attn_timer_ref, pak_header: "", pak_data: "", tail: "", state: :attn})
|
271
|
+ Protocol.send_attn(%{s | attn_timer: attn_timer_ref, pak_header: "", pak_data: "", tail: "", state: :attn})
|
274
272
|
end
|
275
273
|
|
274
|
+ #no data to process
|
276
275
|
defp new_data(<<_data::0>>, s) do
|
277
276
|
{:ok, s}
|
278
277
|
end
|
278
|
+
|
279
|
+ #DONE_ATTN The DONE message is a server acknowledgement of a client ATTENTION message.
|
279
280
|
defp new_data(<<0xFD, 0x20, _cur_cmd::binary(2), 0::size(8)-unit(8), _tail::binary>>, %{state: :attn} = s) do
|
280
281
|
s = %{s | pak_header: "", pak_data: "", tail: ""}
|
281
282
|
Protocol.message(:attn, :attn, s)
|
282
283
|
end
|
284
|
+
|
285
|
+ #shift 8 bytes while in attention state, Protocol updates state
|
283
286
|
defp new_data(<<_b::size(1)-unit(8), tail::binary>>, %{state: :attn} = s), do: new_data(tail, s)
|
284
287
|
|
285
|
- defp new_data(<<packet::binary>>, %{state: state, pak_data: buf_data, pak_header: buf_header, tail: tail} = s) do
|
286
|
- <<type::int8, status::int8, size::int16, head_rem::int32, data::binary>> = tail <> packet
|
287
|
- if buf_header == "" do
|
288
|
- buf_header = <<type::int8, status::int8, size::int16, head_rem::int32>>
|
288
|
+ #no packet header yet
|
289
|
+ defp new_data(<<data::binary>>, %{pak_header: ""} = s) do
|
290
|
+ if byte_size(data) >= 8 do
|
291
|
+ #assume incoming data starts with packet header, if it's long enough
|
292
|
+ <<pak_header::binary(8), tail::binary>> = data
|
293
|
+ new_data(tail, %{s | pak_header: pak_header})
|
289
294
|
else
|
290
|
- data = tail <> packet
|
295
|
+ #have no packet header yet, wait for more data
|
296
|
+ {:ok, %{s | tail: data}}
|
291
297
|
end
|
298
|
+ end
|
292
299
|
|
293
|
- <<type::int8, status::int8, size::int16, _spid::int16, _pack_id::int8, _window::int8>> = buf_header
|
294
|
- size = size - 8
|
300
|
+ defp new_data(<<data::binary>>, %{state: state, pak_header: pak_header, pak_data: pak_data} = s) do
|
301
|
+ <<type::int8, status::int8, size::int16, _head_rem::int32>> = pak_header
|
302
|
+ size = size - 8 #size includes packet header
|
295
303
|
|
296
304
|
case data do
|
297
|
- <<data :: binary(size), tail :: binary>> ->
|
305
|
+ <<data::binary(size), tail::binary>> ->
|
306
|
+ #satisfied size specified in packet header
|
298
307
|
case status do
|
299
308
|
1 ->
|
300
|
- msg = Messages.parse(state, type, buf_header, buf_data<>data)
|
309
|
+ #status 1 means last packet of message
|
310
|
+ #TODO Messages.parse does not use pak_header
|
311
|
+ msg = Messages.parse(state, type, pak_header, pak_data <> data)
|
301
312
|
case Protocol.message(state, msg, s) do
|
302
313
|
{:ok, s} ->
|
303
|
- new_data(tail, %{s | pak_header: "", pak_data: "", tail: tail})
|
314
|
+ #message processed, reset header and msg buffer, then process tail
|
315
|
+ new_data(tail, %{s | pak_header: "", pak_data: ""})
|
304
316
|
{:error, _, _} = err ->
|
305
317
|
err
|
306
318
|
end
|
307
319
|
_ ->
|
308
|
- new_data(tail, %{s | pak_data: buf_data <> data, pak_header: "", tail: ""})
|
320
|
+ #not the last packet of message, more packets coming with new packet header
|
321
|
+ new_data(tail, %{s | pak_header: "", pak_data: pak_data <> data})
|
309
322
|
end
|
310
323
|
_ ->
|
311
|
- {:ok, %{s | tail: tail <> data, pak_header: buf_header}}
|
324
|
+ #size specified in packet header still unsatisfied, wait for more data
|
325
|
+ {:ok, %{s | tail: data, pak_header: pak_header}}
|
312
326
|
end
|
313
327
|
end
|
changed
lib/tds/messages.ex
|
@@ -89,7 +89,7 @@ defmodule Tds.Messages do
|
89
89
|
def parse(:executing, @tds_pack_reply, _header, tail) do
|
90
90
|
tokens = []
|
91
91
|
tokens = decode_tokens(tail, tokens)
|
92
|
-
|
92
|
+
|
93
93
|
case tokens do
|
94
94
|
[error: error] ->
|
95
95
|
msg_error(e: error)
|
|
@@ -100,12 +100,12 @@ defmodule Tds.Messages do
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
-
|
103
|
+
|
104
104
|
|
105
105
|
## Encoders
|
106
106
|
|
107
107
|
def encode_msg(msg, env) do
|
108
|
- encode(msg, env)
|
108
|
+ encode(msg, env)
|
109
109
|
end
|
110
110
|
|
111
111
|
defp encode(msg_prelogin(params: _params), _env) do
|
|
@@ -227,7 +227,7 @@ defmodule Tds.Messages do
|
227
227
|
defp encode(msg_sql(query: q), %{trans: trans}) do
|
228
228
|
#convert query to unicodestream
|
229
229
|
q_ucs = to_little_ucs2(q)
|
230
|
-
|
230
|
+
|
231
231
|
#Transaction Descriptor header
|
232
232
|
header_type = <<2::little-size(2)-unit(8)>>
|
233
233
|
trans_size = byte_size(trans)
|
|
@@ -275,7 +275,7 @@ defmodule Tds.Messages do
|
275
275
|
end
|
276
276
|
|
277
277
|
# Finished processing params
|
278
|
- defp encode_rpc_params([], ret), do: ret
|
278
|
+ defp encode_rpc_params([], ret), do: ret
|
279
279
|
defp encode_rpc_params([%Tds.Parameter{} = param | tail], ret) do
|
280
280
|
p = encode_rpc_param(param)
|
281
281
|
encode_rpc_params(tail, ret <> p)
|
|
@@ -309,7 +309,7 @@ defmodule Tds.Messages do
|
309
309
|
Enum.reverse paks
|
310
310
|
end
|
311
311
|
defp encode_packets(type, <<data::binary-size(@tds_pack_data_size)-unit(8), tail::binary>>, paks) do
|
312
|
- status =
|
312
|
+ status =
|
313
313
|
if byte_size(tail) > 0, do: 0, else: 1
|
314
314
|
header = encode_header(type, data, id: length(paks)+1, status: status)
|
315
315
|
encode_packets(type, tail, [header <> data | paks])
|
changed
lib/tds/tokens.ex
|
@@ -121,16 +121,16 @@ defmodule Tds.Tokens do
|
121
121
|
defp decode_token(<<@tds_token_envchange, _length::little-unsigned-16, env_type::unsigned-8, tail::binary>>, tokens) do
|
122
122
|
token = case env_type do
|
123
123
|
@tds_envtype_database ->
|
124
|
- <<new_value_size::unsigned-8,
|
125
|
- new_value::binary-little-size(new_value_size)-unit(8),
|
126
|
- old_value_size::unsigned-8,
|
127
|
- _old_value::binary-little-size(old_value_size)-unit(8),
|
124
|
+ <<new_value_size::unsigned-8,
|
125
|
+ new_value::binary-little-size(new_value_size)-unit(8),
|
126
|
+ old_value_size::unsigned-8,
|
127
|
+ _old_value::binary-little-size(old_value_size)-unit(8),
|
128
128
|
tail::binary>> = tail
|
129
129
|
@tds_envtype_packetsize ->
|
130
|
- <<new_value_size::unsigned-8,
|
131
|
- new_value::binary-little-size(new_value_size)-unit(8),
|
132
|
- old_value_size::unsigned-8,
|
133
|
- _old_value::binary-little-size(old_value_size)-unit(8),
|
130
|
+ <<new_value_size::unsigned-8,
|
131
|
+ new_value::binary-little-size(new_value_size)-unit(8),
|
132
|
+ old_value_size::unsigned-8,
|
133
|
+ _old_value::binary-little-size(old_value_size)-unit(8),
|
134
134
|
tail::binary>> = tail
|
135
135
|
@tds_envtype_begintrans ->
|
136
136
|
<<value_size::unsigned-8, new_value::binary-little-size(value_size)-unit(8), 0x00, tail::binary>> = tail
|
|
@@ -148,8 +148,8 @@ defmodule Tds.Tokens do
|
148
148
|
## DONE
|
149
149
|
defp decode_token(<<@tds_token_done, status::int16, cur_cmd::binary(2), row_count::little-size(8)-unit(8), _tail::binary>>, tokens) do
|
150
150
|
case tokens do
|
151
|
- [done: done] ->
|
152
|
-
|
151
|
+ [done: done] ->
|
152
|
+
|
153
153
|
cond do
|
154
154
|
row_count > done.rows -> {[done: %{status: status, cmd: cur_cmd, rows: row_count}] ++ tokens, nil}
|
155
155
|
true -> {tokens, nil}
|
|
@@ -162,7 +162,7 @@ defmodule Tds.Tokens do
|
162
162
|
## DONEPROC
|
163
163
|
defp decode_token(<<@tds_token_doneproc, status::int16, cur_cmd::binary(2), row_count::little-size(8)-unit(8), _tail::binary>>, tokens) do
|
164
164
|
case tokens do
|
165
|
- [done: done] ->
|
165
|
+ [done: done] ->
|
166
166
|
cond do
|
167
167
|
row_count > done.rows -> {[done: %{status: status, cmd: cur_cmd, rows: row_count}] ++ tokens, nil}
|
168
168
|
true -> {tokens, nil}
|
|
@@ -175,7 +175,7 @@ defmodule Tds.Tokens do
|
175
175
|
## DONEINPROC
|
176
176
|
defp decode_token(<<@tds_token_doneinproc, status::int16, cur_cmd::binary(2), row_count::little-size(8)-unit(8), _something::binary-size(5), _tail::binary>>, tokens) do
|
177
177
|
case tokens do
|
178
|
- [done: done] ->
|
178
|
+ [done: done] ->
|
179
179
|
cond do
|
180
180
|
row_count > done.rows -> {[done: %{status: status, cmd: cur_cmd, rows: row_count}] ++ tokens, nil}
|
181
181
|
true -> {tokens, nil}
|
|
@@ -185,7 +185,7 @@ defmodule Tds.Tokens do
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
188
|
- defp decode_column_order(<<tail::binary>>, n, columns) when n == 0 do
|
188
|
+ defp decode_column_order(<<tail::binary>>, n, columns) when n == 0 do
|
189
189
|
{columns, tail}
|
190
190
|
end
|
191
191
|
defp decode_column_order(<<col_id::little-unsigned-16, tail::binary>>, n, columns) do
|
|
@@ -257,4 +257,4 @@ defmodule Tds.Tokens do
|
257
257
|
Types.decode_data(column, tail)
|
258
258
|
end
|
259
259
|
|
260
|
- end
|
|
\ No newline at end of file
|
260
|
+ end
|
changed
lib/tds/types.ex
|
@@ -139,7 +139,7 @@ defmodule Tds.Types do
|
139
139
|
{%{data_type: :fixed, data_type_code: data_type_code, length: length},tail}
|
140
140
|
end
|
141
141
|
|
142
|
- def decode_info(<<data_type_code::unsigned-8, tail::binary>>) when data_type_code in @variable_data_types do
|
142
|
+ def decode_info(<<data_type_code::unsigned-8, tail::binary>>) when data_type_code in @variable_data_types do
|
143
143
|
col_info = %{data_type: :variable, data_type_code: data_type_code}
|
144
144
|
cond do
|
145
145
|
data_type_code == @tds_data_type_daten ->
|
|
@@ -188,7 +188,7 @@ defmodule Tds.Types do
|
188
188
|
@tds_data_type_varchar,
|
189
189
|
@tds_data_type_binary,
|
190
190
|
@tds_data_type_varbinary
|
191
|
- ] ->
|
191
|
+ ] ->
|
192
192
|
<<length::little-unsigned-8, tail::binary>> = tail
|
193
193
|
if data_type_code in [
|
194
194
|
@tds_data_type_numericn,
|
|
@@ -245,7 +245,7 @@ defmodule Tds.Types do
|
245
245
|
@tds_data_type_text,
|
246
246
|
@tds_data_type_image,
|
247
247
|
@tds_data_type_ntext,
|
248
|
- @tds_data_type_variant
|
248
|
+ @tds_data_type_variant
|
249
249
|
] ->
|
250
250
|
<<length::signed-32, tail::binary>> = tail
|
251
251
|
col_info = col_info
|
|
@@ -258,7 +258,7 @@ defmodule Tds.Types do
|
258
258
|
|> Map.put(:collation, collation)
|
259
259
|
|> Map.put(:data_reader, :longlen)
|
260
260
|
<<numparts::signed-8, tail::binary>> = tail
|
261
|
- tail =
|
261
|
+ tail =
|
262
262
|
Enum.reduce([1..numparts], tail, fn(_, acc) ->
|
263
263
|
<<tsize::little-unsigned-16, _table_name::binary-size(tsize)-unit(16), tail::binary>> = acc
|
264
264
|
tail
|
|
@@ -267,7 +267,7 @@ defmodule Tds.Types do
|
267
267
|
# TODO NumBarts Reader
|
268
268
|
<<numparts::signed-8, tail::binary>> = tail
|
269
269
|
tail =
|
270
|
- Enum.reduce([1..numparts], tail, fn(_, acc) ->
|
270
|
+ Enum.reduce([1..numparts], tail, fn(_, acc) ->
|
271
271
|
<<size::unsigned-16, _str::size(size)-unit(16), tail::binary>> = acc
|
272
272
|
tail
|
273
273
|
end)
|
|
@@ -291,9 +291,9 @@ defmodule Tds.Types do
|
291
291
|
def decode_data(%{data_type: :fixed, data_type_code: data_type_code, length: length}, <<tail::binary>>) do
|
292
292
|
<<value_binary::binary-size(length)-unit(8), tail::binary>> = tail
|
293
293
|
value = case data_type_code do
|
294
|
- @tds_data_type_null ->
|
294
|
+ @tds_data_type_null ->
|
295
295
|
nil
|
296
|
- @tds_data_type_bit ->
|
296
|
+ @tds_data_type_bit ->
|
297
297
|
value_binary != <<0x00>>
|
298
298
|
@tds_data_type_smalldatetime -> decode_smalldatetime(value_binary)
|
299
299
|
@tds_data_type_smallmoney -> decode_smallmoney(value_binary)
|
|
@@ -301,7 +301,7 @@ defmodule Tds.Types do
|
301
301
|
<<value::little-float-32>> = value_binary
|
302
302
|
Float.round value, 4
|
303
303
|
@tds_data_type_datetime -> decode_datetime(value_binary)
|
304
|
- @tds_data_type_float ->
|
304
|
+ @tds_data_type_float ->
|
305
305
|
<<value::little-float-64>> = value_binary
|
306
306
|
Float.round value, 8
|
307
307
|
@tds_data_type_money -> decode_money(value_binary)
|
|
@@ -341,9 +341,9 @@ defmodule Tds.Types do
|
341
341
|
data_type_code == @tds_data_type_floatn ->
|
342
342
|
data = data <> tail
|
343
343
|
case length do
|
344
|
- 4 ->
|
344
|
+ 4 ->
|
345
345
|
<<value::little-float-32, tail::binary>> = data
|
346
|
- 8 ->
|
346
|
+ 8 ->
|
347
347
|
<<value::little-float-64, tail::binary>> = data
|
348
348
|
end
|
349
349
|
value
|
|
@@ -396,7 +396,7 @@ defmodule Tds.Types do
|
396
396
|
|
397
397
|
def decode_data(%{data_reader: :longlen}, <<0x00, tail::binary>>), do: {nil, tail}
|
398
398
|
def decode_data(%{data_type_code: data_type_code, data_reader: :longlen} = data_info, <<text_ptr_size::unsigned-8, _text_ptr::size(text_ptr_size)-unit(8), _timestamp::unsigned-64, size::little-signed-32, data::binary-size(size)-unit(8), tail::binary>>) do
|
399
|
- value =
|
399
|
+ value =
|
400
400
|
case data_type_code do
|
401
401
|
@tds_data_type_text -> decode_char(data_info[:collation], data)
|
402
402
|
@tds_data_type_ntext -> decode_nchar(data)
|
|
@@ -410,7 +410,7 @@ defmodule Tds.Types do
|
410
410
|
|
411
411
|
def decode_data(%{data_reader: :plp}, <<@tds_plp_null, tail::binary>>), do: {nil, tail}
|
412
412
|
def decode_data(%{data_type_code: data_type_code, data_reader: :plp} = data_info, <<_size::little-unsigned-64, tail::binary>>) do
|
413
|
- {data, tail} = decode_plp_chunk(tail, <<>>)
|
413
|
+ {data, tail} = decode_plp_chunk(tail, <<>>)
|
414
414
|
value = cond do
|
415
415
|
data_type_code == @tds_data_type_xml ->
|
416
416
|
decode_xml(data_info, data)
|
|
@@ -453,7 +453,7 @@ defmodule Tds.Types do
|
453
453
|
money = pow10(money,(4 * -1))
|
454
454
|
Float.round money, 4
|
455
455
|
end
|
456
|
-
|
456
|
+
|
457
457
|
def decode_datetime(<<days::little-signed-32, sec::little-unsigned-32>>) do
|
458
458
|
date = Date.shift(@datetime, days: days)
|
459
459
|
date = Date.shift(date, secs: (sec/300))
|
|
@@ -544,7 +544,7 @@ defmodule Tds.Types do
|
544
544
|
Decimal.set_context d_ctx
|
545
545
|
d = Decimal.new pow10(value,(scale * -1))
|
546
546
|
value = pow10(d.coef, d.exp)
|
547
|
- value =
|
547
|
+ value =
|
548
548
|
case sign do
|
549
549
|
0 -> value * -1
|
550
550
|
_ -> value
|
|
@@ -566,7 +566,7 @@ defmodule Tds.Types do
|
566
566
|
end
|
567
567
|
|
568
568
|
def decode_udt(%{}, <<_data::binary>>) do
|
569
|
- # TODO: Decode UDT Data
|
569
|
+ # TODO: Decode UDT Data
|
570
570
|
nil
|
571
571
|
end
|
572
572
|
|
|
@@ -588,37 +588,37 @@ defmodule Tds.Types do
|
588
588
|
end
|
589
589
|
end
|
590
590
|
|
591
|
- def encode_data_type(%Parameter{value: value} = param)
|
592
|
- when value == true or value == false do
|
591
|
+ def encode_data_type(%Parameter{value: value} = param)
|
592
|
+ when value == true or value == false do
|
593
593
|
encode_data_type(%{param | type: :boolean})
|
594
594
|
end
|
595
595
|
|
596
|
- def encode_data_type(%Parameter{value: value} = param)
|
597
|
- when is_binary(value) and value == "" do
|
596
|
+ def encode_data_type(%Parameter{value: value} = param)
|
597
|
+ when is_binary(value) and value == "" do
|
598
598
|
encode_data_type(%{param | type: :string})
|
599
599
|
end
|
600
600
|
|
601
|
- def encode_data_type(%Parameter{value: value} = param)
|
602
|
- when is_binary(value) do
|
601
|
+ def encode_data_type(%Parameter{value: value} = param)
|
602
|
+ when is_binary(value) do
|
603
603
|
encode_data_type(%{param | type: :binary})
|
604
604
|
end
|
605
605
|
|
606
|
- def encode_data_type(%Parameter{value: value} = param)
|
607
|
- when is_integer(value) and value >= 0 do
|
606
|
+ def encode_data_type(%Parameter{value: value} = param)
|
607
|
+ when is_integer(value) and value >= 0 do
|
608
608
|
encode_data_type(%{param | type: :integer})
|
609
609
|
end
|
610
610
|
|
611
|
- def encode_data_type(%Parameter{value: value} = param)
|
612
|
- when is_float(value) do
|
611
|
+ def encode_data_type(%Parameter{value: value} = param)
|
612
|
+ when is_float(value) do
|
613
613
|
encode_data_type(%{param | type: :float})
|
614
614
|
end
|
615
615
|
|
616
|
- def encode_data_type(%Parameter{value: value} = param)
|
617
|
- when (is_integer(value) and value < 0) do
|
616
|
+ def encode_data_type(%Parameter{value: value} = param)
|
617
|
+ when (is_integer(value) and value < 0) do
|
618
618
|
encode_data_type(%{param | value: Decimal.new(value), type: :decimal})
|
619
619
|
end
|
620
620
|
|
621
|
- def encode_data_type(%Parameter{value: %Decimal{}} = param) do
|
621
|
+ def encode_data_type(%Parameter{value: %Decimal{}} = param) do
|
622
622
|
encode_data_type(%{param | type: :decimal})
|
623
623
|
end
|
624
624
|
|
|
@@ -642,13 +642,13 @@ defmodule Tds.Types do
|
642
642
|
encode_data_type(%{param | type: :datetime2})
|
643
643
|
end
|
644
644
|
|
645
|
- def encode_binary_type(%Parameter{value: value} = param)
|
645
|
+ def encode_binary_type(%Parameter{value: value} = param)
|
646
646
|
when value == "" do
|
647
647
|
encode_string_type(param)
|
648
648
|
end
|
649
649
|
|
650
|
- def encode_binary_type(%Parameter{value: value} = param)
|
651
|
- when is_integer(value) do
|
650
|
+ def encode_binary_type(%Parameter{value: value} = param)
|
651
|
+ when is_integer(value) do
|
652
652
|
%{param | value: <<value>>} |> encode_binary_type
|
653
653
|
end
|
654
654
|
|
|
@@ -681,9 +681,9 @@ defmodule Tds.Types do
|
681
681
|
end
|
682
682
|
|
683
683
|
def encode_string_type(%Parameter{value: value}) do
|
684
|
-
|
684
|
+
|
685
685
|
collation = <<0x00, 0x00, 0x00, 0x00, 0x00>>
|
686
|
- length =
|
686
|
+ length =
|
687
687
|
if value != nil do
|
688
688
|
value = value |> to_little_ucs2
|
689
689
|
value_size = byte_size(value)
|
|
@@ -701,12 +701,12 @@ defmodule Tds.Types do
|
701
701
|
{type, data, [collation: collation]}
|
702
702
|
end
|
703
703
|
|
704
|
- def encode_integer_type(%Parameter{value: value} = param)
|
704
|
+ def encode_integer_type(%Parameter{value: value} = param)
|
705
705
|
when value < 0 do
|
706
706
|
encode_decimal_type(param)
|
707
707
|
end
|
708
708
|
|
709
|
- def encode_integer_type(%Parameter{value: value})
|
709
|
+ def encode_integer_type(%Parameter{value: value})
|
710
710
|
when value >= 0 do
|
711
711
|
attributes = []
|
712
712
|
type = @tds_data_type_intn
|
|
@@ -715,14 +715,14 @@ defmodule Tds.Types do
|
715
715
|
attributes = attributes
|
716
716
|
|> Keyword.put(:length, 1)
|
717
717
|
<<0x01::int8>>
|
718
|
- else
|
718
|
+ else
|
719
719
|
value_size = int_type_size(value)
|
720
720
|
# cond do
|
721
|
- # value_size == 1 ->
|
721
|
+ # value_size == 1 ->
|
722
722
|
# data_type_code = @tds_data_type_tinyint #Enum.find(data_types, fn(x) -> x[:name] == :tinyint end)
|
723
|
- # value_size == 2 ->
|
723
|
+ # value_size == 2 ->
|
724
724
|
# data_type_code = @tds_data_type_smallint #Enum.find(data_types, fn(x) -> x[:name] == :smallint end)
|
725
|
- # value_size > 2 and value_size <= 4 ->
|
725
|
+ # value_size > 2 and value_size <= 4 ->
|
726
726
|
# data_type_code = @tds_data_type_int #Enum.find(data_types, fn(x) -> x[:name] == :int end)
|
727
727
|
# value_size > 4 and value_size <= 8 ->
|
728
728
|
# data_type_code = @tds_data_type_bigint #Enum.find(data_types, fn(x) -> x[:name] == :bigint end)
|
|
@@ -737,7 +737,7 @@ defmodule Tds.Types do
|
737
737
|
|
738
738
|
def encode_decimal_type(%Parameter{value: nil} = param) do
|
739
739
|
encode_binary_type(param)
|
740
|
- end
|
740
|
+ end
|
741
741
|
def encode_decimal_type(%Parameter{value: value}) do
|
742
742
|
d_ctx = Decimal.get_context
|
743
743
|
d_ctx = %{d_ctx | precision: 38}
|
|
@@ -747,29 +747,29 @@ defmodule Tds.Types do
|
747
747
|
|> Decimal.to_string(:normal)
|
748
748
|
|> String.split(".")
|
749
749
|
case value_list do
|
750
|
- [p,s] ->
|
750
|
+ [p,s] ->
|
751
751
|
precision = String.length(p) + String.length(s); scale = String.length(s)
|
752
|
- [p] ->
|
752
|
+ [p] ->
|
753
753
|
precision = String.length(p); scale = 0
|
754
754
|
end
|
755
755
|
|
756
|
- dec_abs = value
|
757
|
- |> Decimal.abs
|
758
|
- value = dec_abs.coef
|
756
|
+ dec_abs = value
|
757
|
+ |> Decimal.abs
|
758
|
+ value = dec_abs.coef
|
759
759
|
|> :binary.encode_unsigned(:little)
|
760
760
|
value_size = byte_size(value)
|
761
|
-
|
761
|
+
|
762
762
|
padding = cond do
|
763
763
|
precision <= 9 ->
|
764
|
- byte_len = 4
|
764
|
+ byte_len = 4
|
765
765
|
byte_len - value_size
|
766
|
- precision <= 19 ->
|
766
|
+ precision <= 19 ->
|
767
767
|
byte_len = 8
|
768
768
|
byte_len - value_size
|
769
|
- precision <= 28 ->
|
769
|
+ precision <= 28 ->
|
770
770
|
byte_len = 12
|
771
771
|
byte_len - value_size
|
772
|
- precision <= 38 ->
|
772
|
+ precision <= 38 ->
|
773
773
|
byte_len = 16
|
774
774
|
byte_len - value_size
|
775
775
|
end
|
|
@@ -797,23 +797,23 @@ defmodule Tds.Types do
|
797
797
|
|> Decimal.to_string(:normal)
|
798
798
|
|> String.split(".")
|
799
799
|
case value_list do
|
800
|
- [p,s] ->
|
800
|
+ [p,s] ->
|
801
801
|
precision = String.length(p) + String.length(s); scale = String.length(s)
|
802
|
- [p] ->
|
802
|
+ [p] ->
|
803
803
|
precision = String.length(p); scale = 0
|
804
804
|
end
|
805
805
|
|
806
|
- dec_abs = value
|
807
|
- |> Decimal.abs
|
808
|
- value = dec_abs.coef
|
806
|
+ dec_abs = value
|
807
|
+ |> Decimal.abs
|
808
|
+ value = dec_abs.coef
|
809
809
|
|> :binary.encode_unsigned(:little)
|
810
810
|
value_size = byte_size(value)
|
811
|
-
|
811
|
+
|
812
812
|
padding = cond do
|
813
813
|
precision <= 9 ->
|
814
|
- byte_len = 4
|
814
|
+ byte_len = 4
|
815
815
|
byte_len - value_size
|
816
|
- precision <= 19 ->
|
816
|
+ precision <= 19 ->
|
817
817
|
byte_len = 8
|
818
818
|
byte_len - value_size
|
819
819
|
end
|
|
@@ -846,7 +846,7 @@ defmodule Tds.Types do
|
846
846
|
:datetime -> "datetime"
|
847
847
|
:datetime2 -> "datetime2"
|
848
848
|
:binary -> encode_binary_descriptor(value)
|
849
|
- :string ->
|
849
|
+ :string ->
|
850
850
|
if value == nil do
|
851
851
|
length = 0
|
852
852
|
else
|
|
@@ -855,19 +855,19 @@ defmodule Tds.Types do
|
855
855
|
if length <= 0, do: length = 1
|
856
856
|
if length > 4000, do: length = "max"
|
857
857
|
"nvarchar(#{length})"
|
858
|
- :integer ->
|
858
|
+ :integer ->
|
859
859
|
if value >= 0 do
|
860
860
|
"bigint"
|
861
861
|
else
|
862
|
- precision = value
|
862
|
+ precision = value
|
863
863
|
|> Integer.to_string
|
864
864
|
|> String.length
|
865
865
|
"decimal(#{precision-1}, 0)"
|
866
|
- end
|
866
|
+ end
|
867
867
|
:decimal -> encode_decimal_descriptor(param)
|
868
868
|
:float -> encode_float_descriptor(param)
|
869
869
|
:boolean -> "bit"
|
870
|
- _ ->
|
870
|
+ _ ->
|
871
871
|
if value == nil do
|
872
872
|
length = 0
|
873
873
|
else
|
|
@@ -886,12 +886,13 @@ defmodule Tds.Types do
|
886
886
|
"""
|
887
887
|
# nil
|
888
888
|
def encode_param_descriptor(%Parameter{value: nil} = param) do
|
889
|
+ #Logger.debug "Param Descriptor nil"
|
889
890
|
param = %{param | type: :boolean}
|
890
891
|
encode_param_descriptor(param)
|
891
892
|
end
|
892
893
|
|
893
894
|
# Boolean
|
894
|
- def encode_param_descriptor(%Parameter{value: value} = param)
|
895
|
+ def encode_param_descriptor(%Parameter{value: value} = param)
|
895
896
|
when value == true or value == false do
|
896
897
|
param = %{param | type: :boolean}
|
897
898
|
encode_param_descriptor(param)
|
|
@@ -913,26 +914,27 @@ defmodule Tds.Types do
|
913
914
|
encode_param_descriptor(param)
|
914
915
|
end
|
915
916
|
def encode_param_descriptor(%Parameter{value: {{_,_,_},{_,_,_,_}}} = param) do
|
917
|
+ #Logger.debug "Param Descriptor datetime2"
|
916
918
|
param = %{param | type: :datetime2}
|
917
919
|
encode_param_descriptor(param)
|
918
920
|
end
|
919
921
|
|
920
922
|
# Positive Integers
|
921
|
- def encode_param_descriptor(%Parameter{value: value} = param)
|
923
|
+ def encode_param_descriptor(%Parameter{value: value} = param)
|
922
924
|
when is_integer(value) and value >= 0 do
|
923
925
|
param = %{param | type: :integer}
|
924
926
|
encode_param_descriptor(param)
|
925
927
|
end
|
926
928
|
|
927
929
|
# Float
|
928
|
- def encode_param_descriptor(%Parameter{value: value} = param)
|
929
|
- when is_float(value) do
|
930
|
+ def encode_param_descriptor(%Parameter{value: value} = param)
|
931
|
+ when is_float(value) do
|
930
932
|
param = %{param | type: :float}
|
931
933
|
encode_param_descriptor(param)
|
932
934
|
end
|
933
935
|
|
934
936
|
# Negative Integers
|
935
|
- def encode_param_descriptor(%Parameter{value: value} = param)
|
937
|
+ def encode_param_descriptor(%Parameter{value: value} = param)
|
936
938
|
when is_integer(value) and value < 0 do
|
937
939
|
param = %{param | type: :decimal, value: Decimal.new(value)}
|
938
940
|
encode_param_descriptor(param)
|
|
@@ -945,13 +947,14 @@ defmodule Tds.Types do
|
945
947
|
end
|
946
948
|
|
947
949
|
# Binary
|
948
|
- def encode_param_descriptor(%Parameter{value: value} = param)
|
950
|
+ def encode_param_descriptor(%Parameter{value: value} = param)
|
949
951
|
when is_binary(value) and value == "" do
|
952
|
+ #Logger.debug "Param Descriptor String"
|
950
953
|
param = %{param | type: :string}
|
951
954
|
encode_param_descriptor(param)
|
952
955
|
end
|
953
956
|
|
954
|
- def encode_param_descriptor(%Parameter{value: value} = param)
|
957
|
+ def encode_param_descriptor(%Parameter{value: value} = param)
|
955
958
|
when is_binary(value) do
|
956
959
|
param = %{param | type: :binary}
|
957
960
|
encode_param_descriptor(param)
|
|
@@ -961,7 +964,7 @@ defmodule Tds.Types do
|
961
964
|
Decimal Type Parameter Descriptor
|
962
965
|
"""
|
963
966
|
def encode_decimal_descriptor(%Parameter{value: nil}), do: encode_binary_descriptor(nil)
|
964
|
- def encode_decimal_descriptor(%Parameter{value: value} = param) when is_float(value) do
|
967
|
+ def encode_decimal_descriptor(%Parameter{value: value} = param) when is_float(value) do
|
965
968
|
param = param
|
966
969
|
|> Map.put(:value, Decimal.new(value))
|
967
970
|
encode_decimal_descriptor(param)
|
|
@@ -976,9 +979,9 @@ defmodule Tds.Types do
|
976
979
|
|> Decimal.to_string(:normal)
|
977
980
|
|> String.split(".")
|
978
981
|
case value_list do
|
979
|
- [p,s] ->
|
982
|
+ [p,s] ->
|
980
983
|
precision = String.length(p) + String.length(s); scale = String.length(s)
|
981
|
- [p] ->
|
984
|
+ [p] ->
|
982
985
|
precision = String.length(p); scale = 0
|
983
986
|
end
|
984
987
|
"decimal(#{precision}, #{scale})"
|
|
@@ -995,7 +998,7 @@ defmodule Tds.Types do
|
995
998
|
param = param
|
996
999
|
|> Map.put(:value, Decimal.new(value))
|
997
1000
|
encode_float_descriptor(param)
|
998
|
- end
|
1001
|
+ end
|
999
1002
|
def encode_float_descriptor(%Parameter{value: %Decimal{} = dec}) do
|
1000
1003
|
d_ctx = Decimal.get_context
|
1001
1004
|
d_ctx = %{d_ctx | precision: 38}
|
|
@@ -1005,9 +1008,9 @@ defmodule Tds.Types do
|
1005
1008
|
|> Decimal.to_string(:normal)
|
1006
1009
|
|> String.split(".")
|
1007
1010
|
case value_list do
|
1008
|
- [p,s] ->
|
1011
|
+ [p,s] ->
|
1009
1012
|
precision = String.length(p) + String.length(s); scale = String.length(s)
|
1010
|
- [p] ->
|
1013
|
+ [p] ->
|
1011
1014
|
precision = String.length(p)
|
1012
1015
|
end
|
1013
1016
|
"float(#{precision})"
|
|
@@ -1020,7 +1023,7 @@ defmodule Tds.Types do
|
1020
1023
|
def encode_binary_descriptor(value) do
|
1021
1024
|
if value == nil do
|
1022
1025
|
size = 1
|
1023
|
- else
|
1026
|
+ else
|
1024
1027
|
size = byte_size(value)
|
1025
1028
|
end
|
1026
1029
|
"varbinary(#{size})"
|
|
@@ -1029,8 +1032,8 @@ defmodule Tds.Types do
|
1029
1032
|
@doc """
|
1030
1033
|
Data Encoding Binary Types
|
1031
1034
|
"""
|
1032
|
- def encode_data(@tds_data_type_bigvarbinary = data_type, value, attr)
|
1033
|
- when is_integer(value),
|
1035
|
+ def encode_data(@tds_data_type_bigvarbinary = data_type, value, attr)
|
1036
|
+ when is_integer(value),
|
1034
1037
|
do: encode_data(data_type, <<value>>, attr)
|
1035
1038
|
|
1036
1039
|
def encode_data(@tds_data_type_bigvarbinary, value, _) do
|
|
@@ -1050,7 +1053,7 @@ defmodule Tds.Types do
|
1050
1053
|
else
|
1051
1054
|
value = value |> to_little_ucs2
|
1052
1055
|
value_size = byte_size(value)
|
1053
|
-
|
1056
|
+
|
1054
1057
|
cond do
|
1055
1058
|
value_size == 0 ->
|
1056
1059
|
<<0x00::unsigned-64, 0x00::unsigned-32>>
|
|
@@ -1096,28 +1099,28 @@ defmodule Tds.Types do
|
1096
1099
|
Decimal.set_context d_ctx
|
1097
1100
|
precision = attr[:precision]
|
1098
1101
|
d = value
|
1099
|
- |> Decimal.to_string
|
1102
|
+ |> Decimal.to_string
|
1100
1103
|
|> Decimal.new
|
1101
1104
|
sign = case d.sign do 1 -> 1; -1 -> 0 end
|
1102
|
-
|
1105
|
+
|
1103
1106
|
d_abs = Decimal.abs d
|
1104
1107
|
|
1105
1108
|
value = d_abs.coef
|
1106
1109
|
|
1107
|
- value_binary = value
|
1110
|
+ value_binary = value
|
1108
1111
|
|> :binary.encode_unsigned(:little)
|
1109
1112
|
value_size = byte_size(value_binary)
|
1110
1113
|
padding = cond do
|
1111
1114
|
precision <= 9 ->
|
1112
|
- byte_len = 4
|
1115
|
+ byte_len = 4
|
1113
1116
|
byte_len - value_size
|
1114
|
- precision <= 19 ->
|
1117
|
+ precision <= 19 ->
|
1115
1118
|
byte_len = 8
|
1116
1119
|
byte_len - value_size
|
1117
|
- precision <= 28 ->
|
1120
|
+ precision <= 28 ->
|
1118
1121
|
byte_len = 12
|
1119
1122
|
byte_len - value_size
|
1120
|
- precision <= 38 ->
|
1123
|
+ precision <= 38 ->
|
1121
1124
|
byte_len = 16
|
1122
1125
|
byte_len - value_size
|
1123
1126
|
end
|
|
@@ -1140,7 +1143,6 @@ defmodule Tds.Types do
|
1140
1143
|
else
|
1141
1144
|
<<0x08>> <> data
|
1142
1145
|
end
|
1143
|
-
|
1144
1146
|
end
|
1145
1147
|
|
1146
1148
|
|
|
@@ -1151,20 +1153,20 @@ defmodule Tds.Types do
|
1151
1153
|
if value != nil do
|
1152
1154
|
<<
|
1153
1155
|
p1::binary-size(1),
|
1154
|
- p2::binary-size(1),
|
1155
|
- p3::binary-size(1),
|
1156
|
- p4::binary-size(1),
|
1157
|
- p5::binary-size(1),
|
1158
|
- p6::binary-size(1),
|
1159
|
- p7::binary-size(1),
|
1160
|
- p8::binary-size(1),
|
1161
|
- p9::binary-size(1),
|
1162
|
- p10::binary-size(1),
|
1163
|
- p11::binary-size(1),
|
1164
|
- p12::binary-size(1),
|
1165
|
- p13::binary-size(1),
|
1166
|
- p14::binary-size(1),
|
1167
|
- p15::binary-size(1),
|
1156
|
+ p2::binary-size(1),
|
1157
|
+ p3::binary-size(1),
|
1158
|
+ p4::binary-size(1),
|
1159
|
+ p5::binary-size(1),
|
1160
|
+ p6::binary-size(1),
|
1161
|
+ p7::binary-size(1),
|
1162
|
+ p8::binary-size(1),
|
1163
|
+ p9::binary-size(1),
|
1164
|
+ p10::binary-size(1),
|
1165
|
+ p11::binary-size(1),
|
1166
|
+ p12::binary-size(1),
|
1167
|
+ p13::binary-size(1),
|
1168
|
+ p14::binary-size(1),
|
1169
|
+ p15::binary-size(1),
|
1168
1170
|
p16::binary-size(1)>> = value
|
1169
1171
|
|
1170
1172
|
# <<v1::little-signed-32>> = p4 <> p3 <> p2 <>p1
|
|
@@ -1178,7 +1180,7 @@ defmodule Tds.Types do
|
1178
1180
|
else
|
1179
1181
|
<<0x00>>
|
1180
1182
|
end
|
1181
|
-
|
1183
|
+
|
1182
1184
|
end
|
1183
1185
|
|
1184
1186
|
def encode_plp(data) do
|
|
@@ -1199,4 +1201,4 @@ defmodule Tds.Types do
|
1199
1201
|
defp int_type_size(int) when int in -2147483648..2147483647, do: 4
|
1200
1202
|
defp int_type_size(int) when int in -9223372036854775808..9223372036854775807, do: 8
|
1201
1203
|
|
1202
|
- end
|
|
\ No newline at end of file
|
1204
|
+ end
|
changed
lib/tds/utils.ex
|
@@ -57,7 +57,7 @@ defmodule Tds.Utils do
|
57
57
|
end
|
58
58
|
|
59
59
|
def ready(%{queue: queue} = s) do
|
60
|
- queue =
|
60
|
+ queue =
|
61
61
|
case :queue.out(queue) do
|
62
62
|
{{:value, {_, _, ref}}, q} ->
|
63
63
|
Process.demonitor(ref)
|
changed
mix.exs
|
@@ -3,7 +3,7 @@ defmodule Tds.Mixfile do
|
3
3
|
|
4
4
|
def project do
|
5
5
|
[app: :tds,
|
6
|
- version: "0.2.7",
|
6
|
+ version: "0.2.8",
|
7
7
|
elixir: "~> 1.0.0",
|
8
8
|
deps: deps,
|
9
9
|
source_url: "https://github.com/livehelpnow/tds",
|