@@ -4,6 +4,7 @@ defmodule Tds.Types do
44 use Bitwise
55
66 alias Tds.Parameter
7+ alias Tds.Column
78 alias Tds.DateTime
89 alias Tds.DateTime2
910
@@ -987,8 +988,8 @@ defmodule Tds.Types do
987988
988989 def encode_data ( @ tds_data_type_tvp , % { columns: columns , rows: rows } , _attrs ) do
989990 column_length = << length ( columns ) :: little - unsigned - 16 >>
990- { column_attrs , column_meta } = Enum . reduce ( columns , { [ ] , << >> } , fn ( % Parameter { } = param , { attrs , acc_bin } ) ->
991- { bin_type , data , attr } = encode_data_type ( param )
991+ { column_attrs , column_meta } = Enum . reduce ( columns , { [ ] , << >> } , fn ( % Column { } = param , { attrs , acc_bin } ) ->
992+ { bin_type , data , attr } = encode_column_type ( param )
992993 bin = acc_bin <> << 0x00 :: little - unsigned - 32 , 0x00 :: little - unsigned - 16 >> <> data <> << 0x00 >>
993994
994995 { [ { bin_type , attr } | attrs ] , bin }
@@ -1008,9 +1009,66 @@ defmodule Tds.Types do
10081009 column_length <> column_meta <> << 0x00 >> <> row_data <> << 0x00 >>
10091010 end
10101011
1012+ def encode_column_type ( % Column { type: type } = col ) when type != nil do
1013+ case type do
1014+ :varchar -> encode_bigvarchar_col_type ( col )
1015+ :boolean -> encode_binary_type ( % Parameter { type: :boolean , value: nil } )
1016+ :varbinary -> encode_varbinary_col_type ( col )
1017+ :int -> encode_integer_type ( % Parameter { type: :integer , value: nil } )
1018+ :decimal -> encode_decimal_type ( % Parameter { type: :decimal , value: nil } )
1019+ :float -> encode_float_type ( % Parameter { type: :float , value: nil } )
1020+ :datetime -> encode_datetime_type ( % Parameter { type: :datetime , value: nil } )
1021+ :smalldatetime -> encode_smalldatetime_type ( % Parameter { type: :smalldatetime , value: nil } )
1022+ :datetime2 -> encode_datetime2_type ( % Parameter { type: :datetime2 , value: nil } )
1023+ :datetimeoffset -> encode_datetimeoffset_type ( % Parameter { type: :datetimeoffset , value: nil } )
1024+ :date -> encode_date_type ( % Parameter { type: :datetimeoffset , value: nil } )
1025+ :time -> encode_time_type ( % Parameter { type: :time , value: nil } )
1026+ :uuid -> encode_uuid_type ( % Parameter { type: :uuid , value: nil } )
1027+ end
1028+ end
1029+
1030+ def encode_bigvarchar_col_type ( % Column { opts: opts } = col ) do
1031+ type = @ tds_data_type_bigvarchar
1032+ length = Keyword . get ( opts , :length , 0 )
1033+ collation = << 0x00 , 0x00 , 0x00 , 0x00 , 0x00 >>
1034+ bin_length = if length <= 8000 , do: << 8000 :: little - unsigned - 16 >> , else: << 0xFF , 0xFF >>
1035+ data = << type >> <> bin_length <> collation
1036+
1037+ { type , data , length: length }
1038+ end
1039+
1040+ def encode_varbinary_col_type ( % Column { opts: opts } = col ) do
1041+ type = @ tds_data_type_bigvarbinary
1042+ length = Keyword . get ( opts , :length , 0 )
1043+ bin_length = if length <= 8000 , do: << 8000 :: little - unsigned - 16 >> , else: << 0xFF , 0xFF >>
1044+ data = << type >> <> bin_length
1045+
1046+ { type , data , length: length }
1047+ end
1048+
10111049 @ doc """
10121050 Data Encoding String Types
10131051 """
1052+
1053+ def encode_data ( @ tds_data_type_bigvarchar , nil , opts ) do
1054+ length = Keyword . get ( opts , :length , 0 )
1055+ if length <= 8000 ,
1056+ do: << 65535 :: little - unsigned - 16 >> ,
1057+ else: << @ tds_plp_null :: little - unsigned - 64 >>
1058+ end
1059+
1060+ def encode_data ( @ tds_data_type_bigvarchar , value , opts ) do
1061+ value_size = byte_size ( value )
1062+ cond do
1063+ value_size <= 0 ->
1064+ << 0x00 :: unsigned - 64 , 0x00 :: unsigned - 32 >>
1065+ value_size > 8000 ->
1066+ encode_plp ( value )
1067+ true ->
1068+ << value_size :: little - size ( 2 ) - unit ( 8 ) >> <> value
1069+ end
1070+ end
1071+
10141072 def encode_data ( @ tds_data_type_nvarchar , nil , _ ) ,
10151073 do: << @ tds_plp_null :: little - unsigned - 64 >>
10161074 def encode_data ( @ tds_data_type_nvarchar , value , _ ) do
0 commit comments