|
@@ -20,8 +20,9 @@
|
|
|
codec :: module(),
|
|
|
codec_state :: any()}).
|
|
|
-record(oid_db,
|
|
|
- {by_oid :: kv(oid(), #type{}),
|
|
|
- by_name :: kv({epgsql:type_name(), boolean()}, oid())}).
|
|
|
+ {by_oid :: #{oid() => #type{}},
|
|
|
+ by_name :: #{ {epgsql:type_name(), boolean()} => oid() }
|
|
|
+ }).
|
|
|
|
|
|
-type oid() :: non_neg_integer().
|
|
|
%% Row of `typname', `oid', `typarray' from pg_type table.
|
|
@@ -88,41 +89,41 @@ do_join([], _) ->
|
|
|
|
|
|
-spec from_list([type_info()]) -> db().
|
|
|
from_list(Types) ->
|
|
|
- #oid_db{by_oid = kv_from_list(
|
|
|
+ #oid_db{by_oid = maps:from_list(
|
|
|
[{Oid, Type} || #type{oid = Oid} = Type <- Types]),
|
|
|
- by_name = kv_from_list(
|
|
|
+ by_name = maps:from_list(
|
|
|
[{{Name, IsArray}, Oid}
|
|
|
|| #type{name = Name, is_array = IsArray, oid = Oid}
|
|
|
<- Types])}.
|
|
|
|
|
|
to_list(#oid_db{by_oid = Dict}) ->
|
|
|
- [Type || {_Oid, Type} <- kv_to_list(Dict)].
|
|
|
+ [Type || {_Oid, Type} <- maps:to_list(Dict)].
|
|
|
|
|
|
%% @doc update DB adding new type definitions.
|
|
|
%% If some of type definitions already exist, old ones will be overwritten by new ones
|
|
|
-spec update([type_info()], db()) -> db().
|
|
|
update(Types, #oid_db{by_oid = OldByOid, by_name = OldByName} = Store) ->
|
|
|
#oid_db{by_oid = NewByOid, by_name = NewByName} = from_list(Types),
|
|
|
- ByOid = kv_merge(OldByOid, NewByOid),
|
|
|
- ByName = kv_merge(OldByName, NewByName),
|
|
|
+ ByOid = maps:merge(OldByOid, NewByOid),
|
|
|
+ ByName = maps:merge(OldByName, NewByName),
|
|
|
Store#oid_db{by_oid = ByOid,
|
|
|
by_name = ByName}.
|
|
|
|
|
|
%% @doc find type by OID
|
|
|
-spec find_by_oid(oid(), db()) -> type_info() | undefined.
|
|
|
find_by_oid(Oid, #oid_db{by_oid = Dict}) ->
|
|
|
- kv_get(Oid, Dict, undefined).
|
|
|
+ maps:get(Oid, Dict, undefined).
|
|
|
|
|
|
%% @doc find type by type name
|
|
|
-spec find_by_name(epgsql:type_name(), boolean(), db()) -> type_info().
|
|
|
find_by_name(Name, IsArray, #oid_db{by_oid = ByOid} = Db) ->
|
|
|
Oid = oid_by_name(Name, IsArray, Db),
|
|
|
- kv_get(Oid, ByOid). % or maybe find_by_oid(Oid, Store)
|
|
|
+ maps:get(Oid, ByOid). % or maybe find_by_oid(Oid, Store)
|
|
|
|
|
|
%% @doc lookup OID by type name. May fall
|
|
|
-spec oid_by_name(epgsql:type_name(), boolean(), db()) -> oid().
|
|
|
oid_by_name(Name, IsArray, #oid_db{by_name = ByName}) ->
|
|
|
- kv_get({Name, IsArray}, ByName).
|
|
|
+ maps:get({Name, IsArray}, ByName).
|
|
|
|
|
|
%% @doc convert type to codec_entry()
|
|
|
-spec type_to_codec_entry(type_info()) -> epgsql_codec:codec_entry().
|
|
@@ -146,50 +147,3 @@ join(Sep, [H | T]) -> [H | join_prepend(Sep, T)].
|
|
|
|
|
|
join_prepend(_Sep, []) -> [];
|
|
|
join_prepend(Sep, [H | T]) -> [Sep, H | join_prepend(Sep, T)].
|
|
|
-
|
|
|
-
|
|
|
-%% K-V storage
|
|
|
-%% In Erlang 17 map access time is O(n), so, it's faster to use dicts.
|
|
|
-%% In Erlang >=18 maps are the most eficient choice
|
|
|
--ifndef(SLOW_MAPS).
|
|
|
-
|
|
|
--type kv(K, V) :: #{K => V}.
|
|
|
-
|
|
|
-kv_from_list(L) ->
|
|
|
- maps:from_list(L).
|
|
|
-
|
|
|
-kv_to_list(Map) ->
|
|
|
- maps:to_list(Map).
|
|
|
-
|
|
|
-kv_get(Key, Map) ->
|
|
|
- maps:get(Key, Map).
|
|
|
-
|
|
|
-kv_get(Key, Map, Default) ->
|
|
|
- maps:get(Key, Map, Default).
|
|
|
-
|
|
|
-kv_merge(Map1, Map2) ->
|
|
|
- maps:merge(Map1, Map2).
|
|
|
-
|
|
|
--else.
|
|
|
-
|
|
|
--type kv(_K, _V) :: any(). % dict:dict(K, V) causes dialyzer errors on erl <= 17
|
|
|
-
|
|
|
-kv_from_list(L) ->
|
|
|
- dict:from_list(L).
|
|
|
-
|
|
|
-kv_to_list(Dict) ->
|
|
|
- dict:to_list(Dict).
|
|
|
-
|
|
|
-kv_get(Key, Dict) ->
|
|
|
- dict:fetch(Key, Dict).
|
|
|
-
|
|
|
-kv_get(Key, Dict, Default) ->
|
|
|
- case dict:find(Key, Dict) of
|
|
|
- {ok, Value} -> Value;
|
|
|
- error -> Default
|
|
|
- end.
|
|
|
-
|
|
|
-kv_merge(Dict1, Dict2) ->
|
|
|
- dict:merge(fun(_, _, V2) -> V2 end, Dict1, Dict2).
|
|
|
-
|
|
|
--endif.
|