@@ -2,54 +2,140 @@ defmodule EctoStreamFactory.Factory do
22 @ moduledoc false
33
44 def build ( module , generator_name , attrs ) do
5+ do_build ( module , generator_name , attrs , & build_list / 4 )
6+ end
7+
8+ def build! ( module , generator_name , attrs ) do
9+ do_build ( module , generator_name , attrs , & build_list! / 4 )
10+ end
11+
12+ defp do_build ( module , generator_name , attrs , build_list_fun ) do
513 module
6- |> build_list ( 1 , generator_name , attrs )
14+ |> build_list_fun . ( 1 , generator_name , attrs )
715 |> hd ( )
816 end
917
1018 def build_list ( module , count , generator_name , attrs ) do
19+ do_build_list ( module , count , generator_name , attrs , & create_records_stream / 3 )
20+ end
21+
22+ def build_list! ( module , count , generator_name , attrs ) do
23+ do_build_list ( module , count , generator_name , attrs , & create_records_stream! / 3 )
24+ end
25+
26+ defp do_build_list ( module , count , generator_name , attrs , create_records_stream_fun ) do
1127 module
12- |> create_records_stream ( generator_name , attrs )
28+ |> create_records_stream_fun . ( generator_name , attrs )
1329 |> Enum . take ( count )
1430 end
1531
1632 def insert ( module , repo , generator_name , attrs , opts ) do
33+ do_insert ( module , repo , generator_name , attrs , opts , & insert_list / 6 )
34+ end
35+
36+ def insert! ( module , repo , generator_name , attrs , opts ) do
37+ do_insert ( module , repo , generator_name , attrs , opts , & insert_list! / 6 )
38+ end
39+
40+ def do_insert ( module , repo , generator_name , attrs , opts , insert_list_fun ) do
1741 module
18- |> insert_list ( repo , 1 , generator_name , attrs , opts )
42+ |> insert_list_fun . ( repo , 1 , generator_name , attrs , opts )
1943 |> hd ( )
2044 end
2145
2246 def insert_list ( module , repo , count , generator_name , attrs , opts ) do
47+ do_insert_list ( module , repo , count , generator_name , attrs , opts , & create_records_stream / 3 )
48+ end
49+
50+ def insert_list! ( module , repo , count , generator_name , attrs , opts ) do
51+ do_insert_list ( module , repo , count , generator_name , attrs , opts , & create_records_stream! / 3 )
52+ end
53+
54+ def do_insert_list ( module , repo , count , generator_name , attrs , opts , create_records_stream_fun ) do
2355 module
24- |> create_records_stream ( generator_name , attrs )
56+ |> create_records_stream_fun . ( generator_name , attrs )
2557 |> Stream . map ( & insert_record ( & 1 , repo , opts ) )
2658 |> Enum . take ( count )
2759 end
2860
2961 defp create_records_stream ( module , generator_name , attrs ) do
62+ do_create_records_stream ( module , generator_name , attrs , & merge_attributes / 4 )
63+ end
64+
65+ defp create_records_stream! ( module , generator_name , attrs ) do
66+ do_create_records_stream ( module , generator_name , attrs , & merge_attributes! / 4 )
67+ end
68+
69+ defp do_create_records_stream ( module , generator_name , attrs , merge_attrs_fun ) do
3070 module
3171 |> create_stream ( generator_name )
3272 |> Stream . with_index ( 1 )
33- |> Stream . map ( & merge_attributes ( & 1 , attrs ) )
73+ |> Stream . map ( & merge_attrs_fun . ( & 1 , attrs , module , generator_name ) )
3474 end
3575
36- defp merge_attributes ( { record , index } , attrs ) when is_struct ( record ) do
76+ defp merge_attributes ( { record , index } , attrs , _ , _ ) when is_struct ( record ) do
3777 struct ( record , prepare_attributes ( attrs , index ) )
3878 end
3979
40- defp merge_attributes ( { map , index } , attrs ) when is_map ( map ) do
80+ defp merge_attributes ( { map , index } , attrs , _ , _ ) when is_map ( map ) do
4181 attrs = attrs |> prepare_attributes ( index ) |> Map . new ( )
4282 Map . merge ( map , attrs )
4383 end
4484
45- defp merge_attributes ( { maybe_keyword , index } , attrs ) do
85+ defp merge_attributes ( { maybe_keyword , index } , attrs , _ , _ ) do
4686 if Keyword . keyword? ( maybe_keyword ) do
4787 Keyword . merge ( maybe_keyword , prepare_attributes ( attrs , index ) )
4888 else
4989 maybe_keyword
5090 end
5191 end
5292
93+ defp merge_attributes! ( { record , index } , attrs , module , generator_name ) when is_struct ( record ) do
94+ try do
95+ struct! ( record , prepare_attributes ( attrs , index ) )
96+ rescue
97+ err in KeyError ->
98+ raise EctoStreamFactory.MissingKeyError ,
99+ module: module ,
100+ generator_name: generator_name ,
101+ key: err . key
102+ end
103+ end
104+
105+ defp merge_attributes! ( { map , index } , attrs , module , generator_name ) when is_map ( map ) do
106+ check_missing_key ( map , attrs , & Map . has_key? / 2 , module , generator_name )
107+
108+ merge_attributes ( { map , index } , attrs , module , generator_name )
109+ end
110+
111+ defp merge_attributes! ( { maybe_keyword , index } , attrs , module , generator_name ) do
112+ if Keyword . keyword? ( maybe_keyword ) do
113+ check_missing_key ( maybe_keyword , attrs , & Keyword . has_key? / 2 , module , generator_name )
114+ end
115+
116+ merge_attributes ( { maybe_keyword , index } , attrs , module , generator_name )
117+ end
118+
119+ defp check_missing_key ( map_or_keyword , attrs , has_key_fun , module , generator_name ) do
120+ missing_key =
121+ attrs
122+ |> Keyword . keys ( )
123+ |> Enum . find_value ( fn key ->
124+ if has_key_fun . ( map_or_keyword , key ) do
125+ false
126+ else
127+ key
128+ end
129+ end )
130+
131+ if missing_key do
132+ raise EctoStreamFactory.MissingKeyError ,
133+ module: module ,
134+ generator_name: generator_name ,
135+ key: missing_key
136+ end
137+ end
138+
53139 defp prepare_attributes ( attrs , index ) do
54140 Enum . map ( attrs , fn
55141 { key , fun } when is_function ( fun , 1 ) ->
@@ -71,7 +157,7 @@ defmodule EctoStreamFactory.Factory do
71157 apply ( module , function_name , [ ] )
72158 else
73159 raise EctoStreamFactory.UndefinedGeneratorError ,
74- module: module_to_string ( module ) ,
160+ module: module ,
75161 generator_name: generator_name
76162 end
77163 end
@@ -87,11 +173,7 @@ defmodule EctoStreamFactory.Factory do
87173 def get_repo ( module , opts ) do
88174 case Keyword . fetch ( opts , :repo ) do
89175 { :ok , repo } -> repo
90- _ -> raise EctoStreamFactory.RepoNotSpecifiedError , module: module_to_string ( module )
176+ _ -> raise EctoStreamFactory.RepoNotSpecifiedError , module: module
91177 end
92178 end
93-
94- defp module_to_string ( module ) do
95- module |> to_string ( ) |> String . replace_prefix ( "Elixir." , "" )
96- end
97179end
0 commit comments