@@ -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
@@ -983,8 +984,8 @@ defmodule Tds.Types do
983984
984985 def encode_data ( @ tds_data_type_tvp , % { columns: columns , rows: rows } , _attrs ) do
985986 column_length = << length ( columns ) :: little - unsigned - 16 >>
986- { column_attrs , column_meta } = Enum . reduce ( columns , { [ ] , << >> } , fn ( % Parameter { } = param , { attrs , acc_bin } ) ->
987- { bin_type , data , attr } = encode_data_type ( param )
987+ { column_attrs , column_meta } = Enum . reduce ( columns , { [ ] , << >> } , fn ( % Column { } = param , { attrs , acc_bin } ) ->
988+ { bin_type , data , attr } = encode_column_type ( param )
988989 bin = acc_bin <> << 0x00 :: little - unsigned - 32 , 0x00 :: little - unsigned - 16 >> <> data <> << 0x00 >>
989990
990991 { [ { bin_type , attr } | attrs ] , bin }
@@ -1004,9 +1005,66 @@ defmodule Tds.Types do
10041005 column_length <> column_meta <> << 0x00 >> <> row_data <> << 0x00 >>
10051006 end
10061007
1008+ def encode_column_type ( % Column { type: type } = col ) when type != nil do
1009+ case type do
1010+ :varchar -> encode_bigvarchar_col_type ( col )
1011+ :boolean -> encode_binary_type ( % Parameter { type: :boolean , value: nil } )
1012+ :varbinary -> encode_varbinary_col_type ( col )
1013+ :int -> encode_integer_type ( % Parameter { type: :integer , value: nil } )
1014+ :decimal -> encode_decimal_type ( % Parameter { type: :decimal , value: nil } )
1015+ :float -> encode_float_type ( % Parameter { type: :float , value: nil } )
1016+ :datetime -> encode_datetime_type ( % Parameter { type: :datetime , value: nil } )
1017+ :smalldatetime -> encode_smalldatetime_type ( % Parameter { type: :smalldatetime , value: nil } )
1018+ :datetime2 -> encode_datetime2_type ( % Parameter { type: :datetime2 , value: nil } )
1019+ :datetimeoffset -> encode_datetimeoffset_type ( % Parameter { type: :datetimeoffset , value: nil } )
1020+ :date -> encode_date_type ( % Parameter { type: :datetimeoffset , value: nil } )
1021+ :time -> encode_time_type ( % Parameter { type: :time , value: nil } )
1022+ :uuid -> encode_uuid_type ( % Parameter { type: :uuid , value: nil } )
1023+ end
1024+ end
1025+
1026+ def encode_bigvarchar_col_type ( % Column { opts: opts } = col ) do
1027+ type = @ tds_data_type_bigvarchar
1028+ length = Keyword . get ( opts , :length , 0 )
1029+ collation = << 0x00 , 0x00 , 0x00 , 0x00 , 0x00 >>
1030+ bin_length = if length <= 8000 , do: << 8000 :: little - unsigned - 16 >> , else: << 0xFF , 0xFF >>
1031+ data = << type >> <> bin_length <> collation
1032+
1033+ { type , data , length: length }
1034+ end
1035+
1036+ def encode_varbinary_col_type ( % Column { opts: opts } = col ) do
1037+ type = @ tds_data_type_bigvarbinary
1038+ length = Keyword . get ( opts , :length , 0 )
1039+ bin_length = if length <= 8000 , do: << 8000 :: little - unsigned - 16 >> , else: << 0xFF , 0xFF >>
1040+ data = << type >> <> bin_length
1041+
1042+ { type , data , length: length }
1043+ end
1044+
10071045 @ doc """
10081046 Data Encoding String Types
10091047 """
1048+
1049+ def encode_data ( @ tds_data_type_bigvarchar , nil , opts ) do
1050+ length = Keyword . get ( opts , :length , 0 )
1051+ if length <= 8000 ,
1052+ do: << 65535 :: little - unsigned - 16 >> ,
1053+ else: << @ tds_plp_null :: little - unsigned - 64 >>
1054+ end
1055+
1056+ def encode_data ( @ tds_data_type_bigvarchar , value , opts ) do
1057+ value_size = byte_size ( value )
1058+ cond do
1059+ value_size <= 0 ->
1060+ << 0x00 :: unsigned - 64 , 0x00 :: unsigned - 32 >>
1061+ value_size > 8000 ->
1062+ encode_plp ( value )
1063+ true ->
1064+ << value_size :: little - size ( 2 ) - unit ( 8 ) >> <> value
1065+ end
1066+ end
1067+
10101068 def encode_data ( @ tds_data_type_nvarchar , nil , _ ) ,
10111069 do: << @ tds_plp_null :: little - unsigned - 64 >>
10121070 def encode_data ( @ tds_data_type_nvarchar , value , _ ) do
0 commit comments