6262
6363-include (" avro_internal.hrl" ).
6464
65- -opaque store () :: ets :tab () | {dict , dict :dict ()}.
66- -type option_key () :: access | name | dict .
65+ -type store () :: ets :tab () | {dict , dict :dict ()} | map () .
66+ -type option_key () :: access | name | dict | map .
6767-type options () :: [option_key () | {option_key (), term ()}].
6868-type filename () :: file :filename_all ().
6969
@@ -81,12 +81,20 @@ new() -> new([]).
8181% % mode in ets:new and defines what processes can have access to
8282% % * `{name, atom()}' - used to create a named ets table.
8383% % * `dict' - use dict as store backend, ignore `access' and `name' options
84+ % % * `map' - use map as store backend, ignore `access' and `name' options
8485% % @end
8586-spec new (options ()) -> store ().
8687new (Options ) ->
8788 case proplists :get_bool (dict , Options ) of
88- true -> {dict , dict :new ()};
89- false -> new_ets (Options )
89+ true ->
90+ {dict , dict :new ()};
91+ false ->
92+ case proplists :get_bool (map , Options ) of
93+ true ->
94+ #{};
95+ false ->
96+ new_ets (Options )
97+ end
9098 end .
9199
92100% % @doc Create a new schema store and improt the given schema JSON files.
@@ -98,6 +106,7 @@ new(Options, Files) ->
98106% % @doc Return true if the given arg is a schema store.
99107-spec is_store (term ()) -> boolean ().
100108is_store ({dict , _ }) -> true ;
109+ is_store (Map ) when is_map (Map ) -> true ;
101110is_store (T ) -> is_integer (T ) orelse is_atom (T ) orelse is_reference (T ).
102111
103112% % @doc Make a schema lookup function from store.
@@ -143,12 +152,13 @@ import_schema_json(Json, Store) ->
143152% % @doc Delete the ets table.
144153-spec close (store ()) -> ok .
145154close ({dict , _ }) -> ok ;
155+ close (Map ) when is_map (Map ) -> ok ;
146156close (Store ) ->
147157 ets :delete (Store ),
148158 ok .
149159
150160% % @doc To make dialyzer happy.
151- -spec ensure_store (atom () | integer () | reference () | { dict , dict : dict ()} ) ->
161+ -spec ensure_store (atom () | integer () | reference () | store () ) ->
152162 store ().
153163ensure_store (Store ) ->
154164 true = is_store (Store ),
@@ -194,6 +204,7 @@ get_all_types(Store) ->
194204
195205-spec to_list (store ()) -> [{name (), avro_type ()}].
196206to_list ({dict , Dict }) -> dict :to_list (Dict );
207+ to_list (Map ) when is_map (Map ) -> maps :to_list (Map );
197208to_list (Store ) -> ets :tab2list (Store ).
198209
199210-spec new_ets (options ()) -> store ().
@@ -212,8 +223,8 @@ new_ets(Options) ->
212223-spec add_by_assigned_name (undefined | name_raw (),
213224 type_or_name (), store ()) -> store ().
214225add_by_assigned_name (undefined , _Type , Store ) -> Store ;
215- add_by_assigned_name (AssignedName , Type , Store ) ->
216- do_add_type_by_names ([ ? NAME (AssignedName )], Type , Store ).
226+ add_by_assigned_name (AssignedName , TypeOrName , Store ) ->
227+ add_type_by_name ( ? NAME (AssignedName ), TypeOrName , Store ).
217228
218229% % @private Parse file basename. try to strip ".avsc" or ".json" extension.
219230-spec parse_basename (filename ()) -> name ().
@@ -241,13 +252,19 @@ import_schema_json(AssignedName, Json, Store) ->
241252do_add_type (Type , Store ) ->
242253 FullName = avro :get_type_fullname (Type ),
243254 Aliases = avro :get_aliases (Type ),
244- do_add_type_by_names ([FullName |Aliases ], Type , Store ).
255+ Store1 = add_type_by_name (FullName , Type , Store ),
256+ add_aliases (Aliases , FullName , Store1 ).
257+
258+ add_aliases ([], _FullName , Store ) ->
259+ Store ;
260+ add_aliases ([Alias | More ], FullName , Store ) ->
261+ NewStore = put_type_to_store (Alias , FullName , Store ),
262+ add_aliases (More , FullName , NewStore ).
245263
246264% % @private
247- -spec do_add_type_by_names ([fullname ()], avro_type (), store ()) ->
265+ -spec add_type_by_name ([fullname ()], avro_type (), store ()) ->
248266 store () | no_return ().
249- do_add_type_by_names ([], _Type , Store ) -> Store ;
250- do_add_type_by_names ([Name |Rest ], Type , Store ) ->
267+ add_type_by_name (Name , Type , Store ) ->
251268 case get_type_from_store (Name , Store ) of
252269 {ok , Type } ->
253270 Store ;
@@ -257,27 +274,45 @@ do_add_type_by_names([Name|Rest], Type, Store) ->
257274 % % old / new types.
258275 erlang :error ({name_clash , Name , Type , OtherType });
259276 false ->
260- Store1 = put_type_to_store (Name , Type , Store ),
261- do_add_type_by_names (Rest , Type , Store1 )
277+ put_type_to_store (Name , Type , Store )
262278 end .
263279
264280% % @private
265- -spec put_type_to_store (fullname (), avro_type (), store ()) -> store ().
281+ -spec put_type_to_store (fullname (), name () | avro_type (), store ()) -> store ().
266282put_type_to_store (Name , Type , {dict , Dict }) ->
267283 NewDict = dict :store (Name , Type , Dict ),
268284 {dict , NewDict };
285+ put_type_to_store (Name , Type , Map ) when is_map (Map ) ->
286+ Map #{Name => Type };
269287put_type_to_store (Name , Type , Store ) ->
270288 true = ets :insert (Store , {Name , Type }),
271289 Store .
272290
273- % % @private
291+ % % @private Get type by name or alias.
274292-spec get_type_from_store (fullname (), store ()) -> false | {ok , avro_type ()}.
275- get_type_from_store (Name , {dict , Dict }) ->
293+ get_type_from_store (NameRef , Store ) ->
294+ case do_get_type_from_store (NameRef , Store ) of
295+ false ->
296+ false ;
297+ {ok , FullName } when is_binary (FullName ) ->
298+ do_get_type_from_store (FullName , Store );
299+ {ok , Type } ->
300+ {ok , Type }
301+ end .
302+
303+ % % @private
304+ -spec do_get_type_from_store (fullname (), store ()) -> false | {ok , fullname () | avro_type ()}.
305+ do_get_type_from_store (Name , {dict , Dict }) ->
276306 case dict :find (Name , Dict ) of
277307 error -> false ;
278308 {ok , Type } -> {ok , Type }
279309 end ;
280- get_type_from_store (Name , Store ) ->
310+ do_get_type_from_store (Name , Map ) when is_map (Map ) ->
311+ case maps :find (Name , Map ) of
312+ error -> false ;
313+ {ok , Type } -> {ok , Type }
314+ end ;
315+ do_get_type_from_store (Name , Store ) ->
281316 case ets :lookup (Store , Name ) of
282317 [] -> false ;
283318 [{Name , Type }] -> {ok , Type }
0 commit comments