Sophie

Sophie

distrib > Fedora > 13 > i386 > media > updates-src > by-pkgid > 04267ea2d4e51063a2636815bd20b41f > files > 1

ruby-postgres-0.7.9-2008.01.28.2.fc13.src.rpm

From 6c2d7f91f421e926f2588fcd24857b58265b5133 Mon Sep 17 00:00:00 2001
From: Chris Lalancette <clalance@redhat.com>
Date: Tue, 7 Sep 2010 16:13:34 -0400
Subject: [PATCH] Implement trace.

This is a backport of the upstream ruby-pg changesets 56, 57, and 59.

Signed-off-by: Chris Lalancette <clalance@redhat.com>
---
 ext/postgres.c |   64 +++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/ext/postgres.c b/ext/postgres.c
index c6c2bb7..e9bb032 100644
--- a/ext/postgres.c
+++ b/ext/postgres.c
@@ -33,6 +33,7 @@
 #include <libpq/libpq-fs.h>              /* large-object interface */
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <sys/types.h>
 
 #ifndef HAVE_PQSERVERVERSION
@@ -1212,26 +1213,48 @@ pgconn_error(obj)
     return rb_tainted_str_new2(error);
 }
 
-/*TODO broken for ruby 1.9
+/*
  * call-seq:
- *    conn.trace( port )
+ *    conn.trace( stream )
  * 
- * Enables tracing message passing between backend.
- * The trace message will be written to the _port_ object,
- * which is an instance of the class +File+.
+ * Enables tracing message passing between backend. The
+ * trace message will be written to the stream _stream_,
+ * which must implement a method +fileno+ that returns
+ * a writable file descriptor.
  */
 static VALUE
-pgconn_trace(obj, port)
-    VALUE obj, port;
+pgconn_trace(VALUE self, VALUE stream)
 {
-    //OpenFile* fp;
+	VALUE fileno;
+	FILE *new_fp;
+	int old_fd, new_fd;
+	VALUE new_file;
 
-    Check_Type(port, T_FILE);
-    //GetOpenFile(port, fp);
+	if(rb_respond_to(stream,rb_intern("fileno")) == Qfalse)
+		rb_raise(rb_eArgError, "stream does not respond to method: fileno");
 
-    //PQtrace(get_pgconn(obj), fp->f2?fp->f2:fp->f);
+	fileno = rb_funcall(stream, rb_intern("fileno"), 0);
+	if(fileno == Qnil)
+		rb_raise(rb_eArgError, "can't get file descriptor from stream");
 
-    return obj;
+	/* Duplicate the file descriptor and re-open
+	 * it. Then, make it into a ruby File object
+	 * and assign it to an instance variable.
+	 * This prevents a problem when the File
+	 * object passed to this function is closed
+	 * before the connection object is. */
+	old_fd = NUM2INT(fileno);
+	new_fd = dup(old_fd);
+	new_fp = fdopen(new_fd, "w");
+
+	if(new_fp == NULL)
+		rb_raise(rb_eArgError, "stream is not writable");
+
+	new_file = rb_funcall(rb_cIO, rb_intern("new"), 1, INT2NUM(new_fd));
+	rb_iv_set(self, "@trace_file", new_file);
+
+	PQtrace(get_pgconn(self), new_fp);
+	return self;
 }
 
 /*
@@ -1241,11 +1264,14 @@ pgconn_trace(obj, port)
  * Disables the message tracing.
  */
 static VALUE
-pgconn_untrace(obj)
-    VALUE obj;
+pgconn_untrace(VALUE self)
 {
-    PQuntrace(get_pgconn(obj));
-    return obj;
+	VALUE trace_stream;
+	PQuntrace(get_pgconn(self));
+	trace_stream = rb_iv_get(self, "@trace_stream");
+	rb_funcall(trace_stream, rb_intern("close"), 0);
+	rb_iv_set(self, "@trace_stream", Qnil);
+	return self;
 }
 
 /*
-- 
1.7.2.2