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",