@@ -122,6 +122,16 @@ impl Default for Address {
122122 }
123123}
124124
125+ impl std:: fmt:: Display for Address {
126+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
127+ write ! (
128+ f,
129+ "[address: {}:{}][database: {}][user: {}]" ,
130+ self . host, self . port, self . database, self . username
131+ )
132+ }
133+ }
134+
125135// We need to implement PartialEq by ourselves so we skip stats in the comparison
126136impl PartialEq for Address {
127137 fn eq ( & self , other : & Self ) -> bool {
@@ -235,6 +245,8 @@ pub struct General {
235245 pub port : u16 ,
236246
237247 pub enable_prometheus_exporter : Option < bool > ,
248+
249+ #[ serde( default = "General::default_prometheus_exporter_port" ) ]
238250 pub prometheus_exporter_port : i16 ,
239251
240252 #[ serde( default = "General::default_connect_timeout" ) ]
@@ -374,6 +386,10 @@ impl General {
374386 pub fn default_validate_config ( ) -> bool {
375387 true
376388 }
389+
390+ pub fn default_prometheus_exporter_port ( ) -> i16 {
391+ 9930
392+ }
377393}
378394
379395impl Default for General {
@@ -462,6 +478,7 @@ pub struct Pool {
462478 #[ serde( default = "Pool::default_load_balancing_mode" ) ]
463479 pub load_balancing_mode : LoadBalancingMode ,
464480
481+ #[ serde( default = "Pool::default_default_role" ) ]
465482 pub default_role : String ,
466483
467484 #[ serde( default ) ] // False
@@ -476,6 +493,7 @@ pub struct Pool {
476493
477494 pub server_lifetime : Option < u64 > ,
478495
496+ #[ serde( default = "Pool::default_sharding_function" ) ]
479497 pub sharding_function : ShardingFunction ,
480498
481499 #[ serde( default = "Pool::default_automatic_sharding_key" ) ]
@@ -489,6 +507,7 @@ pub struct Pool {
489507 pub auth_query_user : Option < String > ,
490508 pub auth_query_password : Option < String > ,
491509
510+ pub plugins : Option < Plugins > ,
492511 pub shards : BTreeMap < String , Shard > ,
493512 pub users : BTreeMap < String , User > ,
494513 // Note, don't put simple fields below these configs. There's a compatibility issue with TOML that makes it
@@ -521,6 +540,14 @@ impl Pool {
521540 None
522541 }
523542
543+ pub fn default_default_role ( ) -> String {
544+ "any" . into ( )
545+ }
546+
547+ pub fn default_sharding_function ( ) -> ShardingFunction {
548+ ShardingFunction :: PgBigintHash
549+ }
550+
524551 pub fn validate ( & mut self ) -> Result < ( ) , Error > {
525552 match self . default_role . as_ref ( ) {
526553 "any" => ( ) ,
@@ -609,6 +636,7 @@ impl Default for Pool {
609636 auth_query_user : None ,
610637 auth_query_password : None ,
611638 server_lifetime : None ,
639+ plugins : None ,
612640 }
613641 }
614642}
@@ -687,30 +715,50 @@ impl Default for Shard {
687715 }
688716}
689717
690- #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default ) ]
718+ #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default , Hash , Eq ) ]
691719pub struct Plugins {
692720 pub intercept : Option < Intercept > ,
693721 pub table_access : Option < TableAccess > ,
694722 pub query_logger : Option < QueryLogger > ,
723+ pub prewarmer : Option < Prewarmer > ,
695724}
696725
697- #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default ) ]
726+ impl std:: fmt:: Display for Plugins {
727+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
728+ write ! (
729+ f,
730+ "interceptor: {}, table_access: {}, query_logger: {}, prewarmer: {}" ,
731+ self . intercept. is_some( ) ,
732+ self . table_access. is_some( ) ,
733+ self . query_logger. is_some( ) ,
734+ self . prewarmer. is_some( ) ,
735+ )
736+ }
737+ }
738+
739+ #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default , Hash , Eq ) ]
698740pub struct Intercept {
699741 pub enabled : bool ,
700742 pub queries : BTreeMap < String , Query > ,
701743}
702744
703- #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default ) ]
745+ #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default , Hash , Eq ) ]
704746pub struct TableAccess {
705747 pub enabled : bool ,
706748 pub tables : Vec < String > ,
707749}
708750
709- #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default ) ]
751+ #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default , Hash , Eq ) ]
710752pub struct QueryLogger {
711753 pub enabled : bool ,
712754}
713755
756+ #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default , Hash , Eq ) ]
757+ pub struct Prewarmer {
758+ pub enabled : bool ,
759+ pub queries : Vec < String > ,
760+ }
761+
714762impl Intercept {
715763 pub fn substitute ( & mut self , db : & str , user : & str ) {
716764 for ( _, query) in self . queries . iter_mut ( ) {
@@ -720,7 +768,7 @@ impl Intercept {
720768 }
721769}
722770
723- #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default ) ]
771+ #[ derive( Serialize , Deserialize , Debug , Clone , PartialEq , Default , Hash , Eq ) ]
724772pub struct Query {
725773 pub query : String ,
726774 pub schema : Vec < Vec < String > > ,
@@ -754,8 +802,13 @@ pub struct Config {
754802 #[ serde( default = "Config::default_path" ) ]
755803 pub path : String ,
756804
805+ // General and global settings.
757806 pub general : General ,
807+
808+ // Plugins that should run in all pools.
758809 pub plugins : Option < Plugins > ,
810+
811+ // Connection pools.
759812 pub pools : HashMap < String , Pool > ,
760813}
761814
@@ -940,6 +993,13 @@ impl Config {
940993 "Server TLS certificate verification: {}" ,
941994 self . general. verify_server_certificate
942995 ) ;
996+ info ! (
997+ "Plugins: {}" ,
998+ match self . plugins {
999+ Some ( ref plugins) => plugins. to_string( ) ,
1000+ None => "not configured" . into( ) ,
1001+ }
1002+ ) ;
9431003
9441004 for ( pool_name, pool_config) in & self . pools {
9451005 // TODO: Make this output prettier (maybe a table?)
@@ -1006,6 +1066,14 @@ impl Config {
10061066 None => "default" . to_string( ) ,
10071067 }
10081068 ) ;
1069+ info ! (
1070+ "[pool: {}] Plugins: {}" ,
1071+ pool_name,
1072+ match pool_config. plugins {
1073+ Some ( ref plugins) => plugins. to_string( ) ,
1074+ None => "not configured" . into( ) ,
1075+ }
1076+ ) ;
10091077
10101078 for user in & pool_config. users {
10111079 info ! (
0 commit comments