@@ -188,6 +188,36 @@ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='#{table}';
188188 end
189189 end
190190
191+ @ doc """
192+ Generate ash resource from schema.
193+
194+ ## Examples
195+
196+ iex> ExDbmigrate.resource()
197+ ["mix ash.gen.resource Helpdesk.Support.Ticket \
198+ --default-actions read \
199+ --uuid-primary-key id \
200+ --attribute subject:string:required:public \
201+ --relationship belongs_to:representative:Helpdesk.Support.Representative \
202+ --timestamps \
203+ --extend postgres"]
204+
205+ """
206+ def resource ( schema \\ "public" , mode \\ :read , filename \\ "db_migrate" ) do
207+ results = fetch_results ( schema )
208+
209+ map =
210+ Enum . map ( results . rows , fn [ r ] ->
211+ application_table_data ( r )
212+ |> generate_resources_command ( r )
213+ end )
214+
215+ case mode do
216+ :read -> map
217+ :write -> map |> write_file ( filename )
218+ end
219+ end
220+
191221 @ doc """
192222 Generate schema from config.
193223
@@ -229,6 +259,10 @@ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='#{table}';
229259 Ecto.Adapters.SQL . query! ( @ repo , query , [ ] )
230260 end
231261
262+ def application_table_data ( name ) do
263+ ExDbmigrate.Table.Server . show ( name )
264+ end
265+
232266 def fetch_table_data ( r , schema \\ "public" ) do
233267 query =
234268 "SELECT column_name, is_nullable, data_type, ordinal_position, character_maximum_length FROM information_schema.columns
@@ -252,6 +286,24 @@ WHERE table_schema = '#{schema}'
252286 "mix phx.gen.json #{ module } #{ module_name } #{ table } #{ migration_string } "
253287 end
254288
289+ def generate_resources_command ( data , table_name , extends \\ "postgres" ) do
290+ name = migration_module ( table_name ) |> singularize ( )
291+
292+ attributes =
293+ build_attributes ( data ) |> Enum . map ( fn x -> "--attribute #{ x } " end ) |> Enum . join ( " " )
294+
295+ relationships =
296+ build_relationships ( data ) |> Enum . map ( fn x -> "--relationship #{ x } " end ) |> Enum . join ( " " )
297+
298+ "mix ash.gen.resource #{ name } \
299+ --default-actions read \
300+ --uuid-primary-key id \
301+ #{ attributes } \
302+ #{ relationships } \
303+ --timestamps \
304+ --extend #{ extends } "
305+ end
306+
255307 def generate_lives_command ( data , [ migration_name ] ) do
256308 migration_string = migration_string ( data )
257309
@@ -275,14 +327,34 @@ WHERE table_schema = '#{schema}'
275327
276328 def migration_string ( data ) do
277329 data . rows
330+ |> build_attributes ( )
331+ |> Enum . join ( " " )
332+ |> String . trim ( )
333+ end
334+
335+ def build_relationships ( data ) do
336+ data . links
337+ |> Enum . map ( fn % {
338+ column_name: column_name ,
339+ references: % {
340+ ref_table: foreign_table_name ,
341+ ref_column: foreign_column_name ,
342+ type: type
343+ }
344+ } ->
345+ relation_module_name = migration_module ( foreign_table_name ) |> singularize ( )
346+ "#{ type } :#{ foreign_table_name } :#{ relation_module_name } "
347+ end )
348+ end
349+
350+ def build_attributes ( data ) do
351+ data
278352 |> Enum . map ( fn [ id , _is_null , type , _position , _max_length ] ->
279353 unless id == "id" || id == "inserted_at" || id == "updated_at" do
280354 type = type_select ( type )
281355 "#{ id } :#{ type } "
282356 end
283357 end )
284- |> Enum . join ( " " )
285- |> String . trim ( )
286358 end
287359
288360 def table_name ( migration_name ) do
@@ -402,17 +474,18 @@ WHERE table_schema = '#{schema}'
402474 target = String . split ( file , "/" )
403475
404476 if is_list ( target ) do
405- target = case Enum . count ( target ) do
406- 1 ->
407- Path . join ( File . cwd! ( ) , "/priv/#{ file } " )
408-
409- 0 ->
410- Path . join ( File . cwd! ( ) , "/priv/db_migrate.txt" )
411-
412- _ ->
413- filename = "#{ timestamp ( ) } _#{ List . last ( target ) } "
414- Path . join ( File . cwd! ( ) , "/priv/#{ filename } " )
415- end
477+ target =
478+ case Enum . count ( target ) do
479+ 1 ->
480+ Path . join ( File . cwd! ( ) , "/priv/#{ file } " )
481+
482+ 0 ->
483+ Path . join ( File . cwd! ( ) , "/priv/db_migrate.txt" )
484+
485+ _ ->
486+ filename = "#{ timestamp ( ) } _#{ List . last ( target ) } "
487+ Path . join ( File . cwd! ( ) , "/priv/#{ filename } " )
488+ end
416489
417490 data = Enum . join ( data , "\n " )
418491 target |> File . write ( data )
0 commit comments