@@ -480,8 +480,22 @@ defmodule Ecto.Adapters.SQL do
480
480
disconnect_all ( Ecto.Adapter . lookup_meta ( repo ) , interval , opts )
481
481
end
482
482
483
- def disconnect_all ( % { pid: pid } = _adapter_meta , interval , opts ) do
484
- DBConnection . disconnect_all ( pid , interval , opts )
483
+ def disconnect_all ( adapter_meta , interval , opts ) do
484
+ case adapter_meta do
485
+ % { partition_supervisor: { name , count } } ->
486
+ 1 .. count
487
+ |> Enum . map ( fn i ->
488
+ Task . async ( fn ->
489
+ DBConnection . disconnect_all ( { :via , PartitionSupervisor , { name , i } } , interval , opts )
490
+ end )
491
+ end )
492
+ |> Task . await_many ( :infinity )
493
+
494
+ :ok
495
+
496
+ % { pid: pool } ->
497
+ DBConnection . disconnect_all ( pool , interval , opts )
498
+ end
485
499
end
486
500
487
501
@ doc """
@@ -646,7 +660,7 @@ defmodule Ecto.Adapters.SQL do
646
660
647
661
defp sql_call ( adapter_meta , callback , args , params , opts ) do
648
662
% { pid: pool , telemetry: telemetry , sql: sql , opts: default_opts } = adapter_meta
649
- conn = get_conn_or_pool ( pool )
663
+ conn = get_conn_or_pool ( pool , adapter_meta )
650
664
opts = with_log ( telemetry , params , opts ++ default_opts )
651
665
args = args ++ [ params , opts ]
652
666
apply ( sql , callback , [ conn | args ] )
@@ -662,7 +676,7 @@ defmodule Ecto.Adapters.SQL do
662
676
end
663
677
664
678
@ doc """
665
- Check if the given `table` exists.
679
+ Checks if the given `table` exists.
666
680
667
681
Returns `true` if the `table` exists in the `repo`, otherwise `false`.
668
682
The table is checked against the current database/schema in the connection.
@@ -702,7 +716,7 @@ defmodule Ecto.Adapters.SQL do
702
716
def format_table ( % { columns: columns , rows: rows } ) do
703
717
column_widths =
704
718
[ columns | rows ]
705
- |> List . zip ( )
719
+ |> Enum . zip ( )
706
720
|> Enum . map ( & Tuple . to_list / 1 )
707
721
|> Enum . map ( fn column_with_rows ->
708
722
column_with_rows |> Enum . map ( & binary_length / 1 ) |> Enum . max ( )
@@ -733,7 +747,7 @@ defmodule Ecto.Adapters.SQL do
733
747
defp cells ( items , widths ) do
734
748
cell =
735
749
[ items , widths ]
736
- |> List . zip ( )
750
+ |> Enum . zip ( )
737
751
|> Enum . map ( fn { item , width } -> [ ?| , " " , format_item ( item , width ) , " " ] end )
738
752
739
753
[ cell | [ ?| ] ]
@@ -827,6 +841,8 @@ defmodule Ecto.Adapters.SQL do
827
841
@ pool_opts [ :timeout , :pool , :pool_size ] ++
828
842
[ :queue_target , :queue_interval , :ownership_timeout , :repo ]
829
843
844
+ @ valid_log_levels ~w( false debug info notice warning error critical alert emergency) a
845
+
830
846
@ doc false
831
847
def init ( connection , driver , config ) do
832
848
unless Code . ensure_loaded? ( connection ) do
@@ -845,24 +861,12 @@ defmodule Ecto.Adapters.SQL do
845
861
846
862
log = Keyword . get ( config , :log , :debug )
847
863
848
- valid_log_levels = [
849
- false ,
850
- :debug ,
851
- :info ,
852
- :notice ,
853
- :warning ,
854
- :error ,
855
- :critical ,
856
- :alert ,
857
- :emergency
858
- ]
859
-
860
- if log not in valid_log_levels do
864
+ if log not in @ valid_log_levels do
861
865
raise """
862
866
invalid value for :log option in Repo config
863
867
864
868
The accepted values for the :log option are:
865
- #{ Enum . map_join ( valid_log_levels , ", " , & inspect / 1 ) }
869
+ #{ Enum . map_join ( @ valid_log_levels , ", " , & inspect / 1 ) }
866
870
867
871
See https://hexdocs.pm/ecto/Ecto.Repo.html for more information.
868
872
"""
@@ -872,35 +876,49 @@ defmodule Ecto.Adapters.SQL do
872
876
telemetry_prefix = Keyword . fetch! ( config , :telemetry_prefix )
873
877
telemetry = { config [ :repo ] , log , telemetry_prefix ++ [ :query ] }
874
878
875
- config = adapter_config ( config )
876
- opts = Keyword . take ( config , @ pool_opts )
877
- meta = % { telemetry: telemetry , sql: connection , stacktrace: stacktrace , opts: opts }
878
- { :ok , connection . child_spec ( config ) , meta }
879
- end
879
+ { name , config } = Keyword . pop ( config , :name , config [ :repo ] )
880
+ { pool_count , config } = Keyword . pop ( config , :pool_count , 1 )
881
+ { pool , config } = pool_config ( config )
882
+ child_spec = connection . child_spec ( config )
880
883
881
- defp adapter_config ( config ) do
882
- if Keyword . has_key? ( config , :pool_timeout ) do
883
- message = """
884
- :pool_timeout option no longer has an effect and has been replaced with an improved queuing system.
885
- See \" Queue config\" in DBConnection.start_link/2 documentation for more information.
886
- """
884
+ meta = % {
885
+ telemetry: telemetry ,
886
+ sql: connection ,
887
+ stacktrace: stacktrace ,
888
+ opts: Keyword . take ( config , @ pool_opts )
889
+ }
887
890
888
- IO . warn ( message )
889
- end
891
+ if pool_count > 1 do
892
+ if name == nil do
893
+ raise ArgumentError , "the option :pool_count requires a :name"
894
+ end
890
895
891
- config
892
- |> Keyword . delete ( :name )
893
- |> Keyword . update ( :pool , DBConnection.ConnectionPool , & normalize_pool / 1 )
894
- end
896
+ if pool == DBConnection.Ownership do
897
+ raise ArgumentError , "the option :pool_count does not work with the SQL sandbox"
898
+ end
895
899
896
- defp normalize_pool ( pool ) do
897
- if Code . ensure_loaded? ( pool ) && function_exported? ( pool , :unboxed_run , 2 ) do
898
- DBConnection.Ownership
900
+ name = Module . concat ( name , PartitionSupervisor )
901
+ partition_opts = [ name: name , child_spec: child_spec , partitions: pool_count ]
902
+ child_spec = Supervisor . child_spec ( { PartitionSupervisor , partition_opts } , [ ] )
903
+ { :ok , child_spec , Map . put ( meta , :partition_supervisor , { name , pool_count } ) }
899
904
else
900
- pool
905
+ { :ok , child_spec , meta }
901
906
end
902
907
end
903
908
909
+ defp pool_config ( config ) do
910
+ { pool , config } = Keyword . pop ( config , :pool , DBConnection.ConnectionPool )
911
+
912
+ pool =
913
+ if Code . ensure_loaded? ( pool ) && function_exported? ( pool , :unboxed_run , 2 ) do
914
+ DBConnection.Ownership
915
+ else
916
+ pool
917
+ end
918
+
919
+ { pool , [ pool: pool ] ++ config }
920
+ end
921
+
904
922
@ doc false
905
923
def checkout ( adapter_meta , opts , callback ) do
906
924
checkout_or_transaction ( :run , adapter_meta , opts , callback )
@@ -1385,11 +1403,20 @@ defmodule Ecto.Adapters.SQL do
1385
1403
end
1386
1404
end
1387
1405
1388
- apply ( DBConnection , fun , [ get_conn_or_pool ( pool ) , callback , opts ] )
1406
+ apply ( DBConnection , fun , [ get_conn_or_pool ( pool , adapter_meta ) , callback , opts ] )
1389
1407
end
1390
1408
1391
- defp get_conn_or_pool ( pool ) do
1392
- Process . get ( key ( pool ) , pool )
1409
+ defp get_conn_or_pool ( pool , adapter_meta ) do
1410
+ case :erlang . get ( key ( pool ) ) do
1411
+ :undefined ->
1412
+ case adapter_meta do
1413
+ % { partition_supervisor: { name , _ } } -> { :via , PartitionSupervisor , { name , self ( ) } }
1414
+ _ -> pool
1415
+ end
1416
+
1417
+ conn ->
1418
+ conn
1419
+ end
1393
1420
end
1394
1421
1395
1422
defp get_conn ( pool ) do
0 commit comments