Browse Source

Add elvis; fix elvis warnings; add elvis to travis

Сергей Прохоров 7 years ago
parent
commit
084ca7b010

+ 1 - 0
.travis.yml

@@ -20,3 +20,4 @@ otp_release:
 script:
   - make test
   - make dialyzer
+  - make elvis

+ 12 - 1
Makefile

@@ -1,4 +1,5 @@
 REBAR = rebar3
+ERL_VSN = $(shell erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().'  -noshell)
 
 all: compile
 
@@ -17,4 +18,14 @@ test: compile
 dialyzer: compile
 	@$(REBAR) dialyzer
 
-.PHONY: all compile clean test dialyzer
+elvis:
+	@case "$(ERL_VSN)" in\
+		"R16"*)\
+			echo "Elvis is disabled on erl 16"\
+			;;\
+		*)\
+			$(REBAR) as lint lint\
+			;;\
+	esac
+
+.PHONY: all compile clean test dialyzer elvis

+ 17 - 0
rebar.config

@@ -11,9 +11,26 @@
         {deps, [
             {erlexec, {git, "https://github.com/saleyn/erlexec.git", {ref, "576fb5d"}}}
         ]}
+    ]},
+    {lint, [
+        {plugins, [rebar3_lint]}
     ]}
 ]}.
 
 {ct_opts, [
     {ct_hooks, [epgsql_cth]}
 ]}.
+
+%% See rebar.config.script
+%% {elvis,
+%%   [#{dirs => ["src", "src/*"],
+%%      include_dirs => ["include"],
+%%      filter => "*.erl",
+%%      ruleset => erl_files,
+%%      rules =>
+%%          [{elvis_style, line_length, #{limit => 120}},
+%%           {elvis_style, god_modules, #{limit => 40}},
+%%           {elvis_style, state_record_and_type, disable} % epgsql_sock
+%%          ]}
+%%   ]
+%%  }.

+ 19 - 0
rebar.config.script

@@ -0,0 +1,19 @@
+%% Elvis config uses maps, but they are not available in Erlang < 17
+case erlang:is_builtin(erlang, is_map, 1) of
+    true ->
+        [{elvis,
+          [maps:from_list(
+             [{dirs, ["src", "src/*"]},
+              {include_dirs, ["include"]},
+              {filter, "*.erl"},
+              {ruleset, erl_files},
+              {rules,
+                 [{elvis_style, line_length, maps:from_list([{limit, 120}])},
+                  {elvis_style, god_modules, maps:from_list([{limit, 40}])},
+                  {elvis_style, state_record_and_type, disable} % epgsql_sock
+                 ]}
+              ])
+          ]
+         } | CONFIG];
+    false -> CONFIG
+end.

+ 9 - 5
src/datatypes/epgsql_codec_datetime.erl

@@ -46,10 +46,14 @@ names() ->
 
 %% FIXME: move common logick out from fdatetime/idatetime; make them more
 %% low-level
-encode(Val, Type, Mod) ->
-    Mod:encode(Type, Val).
-
-decode(Bin, Type, Mod) ->
-    Mod:decode(Type, Bin).
+encode(Val, Type, epgsql_idatetime) ->
+    epgsql_idatetime:encode(Type, Val);
+encode(Val, Type, epgsql_fdatetime) ->
+    epgsql_fdatetime:encode(Type, Val).
+
+decode(Bin, Type, epgsql_idatetime) ->
+    epgsql_idatetime:decode(Type, Bin);
+decode(Bin, Type, epgsql_fdatetime) ->
+    epgsql_fdatetime:decode(Type, Bin).
 
 decode_text(V, _, _) -> V.

+ 27 - 18
src/epgsql.erl

@@ -28,10 +28,11 @@
          start_replication/5,
          start_replication/6,
          to_proplist/1]).
