Browse Source

Rework codec structure

Сергей Прохоров 7 years ago
parent
commit
13f05ed161
1 changed files with 37 additions and 32 deletions
  1. 37 32
      src/epgsql_binary.erl

+ 37 - 32
src/epgsql_binary.erl

@@ -18,11 +18,16 @@
 
 
 -include("protocol.hrl").
 -include("protocol.hrl").
 
 
--opaque codec() :: {module(), epgsql_oid_db:db()}.
+-record(codec,
+        {opts = [] :: list(),                   % not used yet
+         oid_db :: epgsql_oid_db:db()}).
+
+-opaque codec() :: #codec{}.
 -opaque decoder() :: {fun((binary(), epgsql:type_name(), epgsql_codec:codec_state()) -> any()),
 -opaque decoder() :: {fun((binary(), epgsql:type_name(), epgsql_codec:codec_state()) -> any()),
                       epgsql:type_name(),
                       epgsql:type_name(),
                       epgsql_codec:state()}.
                       epgsql_codec:state()}.
 
 
+
 -define(RECORD_OID, 2249).
 -define(RECORD_OID, 2249).
 -define(RECORD_ARRAY_OID, 2287).
 -define(RECORD_ARRAY_OID, 2287).
 
 
@@ -35,11 +40,11 @@ new_codec(OidDb, PgSock) ->
 new_codec(OidDb, PgSock, Codecs, Oids) ->
 new_codec(OidDb, PgSock, Codecs, Oids) ->
     CodecEntries = epgsql_codec:init_mods(Codecs, PgSock),
     CodecEntries = epgsql_codec:init_mods(Codecs, PgSock),
     Types = OidDb:join_codecs_oids(Oids, CodecEntries),
     Types = OidDb:join_codecs_oids(Oids, CodecEntries),
-    {OidDb, OidDb:from_list(Types)}.
+    #codec{oid_db = epgsql_oid_db:from_list(Types)}.
 
 
 -spec update_codec([epgsql_oid_db:type_info()], codec()) -> codec().
 -spec update_codec([epgsql_oid_db:type_info()], codec()) -> codec().
