Current section
Files
Jump to
Current section
Files
src/sql_bridge_epgsql_codec_datetime.erl
-module(sql_bridge_epgsql_codec_datetime).
-behaviour(epgsql_codec).
-export([init/2, names/0, encode/3, decode/3, decode_text/3]).
-define(MAIN_MOD, epgsql_codec_datetime).
-define(IS_STRING(Val), (is_binary(Data) orelse is_list(Data))).
init(State, Sock) ->
?MAIN_MOD:init(State, Sock).
names() ->
?MAIN_MOD:names().
encode(Data, date=Type, State) when ?IS_STRING(Data) ->
Data2 = s2date(Data),
?MAIN_MOD:encode(Data2, Type, State);
encode(Data, time=Type, State) when ?IS_STRING(Data) ->
Data2 = s2time(Data),
?MAIN_MOD:encode(Data2, Type, State);
encode({Data, TZ}, timetz=Type, State) when ?IS_STRING(Data) ->
Data2 = s2time(Data),
?MAIN_MOD:encode({Data2, TZ}, Type, State);
encode(Data, timestamp=Type, State) when ?IS_STRING(Data) ->
Data2 = s2timestamp(Data),
?MAIN_MOD:encode(Data2, Type, State);
encode(Data, timestamptz=Type, State) when ?IS_STRING(Data) ->
Data2 = s2timestamp(Data),
?MAIN_MOD:encode(Data2, Type, State);
encode(Data, Type, State) ->
?MAIN_MOD:encode(Data, Type, State).
s2date(Data) ->
RE = "^(\\d{4})-(\\d{1,2})-(\\d{1,2})$",
case re:run(Data, RE, [{capture, all_but_first, list}]) of
nomatch ->
exit({invalid_date_format, Data});
{match, [Y,M,D]} ->
{list_to_integer(Y), list_to_integer(M), list_to_integer(D)}
end.
s2time(Data) ->
RE = "^(\\d{1,2}):(\\d{2})(?::(\\d{2}))?$",
case re:run(Data, RE, [{capture, all_but_first, list}]) of
nomatch ->
exit({invalid_time_format, Data});
{match, [H, M]} ->
{list_to_integer(H), list_to_integer(M), 0};
{match, [H, M, S]} ->
{list_to_integer(H), list_to_integer(M), list_to_integer(S)}
end.
s2timestamp(Data) ->
case re:split(Data, "[\\sT]", [{return, list}]) of
[DateStr, TimeStr] ->
Date = s2date(DateStr),
Time = s2time(TimeStr),
{Date, Time};
_ ->
exit({invalid_datetime_format, Data})
end.
decode(Data, Type, State) ->
?MAIN_MOD:decode(Data, Type, State).
decode_text(Data, Type, State) ->
?MAIN_MOD:decode_text(Data, Type, State).