+-export([handle_x_log_data/5]).                 % private
 
 -export_type([connection/0, connect_option/0, connect_opts/0,
               connect_error/0, query_error/0, sql_query/0, column/0,
-              type_name/0, epgsql_type/0]).
+              type_name/0, epgsql_type/0, statement/0]).
 
 %% Deprecated types
 -export_type([bind_param/0, typed_param/0,
@@ -95,12 +96,16 @@
 -type typed_param() :: {epgsql_type(), bind_param()}.
 
 -type column() :: #column{}.
+-type statement() :: #statement{}.
 -type squery_row() :: tuple(). % tuple of binary().
 -type equery_row() :: tuple(). % tuple of bind_param().
 -type ok_reply(RowType) ::
-    {ok, ColumnsDescription :: [column()], RowsValues :: [RowType]} |                            % select
-    {ok, Count :: non_neg_integer()} |                                                            % update/insert/delete
-    {ok, Count :: non_neg_integer(), ColumnsDescription :: [column()], RowsValues :: [RowType]}. % update/insert/delete + returning
+        %% select
+    {ok, ColumnsDescription :: [column()], RowsValues :: [RowType]} |
+        %% update/insert/delete
+    {ok, Count :: non_neg_integer()} |
+        %% update/insert/delete + returning
+    {ok, Count :: non_neg_integer(), ColumnsDescription :: [column()], RowsValues :: [RowType]}.
 -type error_reply() :: {error, query_error()}.
 -type reply(RowType) :: ok_reply(RowType) | error_reply().
 -type lsn() :: integer().
@@ -118,10 +123,10 @@
         -> {ok, Connection :: connection()} | {error, Reason :: connect_error()}.
 connect(Settings0) ->
     Settings = to_proplist(Settings0),
-	Host = proplists:get_value(host, Settings, "localhost"),
-	Username = proplists:get_value(username, Settings, os:getenv("USER")),
-	Password = proplists:get_value(password, Settings, ""),
-	connect(Host, Username, Password, Settings).
+    Host = proplists:get_value(host, Settings, "localhost"),
+    Username = proplists:get_value(username, Settings, os:getenv("USER")),
+    Password = proplists:get_value(password, Settings, ""),
+    connect(Host, Username, Password, Settings).
 
 connect(Host, Opts) ->
     connect(Host, os:getenv("USER"), "", Opts).
@@ -220,8 +225,8 @@ equery(C, Sql) ->
 equery(C, Sql, Parameters) ->
     case parse(C, "", Sql, []) of
         {ok, #statement{types = Types} = S} ->
-            Typed_Parameters = lists:zip(Types, Parameters),
-            epgsql_sock:sync_command(C, epgsql_cmd_equery, {S, Typed_Parameters});
+            TypedParameters = lists:zip(Types, Parameters),
+            epgsql_sock:sync_command(C, epgsql_cmd_equery, {S, TypedParameters});
         Error ->
             Error
     end.
@@ -242,8 +247,8 @@ equery(C, Name, Sql, Parameters) ->
 prepared_query(C, Name, Parameters) ->
     case describe(C, statement, Name) of
         {ok, #statement{types = Types} = S} ->
-            Typed_Parameters = lists:zip(Types, Parameters),
-            epgsql_sock:sync_command(C, epgsql_cmd_prepared_query, {S, Typed_Parameters});
+            TypedParameters = lists:zip(Types, Parameters),
+            epgsql_sock:sync_command(C, epgsql_cmd_prepared_query, {S, TypedParameters});
         Error ->
             Error
     end.
@@ -269,7 +274,7 @@ parse(C, Name, Sql, Types) ->
 bind(C, Statement, Parameters) ->
     bind(C, Statement, "", Parameters).
 
--spec bind(connection(), #statement{}, string(), [bind_param()]) ->
+-spec bind(connection(), statement(), string(), [bind_param()]) ->
                   epgsql_cmd_bind:response().
 bind(C, Statement, PortalName, Parameters) ->
     sync_on_error(
@@ -285,18 +290,18 @@ execute(C, S) ->
 execute(C, S, N) ->
     execute(C, S, "", N).
 
--spec execute(connection(), #statement{}, string(), non_neg_integer()) -> Reply when
+-spec execute(connection(), statement(), string(), non_neg_integer()) -> Reply when
       Reply :: epgsql_cmd_execute:response().
 execute(C, S, PortalName, N) ->
     epgsql_sock:sync_command(C, epgsql_cmd_execute, {S, PortalName, N}).
 
--spec execute_batch(connection(), [{#statement{}, [bind_param()]}]) ->
+-spec execute_batch(connection(), [{statement(), [bind_param()]}]) ->
                            epgsql_cmd_batch:response().
 execute_batch(C, Batch) ->
     epgsql_sock:sync_command(C, epgsql_cmd_batch, Batch).
 
 %% statement/portal functions
--spec describe(connection(), #statement{}) -> epgsql_cmd_describe_statement:response().
+-spec describe(connection(), statement()) -> epgsql_cmd_describe_statement:response().
 describe(C, #statement{name = Name}) ->
     describe(C, statement, Name).
 
@@ -313,7 +318,7 @@ describe(C, portal, Name) ->
            C, epgsql_cmd_describe_portal, Name)).
 
 %% @doc close statement
--spec close(connection(), #statement{}) -> epgsql_cmd_close:response().
+-spec close(connection(), statement()) -> epgsql_cmd_close:response().
 close(C, #statement{name = Name}) ->
     close(C, statement, Name).
 
@@ -392,10 +397,14 @@ sync_on_error(_C, R) ->
     R.
 
 -spec standby_status_update(connection(), lsn(), lsn()) -> ok.
-%% @doc sends last flushed and applied WAL positions to the server in a standby status update message via given `Connection'
+%% @doc sends last flushed and applied WAL positions to the server in a standby status update message via
+%% given `Connection'
 standby_status_update(Connection, FlushedLSN, AppliedLSN) ->
     gen_server:call(Connection, {standby_status_update, FlushedLSN, AppliedLSN}).
 
+handle_x_log_data(Mod, StartLSN, EndLSN, WALRecord, Repl) ->
+    Mod:handle_x_log_data(StartLSN, EndLSN, WALRecord, Repl).
+
 -spec start_replication(connection(), string(), Callback, cb_state(), string(), string()) -> Response when
       Response :: epgsql_cmd_start_replication:response(),
       Callback :: module() | pid().

+ 12 - 12
src/epgsql_binary.erl

@@ -206,7 +206,7 @@ decode_record1(<<Oid:?int32, Len:?int32, ValueBin:Len/binary, Rest/binary>>, Siz
             undefined -> ValueBin;
             Type ->
                 {Name, Mod, State} = epgsql_oid_db:type_to_codec_entry(Type),
-                Mod:decode(ValueBin, Name, State)
+                epgsql_codec:decode(Mod, ValueBin, Name, State)
         end,
     [Value | decode_record1(Rest, Size - 1, Codec)].
 
@@ -233,7 +233,7 @@ encode_with_type(Type, Value) ->
     end.
 
 encode_value(Value, {Mod, Name, State}) ->
-    Payload = Mod:encode(Value, Name, State),
+    Payload = epgsql_codec:encode(Mod, Value, Name, State),
     [<<(iolist_size(Payload)):?int32>> | Payload].
 
 
@@ -269,19 +269,19 @@ supports(Oid, #codec{oid_db = Db}) ->
 %% XXX: maybe move to application env?
 -spec default_codecs() -> [{epgsql_codec:codec_mod(), any()}].
 default_codecs() ->
-    [{epgsql_codec_boolean,[]},
-     {epgsql_codec_bpchar,[]},
-     {epgsql_codec_datetime,[]},
-     {epgsql_codec_float,[]},
+    [{epgsql_codec_boolean, []},
+     {epgsql_codec_bpchar, []},
+     {epgsql_codec_datetime, []},
+     {epgsql_codec_float, []},
      {epgsql_codec_geometric, []},
      %% {epgsql_codec_hstore, []},
-     {epgsql_codec_integer,[]},
-     {epgsql_codec_intrange,[]},
-     {epgsql_codec_json,[]},
-     {epgsql_codec_net,[]},
+     {epgsql_codec_integer, []},
+     {epgsql_codec_intrange, []},
+     {epgsql_codec_json, []},
+     {epgsql_codec_net, []},
      %% {epgsql_codec_postgis,[]},
-     {epgsql_codec_text,[]},
-     {epgsql_codec_uuid,[]}].
+     {epgsql_codec_text, []},
+     {epgsql_codec_uuid, []}].
 
 -spec default_oids() -> [epgsql_oid_db:oid_entry()].
 default_oids() ->

+ 13 - 1
src/epgsql_codec.erl

@@ -7,7 +7,7 @@
 %%% Created : 12 Oct 2017 by Sergey Prokhorov <me@seriyps.ru>
 
 -module(epgsql_codec).
--export([init_mods/2]).
+-export([init_mods/2, encode/4, decode/4, decode_text/4]).
 
 -export_type([codec_state/0, codec_mod/0, codec_entry/0]).
 
@@ -67,3 +67,15 @@ add_names([Name | Names], {Mod, State} = MS, Set, Acc) ->
     end;
 add_names([], _, Set, Acc) ->
     {Set, Acc}.
+
+-spec encode(codec_mod(), any(), epgsql:type_name(), codec_state()) -> iodata().
+encode(Mod, Cell, TypeName, CodecState) ->
+    Mod:encode(Cell, TypeName, CodecState).
+
+-spec decode(codec_mod(), binary(), epgsql:type_name(), codec_state()) -> any().
+decode(Mod, Cell, TypeName, CodecState) ->
+    Mod:decode(Cell, TypeName, CodecState).
+
+-spec decode_text(codec_mod(), binary(), epgsql:type_name(), codec_state()) -> any().
+decode_text(Mod, Cell, TypeName, CodecState) ->
+    Mod:decode(Cell, TypeName, CodecState).

+ 18 - 18
src/epgsql_fdatetime.erl

@@ -6,22 +6,22 @@
 
 -include("protocol.hrl").
 
--define(postgres_epoc_jdate, 2451545).
--define(postgres_epoc_secs, 946684800).
+-define(POSTGRES_EPOC_JDATE, 2451545).
+-define(POSTGRES_EPOC_SECS, 946684800).
 
--define(mins_per_hour, 60).
--define(secs_per_day, 86400.0).
--define(secs_per_hour, 3600.0).
--define(secs_per_minute, 60.0).
+-define(MINS_PER_HOUR, 60).
+-define(SECS_PER_DAY, 86400.0).
+-define(SECS_PER_HOUR, 3600.0).
+-define(SECS_PER_MINUTE, 60.0).
 
-decode(date, <<J:1/big-signed-unit:32>>)             -> epgsql_idatetime:j2date(?postgres_epoc_jdate + J);
+decode(date, <<J:1/big-signed-unit:32>>)             -> epgsql_idatetime:j2date(?POSTGRES_EPOC_JDATE + J);
 decode(time, <<N:1/big-float-unit:64>>)              -> f2time(N);
 decode(timetz, <<N:1/big-float-unit:64, TZ:?int32>>) -> {f2time(N), TZ};
 decode(timestamp, <<N:1/big-float-unit:64>>)         -> f2timestamp(N);
 decode(timestamptz, <<N:1/big-float-unit:64>>)       -> f2timestamp(N);
 decode(interval, <<N:1/big-float-unit:64, D:?int32, M:?int32>>) -> {f2time(N), D, M}.
 
-encode(date, D)         -> <<(epgsql_idatetime:date2j(D) - ?postgres_epoc_jdate):1/big-signed-unit:32>>;
+encode(date, D)         -> <<(epgsql_idatetime:date2j(D) - ?POSTGRES_EPOC_JDATE):1/big-signed-unit:32>>;
 encode(time, T)         -> <<(time2f(T)):1/big-float-unit:64>>;
 encode(timetz, {T, TZ}) -> <<(time2f(T)):1/big-float-unit:64, TZ:?int32>>;
 encode(timestamp, TS = {_, _, _})   -> <<(now2f(TS)):1/big-float-unit:64>>;
@@ -31,8 +31,8 @@ encode(timestamptz, TS) -> <<(timestamp2f(TS)):1/big-float-unit:64>>;
 encode(interval, {T, D, M}) -> <<(time2f(T)):1/big-float-unit:64, D:?int32, M:?int32>>.
 
 f2time(N) ->
-    {R1, Hour} = tmodulo(N, ?secs_per_hour),
-    {R2, Min}  = tmodulo(R1, ?secs_per_minute),
+    {R1, Hour} = tmodulo(N, ?SECS_PER_HOUR),
+    {R2, Min}  = tmodulo(R1, ?SECS_PER_MINUTE),
     {R3, Sec}  = tmodulo(R2, 1.0),
     case timeround(R3) of
         US when US >= 1.0 -> f2time(ceiling(N));
@@ -40,12 +40,12 @@ f2time(N) ->
     end.
 
 time2f({H, M, S}) ->
-    ((H * ?mins_per_hour + M) * ?secs_per_minute) + S.
+    ((H * ?MINS_PER_HOUR + M) * ?SECS_PER_MINUTE) + S.
 
 f2timestamp(N) ->
-    case tmodulo(N, ?secs_per_day) of
-        {T, D} when T < 0 -> f2timestamp2(D - 1 + ?postgres_epoc_jdate, T + ?secs_per_day);
-        {T, D}            -> f2timestamp2(D + ?postgres_epoc_jdate, T)
+    case tmodulo(N, ?SECS_PER_DAY) of
+        {T, D} when T < 0 -> f2timestamp2(D - 1 + ?POSTGRES_EPOC_JDATE, T + ?SECS_PER_DAY);
+        {T, D}            -> f2timestamp2(D + ?POSTGRES_EPOC_JDATE, T)
     end.
 
 f2timestamp2(D, T) ->
@@ -54,7 +54,7 @@ f2timestamp2(D, T) ->
     case tsround(S - trunc(S)) of
         N when N >= 1.0 ->
             case ceiling(T) of
-                T2 when T2 > ?secs_per_day -> f2timestamp2(D + 1, 0.0);
+                T2 when T2 > ?SECS_PER_DAY -> f2timestamp2(D + 1, 0.0);
                 T2                         -> f2timestamp2(T2, D)
             end;
         _ -> ok
@@ -62,11 +62,11 @@ f2timestamp2(D, T) ->
     {Date, Time}.
 
 timestamp2f({Date, Time}) ->
-    D = epgsql_idatetime:date2j(Date) - ?postgres_epoc_jdate,
-    D * ?secs_per_day + time2f(Time).
+    D = epgsql_idatetime:date2j(Date) - ?POSTGRES_EPOC_JDATE,
+    D * ?SECS_PER_DAY + time2f(Time).
 
 now2f({MegaSecs, Secs, MicroSecs}) ->
-    MegaSecs * 1000000 + Secs + MicroSecs / 1000000.0 - ?postgres_epoc_secs.
+    MegaSecs * 1000000 + Secs + MicroSecs / 1000000.0 - ?POSTGRES_EPOC_SECS.
 
 tmodulo(T, U) ->
     Q = case T < 0 of

+ 25 - 25
src/epgsql_idatetime.erl

@@ -7,25 +7,25 @@
 
 -include("protocol.hrl").
 
--define(postgres_epoc_jdate, 2451545).
--define(postgres_epoc_usecs, 946684800000000).
+-define(POSTGRES_EPOC_JDATE, 2451545).
+-define(POSTGRES_EPOC_USECS, 946684800000000).
 
--define(mins_per_hour, 60).
--define(secs_per_minute, 60).
+-define(MINS_PER_HOUR, 60).
+-define(SECS_PER_MINUTE, 60).
 
--define(usecs_per_day, 86400000000).
--define(usecs_per_hour, 3600000000).
--define(usecs_per_minute, 60000000).
--define(usecs_per_sec, 1000000).
+-define(USECS_PER_DAY, 86400000000).
+-define(USECS_PER_HOUR, 3600000000).
+-define(USECS_PER_MINUTE, 60000000).
+-define(USECS_PER_SEC, 1000000).
 
-decode(date, <<J:?int32>>)                         -> j2date(?postgres_epoc_jdate + J);
+decode(date, <<J:?int32>>)                         -> j2date(?POSTGRES_EPOC_JDATE + J);
 decode(time, <<N:?int64>>)                         -> i2time(N);
 decode(timetz, <<N:?int64, TZ:?int32>>)            -> {i2time(N), TZ};
 decode(timestamp, <<N:?int64>>)                    -> i2timestamp(N);
 decode(timestamptz, <<N:?int64>>)                  -> i2timestamp(N);
 decode(interval, <<N:?int64, D:?int32, M:?int32>>) -> {i2time(N), D, M}.
 
-encode(date, D)         -> <<(date2j(D) - ?postgres_epoc_jdate):?int32>>;
+encode(date, D)         -> <<(date2j(D) - ?POSTGRES_EPOC_JDATE):?int32>>;
 encode(time, T)         -> <<(time2i(T)):?int64>>;
 encode(timetz, {T, TZ}) -> <<(time2i(T)):?int64, TZ:?int32>>;
 encode(timestamp, TS = {_, _, _})   -> <<(now2i(TS)):?int64>>;
@@ -73,33 +73,33 @@ date2j({Y, M, D}) ->
     J2 + 7834 * M2 div 256 + D.
 
 i2time(N) ->
-    Hour = N div ?usecs_per_hour,
-    R1 = N - Hour * ?usecs_per_hour,
-    Min = R1 div ?usecs_per_minute,
-    R2 = R1 - Min * ?usecs_per_minute,
-    Sec = R2 div ?usecs_per_sec,
-    US = R2 - Sec * ?usecs_per_sec,
-    {Hour, Min, Sec + US / ?usecs_per_sec}.
+    Hour = N div ?USECS_PER_HOUR,
+    R1 = N - Hour * ?USECS_PER_HOUR,
+    Min = R1 div ?USECS_PER_MINUTE,
+    R2 = R1 - Min * ?USECS_PER_MINUTE,
+    Sec = R2 div ?USECS_PER_SEC,
+    US = R2 - Sec * ?USECS_PER_SEC,
+    {Hour, Min, Sec + US / ?USECS_PER_SEC}.
 
 time2i({H, M, S}) ->
-    US = trunc(round(S * ?usecs_per_sec)),
-    ((H * ?mins_per_hour + M) * ?secs_per_minute) * ?usecs_per_sec + US.
+    US = trunc(round(S * ?USECS_PER_SEC)),
+    ((H * ?MINS_PER_HOUR + M) * ?SECS_PER_MINUTE) * ?USECS_PER_SEC + US.
 
 i2timestamp(N) ->
-    case tmodulo(N, ?usecs_per_day) of
-        {T, D} when T < 0 -> i2timestamp2(D - 1 + ?postgres_epoc_jdate, T + ?usecs_per_day);
-        {T, D}            -> i2timestamp2(D + ?postgres_epoc_jdate, T)
+    case tmodulo(N, ?USECS_PER_DAY) of
+        {T, D} when T < 0 -> i2timestamp2(D - 1 + ?POSTGRES_EPOC_JDATE, T + ?USECS_PER_DAY);
+        {T, D}            -> i2timestamp2(D + ?POSTGRES_EPOC_JDATE, T)
     end.
 
 i2timestamp2(D, T) ->
     {j2date(D), i2time(T)}.
 
 timestamp2i({Date, Time}) ->
-    D = date2j(Date) - ?postgres_epoc_jdate,
-    D * ?usecs_per_day + time2i(Time).
+    D = date2j(Date) - ?POSTGRES_EPOC_JDATE,
+    D * ?USECS_PER_DAY + time2i(Time).
 
 now2i({MegaSecs, Secs, MicroSecs}) ->
-    (MegaSecs * 1000000 + Secs) * 1000000 + MicroSecs - ?postgres_epoc_usecs.
+    (MegaSecs * 1000000 + Secs) * 1000000 + MicroSecs - ?POSTGRES_EPOC_USECS.
 
 tmodulo(T, U) ->
     case T div U of

+ 6 - 7
src/epgsql_sock.erl

@@ -57,6 +57,7 @@
                    | {incremental, pid(), reference()}.
 
 -type tcp_socket() :: port(). %gen_tcp:socket() isn't exported prior to erl 18
+-type repl_state() :: #repl{}.
 
 -record(state, {mod :: gen_tcp | ssl | undefined,
                 sock :: tcp_socket() | ssl:sslsocket() | undefined,
@@ -75,11 +76,10 @@
                 sync_required :: boolean() | undefined,
                 txstatus :: byte() | undefined,  % $I | $T | $E,
                 complete_status :: atom() | {atom(), integer()} | undefined,
-                repl :: #repl{} | undefined}).
+                repl :: repl_state() | undefined}).
 
 -opaque pg_sock() :: #state{}.
 
-
 %% -- client interface --
 
 start_link() ->
@@ -153,7 +153,7 @@ set_packet_handler(Handler, State) ->
 get_codec(#state{codec = Codec}) ->
     Codec.
 
--spec get_replication_state(pg_sock()) -> #repl{}.
+-spec get_replication_state(pg_sock()) -> repl_state().
 get_replication_state(#state{repl = Repl}) ->
     Repl.
 
@@ -366,9 +366,8 @@ do_send(gen_tcp, Sock, Bin) ->
         error:_Error ->
             {error, einval}
     end;
-
-do_send(Mod, Sock, Bin) ->
-    Mod:send(Sock, Bin).
+do_send(ssl, Sock, Bin) ->
+    ssl:send(Sock, Bin).
 
 loop(#state{data = Data, handler = Handler, repl = Repl} = State) ->
     case epgsql_wire:decode_message(Data) of
@@ -562,7 +561,7 @@ handle_xlog_data(StartLSN, EndLSN, WALRecord,
                  #repl{cbmodule = CbModule, cbstate = CbState, receiver = undefined} = Repl) ->
     %% with callback method
     {ok, LastFlushedLSN, LastAppliedLSN, NewCbState} =
-        CbModule:handle_x_log_data(StartLSN, EndLSN, WALRecord, CbState),
+        epgsql:handle_x_log_data(CbModule, StartLSN, EndLSN, WALRecord, CbState),
     Repl#repl{feedback_required = true,
               last_received_lsn = EndLSN,
               last_flushed_lsn = LastFlushedLSN,

+ 5 - 4
src/epgsql_wire.erl

@@ -61,7 +61,7 @@ decode_fields(<<Type:8, Rest/binary>>, Acc) ->
 
 %% @doc decode ErrorResponse
 %% See http://www.postgresql.org/docs/current/interactive/protocol-error-fields.html
--spec decode_error(binary()) -> #error{}.
+-spec decode_error(binary()) -> epgsql:query_error().
 decode_error(Bin) ->
     Fields = decode_fields(Bin),
     ErrCode = proplists:get_value($C, Fields),
@@ -144,7 +144,7 @@ decode_data(<<Len:?int32, Value:Len/binary, Rest/binary>>, [Decoder | Decs], [_C
      | decode_data(Rest, Decs, Cols, Codec)].
 
 %% @doc decode column information
--spec decode_columns(non_neg_integer(), binary(), epgsql_binary:codec()) -> [#column{}].
+-spec decode_columns(non_neg_integer(), binary(), epgsql_binary:codec()) -> [epgsql:column()].
 decode_columns(0, _Bin, _Codec) -> [];
 decode_columns(Count, Bin, Codec) ->
     [Name, Rest] = decode_string(Bin),
@@ -202,7 +202,7 @@ encode_types([Type | T], Count, Acc, Codec) ->
     encode_types(T, Count + 1, <<Acc/binary, Oid:?int32>>, Codec).
 
 %% @doc encode expected column formats
--spec encode_formats([#column{}]) -> binary().
+-spec encode_formats([epgsql:column()]) -> binary().
 encode_formats(Columns) ->
     encode_formats(Columns, 0, <<>>).
 
@@ -272,5 +272,6 @@ encode_command(Type, Data) ->
 %% @doc encode replication status message
 encode_standby_status_update(ReceivedLSN, FlushedLSN, AppliedLSN) ->
     {MegaSecs, Secs, MicroSecs} = os:timestamp(),
-    Timestamp = ((MegaSecs * 1000000 + Secs) * 1000000 + MicroSecs) - 946684800*1000000, %% microseconds since midnight on 2000-01-01
+    %% microseconds since midnight on 2000-01-01
+    Timestamp = ((MegaSecs * 1000000 + Secs) * 1000000 + MicroSecs) - 946684800*1000000,
     <<$r:8, ReceivedLSN:?int64, FlushedLSN:?int64, AppliedLSN:?int64, Timestamp:?int64, 0:8>>.

+ 5 - 5
src/epgsqla.erl

@@ -78,11 +78,11 @@ squery(C, Sql) ->
 equery(C, Sql) ->
     equery(C, Sql, []).
 
--spec equery(epgsql:connection(), #statement{}, [epgsql:typed_param()]) -> reference().
+-spec equery(epgsql:connection(), epgsql:statement(), [epgsql:typed_param()]) -> reference().
 equery(C, Statement, TypedParameters) ->
     cast(C, epgsql_cmd_equery, {Statement, TypedParameters}).
 
--spec prepared_query(epgsql:connection(), #statement{}, [epgsql:typed_param()]) -> reference().
+-spec prepared_query(epgsql:connection(), epgsql:statement(), [epgsql:typed_param()]) -> reference().
 prepared_query(C, Statement, TypedParameters) ->
     cast(C, epgsql_cmd_prepared_query, {Statement, TypedParameters}).
 
@@ -99,7 +99,7 @@ parse(C, Name, Sql, Types) ->
 bind(C, Statement, Parameters) ->
     bind(C, Statement, "", Parameters).
 
--spec bind(epgsql:connection(), #statement{}, string(), [epgsql:bind_param()]) -> reference().
+-spec bind(epgsql:connection(), epgsql:statement(), string(), [epgsql:bind_param()]) -> reference().
 bind(C, Statement, PortalName, Parameters) ->
     cast(C, epgsql_cmd_bind, {Statement, PortalName, Parameters}).
 
@@ -109,11 +109,11 @@ execute(C, S) ->
 execute(C, S, N) ->
     execute(C, S, "", N).
 
--spec execute(epgsql:connection(), #statement{}, string(), non_neg_integer()) -> reference().
+-spec execute(epgsql:connection(), epgsql:statement(), string(), non_neg_integer()) -> reference().
 execute(C, Statement, PortalName, MaxRows) ->
     cast(C, epgsql_cmd_execute, {Statement, PortalName, MaxRows}).
 
--spec execute_batch(epgsql:connection(), [{#statement{}, [epgsql:bind_param()]}]) -> reference().
+-spec execute_batch(epgsql:connection(), [{epgsql:statement(), [epgsql:bind_param()]}]) -> reference().
 execute_batch(C, Batch) ->
     cast(C, epgsql_cmd_batch, Batch).
 

+ 5 - 5
src/epgsqli.erl

@@ -77,11 +77,11 @@ squery(C, Sql) ->
 equery(C, Sql) ->
     equery(C, Sql, []).
 
--spec equery(epgsql:connection(), #statement{}, [epgsql:typed_param()]) -> reference().
+-spec equery(epgsql:connection(), epgsql:statement(), [epgsql:typed_param()]) -> reference().
 equery(C, Statement, TypedParameters) ->
     incremental(C, epgsql_cmd_equery, {Statement, TypedParameters}).
 
--spec prepared_query(epgsql:connection(), #statement{}, [epgsql:typed_param()]) -> reference().
+-spec prepared_query(epgsql:connection(), epgsql:statement(), [epgsql:typed_param()]) -> reference().
 prepared_query(C, Statement, TypedParameters) ->
     incremental(C, epgsql_cmd_prepared_query, {Statement, TypedParameters}).
 
@@ -98,7 +98,7 @@ parse(C, Name, Sql, Types) ->
 bind(C, Statement, Parameters) ->
     bind(C, Statement, "", Parameters).
 
--spec bind(epgsql:connection(), #statement{}, string(), [epgsql:bind_param()]) -> reference().
+-spec bind(epgsql:connection(), epgsql:statement(), string(), [epgsql:bind_param()]) -> reference().
 bind(C, Statement, PortalName, Parameters) ->
     incremental(C, epgsql_cmd_bind, {Statement, PortalName, Parameters}).
 
@@ -108,11 +108,11 @@ execute(C, S) ->
 execute(C, S, N) ->
     execute(C, S, "", N).
 
--spec execute(epgsql:connection(), #statement{}, string(), non_neg_integer()) -> reference().
+-spec execute(epgsql:connection(), epgsql:statement(), string(), non_neg_integer()) -> reference().
 execute(C, Statement, PortalName, MaxRows) ->
     incremental(C, epgsql_cmd_execute, {Statement, PortalName, MaxRows}).
 
--spec execute_batch(epgsql:connection(), [{#statement{}, [epgsql:bind_param()]}]) -> reference().
+-spec execute_batch(epgsql:connection(), [{epgsql:statement(), [epgsql:bind_param()]}]) -> reference().
 execute_batch(C, Batch) ->
     incremental(C, epgsql_cmd_batch, Batch).
 

+ 33 - 33
src/ewkb.erl

@@ -104,7 +104,7 @@ encode_geometry_data({SimpleCollection, _, Data})
          SimpleCollection == triangle ->
   encode_collection(Data);
 encode_geometry_data({TypedCollection, _, Data})
-    when 
+    when
         TypedCollection == multi_point;
         TypedCollection == multi_line_string;
         TypedCollection == multi_curve;
@@ -139,8 +139,8 @@ encode_typed_collection(Collection) when is_list(Collection) ->
     end,
     <<>>,
     Collection),
-  <<LengthBin/binary, CollectionBin/binary>>.  
-  
+  <<LengthBin/binary, CollectionBin/binary>>.
+
 
 encode_int32(Int) when is_integer(Int) ->
   <<Int:1/little-integer-unit:32>>.
@@ -161,8 +161,8 @@ decode_geometry_data(surface, _, _) -> error({surface, not_supported});
 decode_geometry_data(geometry, _, _) -> error({geometry, not_supported});
 decode_geometry_data(point, PointType, Data) ->
   decode_point(PointType, Data);
-decode_geometry_data(LineType, PointType, Data) 
-    when LineType == line_string; 
+decode_geometry_data(LineType, PointType, Data)
+    when LineType == line_string;
          LineType == circular_string ->
   {Points, Rest} = decode_collection(point, PointType, Data),
   {{LineType, PointType, Points}, Rest};
@@ -173,7 +173,7 @@ decode_geometry_data(triangle, PointType, Data) ->
   {#polygon{ rings = Rings }, Rest} = decode_geometry_data(polygon, PointType, Data),
   {#triangle{ point_type = PointType, rings = Rings }, Rest};
 decode_geometry_data(Collection, PointType, Data)
-    when 
+    when
         Collection == multi_point;
         Collection == multi_line_string;
         Collection == multi_curve;
@@ -229,13 +229,13 @@ decode_point(PointType, Data) ->
     {[], Data},
     lists:seq(1, point_size(PointType))),
   Point = case {PointType, Values} of
-    {'2d', [X,Y]} ->
+    {'2d', [X, Y]} ->
       #point{ point_type = PointType, x = X, y = Y };
-    {'2dm', [X,Y,M]} ->
+    {'2dm', [X, Y, M]} ->
       #point{ point_type = PointType, x = X, y = Y, m = M };
-    {'3d', [X,Y,Z]} ->
+    {'3d', [X, Y, Z]} ->
       #point{ point_type = PointType, x = X, y = Y, z = Z };
-    {'3dm', [X,Y,Z,M]} ->
+    {'3dm', [X, Y, Z, M]} ->
       #point{ point_type = PointType, x = X, y = Y, z = Z, m = M }
   end,
   {Point, Rest}.
@@ -247,24 +247,24 @@ point_size('3d')  -> 3;
 point_size('3dm') -> 4.
 
 -spec decode_type(binary()) -> geom_type().
-decode_type(<<0,0>>) -> geometry;
-decode_type(<<1,0>>) -> point;
-decode_type(<<2,0>>) -> line_string;
-decode_type(<<3,0>>) -> polygon;
-decode_type(<<4,0>>) -> multi_point;
-decode_type(<<5,0>>) -> multi_line_string;
-decode_type(<<6,0>>) -> multi_polygon;
-decode_type(<<7,0>>) -> geometry_collection;
-decode_type(<<8,0>>) -> circular_string;
-decode_type(<<9,0>>) -> compound_curve;
-decode_type(<<10,0>>) -> curve_polygon;
-decode_type(<<11,0>>) -> multi_curve;
-decode_type(<<12,0>>) -> multi_surface;
-decode_type(<<13,0>>) -> curve;
-decode_type(<<14,0>>) -> surface;
-decode_type(<<15,0>>) -> polyhedral_surface;
-decode_type(<<16,0>>) -> tin;
-decode_type(<<17,0>>) -> triangle.
+decode_type(<<0, 0>>) -> geometry;
+decode_type(<<1, 0>>) -> point;
+decode_type(<<2, 0>>) -> line_string;
+decode_type(<<3, 0>>) -> polygon;
+decode_type(<<4, 0>>) -> multi_point;
+decode_type(<<5, 0>>) -> multi_line_string;
+decode_type(<<6, 0>>) -> multi_polygon;
+decode_type(<<7, 0>>) -> geometry_collection;
+decode_type(<<8, 0>>) -> circular_string;
+decode_type(<<9, 0>>) -> compound_curve;
+decode_type(<<10, 0>>) -> curve_polygon;
+decode_type(<<11, 0>>) -> multi_curve;
+decode_type(<<12, 0>>) -> multi_surface;
+decode_type(<<13, 0>>) -> curve;
+decode_type(<<14, 0>>) -> surface;
+decode_type(<<15, 0>>) -> polyhedral_surface;
+decode_type(<<16, 0>>) -> tin;
+decode_type(<<17, 0>>) -> triangle.
 
 -spec encode_type(geometry() | geom_type()) -> binary().
 encode_type(Geometry) when is_tuple(Geometry) ->
@@ -290,7 +290,7 @@ encode_type(triangle)            -> <<17, 0>>.
 
 
 -spec decode_point_type(binary()) -> point_type().
-decode_point_type(<<0,0>>) -> '2d';
+decode_point_type(<<0, 0>>) -> '2d';
 decode_point_type(<<0, 64>>) -> '2dm';
 decode_point_type(<<0, 128>>) -> '3d';
 decode_point_type(<<0, 192>>) -> '3dm'.
@@ -298,7 +298,7 @@ decode_point_type(<<0, 192>>) -> '3dm'.
 -spec encode_point_type(geometry() | point_type()) -> binary().
 encode_point_type(Geometry) when is_tuple(Geometry) ->
   encode_point_type(element(2, Geometry));
-encode_point_type('2d') -> <<0,0>>;
-encode_point_type('2dm') -> <<0,64>>;
-encode_point_type('3d') -> <<0,128>>;
-encode_point_type('3dm') -> <<0,192>>.
+encode_point_type('2d') -> <<0, 0>>;
+encode_point_type('2dm') -> <<0, 64>>;
+encode_point_type('3d') -> <<0, 128>>;
+encode_point_type('3dm') -> <<0, 192>>.