@@ -499,12 +499,46 @@ defmodule Ecto.Adapters.MyXQL do
499499 "please guarantee it is available before running ecto commands"
500500 end
501501
502- { args , cmd_opts } = args_cmd_opts ( opts , opt_args , cmd_opts )
502+ { args , env } = args_env ( opts , opt_args )
503+
504+ cmd_opts =
505+ cmd_opts
506+ |> Keyword . put_new ( :stderr_to_stdout , true )
507+ |> Keyword . update ( :env , env , & Enum . concat ( env , & 1 ) )
503508
504509 System . cmd ( cmd , args , cmd_opts )
505510 end
506511
507- defp args_cmd_opts ( opts , opt_args , cmd_opts ) do
512+ defp run_with_port ( cmd , opts , opt_args , contents ) do
513+ abs_cmd = System . find_executable ( cmd )
514+
515+ unless abs_cmd do
516+ raise "could not find executable `#{ cmd } ` in path, " <>
517+ "please guarantee it is available before running ecto commands"
518+ end
519+
520+ abs_cmd = String . to_charlist ( abs_cmd )
521+ { args , env } = args_env ( opts , opt_args )
522+
523+ port_opts = [
524+ :use_stdio ,
525+ :exit_status ,
526+ :binary ,
527+ :hide ,
528+ :stderr_to_stdout ,
529+ env: validate_env ( env ) ,
530+ args: args
531+ ]
532+
533+ port = Port . open ( { :spawn_executable , abs_cmd } , port_opts )
534+ Port . command ( port , contents )
535+ # Use this as a signal to close the port since we cannot
536+ # send an exit command to mysql in batch mode
537+ Port . command ( port , ";SELECT '__ECTO_EOF__';\n " )
538+ collect_output ( port , "" )
539+ end
540+
541+ defp args_env ( opts , opt_args ) do
508542 env =
509543 if password = opts [ :password ] do
510544 [ { "MYSQL_PWD" , password } ]
@@ -533,60 +567,7 @@ defmodule Ecto.Adapters.MyXQL do
533567 protocol
534568 ] ++ user_args ++ opt_args
535569
536- cmd_opts =
537- cmd_opts
538- |> Keyword . put_new ( :stderr_to_stdout , true )
539- |> Keyword . update ( :env , env , & Enum . concat ( env , & 1 ) )
540-
541- { args , cmd_opts }
542- end
543-
544- # Ported from Elixir System.cmd implementation with the
545- # intent of using file redirection for passing dumps
546- # into the mysql client so that users don't run into
547- # shell limits when files are too large
548- defp run_with_port ( cmd , opts , opt_args , contents , cmd_opts \\ [ ] ) do
549- abs_cmd = System . find_executable ( cmd )
550-
551- unless abs_cmd do
552- raise "could not find executable `#{ cmd } ` in path, " <>
553- "please guarantee it is available before running ecto commands"
554- end
555-
556- abs_cmd = String . to_charlist ( abs_cmd )
557- { args , cmd_opts } = args_cmd_opts ( opts , opt_args , cmd_opts )
558-
559- port_opts = port_opts ( cmd_opts , args: args )
560- port = Port . open ( { :spawn_executable , abs_cmd } , port_opts )
561- Port . command ( port , contents )
562- # Use this as a signal to close the port since we cannot
563- # send an exit command to mysql in batch mode
564- Port . command ( port , ";SELECT '__ECTO_EOF__';\n " )
565-
566- { initial , fun } = Collectable . into ( "" )
567-
568- try do
569- collect_output ( port , initial , fun )
570- catch
571- kind , reason ->
572- fun . ( initial , :halt )
573- :erlang . raise ( kind , reason , __STACKTRACE__ )
574- else
575- { acc , status } -> { fun . ( acc , :done ) , status }
576- end
577- end
578-
579- defp port_opts ( [ { :stderr_to_stdout , true } | t ] , acc ) ,
580- do: port_opts ( t , [ :stderr_to_stdout | acc ] )
581-
582- defp port_opts ( [ { :stderr_to_stdout , _ } | t ] , acc ) ,
583- do: port_opts ( t , acc )
584-
585- defp port_opts ( [ { :env , enum } | t ] , acc ) ,
586- do: port_opts ( t , [ { :env , validate_env ( enum ) } | acc ] )
587-
588- defp port_opts ( [ ] , acc ) do
589- [ :use_stdio , :exit_status , :binary , :hide ] ++ acc
570+ { args , env }
590571 end
591572
592573 defp validate_env ( enum ) do
@@ -602,13 +583,16 @@ defmodule Ecto.Adapters.MyXQL do
602583 end )
603584 end
604585
605- defp collect_output ( port , acc , fun ) do
586+ defp collect_output ( port , acc ) do
606587 receive do
607- { ^ port , { :data , "__ECTO_EOF__" <> _rest } } ->
608- { acc , 0 }
609-
610588 { ^ port , { :data , data } } ->
611- collect_output ( port , fun . ( acc , { :cont , data } ) , fun )
589+ acc = acc <> data
590+
591+ if acc =~ "__ECTO_EOF__" do
592+ { acc , 0 }
593+ else
594+ collect_output ( port , acc )
595+ end
612596
613597 { ^ port , { :exit_status , status } } ->
614598 { acc , status }
0 commit comments