@@ -22,6 +22,9 @@ static VALUE pgconn_wait_for_flush( VALUE self );
2222static void pgconn_set_internal_encoding_index ( VALUE );
2323static const rb_data_type_t pg_connection_type ;
2424static VALUE pgconn_async_flush (VALUE self );
25+ #ifdef LIBPQ_HAS_PROMPT_OAUTH_DEVICE
26+ extern struct st_table * pgconn2value ;
27+ #endif
2528
2629/*
2730 * Global functions
@@ -179,11 +182,17 @@ pgconn_gc_mark( void *_this )
179182 rb_gc_mark_movable ( this -> trace_stream );
180183 rb_gc_mark_movable ( this -> encoder_for_put_copy_data );
181184 rb_gc_mark_movable ( this -> decoder_for_get_copy_data );
185+ #ifdef LIBPQ_HAS_PROMPT_OAUTH_DEVICE
186+ rb_gc_mark_movable ( this -> auth_data_hook );
187+ #endif
182188}
183189
184190static void
185191pgconn_gc_compact ( void * _this )
186192{
193+ #ifdef LIBPQ_HAS_PROMPT_OAUTH_DEVICE
194+ VALUE old_rb_conn ;
195+ #endif
187196 t_pg_connection * this = (t_pg_connection * )_this ;
188197 pg_gc_location ( this -> socket_io );
189198 pg_gc_location ( this -> notice_receiver );
@@ -193,6 +202,15 @@ pgconn_gc_compact( void *_this )
193202 pg_gc_location ( this -> trace_stream );
194203 pg_gc_location ( this -> encoder_for_put_copy_data );
195204 pg_gc_location ( this -> decoder_for_get_copy_data );
205+
206+ #ifdef LIBPQ_HAS_PROMPT_OAUTH_DEVICE
207+ pg_gc_location ( this -> auth_data_hook );
208+ /* update the PG::Connection object which is maybe stored in pgconn2value */
209+ if ( st_lookup (pgconn2value , (st_data_t )this -> pgconn , (st_data_t * )& old_rb_conn ) ) {
210+ VALUE new_rb_conn = rb_gc_location (old_rb_conn );
211+ st_insert ( pgconn2value , (st_data_t )this -> pgconn , (st_data_t )new_rb_conn );
212+ }
213+ #endif
196214}
197215
198216
@@ -210,9 +228,15 @@ pgconn_gc_free( void *_this )
210228 }
211229 }
212230#endif
213- if (this -> pgconn != NULL )
231+ if (this -> pgconn != NULL ) {
214232 PQfinish ( this -> pgconn );
215233
234+ #ifdef LIBPQ_HAS_PROMPT_OAUTH_DEVICE
235+ /* Remove from auth hook callback table */
236+ st_delete (pgconn2value , (st_data_t * )& this -> pgconn , NULL );
237+ #endif
238+ }
239+
216240 xfree (this );
217241}
218242
@@ -264,6 +288,9 @@ pgconn_s_allocate( VALUE klass )
264288 RB_OBJ_WRITE (self , & this -> type_map_for_results , pg_typemap_all_strings );
265289 RB_OBJ_WRITE (self , & this -> encoder_for_put_copy_data , Qnil );
266290 RB_OBJ_WRITE (self , & this -> decoder_for_get_copy_data , Qnil );
291+ #ifdef LIBPQ_HAS_PROMPT_OAUTH_DEVICE
292+ RB_OBJ_WRITE (self , & this -> auth_data_hook , Qnil );
293+ #endif
267294 RB_OBJ_WRITE (self , & this -> trace_stream , Qnil );
268295 rb_ivar_set (self , rb_intern ("@calls_to_put_copy_data" ), INT2FIX (0 ));
269296 rb_ivar_set (self , rb_intern ("@iopts_for_reset" ), Qnil );
@@ -623,22 +650,45 @@ pgconn_reset_poll(VALUE self)
623650 return INT2FIX ((int )status );
624651}
625652
653+ #ifdef LIBPQ_HAS_PROMPT_OAUTH_DEVICE
654+
626655/*
627656 * call-seq:
628- * conn.pgconn_address()
629- *
630- * Returns the PGconn address.
657+ * conn.auth_data_hook(&block)
631658 *
632- * It can be used to compare with the address received by the OAuth hook:
659+ * Set a auth data hook.
660+ */
661+ static VALUE
662+ pgconn_auth_data_hook_set (VALUE self , VALUE proc )
663+ {
664+ t_pg_connection * this = pg_get_connection ( self );
665+
666+ if (rb_obj_is_proc (proc )) {
667+ /* set proc */
668+ st_insert ( pgconn2value , (st_data_t )this -> pgconn , (st_data_t )self );
669+ } else if (NIL_P (proc )) {
670+ /* if nil is given, set back to default */
671+ st_delete ( pgconn2value , (st_data_t * )& this -> pgconn , NULL );
672+ } else {
673+ rb_raise (rb_eArgError , "Proc object expected" );
674+ }
675+ RB_OBJ_WRITE (self , & this -> auth_data_hook , proc );
676+ return proc ;
677+ }
678+
679+ /*
680+ * call-seq:
681+ * conn.auth_data_hook()
633682 *
634- * PG.set_auth_data_hook do |pgconn_address, data|
683+ * Returns the defined auth data hook.
635684 */
636685static VALUE
637- pgconn_pgconn_address (VALUE self )
686+ pgconn_auth_data_hook_get (VALUE self )
638687{
639- return PTR2NUM ( pg_get_pgconn ( self )) ;
688+ return pg_get_connection ( self )-> auth_data_hook ;
640689}
641690
691+ #endif
642692
643693/*
644694 * call-seq:
@@ -4766,7 +4816,10 @@ init_pg_connection(void)
47664816 rb_define_private_method (rb_cPGconn , "reset_start2" , pgconn_reset_start2 , 1 );
47674817 rb_define_method (rb_cPGconn , "reset_poll" , pgconn_reset_poll , 0 );
47684818 rb_define_alias (rb_cPGconn , "close" , "finish" );
4769- rb_define_private_method (rb_cPGconn , "pgconn_address" , pgconn_pgconn_address , 0 );
4819+ #ifdef LIBPQ_HAS_PROMPT_OAUTH_DEVICE
4820+ rb_define_method (rb_cPGconn , "auth_data_hook=" , pgconn_auth_data_hook_set , 1 );
4821+ rb_define_method (rb_cPGconn , "auth_data_hook" , pgconn_auth_data_hook_get , 0 );
4822+ #endif
47704823
47714824 /****** PG::Connection INSTANCE METHODS: Connection Status ******/
47724825 rb_define_method (rb_cPGconn , "db" , pgconn_db , 0 );
0 commit comments