diff --git a/ext/pg.h b/ext/pg.h index 825eaf8eb..006eed48f 100644 --- a/ext/pg.h +++ b/ext/pg.h @@ -103,6 +103,8 @@ typedef struct { VALUE notice_receiver; /* Proc object that receives notices as String objects */ VALUE notice_processor; + /* Corresponding PG::Connection ruby object. Only used for the notice_receiver */ + VALUE self; /* Kind of PG::TypeMap object for casting query params */ VALUE type_map_for_queries; /* Kind of PG::TypeMap object for casting result values */ diff --git a/ext/pg_connection.c b/ext/pg_connection.c index bc141d546..b65841e92 100644 --- a/ext/pg_connection.c +++ b/ext/pg_connection.c @@ -188,6 +188,7 @@ pgconn_gc_compact( void *_this ) pg_gc_location( this->socket_io ); pg_gc_location( this->notice_receiver ); pg_gc_location( this->notice_processor ); + pg_gc_location( this->self ); pg_gc_location( this->type_map_for_queries ); pg_gc_location( this->type_map_for_results ); pg_gc_location( this->trace_stream ); @@ -260,6 +261,7 @@ pgconn_s_allocate( VALUE klass ) RB_OBJ_WRITE(self, &this->socket_io, Qnil); RB_OBJ_WRITE(self, &this->notice_receiver, Qnil); RB_OBJ_WRITE(self, &this->notice_processor, Qnil); + RB_OBJ_WRITE(self, &this->self, self); RB_OBJ_WRITE(self, &this->type_map_for_queries, pg_typemap_all_strings); RB_OBJ_WRITE(self, &this->type_map_for_results, pg_typemap_all_strings); RB_OBJ_WRITE(self, &this->encoder_for_put_copy_data, Qnil); @@ -2986,11 +2988,10 @@ pgconn_untrace(VALUE self) void notice_receiver_proxy(void *arg, const PGresult *pgresult) { - VALUE self = (VALUE)arg; - t_pg_connection *this = pg_get_connection( self ); + t_pg_connection *this = (t_pg_connection*)arg; if (this->notice_receiver != Qnil) { - VALUE result = pg_new_result_autoclear( (PGresult *)pgresult, self ); + VALUE result = pg_new_result_autoclear( (PGresult *)pgresult, this->self ); rb_funcall(this->notice_receiver, rb_intern("call"), 1, result); pg_result_clear( result ); @@ -3045,7 +3046,7 @@ pgconn_set_notice_receiver(VALUE self) old_proc = this->notice_receiver; if( rb_block_given_p() ) { proc = rb_block_proc(); - PQsetNoticeReceiver(this->pgconn, gvl_notice_receiver_proxy, (void *)self); + PQsetNoticeReceiver(this->pgconn, gvl_notice_receiver_proxy, (void *)this); } else { /* if no block is given, set back to default */ proc = Qnil; @@ -3064,8 +3065,7 @@ pgconn_set_notice_receiver(VALUE self) void notice_processor_proxy(void *arg, const char *message) { - VALUE self = (VALUE)arg; - t_pg_connection *this = pg_get_connection( self ); + t_pg_connection *this = (t_pg_connection*)arg; if (this->notice_processor != Qnil) { VALUE message_str = rb_str_new2(message); @@ -3106,7 +3106,7 @@ pgconn_set_notice_processor(VALUE self) old_proc = this->notice_processor; if( rb_block_given_p() ) { proc = rb_block_proc(); - PQsetNoticeProcessor(this->pgconn, gvl_notice_processor_proxy, (void *)self); + PQsetNoticeProcessor(this->pgconn, gvl_notice_processor_proxy, (void *)this); } else { /* if no block is given, set back to default */ proc = Qnil; diff --git a/spec/pg/gc_compact_spec.rb b/spec/pg/gc_compact_spec.rb index 97b2d55f9..dd48a0edf 100644 --- a/spec/pg/gc_compact_spec.rb +++ b/spec/pg/gc_compact_spec.rb @@ -42,6 +42,12 @@ def conv_array(value) CONN2 = PG.connect(@conninfo) CONN2.type_map_for_results = PG::BasicTypeMapForResults.new(CONN2) + NOTI3 = [] + CONN3 = PG.connect(@conninfo) + CONN3.set_notice_receiver { |res| NOTI3 << res.error_message } + NOTI4 = [] + CONN4 = PG.connect(@conninfo) + CONN4.set_notice_processor { |res| NOTI4 << res } RES1 = CONN2.exec("SELECT 234") @@ -91,6 +97,16 @@ def conv_array(value) expect( TMBC.coders[0] ).to be_kind_of(PG::TextDecoder::Float) end + it "should compact PG::Connection with set_notice_receiver" do + CONN3.exec("DO $$ BEGIN RAISE NOTICE 'hello'; END $$;") + expect( ["NOTICE: hello\n"] ).to eq( NOTI3 ) + end + + it "should compact PG::Connection with set_notice_processor" do + CONN4.exec("DO $$ BEGIN RAISE NOTICE 'hello'; END $$;") + expect( ["NOTICE: hello\n"] ).to eq( NOTI4 ) + end + it "should compact PG::Result" do expect( RES1.getvalue(0,0) ).to eq( 234 ) end @@ -113,5 +129,7 @@ def conv_array(value) after :all do CONN2.close + CONN3.close + CONN4.close end end