Packages
tds
2.3.6
2.3.8
2.3.7
2.3.6
2.3.5
2.3.4
2.3.2
2.3.1
2.3.0
2.3.0-rc.1
2.3.0-rc.0
2.2.0
2.1.3
2.1.2
2.1.1
2.1.0
2.0.4
2.0.3
2.0.2
2.0.1
2.0.1-rc2
2.0.1-rc1
2.0.0
retired
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.0
1.0.19
1.0.18
1.0.17
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.0
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Microsoft SQL Server client (Elixir implementation of the MS TDS protocol)
Current section
Files
Jump to
Current section
Files
lib/tds/parameter.ex
defmodule Tds.Parameter do
@moduledoc false
alias Tds.Types
@type t :: %__MODULE__{
name: String.t() | nil,
direction: :input | :output,
value: String.t() | nil,
type: atom() | nil,
length: nil | integer
}
defstruct name: "",
direction: :input,
value: "",
type: nil,
length: nil
def option_flags(%__MODULE__{direction: direction, value: value}) do
fByRefValue =
case direction do
:output -> 1
_ -> 0
end
fDefaultValue =
case value do
:default -> 1
_ -> 0
end
<<0::size(6), fDefaultValue::size(1), fByRefValue::size(1)>>
end
def prepared_params(params) do
params
|> List.wrap()
|> name(0)
|> Enum.map_join(", ", fn param ->
param
|> fix_data_type()
|> Types.encode_param_descriptor()
end)
end
@doc """
Prepares parameters by giving them names, define missing type, encoding value
if necessary.
"""
def prepare_params(params) do
params
|> List.wrap()
|> name(0)
|> Enum.map(&fix_data_type/1)
end
def name(params, name) do
do_name(params, name, [])
end
def do_name([param | tail], name, acc) do
name = name + 1
param =
case param do
%__MODULE__{name: nil} -> fix_data_type(%{param | name: "@#{name}"})
%__MODULE__{} -> fix_data_type(param)
raw_param -> fix_data_type(raw_param, name)
end
do_name(tail, name, [param | acc])
end
def do_name([], _, acc) do
acc
end
def fix_data_type(%__MODULE__{type: type, value: _value} = param)
when not is_nil(type) do
param
end
def fix_data_type(%__MODULE__{type: nil, value: nil} = param) do
# should fix Ecto has_one, on_change :nullify issue where type is not known when Ecto
# builds query/statement for on_change callback
%{param | type: :binary}
end
def fix_data_type(%__MODULE__{value: value} = param)
when is_boolean(value) do
%{param | type: :boolean}
end
def fix_data_type(%__MODULE__{value: value} = param)
when is_binary(value) and value == "" do
%{param | type: :string}
end
def fix_data_type(%__MODULE__{value: value} = param)
when is_binary(value) do
if String.valid?(value) do
%{param | type: :string}
else
%{param | type: :binary}
end
end
def fix_data_type(%__MODULE__{value: value} = param)
when is_integer(value) do
# if -2_147_483_648 >= value and value <= 2_147_483_647 do
# %{param | type: :integer}
# else
# %{param | type: :bigint}
# end
%{param | type: :integer}
end
def fix_data_type(%__MODULE__{value: value} = param)
when is_float(value) do
%{param | type: :float}
end
def fix_data_type(%__MODULE__{value: %Decimal{}} = param) do
%{param | type: :decimal}
end
def fix_data_type(%__MODULE__{value: {{_, _, _}}} = param) do
%{param | type: :date}
end
def fix_data_type(%__MODULE__{value: %Date{}} = param) do
%{param | type: :date}
end
def fix_data_type(%__MODULE__{value: {{_, _, _, _}}} = param) do
%{param | type: :time}
end
def fix_data_type(%__MODULE__{value: %Time{}} = param) do
%{param | type: :time}
end
def fix_data_type(%__MODULE__{value: {{_, _, _}, {_, _, _}}} = param) do
%{param | type: :datetime}
end
def fix_data_type(%__MODULE__{value: %NaiveDateTime{microsecond: {_, s}}} = param) do
type = if s > 3, do: :datetime2, else: :datetime
%{param | type: type}
end
def fix_data_type(%__MODULE__{value: {{_, _, _}, {_, _, _, fsec}}} = param) do
# todo: enable warning and introduce Tds.Types.DateTime2 and Tds.Types.DateTime
# Logger.warn(fn -> "Datetime as tuple is obsolete, please use NaiveDateTime." end)
type = if rem(fsec, 1000) > 0, do: :datetime2, else: :datetime
%{param | type: type}
end
def fix_data_type(%__MODULE__{value: %DateTime{}} = param) do
%{param | type: :datetimeoffset}
end
def fix_data_type(%__MODULE__{value: {{_y, _m, _d}, _time, _offset}} = param) do
%{param | type: :datetimeoffset}
end
def fix_data_type(%__MODULE__{} = raw_param, acc) do
param =
if is_nil(raw_param.name) do
%{raw_param | name: "@#{acc}"}
else
raw_param
end
fix_data_type(param)
end
def fix_data_type(raw_param, acc) do
fix_data_type(%__MODULE__{name: "@#{acc}", value: raw_param})
end
end