-update_codec(TypeInfos, {OidDb, Db}) ->
-    {OidDb, OidDb:update(TypeInfos, Db)}.
+update_codec(TypeInfos, #codec{oid_db = Db} = Codec) ->
+    Codec#codec{oid_db = epgsql_oid_db:update(TypeInfos, Db)}.
 
 
 -spec oid_to_name(epgsql_oid_db:oid(), codec()) -> Type | {unknown_oid, epgsql_oid_db:oid()} when
 -spec oid_to_name(epgsql_oid_db:oid(), codec()) -> Type | {unknown_oid, epgsql_oid_db:oid()} when
       Type :: epgsql:type_name() | {array, epgsql:type_name()}.
       Type :: epgsql:type_name() | {array, epgsql:type_name()}.
@@ -60,8 +65,8 @@ type_to_oid(Name, Codec) ->
     type_to_oid(Name, false, Codec).
     type_to_oid(Name, false, Codec).
 
 
 -spec type_to_oid(epgsql:type_name(), boolean(), codec()) -> epgsql_oid_db:oid().
 -spec type_to_oid(epgsql:type_name(), boolean(), codec()) -> epgsql_oid_db:oid().
-type_to_oid(TypeName, IsArray, {OidDb, Db}) ->
-    OidDb:oid_by_name(TypeName, IsArray, Db).
+type_to_oid(TypeName, IsArray, #codec{oid_db = Db}) ->
+    epgsql_oid_db:oid_by_name(TypeName, IsArray, Db).
 
 
 type_to_oid_info({array, Name}, Codec) ->
 type_to_oid_info({array, Name}, Codec) ->
     type_to_info(Name, true, Codec);
     type_to_info(Name, true, Codec);
@@ -69,23 +74,23 @@ type_to_oid_info(Name, Codec) ->
     type_to_info(Name, false, Codec).
     type_to_info(Name, false, Codec).
 
 
 -spec oid_to_info(epgsql_oid_db:oid(), codec()) -> epgsql_oid_db:type_info() | undefined.
 -spec oid_to_info(epgsql_oid_db:oid(), codec()) -> epgsql_oid_db:type_info() | undefined.
-oid_to_info(Oid, {OidDb, Db}) ->
-    OidDb:find_by_oid(Oid, Db).
+oid_to_info(Oid, #codec{oid_db = Db}) ->
+    epgsql_oid_db:find_by_oid(Oid, Db).
 
 
 -spec type_to_info(epgsql:type_name(), boolean(), codec()) -> epgsql_oid_db:type_info().
 -spec type_to_info(epgsql:type_name(), boolean(), codec()) -> epgsql_oid_db:type_info().
-type_to_info(TypeName, IsArray, {OidDb, Db}) ->
-    OidDb:find_by_name(TypeName, IsArray, Db).
+type_to_info(TypeName, IsArray, #codec{oid_db = Db}) ->
+    epgsql_oid_db:find_by_name(TypeName, IsArray, Db).
 
 
 typeinfo_to_name_array({unknown_oid, _} = Unknown, _) -> Unknown;
 typeinfo_to_name_array({unknown_oid, _} = Unknown, _) -> Unknown;
-typeinfo_to_name_array(TypeInfo, {OidDb, _}) ->
-    case OidDb:type_to_oid_info(TypeInfo) of
+typeinfo_to_name_array(TypeInfo, _) ->
+    case epgsql_oid_db:type_to_oid_info(TypeInfo) of
         {_, Name, false} -> Name;
         {_, Name, false} -> Name;
         {_, Name, true} -> {array, Name}
         {_, Name, true} -> {array, Name}
     end.
     end.
 
 
 typeinfo_to_oid_info({unknown_oid, _} = Unknown, _) -> Unknown;
 typeinfo_to_oid_info({unknown_oid, _} = Unknown, _) -> Unknown;
-typeinfo_to_oid_info(TypeInfo, {OidDb, _}) ->
-    OidDb:type_to_oid_info(TypeInfo).
+typeinfo_to_oid_info(TypeInfo, _) ->
+    epgsql_oid_db:type_to_oid_info(TypeInfo).
 
 
 %%
 %%
 %% Decode
 %% Decode
@@ -101,20 +106,20 @@ oid_to_decoder(?RECORD_OID, binary, Codec) ->
 oid_to_decoder(?RECORD_ARRAY_OID, binary, Codec) ->
 oid_to_decoder(?RECORD_ARRAY_OID, binary, Codec) ->
     %% See `make_array_decoder/3'
     %% See `make_array_decoder/3'
     {fun ?MODULE:decode_array/3, [], oid_to_decoder(?RECORD_OID, binary, Codec)};
     {fun ?MODULE:decode_array/3, [], oid_to_decoder(?RECORD_OID, binary, Codec)};
-oid_to_decoder(Oid, Format, {OidDb, Db}) ->
-    case OidDb:find_by_oid(Oid, Db) of
+oid_to_decoder(Oid, Format, #codec{oid_db = Db}) ->
+    case epgsql_oid_db:find_by_oid(Oid, Db) of
         undefined when Format == binary ->
         undefined when Format == binary ->
             {fun epgsql_codec_noop:decode/3, undefined, []};
             {fun epgsql_codec_noop:decode/3, undefined, []};
         undefined when Format == text ->
         undefined when Format == text ->
             {fun epgsql_codec_noop:decode_text/3, undefined, []};
             {fun epgsql_codec_noop:decode_text/3, undefined, []};
         Type ->
         Type ->
-            make_decoder(Type, Format, OidDb)
+            make_decoder(Type, Format)
     end.
     end.
 
 
--spec make_decoder(epgsql_oid_db:type_info(), binary | text, module()) -> decoder().
-make_decoder(Type, Format, OidDb) ->
-    {Name, Mod, State} = OidDb:type_to_codec_entry(Type),
-    {_Oid, Name, IsArray} = OidDb:type_to_oid_info(Type),
+-spec make_decoder(epgsql_oid_db:type_info(), binary | text) -> decoder().
+make_decoder(Type, Format) ->
+    {Name, Mod, State} = epgsql_oid_db:type_to_codec_entry(Type),
+    {_Oid, Name, IsArray} = epgsql_oid_db:type_to_oid_info(Type),
     make_decoder(Name, Mod, State, Format, IsArray).
     make_decoder(Name, Mod, State, Format, IsArray).
 
 
 make_decoder(_Name, _Mod, _State, text, true) ->
 make_decoder(_Name, _Mod, _State, text, true) ->
@@ -182,12 +187,12 @@ decode_record(<<Size:?int32, Bin/binary>>, record, Codec) ->
 decode_record1(<<>>, 0, _Codec) -> [];
 decode_record1(<<>>, 0, _Codec) -> [];
 decode_record1(<<_Type:?int32, -1:?int32, Rest/binary>>, Size, Codec) ->
 decode_record1(<<_Type:?int32, -1:?int32, Rest/binary>>, Size, Codec) ->
     [null | decode_record1(Rest, Size - 1, Codec)];
     [null | decode_record1(Rest, Size - 1, Codec)];
-decode_record1(<<Oid:?int32, Len:?int32, ValueBin:Len/binary, Rest/binary>>, Size, {OidDb, Db} = Codec) ->
+decode_record1(<<Oid:?int32, Len:?int32, ValueBin:Len/binary, Rest/binary>>, Size, #codec{oid_db = Db} = Codec) ->
     Value =
     Value =
-        case OidDb:find_by_oid(Oid, Db) of
+        case epgsql_oid_db:find_by_oid(Oid, Db) of
             undefined -> ValueBin;
             undefined -> ValueBin;
             Type ->
             Type ->
-                {Name, Mod, State} = OidDb:type_to_codec_entry(Type),
+                {Name, Mod, State} = epgsql_oid_db:type_to_codec_entry(Type),
                 Mod:decode(ValueBin, Name, State)
                 Mod:decode(ValueBin, Name, State)
         end,
         end,
     [Value | decode_record1(Rest, Size - 1, Codec)].
     [Value | decode_record1(Rest, Size - 1, Codec)].
@@ -197,16 +202,16 @@ decode_record1(<<Oid:?int32, Len:?int32, ValueBin:Len/binary, Rest/binary>>, Siz
 %% Encode
 %% Encode
 %%
 %%
 -spec encode(epgsql:type_name() | {array, epgsql:type_name()}, any(), codec()) -> iolist().
 -spec encode(epgsql:type_name() | {array, epgsql:type_name()}, any(), codec()) -> iolist().
-encode(TypeName, Value, {OidDb, _Db} = Codec) ->
+encode(TypeName, Value, Codec) ->
     Type = type_to_oid_info(TypeName, Codec),
     Type = type_to_oid_info(TypeName, Codec),
-    encode_with_type(Type, Value, OidDb).
+    encode_with_type(Type, Value).
 
 
-encode_with_type(Type, Value, OidDb) ->
-    {Name, Mod, State} = OidDb:type_to_codec_entry(Type),
-    case OidDb:type_to_oid_info(Type) of
+encode_with_type(Type, Value) ->
+    {Name, Mod, State} = epgsql_oid_db:type_to_codec_entry(Type),
+    case epgsql_oid_db:type_to_oid_info(Type) of
         {_ArrayOid, _, true} ->
         {_ArrayOid, _, true} ->
             %FIXME: check if this OID is the same as was returned by 'Describe'
             %FIXME: check if this OID is the same as was returned by 'Describe'
-            ElementOid = OidDb:type_to_element_oid(Type),
+            ElementOid = epgsql_oid_db:type_to_element_oid(Type),
             encode_array(Value, ElementOid, {Mod, Name, State});
             encode_array(Value, ElementOid, {Mod, Name, State});
         {_Oid, _, false} ->
         {_Oid, _, false} ->
             encode_value(Value, {Mod, Name, State})
             encode_value(Value, {Mod, Name, State})
@@ -242,8 +247,8 @@ encode_array(Array, NDims, Lengths, Codec) ->
 %% Supports
 %% Supports
 supports(RecOid, _) when RecOid == ?RECORD_OID; RecOid == ?RECORD_ARRAY_OID ->
 supports(RecOid, _) when RecOid == ?RECORD_OID; RecOid == ?RECORD_ARRAY_OID ->
     true;
     true;
-supports(Oid, {OidDb, Db}) ->
-    OidDb:find_by_oid(Oid, Db) =/= undefined.
+supports(Oid, #codec{oid_db = Db}) ->
+    epgsql_oid_db:find_by_oid(Oid, Db) =/= undefined.
 
 
 %% Default codec set
 %% Default codec set
 -spec default_codecs() -> [epgsql_codec:codec_entry()].
 -spec default_codecs() -> [epgsql_codec:codec_entry()].