@@ -6919,7 +6919,7 @@ async fn cmd_db_webhook(
69196919 } => cmd_db_webhook_rx_list ( opctx, datastore, fetch_opts, args) . await ,
69206920 WebhookCommands :: Receiver {
69216921 command : WebhookRxCommands :: Info ( args) ,
6922- } => cmd_db_webhook_rx_info ( opctx , datastore, fetch_opts, args) . await ,
6922+ } => cmd_db_webhook_rx_info ( datastore, fetch_opts, args) . await ,
69236923 WebhookCommands :: Event => {
69246924 Err ( anyhow:: anyhow!( "not yet implemented, sorry!" ) )
69256925 }
@@ -6986,12 +6986,217 @@ async fn cmd_db_webhook_rx_list(
69866986}
69876987
69886988async fn cmd_db_webhook_rx_info (
6989- _opctx : & OpContext ,
6990- _datastore : & DataStore ,
6991- _fetch_opts : & DbFetchOptions ,
6992- _args : & WebhookRxInfoArgs ,
6989+ datastore : & DataStore ,
6990+ fetch_opts : & DbFetchOptions ,
6991+ args : & WebhookRxInfoArgs ,
69936992) -> anyhow:: Result < ( ) > {
6994- anyhow:: bail!( "TODO: eliza, implement this one!" )
6993+ use db:: model:: schema:: webhook_receiver:: dsl as rx_dsl;
6994+ use db:: model:: schema:: webhook_rx_event_glob:: dsl as glob_dsl;
6995+ use db:: model:: schema:: webhook_rx_subscription:: dsl as subscription_dsl;
6996+ use db:: model:: schema:: webhook_secret:: dsl as secret_dsl;
6997+
6998+ let conn = datastore. pool_connection_for_tests ( ) . await ?;
6999+ let mut query = match args. receiver {
7000+ NameOrId :: Id ( id) => {
7001+ rx_dsl:: webhook_receiver. filter ( rx_dsl:: id. eq ( id) ) . into_boxed ( )
7002+ }
7003+ NameOrId :: Name ( ref name) => rx_dsl:: webhook_receiver
7004+ . filter ( rx_dsl:: name. eq ( name. to_string ( ) ) )
7005+ . into_boxed ( ) ,
7006+ } ;
7007+ if !fetch_opts. include_deleted {
7008+ query = query. filter ( rx_dsl:: time_deleted. is_null ( ) ) ;
7009+ }
7010+
7011+ let rx = query
7012+ . limit ( 1 )
7013+ . select ( db:: model:: WebhookReceiver :: as_select ( ) )
7014+ . get_result_async ( & * conn)
7015+ . await
7016+ . optional ( )
7017+ . with_context ( || format ! ( "loading webhook receiver {}" , args. receiver) ) ?
7018+ . ok_or_else ( || {
7019+ anyhow:: anyhow!( "no instance {} exists" , args. receiver)
7020+ } ) ?;
7021+
7022+ const ID : & ' static str = "ID" ;
7023+ const NAME : & ' static str = "name" ;
7024+
7025+ const DESCRIPTION : & ' static str = "description" ;
7026+ const CREATED : & ' static str = "created at" ;
7027+ const DELETED : & ' static str = "deleted at" ;
7028+ const MODIFIED : & ' static str = "modified at" ;
7029+ const ENDPOINT : & ' static str = "endpoint" ;
7030+ const GEN : & ' static str = "generation" ;
7031+ const EXACT : & ' static str = "exact subscriptions" ;
7032+ const GLOBS : & ' static str = "glob subscriptions" ;
7033+ const GLOB_REGEX : & ' static str = " regex" ;
7034+ const GLOB_SCHEMA_VERSION : & ' static str = " schema version" ;
7035+ const GLOB_CREATED : & ' static str = " created at" ;
7036+ const GLOB_EXACT : & ' static str = " exact subscriptions" ;
7037+ const WIDTH : usize = const_max_len ( & [
7038+ ID ,
7039+ NAME ,
7040+ DESCRIPTION ,
7041+ CREATED ,
7042+ DELETED ,
7043+ MODIFIED ,
7044+ ENDPOINT ,
7045+ GEN ,
7046+ EXACT ,
7047+ GLOBS ,
7048+ GLOB_REGEX ,
7049+ GLOB_SCHEMA_VERSION ,
7050+ GLOB_CREATED ,
7051+ GLOB_EXACT ,
7052+ ] ) ;
7053+
7054+ let db:: model:: WebhookReceiver {
7055+ identity :
7056+ db:: model:: WebhookReceiverIdentity {
7057+ id,
7058+ name,
7059+ description,
7060+ time_created,
7061+ time_modified,
7062+ time_deleted,
7063+ } ,
7064+ endpoint,
7065+ secret_gen,
7066+ subscription_gen,
7067+ } = rx;
7068+
7069+ println ! ( "\n {:=<80}" , "== RECEIVER " ) ;
7070+ println ! ( " {NAME:>WIDTH$}: {name}" ) ;
7071+ println ! ( " {ID:>WIDTH$}: {id}" ) ;
7072+ println ! ( " {DESCRIPTION:>WIDTH$}: {description}" ) ;
7073+ println ! ( " {ENDPOINT:>WIDTH$}: {endpoint}" ) ;
7074+ println ! ( ) ;
7075+ println ! ( " {CREATED:>WIDTH$}: {time_created}" ) ;
7076+ println ! ( " {MODIFIED:>WIDTH$}: {time_modified}" ) ;
7077+ if let Some ( deleted) = time_deleted {
7078+ println ! ( " {DELETED:>WIDTH$}: {deleted}" ) ;
7079+ }
7080+
7081+ println ! ( "\n {:=<80}" , "== SECRETS " ) ;
7082+ println ! ( " {GEN:>WIDTH$}: {}" , secret_gen. 0 ) ;
7083+
7084+ let query = secret_dsl:: webhook_secret
7085+ . filter ( secret_dsl:: rx_id. eq ( id. into_untyped_uuid ( ) ) )
7086+ . select ( db:: model:: WebhookSecret :: as_select ( ) ) ;
7087+ let secrets = if fetch_opts. include_deleted {
7088+ query. load_async ( & * conn) . await
7089+ } else {
7090+ query
7091+ . filter ( secret_dsl:: time_deleted. is_null ( ) )
7092+ . load_async ( & * conn)
7093+ . await
7094+ } ;
7095+
7096+ match secrets {
7097+ Ok ( secrets) => {
7098+ #[ derive( Tabled ) ]
7099+ struct SecretRow {
7100+ id : Uuid ,
7101+
7102+ #[ tabled( display_with = "datetime_rfc3339_concise" ) ]
7103+ created : chrono:: DateTime < Utc > ,
7104+
7105+ #[ tabled( display_with = "datetime_opt_rfc3339_concise" ) ]
7106+ deleted : Option < chrono:: DateTime < Utc > > ,
7107+ }
7108+ let rows = secrets. into_iter ( ) . map (
7109+ |db:: model:: WebhookSecret {
7110+ identity :
7111+ db:: model:: WebhookSecretIdentity {
7112+ id,
7113+ time_modified : _,
7114+ time_created,
7115+ } ,
7116+ webhook_receiver_id : _,
7117+ secret : _,
7118+ time_deleted,
7119+ } | SecretRow {
7120+ id : id. into_untyped_uuid ( ) ,
7121+ created : time_created,
7122+ deleted : time_deleted,
7123+ } ,
7124+ ) ;
7125+
7126+ let table = tabled:: Table :: new ( rows)
7127+ . with ( tabled:: settings:: Style :: empty ( ) )
7128+ . with ( tabled:: settings:: Padding :: new ( 0 , 1 , 0 , 0 ) )
7129+ . to_string ( ) ;
7130+ println ! ( "{table}" ) ;
7131+ }
7132+ Err ( e) => eprintln ! ( "failed to list secrets: {e}" ) ,
7133+ }
7134+
7135+ println ! ( "\n {:=<80}" , "== SUBSCRIPTIONS " ) ;
7136+ println ! ( " {GEN:>WIDTH$}: {}" , subscription_gen. 0 ) ;
7137+
7138+ let exact = subscription_dsl:: webhook_rx_subscription
7139+ . filter ( subscription_dsl:: rx_id. eq ( id. into_untyped_uuid ( ) ) )
7140+ . filter ( subscription_dsl:: glob. is_null ( ) )
7141+ . select ( subscription_dsl:: event_class)
7142+ . load_async :: < db:: model:: WebhookEventClass > ( & * conn)
7143+ . await ;
7144+ match exact {
7145+ Ok ( exact) => {
7146+ println ! ( " {EXACT:>WIDTH$}: {}" , exact. len( ) ) ;
7147+ for event_class in exact {
7148+ println ! ( " - {event_class}" ) ;
7149+ }
7150+ }
7151+ Err ( e) => {
7152+ eprintln ! ( "failed to list exact subscriptions: {e}" ) ;
7153+ }
7154+ }
7155+
7156+ let globs = glob_dsl:: webhook_rx_event_glob
7157+ . filter ( glob_dsl:: rx_id. eq ( id. into_untyped_uuid ( ) ) )
7158+ . select ( db:: model:: WebhookRxEventGlob :: as_select ( ) )
7159+ . load_async :: < db:: model:: WebhookRxEventGlob > ( & * conn)
7160+ . await ;
7161+ match globs {
7162+ Ok ( globs) => {
7163+ println ! ( " {GLOBS:>WIDTH$}: {}" , globs. len( ) ) ;
7164+ for glob in globs {
7165+ let db:: model:: WebhookRxEventGlob {
7166+ rx_id : _,
7167+ glob : db:: model:: WebhookGlob { glob, regex } ,
7168+ time_created,
7169+ schema_version,
7170+ } = glob;
7171+ println ! ( " - {glob}" ) ;
7172+ println ! ( " {GLOB_CREATED:>WIDTH$}: {time_created}" ) ;
7173+ println ! ( " {GLOB_SCHEMA_VERSION:>WIDTH$}: {schema_version}" ) ;
7174+ println ! ( " {GLOB_REGEX:>WIDTH$}: {regex}" ) ;
7175+ let exact = subscription_dsl:: webhook_rx_subscription
7176+ . filter ( subscription_dsl:: rx_id. eq ( id. into_untyped_uuid ( ) ) )
7177+ . filter ( subscription_dsl:: glob. eq ( glob) )
7178+ . select ( subscription_dsl:: event_class)
7179+ . load_async :: < db:: model:: WebhookEventClass > ( & * conn)
7180+ . await ;
7181+ match exact {
7182+ Ok ( exact) => {
7183+ println ! ( " {GLOB_EXACT:>WIDTH$}: {}" , exact. len( ) ) ;
7184+ for event_class in exact {
7185+ println ! ( " - {event_class}" )
7186+ }
7187+ }
7188+ Err ( e) => eprintln ! (
7189+ "failed to list exact subscriptions for glob: {e}"
7190+ ) ,
7191+ }
7192+ }
7193+ }
7194+ Err ( e) => {
7195+ eprintln ! ( "failed to list glob subscriptions: {e}" ) ;
7196+ }
7197+ }
7198+
7199+ Ok ( ( ) )
69957200}
69967201
69977202// Format a `chrono::DateTime` in RFC3339 with milliseconds precision and using
0 commit comments