pg 1.1.4 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - checksums.yaml.gz.sig +0 -0
 - data.tar.gz.sig +0 -0
 - data/ChangeLog +0 -6595
 - data/History.rdoc +86 -0
 - data/Manifest.txt +3 -2
 - data/README-Windows.rdoc +4 -4
 - data/README.ja.rdoc +1 -2
 - data/README.rdoc +44 -9
 - data/Rakefile +8 -6
 - data/Rakefile.cross +57 -56
 - data/ext/errorcodes.def +64 -0
 - data/ext/errorcodes.txt +18 -2
 - data/ext/extconf.rb +6 -6
 - data/ext/pg.c +132 -95
 - data/ext/pg.h +21 -18
 - data/ext/pg_binary_decoder.c +9 -9
 - data/ext/pg_binary_encoder.c +13 -12
 - data/ext/pg_coder.c +21 -9
 - data/ext/pg_connection.c +388 -298
 - data/ext/pg_copy_coder.c +6 -3
 - data/ext/pg_record_coder.c +491 -0
 - data/ext/pg_result.c +279 -127
 - data/ext/pg_text_decoder.c +14 -8
 - data/ext/pg_text_encoder.c +180 -48
 - data/ext/pg_tuple.c +14 -6
 - data/ext/pg_type_map.c +1 -1
 - data/ext/pg_type_map_all_strings.c +4 -4
 - data/ext/pg_type_map_by_class.c +9 -4
 - data/ext/pg_type_map_by_column.c +7 -6
 - data/ext/pg_type_map_by_mri_type.c +1 -1
 - data/ext/pg_type_map_by_oid.c +3 -2
 - data/ext/pg_type_map_in_ruby.c +1 -1
 - data/ext/{util.c → pg_util.c} +5 -5
 - data/ext/{util.h → pg_util.h} +0 -0
 - data/lib/pg.rb +4 -4
 - data/lib/pg/basic_type_mapping.rb +81 -18
 - data/lib/pg/binary_decoder.rb +1 -0
 - data/lib/pg/coder.rb +22 -1
 - data/lib/pg/connection.rb +2 -2
 - data/lib/pg/constants.rb +1 -0
 - data/lib/pg/exceptions.rb +1 -0
 - data/lib/pg/result.rb +13 -1
 - data/lib/pg/text_decoder.rb +2 -3
 - data/lib/pg/text_encoder.rb +8 -18
 - data/lib/pg/type_map_by_column.rb +2 -1
 - data/spec/helpers.rb +11 -11
 - data/spec/pg/basic_type_mapping_spec.rb +140 -18
 - data/spec/pg/connection_spec.rb +166 -89
 - data/spec/pg/result_spec.rb +194 -4
 - data/spec/pg/tuple_spec.rb +55 -2
 - data/spec/pg/type_map_by_class_spec.rb +1 -1
 - data/spec/pg/type_map_by_column_spec.rb +5 -1
 - data/spec/pg/type_map_by_oid_spec.rb +2 -2
 - data/spec/pg/type_spec.rb +180 -6
 - metadata +31 -30
 - metadata.gz.sig +0 -0
 
    
        data/ext/pg_result.c
    CHANGED
    
    | 
         @@ -6,15 +6,22 @@ 
     | 
|
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            #include "pg.h"
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
9 
     | 
    
         
             
            VALUE rb_cPGresult;
         
     | 
| 
      
 10 
     | 
    
         
            +
            static VALUE sym_symbol, sym_string, sym_static_symbol;
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            static void pgresult_gc_free( t_pg_result * );
         
     | 
| 
       13 
12 
     | 
    
         
             
            static VALUE pgresult_type_map_set( VALUE, VALUE );
         
     | 
| 
       14 
     | 
    
         
            -
            static VALUE pgresult_s_allocate( VALUE );
         
     | 
| 
       15 
13 
     | 
    
         
             
            static t_pg_result *pgresult_get_this( VALUE );
         
     | 
| 
       16 
14 
     | 
    
         
             
            static t_pg_result *pgresult_get_this_safe( VALUE );
         
     | 
| 
       17 
15 
     | 
    
         | 
| 
      
 16 
     | 
    
         
            +
            #if defined(HAVE_PQRESULTMEMORYSIZE)
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            static ssize_t
         
     | 
| 
      
 19 
     | 
    
         
            +
            pgresult_approx_size(const PGresult *result)
         
     | 
| 
      
 20 
     | 
    
         
            +
            {
         
     | 
| 
      
 21 
     | 
    
         
            +
            	return PQresultMemorySize(result);
         
     | 
| 
      
 22 
     | 
    
         
            +
            }
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            #else
         
     | 
| 
       18 
25 
     | 
    
         | 
| 
       19 
26 
     | 
    
         
             
            #define PGRESULT_DATA_BLOCKSIZE 2048
         
     | 
| 
       20 
27 
     | 
    
         
             
            typedef struct pgresAttValue
         
     | 
| 
         @@ -44,7 +51,7 @@ count_leading_zero_bits(unsigned int x) 
     | 
|
| 
       44 
51 
     | 
    
         
             
            }
         
     | 
| 
       45 
52 
     | 
    
         | 
| 
       46 
53 
     | 
    
         
             
            static ssize_t
         
     | 
| 
       47 
     | 
    
         
            -
            pgresult_approx_size(PGresult *result)
         
     | 
| 
      
 54 
     | 
    
         
            +
            pgresult_approx_size(const PGresult *result)
         
     | 
| 
       48 
55 
     | 
    
         
             
            {
         
     | 
| 
       49 
56 
     | 
    
         
             
            	int num_fields = PQnfields(result);
         
     | 
| 
       50 
57 
     | 
    
         
             
            	ssize_t size = 0;
         
     | 
| 
         @@ -94,7 +101,29 @@ pgresult_approx_size(PGresult *result) 
     | 
|
| 
       94 
101 
     | 
    
         | 
| 
       95 
102 
     | 
    
         
             
            	return size;
         
     | 
| 
       96 
103 
     | 
    
         
             
            }
         
     | 
| 
      
 104 
     | 
    
         
            +
            #endif
         
     | 
| 
       97 
105 
     | 
    
         | 
| 
      
 106 
     | 
    
         
            +
            /*
         
     | 
| 
      
 107 
     | 
    
         
            +
             * GC Mark function
         
     | 
| 
      
 108 
     | 
    
         
            +
             */
         
     | 
| 
      
 109 
     | 
    
         
            +
            static void
         
     | 
| 
      
 110 
     | 
    
         
            +
            pgresult_gc_mark( t_pg_result *this )
         
     | 
| 
      
 111 
     | 
    
         
            +
            {
         
     | 
| 
      
 112 
     | 
    
         
            +
            	int i;
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            	rb_gc_mark( this->connection );
         
     | 
| 
      
 115 
     | 
    
         
            +
            	rb_gc_mark( this->typemap );
         
     | 
| 
      
 116 
     | 
    
         
            +
            	rb_gc_mark( this->tuple_hash );
         
     | 
| 
      
 117 
     | 
    
         
            +
            	rb_gc_mark( this->field_map );
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            	for( i=0; i < this->nfields; i++ ){
         
     | 
| 
      
 120 
     | 
    
         
            +
            		rb_gc_mark( this->fnames[i] );
         
     | 
| 
      
 121 
     | 
    
         
            +
            	}
         
     | 
| 
      
 122 
     | 
    
         
            +
            }
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            /*
         
     | 
| 
      
 125 
     | 
    
         
            +
             * GC Free function
         
     | 
| 
      
 126 
     | 
    
         
            +
             */
         
     | 
| 
       98 
127 
     | 
    
         
             
            static void
         
     | 
| 
       99 
128 
     | 
    
         
             
            pgresult_clear( t_pg_result *this )
         
     | 
| 
       100 
129 
     | 
    
         
             
            {
         
     | 
| 
         @@ -104,15 +133,46 @@ pgresult_clear( t_pg_result *this ) 
     | 
|
| 
       104 
133 
     | 
    
         
             
            		rb_gc_adjust_memory_usage(-this->result_size);
         
     | 
| 
       105 
134 
     | 
    
         
             
            #endif
         
     | 
| 
       106 
135 
     | 
    
         
             
            	}
         
     | 
| 
      
 136 
     | 
    
         
            +
            	this->result_size = 0;
         
     | 
| 
      
 137 
     | 
    
         
            +
            	this->nfields = -1;
         
     | 
| 
       107 
138 
     | 
    
         
             
            	this->pgresult = NULL;
         
     | 
| 
       108 
139 
     | 
    
         
             
            }
         
     | 
| 
       109 
140 
     | 
    
         | 
| 
      
 141 
     | 
    
         
            +
            static void
         
     | 
| 
      
 142 
     | 
    
         
            +
            pgresult_gc_free( t_pg_result *this )
         
     | 
| 
      
 143 
     | 
    
         
            +
            {
         
     | 
| 
      
 144 
     | 
    
         
            +
            	pgresult_clear( this );
         
     | 
| 
      
 145 
     | 
    
         
            +
            	xfree(this);
         
     | 
| 
      
 146 
     | 
    
         
            +
            }
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
       110 
148 
     | 
    
         
             
            static size_t
         
     | 
| 
       111 
149 
     | 
    
         
             
            pgresult_memsize( t_pg_result *this )
         
     | 
| 
       112 
150 
     | 
    
         
             
            {
         
     | 
| 
      
 151 
     | 
    
         
            +
            	/* Ideally the memory 'this' is pointing to should be taken into account as well.
         
     | 
| 
      
 152 
     | 
    
         
            +
            	 * However we don't want to store two memory sizes in t_pg_result just for reporting by ObjectSpace.memsize_of.
         
     | 
| 
      
 153 
     | 
    
         
            +
            	 */
         
     | 
| 
       113 
154 
     | 
    
         
             
            	return this->result_size;
         
     | 
| 
       114 
155 
     | 
    
         
             
            }
         
     | 
| 
       115 
156 
     | 
    
         | 
| 
      
 157 
     | 
    
         
            +
            static const rb_data_type_t pgresult_type = {
         
     | 
| 
      
 158 
     | 
    
         
            +
            	"pg",
         
     | 
| 
      
 159 
     | 
    
         
            +
            	{
         
     | 
| 
      
 160 
     | 
    
         
            +
            		(void (*)(void*))pgresult_gc_mark,
         
     | 
| 
      
 161 
     | 
    
         
            +
            		(void (*)(void*))pgresult_gc_free,
         
     | 
| 
      
 162 
     | 
    
         
            +
            		(size_t (*)(const void *))pgresult_memsize,
         
     | 
| 
      
 163 
     | 
    
         
            +
            	},
         
     | 
| 
      
 164 
     | 
    
         
            +
            	0, 0,
         
     | 
| 
      
 165 
     | 
    
         
            +
            #ifdef RUBY_TYPED_FREE_IMMEDIATELY
         
     | 
| 
      
 166 
     | 
    
         
            +
            	RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
      
 167 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 168 
     | 
    
         
            +
            };
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
            /* Needed by sequel_pg gem, do not delete */
         
     | 
| 
      
 171 
     | 
    
         
            +
            int pg_get_result_enc_idx(VALUE self)
         
     | 
| 
      
 172 
     | 
    
         
            +
            {
         
     | 
| 
      
 173 
     | 
    
         
            +
            	return pgresult_get_this(self)->enc_idx;
         
     | 
| 
      
 174 
     | 
    
         
            +
            }
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
       116 
176 
     | 
    
         
             
            /*
         
     | 
| 
       117 
177 
     | 
    
         
             
             * Global functions
         
     | 
| 
       118 
178 
     | 
    
         
             
             */
         
     | 
| 
         @@ -124,12 +184,10 @@ static VALUE 
     | 
|
| 
       124 
184 
     | 
    
         
             
            pg_new_result2(PGresult *result, VALUE rb_pgconn)
         
     | 
| 
       125 
185 
     | 
    
         
             
            {
         
     | 
| 
       126 
186 
     | 
    
         
             
            	int nfields = result ? PQnfields(result) : 0;
         
     | 
| 
       127 
     | 
    
         
            -
            	VALUE self 
     | 
| 
      
 187 
     | 
    
         
            +
            	VALUE self;
         
     | 
| 
       128 
188 
     | 
    
         
             
            	t_pg_result *this;
         
     | 
| 
       129 
189 
     | 
    
         | 
| 
       130 
190 
     | 
    
         
             
            	this = (t_pg_result *)xmalloc(sizeof(*this) +  sizeof(*this->fnames) * nfields);
         
     | 
| 
       131 
     | 
    
         
            -
            	RTYPEDDATA_DATA(self) = this;
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
191 
     | 
    
         
             
            	this->pgresult = result;
         
     | 
| 
       134 
192 
     | 
    
         
             
            	this->connection = rb_pgconn;
         
     | 
| 
       135 
193 
     | 
    
         
             
            	this->typemap = pg_typemap_all_strings;
         
     | 
| 
         @@ -137,18 +195,21 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn) 
     | 
|
| 
       137 
195 
     | 
    
         
             
            	this->nfields = -1;
         
     | 
| 
       138 
196 
     | 
    
         
             
            	this->tuple_hash = Qnil;
         
     | 
| 
       139 
197 
     | 
    
         
             
            	this->field_map = Qnil;
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
            	 
     | 
| 
      
 198 
     | 
    
         
            +
            	this->flags = 0;
         
     | 
| 
      
 199 
     | 
    
         
            +
            	self = TypedData_Wrap_Struct(rb_cPGresult, &pgresult_type, this);
         
     | 
| 
       142 
200 
     | 
    
         | 
| 
       143 
201 
     | 
    
         
             
            	if( result ){
         
     | 
| 
       144 
202 
     | 
    
         
             
            		t_pg_connection *p_conn = pg_get_connection(rb_pgconn);
         
     | 
| 
       145 
203 
     | 
    
         
             
            		VALUE typemap = p_conn->type_map_for_results;
         
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
204 
     | 
    
         
             
            		/* Type check is done when assigned to PG::Connection. */
         
     | 
| 
       148 
205 
     | 
    
         
             
            		t_typemap *p_typemap = DATA_PTR(typemap);
         
     | 
| 
       149 
206 
     | 
    
         | 
| 
      
 207 
     | 
    
         
            +
            		this->enc_idx = p_conn->enc_idx;
         
     | 
| 
       150 
208 
     | 
    
         
             
            		this->typemap = p_typemap->funcs.fit_to_result( typemap, self );
         
     | 
| 
       151 
209 
     | 
    
         
             
            		this->p_typemap = DATA_PTR( this->typemap );
         
     | 
| 
      
 210 
     | 
    
         
            +
            		this->flags = p_conn->flags;
         
     | 
| 
      
 211 
     | 
    
         
            +
            	} else {
         
     | 
| 
      
 212 
     | 
    
         
            +
            		this->enc_idx = rb_locale_encindex();
         
     | 
| 
       152 
213 
     | 
    
         
             
            	}
         
     | 
| 
       153 
214 
     | 
    
         | 
| 
       154 
215 
     | 
    
         
             
            	return self;
         
     | 
| 
         @@ -159,22 +220,38 @@ pg_new_result(PGresult *result, VALUE rb_pgconn) 
     | 
|
| 
       159 
220 
     | 
    
         
             
            {
         
     | 
| 
       160 
221 
     | 
    
         
             
            	VALUE self = pg_new_result2(result, rb_pgconn);
         
     | 
| 
       161 
222 
     | 
    
         
             
            	t_pg_result *this = pgresult_get_this(self);
         
     | 
| 
       162 
     | 
    
         
            -
            	t_pg_connection *p_conn = pg_get_connection(rb_pgconn);
         
     | 
| 
       163 
223 
     | 
    
         | 
| 
       164 
224 
     | 
    
         
             
            	this->autoclear = 0;
         
     | 
| 
       165 
225 
     | 
    
         | 
| 
       166 
     | 
    
         
            -
            	 
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
      
 226 
     | 
    
         
            +
            	/* Estimate size of underlying pgresult memory storage and account to ruby GC.
         
     | 
| 
      
 227 
     | 
    
         
            +
            	 * There's no need to adjust the GC for xmalloc'ed memory, but libpq is using libc malloc() ruby doesn't know about.
         
     | 
| 
      
 228 
     | 
    
         
            +
            	 */
         
     | 
| 
      
 229 
     | 
    
         
            +
            	/* TODO: If someday most systems provide PQresultMemorySize(), it's questionable to store result_size in t_pg_result in addition to the value already stored in PGresult.
         
     | 
| 
      
 230 
     | 
    
         
            +
            	 * For now the memory savings don't justify the ifdefs necessary to support both cases.
         
     | 
| 
      
 231 
     | 
    
         
            +
            	 */
         
     | 
| 
      
 232 
     | 
    
         
            +
            	this->result_size = pgresult_approx_size(result);
         
     | 
| 
       169 
233 
     | 
    
         | 
| 
       170 
234 
     | 
    
         
             
            #ifdef HAVE_RB_GC_ADJUST_MEMORY_USAGE
         
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
      
 235 
     | 
    
         
            +
            	rb_gc_adjust_memory_usage(this->result_size);
         
     | 
| 
       172 
236 
     | 
    
         
             
            #endif
         
     | 
| 
       173 
     | 
    
         
            -
            	}
         
     | 
| 
       174 
237 
     | 
    
         | 
| 
       175 
238 
     | 
    
         
             
            	return self;
         
     | 
| 
       176 
239 
     | 
    
         
             
            }
         
     | 
| 
       177 
240 
     | 
    
         | 
| 
      
 241 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 242 
     | 
    
         
            +
            pg_copy_result(t_pg_result *this)
         
     | 
| 
      
 243 
     | 
    
         
            +
            {
         
     | 
| 
      
 244 
     | 
    
         
            +
            	int nfields = this->nfields == -1 ? (this->pgresult ? PQnfields(this->pgresult) : 0) : this->nfields;
         
     | 
| 
      
 245 
     | 
    
         
            +
            	size_t len = sizeof(*this) +  sizeof(*this->fnames) * nfields;
         
     | 
| 
      
 246 
     | 
    
         
            +
            	t_pg_result *copy;
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
            	copy = (t_pg_result *)xmalloc(len);
         
     | 
| 
      
 249 
     | 
    
         
            +
            	memcpy(copy, this, len);
         
     | 
| 
      
 250 
     | 
    
         
            +
            	this->result_size = 0;
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
            	return TypedData_Wrap_Struct(rb_cPGresult, &pgresult_type, copy);
         
     | 
| 
      
 253 
     | 
    
         
            +
            }
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
       178 
255 
     | 
    
         
             
            VALUE
         
     | 
| 
       179 
256 
     | 
    
         
             
            pg_new_result_autoclear(PGresult *result, VALUE rb_pgconn)
         
     | 
| 
       180 
257 
     | 
    
         
             
            {
         
     | 
| 
         @@ -229,7 +306,7 @@ pg_result_check( VALUE self ) 
     | 
|
| 
       229 
306 
     | 
    
         
             
            		}
         
     | 
| 
       230 
307 
     | 
    
         
             
            	}
         
     | 
| 
       231 
308 
     | 
    
         | 
| 
       232 
     | 
    
         
            -
            	PG_ENCODING_SET_NOCHECK( error,  
     | 
| 
      
 309 
     | 
    
         
            +
            	PG_ENCODING_SET_NOCHECK( error, this->enc_idx );
         
     | 
| 
       233 
310 
     | 
    
         | 
| 
       234 
311 
     | 
    
         
             
            	sqlstate = PQresultErrorField( this->pgresult, PG_DIAG_SQLSTATE );
         
     | 
| 
       235 
312 
     | 
    
         
             
            	klass = lookup_error_class( sqlstate );
         
     | 
| 
         @@ -261,8 +338,7 @@ pg_result_check( VALUE self ) 
     | 
|
| 
       261 
338 
     | 
    
         
             
             * Special care must be taken when PG::Tuple objects are used.
         
     | 
| 
       262 
339 
     | 
    
         
             
             * In this case #clear must not be called unless all PG::Tuple objects of this result are fully materialized.
         
     | 
| 
       263 
340 
     | 
    
         
             
             *
         
     | 
| 
       264 
     | 
    
         
            -
             * If PG::Result#autoclear? is true then the result is marked as cleared
         
     | 
| 
       265 
     | 
    
         
            -
             * and the underlying C struct will be cleared automatically by libpq.
         
     | 
| 
      
 341 
     | 
    
         
            +
             * If PG::Result#autoclear? is +true+ then the result is only marked as cleared but clearing the underlying C struct will happen when the callback returns.
         
     | 
| 
       266 
342 
     | 
    
         
             
             *
         
     | 
| 
       267 
343 
     | 
    
         
             
             */
         
     | 
| 
       268 
344 
     | 
    
         
             
            VALUE
         
     | 
| 
         @@ -290,8 +366,10 @@ pgresult_cleared_p( VALUE self ) 
     | 
|
| 
       290 
366 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       291 
367 
     | 
    
         
             
             *    res.autoclear?      -> boolean
         
     | 
| 
       292 
368 
     | 
    
         
             
             *
         
     | 
| 
       293 
     | 
    
         
            -
             * Returns +true+ if the underlying C struct will be cleared  
     | 
| 
       294 
     | 
    
         
            -
             *  
     | 
| 
      
 369 
     | 
    
         
            +
             * Returns +true+ if the underlying C struct will be cleared at the end of a callback.
         
     | 
| 
      
 370 
     | 
    
         
            +
             * This applies only to Result objects received by the block to PG::Cinnection#set_notice_receiver .
         
     | 
| 
      
 371 
     | 
    
         
            +
             *
         
     | 
| 
      
 372 
     | 
    
         
            +
             * All other Result objects are automatically cleared by the GC when the object is no longer in use or manually by PG::Result#clear .
         
     | 
| 
       295 
373 
     | 
    
         
             
             *
         
     | 
| 
       296 
374 
     | 
    
         
             
             */
         
     | 
| 
       297 
375 
     | 
    
         
             
            VALUE
         
     | 
| 
         @@ -305,37 +383,6 @@ pgresult_autoclear_p( VALUE self ) 
     | 
|
| 
       305 
383 
     | 
    
         
             
             * DATA pointer functions
         
     | 
| 
       306 
384 
     | 
    
         
             
             */
         
     | 
| 
       307 
385 
     | 
    
         | 
| 
       308 
     | 
    
         
            -
            /*
         
     | 
| 
       309 
     | 
    
         
            -
             * GC Mark function
         
     | 
| 
       310 
     | 
    
         
            -
             */
         
     | 
| 
       311 
     | 
    
         
            -
            static void
         
     | 
| 
       312 
     | 
    
         
            -
            pgresult_gc_mark( t_pg_result *this )
         
     | 
| 
       313 
     | 
    
         
            -
            {
         
     | 
| 
       314 
     | 
    
         
            -
            	int i;
         
     | 
| 
       315 
     | 
    
         
            -
             
     | 
| 
       316 
     | 
    
         
            -
            	if( !this ) return;
         
     | 
| 
       317 
     | 
    
         
            -
            	rb_gc_mark( this->connection );
         
     | 
| 
       318 
     | 
    
         
            -
            	rb_gc_mark( this->typemap );
         
     | 
| 
       319 
     | 
    
         
            -
            	rb_gc_mark( this->tuple_hash );
         
     | 
| 
       320 
     | 
    
         
            -
            	rb_gc_mark( this->field_map );
         
     | 
| 
       321 
     | 
    
         
            -
             
     | 
| 
       322 
     | 
    
         
            -
            	for( i=0; i < this->nfields; i++ ){
         
     | 
| 
       323 
     | 
    
         
            -
            		rb_gc_mark( this->fnames[i] );
         
     | 
| 
       324 
     | 
    
         
            -
            	}
         
     | 
| 
       325 
     | 
    
         
            -
            }
         
     | 
| 
       326 
     | 
    
         
            -
             
     | 
| 
       327 
     | 
    
         
            -
            /*
         
     | 
| 
       328 
     | 
    
         
            -
             * GC Free function
         
     | 
| 
       329 
     | 
    
         
            -
             */
         
     | 
| 
       330 
     | 
    
         
            -
            static void
         
     | 
| 
       331 
     | 
    
         
            -
            pgresult_gc_free( t_pg_result *this )
         
     | 
| 
       332 
     | 
    
         
            -
            {
         
     | 
| 
       333 
     | 
    
         
            -
            	if( !this ) return;
         
     | 
| 
       334 
     | 
    
         
            -
            	pgresult_clear( this );
         
     | 
| 
       335 
     | 
    
         
            -
             
     | 
| 
       336 
     | 
    
         
            -
            	xfree(this);
         
     | 
| 
       337 
     | 
    
         
            -
            }
         
     | 
| 
       338 
     | 
    
         
            -
             
     | 
| 
       339 
386 
     | 
    
         
             
            /*
         
     | 
| 
       340 
387 
     | 
    
         
             
             * Fetch the PG::Result object data pointer and check it's
         
     | 
| 
       341 
388 
     | 
    
         
             
             * PGresult data pointer for sanity.
         
     | 
| 
         @@ -365,32 +412,30 @@ pgresult_get(VALUE self) 
     | 
|
| 
       365 
412 
     | 
    
         
             
            	return this->pgresult;
         
     | 
| 
       366 
413 
     | 
    
         
             
            }
         
     | 
| 
       367 
414 
     | 
    
         | 
| 
       368 
     | 
    
         
            -
             
     | 
| 
       369 
     | 
    
         
            -
            static const rb_data_type_t pgresult_type = {
         
     | 
| 
       370 
     | 
    
         
            -
            	"pg",
         
     | 
| 
       371 
     | 
    
         
            -
            	{
         
     | 
| 
       372 
     | 
    
         
            -
            		(void (*)(void*))pgresult_gc_mark,
         
     | 
| 
       373 
     | 
    
         
            -
            		(void (*)(void*))pgresult_gc_free,
         
     | 
| 
       374 
     | 
    
         
            -
            		(size_t (*)(const void *))pgresult_memsize,
         
     | 
| 
       375 
     | 
    
         
            -
            	},
         
     | 
| 
       376 
     | 
    
         
            -
            	0, 0,
         
     | 
| 
       377 
     | 
    
         
            -
            #ifdef RUBY_TYPED_FREE_IMMEDIATELY
         
     | 
| 
       378 
     | 
    
         
            -
            	RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
       379 
     | 
    
         
            -
            #endif
         
     | 
| 
       380 
     | 
    
         
            -
            };
         
     | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
       382 
     | 
    
         
            -
            /*
         
     | 
| 
       383 
     | 
    
         
            -
             * Document-method: allocate
         
     | 
| 
       384 
     | 
    
         
            -
             *
         
     | 
| 
       385 
     | 
    
         
            -
             * call-seq:
         
     | 
| 
       386 
     | 
    
         
            -
             *   PG::Result.allocate -> result
         
     | 
| 
       387 
     | 
    
         
            -
             */
         
     | 
| 
       388 
     | 
    
         
            -
            static VALUE
         
     | 
| 
       389 
     | 
    
         
            -
            pgresult_s_allocate( VALUE klass )
         
     | 
| 
      
 415 
     | 
    
         
            +
            static VALUE pg_cstr_to_sym(char *cstr, unsigned int flags, int enc_idx)
         
     | 
| 
       390 
416 
     | 
    
         
             
            {
         
     | 
| 
       391 
     | 
    
         
            -
            	VALUE  
     | 
| 
       392 
     | 
    
         
            -
             
     | 
| 
       393 
     | 
    
         
            -
            	 
     | 
| 
      
 417 
     | 
    
         
            +
            	VALUE fname;
         
     | 
| 
      
 418 
     | 
    
         
            +
            #ifdef TRUFFLERUBY
         
     | 
| 
      
 419 
     | 
    
         
            +
            	if( flags & (PG_RESULT_FIELD_NAMES_SYMBOL | PG_RESULT_FIELD_NAMES_STATIC_SYMBOL) ){
         
     | 
| 
      
 420 
     | 
    
         
            +
            #else
         
     | 
| 
      
 421 
     | 
    
         
            +
            	if( flags & PG_RESULT_FIELD_NAMES_SYMBOL ){
         
     | 
| 
      
 422 
     | 
    
         
            +
            		rb_encoding *enc = rb_enc_from_index(enc_idx);
         
     | 
| 
      
 423 
     | 
    
         
            +
            		fname = rb_check_symbol_cstr(cstr, strlen(cstr), enc);
         
     | 
| 
      
 424 
     | 
    
         
            +
            		if( fname == Qnil ){
         
     | 
| 
      
 425 
     | 
    
         
            +
            			fname = rb_str_new2(cstr);
         
     | 
| 
      
 426 
     | 
    
         
            +
            			PG_ENCODING_SET_NOCHECK(fname, enc_idx);
         
     | 
| 
      
 427 
     | 
    
         
            +
            			fname = rb_str_intern(fname);
         
     | 
| 
      
 428 
     | 
    
         
            +
            		}
         
     | 
| 
      
 429 
     | 
    
         
            +
            	} else if( flags & PG_RESULT_FIELD_NAMES_STATIC_SYMBOL ){
         
     | 
| 
      
 430 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 431 
     | 
    
         
            +
            		rb_encoding *enc = rb_enc_from_index(enc_idx);
         
     | 
| 
      
 432 
     | 
    
         
            +
            		fname = ID2SYM(rb_intern3(cstr, strlen(cstr), enc));
         
     | 
| 
      
 433 
     | 
    
         
            +
            	} else {
         
     | 
| 
      
 434 
     | 
    
         
            +
            		fname = rb_str_new2(cstr);
         
     | 
| 
      
 435 
     | 
    
         
            +
            		PG_ENCODING_SET_NOCHECK(fname, enc_idx);
         
     | 
| 
      
 436 
     | 
    
         
            +
            		fname = rb_obj_freeze(fname);
         
     | 
| 
      
 437 
     | 
    
         
            +
            	}
         
     | 
| 
      
 438 
     | 
    
         
            +
            	return fname;
         
     | 
| 
       394 
439 
     | 
    
         
             
            }
         
     | 
| 
       395 
440 
     | 
    
         | 
| 
       396 
441 
     | 
    
         
             
            static void pgresult_init_fnames(VALUE self)
         
     | 
| 
         @@ -402,12 +447,9 @@ static void pgresult_init_fnames(VALUE self) 
     | 
|
| 
       402 
447 
     | 
    
         
             
            		int nfields = PQnfields(this->pgresult);
         
     | 
| 
       403 
448 
     | 
    
         | 
| 
       404 
449 
     | 
    
         
             
            		for( i=0; i<nfields; i++ ){
         
     | 
| 
       405 
     | 
    
         
            -
            			 
     | 
| 
       406 
     | 
    
         
            -
            			 
     | 
| 
       407 
     | 
    
         
            -
            			this->fnames[i] = rb_obj_freeze(fname);
         
     | 
| 
      
 450 
     | 
    
         
            +
            			char *cfname = PQfname(this->pgresult, i);
         
     | 
| 
      
 451 
     | 
    
         
            +
            			this->fnames[i] = pg_cstr_to_sym(cfname, this->flags, this->enc_idx);
         
     | 
| 
       408 
452 
     | 
    
         
             
            			this->nfields = i + 1;
         
     | 
| 
       409 
     | 
    
         
            -
             
     | 
| 
       410 
     | 
    
         
            -
            			RB_GC_GUARD(fname);
         
     | 
| 
       411 
453 
     | 
    
         
             
            		}
         
     | 
| 
       412 
454 
     | 
    
         
             
            		this->nfields = nfields;
         
     | 
| 
       413 
455 
     | 
    
         
             
            	}
         
     | 
| 
         @@ -470,8 +512,9 @@ pgresult_result_status(VALUE self) 
     | 
|
| 
       470 
512 
     | 
    
         
             
            static VALUE
         
     | 
| 
       471 
513 
     | 
    
         
             
            pgresult_res_status(VALUE self, VALUE status)
         
     | 
| 
       472 
514 
     | 
    
         
             
            {
         
     | 
| 
       473 
     | 
    
         
            -
            	 
     | 
| 
       474 
     | 
    
         
            -
            	 
     | 
| 
      
 515 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this_safe(self);
         
     | 
| 
      
 516 
     | 
    
         
            +
            	VALUE ret = rb_str_new2(PQresStatus(NUM2INT(status)));
         
     | 
| 
      
 517 
     | 
    
         
            +
            	PG_ENCODING_SET_NOCHECK(ret, this->enc_idx);
         
     | 
| 
       475 
518 
     | 
    
         
             
            	return ret;
         
     | 
| 
       476 
519 
     | 
    
         
             
            }
         
     | 
| 
       477 
520 
     | 
    
         | 
| 
         @@ -484,11 +527,40 @@ pgresult_res_status(VALUE self, VALUE status) 
     | 
|
| 
       484 
527 
     | 
    
         
             
            static VALUE
         
     | 
| 
       485 
528 
     | 
    
         
             
            pgresult_error_message(VALUE self)
         
     | 
| 
       486 
529 
     | 
    
         
             
            {
         
     | 
| 
       487 
     | 
    
         
            -
            	 
     | 
| 
       488 
     | 
    
         
            -
            	 
     | 
| 
      
 530 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this_safe(self);
         
     | 
| 
      
 531 
     | 
    
         
            +
            	VALUE ret = rb_str_new2(PQresultErrorMessage(this->pgresult));
         
     | 
| 
      
 532 
     | 
    
         
            +
            	PG_ENCODING_SET_NOCHECK(ret, this->enc_idx);
         
     | 
| 
       489 
533 
     | 
    
         
             
            	return ret;
         
     | 
| 
       490 
534 
     | 
    
         
             
            }
         
     | 
| 
       491 
535 
     | 
    
         | 
| 
      
 536 
     | 
    
         
            +
            #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
         
     | 
| 
      
 537 
     | 
    
         
            +
            /*
         
     | 
| 
      
 538 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 539 
     | 
    
         
            +
             *    res.verbose_error_message( verbosity, show_context ) -> String
         
     | 
| 
      
 540 
     | 
    
         
            +
             *
         
     | 
| 
      
 541 
     | 
    
         
            +
             * Returns a reformatted version of the error message associated with a PGresult object.
         
     | 
| 
      
 542 
     | 
    
         
            +
             *
         
     | 
| 
      
 543 
     | 
    
         
            +
             * Available since PostgreSQL-9.6
         
     | 
| 
      
 544 
     | 
    
         
            +
             */
         
     | 
| 
      
 545 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 546 
     | 
    
         
            +
            pgresult_verbose_error_message(VALUE self, VALUE verbosity, VALUE show_context)
         
     | 
| 
      
 547 
     | 
    
         
            +
            {
         
     | 
| 
      
 548 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this_safe(self);
         
     | 
| 
      
 549 
     | 
    
         
            +
            	VALUE ret;
         
     | 
| 
      
 550 
     | 
    
         
            +
            	char *c_str;
         
     | 
| 
      
 551 
     | 
    
         
            +
             
     | 
| 
      
 552 
     | 
    
         
            +
            	c_str = PQresultVerboseErrorMessage(this->pgresult, NUM2INT(verbosity), NUM2INT(show_context));
         
     | 
| 
      
 553 
     | 
    
         
            +
            	if(!c_str)
         
     | 
| 
      
 554 
     | 
    
         
            +
            		rb_raise(rb_eNoMemError, "insufficient memory to format error message");
         
     | 
| 
      
 555 
     | 
    
         
            +
             
     | 
| 
      
 556 
     | 
    
         
            +
            	ret = rb_str_new2(c_str);
         
     | 
| 
      
 557 
     | 
    
         
            +
            	PQfreemem(c_str);
         
     | 
| 
      
 558 
     | 
    
         
            +
            	PG_ENCODING_SET_NOCHECK(ret, this->enc_idx);
         
     | 
| 
      
 559 
     | 
    
         
            +
             
     | 
| 
      
 560 
     | 
    
         
            +
            	return ret;
         
     | 
| 
      
 561 
     | 
    
         
            +
            }
         
     | 
| 
      
 562 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 563 
     | 
    
         
            +
             
     | 
| 
       492 
564 
     | 
    
         
             
            /*
         
     | 
| 
       493 
565 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       494 
566 
     | 
    
         
             
             *    res.error_field(fieldcode) -> String
         
     | 
| 
         @@ -538,14 +610,14 @@ pgresult_error_message(VALUE self) 
     | 
|
| 
       538 
610 
     | 
    
         
             
            static VALUE
         
     | 
| 
       539 
611 
     | 
    
         
             
            pgresult_error_field(VALUE self, VALUE field)
         
     | 
| 
       540 
612 
     | 
    
         
             
            {
         
     | 
| 
       541 
     | 
    
         
            -
            	 
     | 
| 
      
 613 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this_safe(self);
         
     | 
| 
       542 
614 
     | 
    
         
             
            	int fieldcode = NUM2INT( field );
         
     | 
| 
       543 
     | 
    
         
            -
            	char * fieldstr = PQresultErrorField(  
     | 
| 
      
 615 
     | 
    
         
            +
            	char * fieldstr = PQresultErrorField( this->pgresult, fieldcode );
         
     | 
| 
       544 
616 
     | 
    
         
             
            	VALUE ret = Qnil;
         
     | 
| 
       545 
617 
     | 
    
         | 
| 
       546 
618 
     | 
    
         
             
            	if ( fieldstr ) {
         
     | 
| 
       547 
     | 
    
         
            -
            		ret =  
     | 
| 
       548 
     | 
    
         
            -
            		PG_ENCODING_SET_NOCHECK( ret,  
     | 
| 
      
 619 
     | 
    
         
            +
            		ret = rb_str_new2( fieldstr );
         
     | 
| 
      
 620 
     | 
    
         
            +
            		PG_ENCODING_SET_NOCHECK( ret, this->enc_idx );
         
     | 
| 
       549 
621 
     | 
    
         
             
            	}
         
     | 
| 
       550 
622 
     | 
    
         | 
| 
       551 
623 
     | 
    
         
             
            	return ret;
         
     | 
| 
         @@ -583,24 +655,25 @@ pgresult_nfields(VALUE self) 
     | 
|
| 
       583 
655 
     | 
    
         | 
| 
       584 
656 
     | 
    
         
             
            /*
         
     | 
| 
       585 
657 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       586 
     | 
    
         
            -
             *    res.fname( index ) -> String
         
     | 
| 
      
 658 
     | 
    
         
            +
             *    res.fname( index ) -> String or Symbol
         
     | 
| 
       587 
659 
     | 
    
         
             
             *
         
     | 
| 
       588 
660 
     | 
    
         
             
             * Returns the name of the column corresponding to _index_.
         
     | 
| 
      
 661 
     | 
    
         
            +
             * Depending on #field_name_type= it's a String or Symbol.
         
     | 
| 
      
 662 
     | 
    
         
            +
             *
         
     | 
| 
       589 
663 
     | 
    
         
             
             */
         
     | 
| 
       590 
664 
     | 
    
         
             
            static VALUE
         
     | 
| 
       591 
665 
     | 
    
         
             
            pgresult_fname(VALUE self, VALUE index)
         
     | 
| 
       592 
666 
     | 
    
         
             
            {
         
     | 
| 
       593 
     | 
    
         
            -
            	 
     | 
| 
       594 
     | 
    
         
            -
            	PGresult *result = pgresult_get(self);
         
     | 
| 
      
 667 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this_safe(self);
         
     | 
| 
       595 
668 
     | 
    
         
             
            	int i = NUM2INT(index);
         
     | 
| 
      
 669 
     | 
    
         
            +
            	char *cfname;
         
     | 
| 
       596 
670 
     | 
    
         | 
| 
       597 
     | 
    
         
            -
            	if (i < 0 || i >= PQnfields( 
     | 
| 
      
 671 
     | 
    
         
            +
            	if (i < 0 || i >= PQnfields(this->pgresult)) {
         
     | 
| 
       598 
672 
     | 
    
         
             
            		rb_raise(rb_eArgError,"invalid field number %d", i);
         
     | 
| 
       599 
673 
     | 
    
         
             
            	}
         
     | 
| 
       600 
674 
     | 
    
         | 
| 
       601 
     | 
    
         
            -
            	 
     | 
| 
       602 
     | 
    
         
            -
            	 
     | 
| 
       603 
     | 
    
         
            -
            	return rb_obj_freeze(fname);
         
     | 
| 
      
 675 
     | 
    
         
            +
            	cfname = PQfname(this->pgresult, i);
         
     | 
| 
      
 676 
     | 
    
         
            +
            	return pg_cstr_to_sym(cfname, this->flags, this->enc_idx);
         
     | 
| 
       604 
677 
     | 
    
         
             
            }
         
     | 
| 
       605 
678 
     | 
    
         | 
| 
       606 
679 
     | 
    
         
             
            /*
         
     | 
| 
         @@ -899,8 +972,9 @@ pgresult_paramtype(VALUE self, VALUE param_number) 
     | 
|
| 
       899 
972 
     | 
    
         
             
            static VALUE
         
     | 
| 
       900 
973 
     | 
    
         
             
            pgresult_cmd_status(VALUE self)
         
     | 
| 
       901 
974 
     | 
    
         
             
            {
         
     | 
| 
       902 
     | 
    
         
            -
            	 
     | 
| 
       903 
     | 
    
         
            -
            	 
     | 
| 
      
 975 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this_safe(self);
         
     | 
| 
      
 976 
     | 
    
         
            +
            	VALUE ret = rb_str_new2(PQcmdStatus(this->pgresult));
         
     | 
| 
      
 977 
     | 
    
         
            +
            	PG_ENCODING_SET_NOCHECK(ret, this->enc_idx);
         
     | 
| 
       904 
978 
     | 
    
         
             
            	return ret;
         
     | 
| 
       905 
979 
     | 
    
         
             
            }
         
     | 
| 
       906 
980 
     | 
    
         | 
| 
         @@ -1100,8 +1174,12 @@ static VALUE 
     | 
|
| 
       1100 
1174 
     | 
    
         
             
            pgresult_field_values( VALUE self, VALUE field )
         
     | 
| 
       1101 
1175 
     | 
    
         
             
            {
         
     | 
| 
       1102 
1176 
     | 
    
         
             
            	PGresult *result = pgresult_get( self );
         
     | 
| 
       1103 
     | 
    
         
            -
            	const char *fieldname 
     | 
| 
       1104 
     | 
    
         
            -
            	int fnum 
     | 
| 
      
 1177 
     | 
    
         
            +
            	const char *fieldname;
         
     | 
| 
      
 1178 
     | 
    
         
            +
            	int fnum;
         
     | 
| 
      
 1179 
     | 
    
         
            +
             
     | 
| 
      
 1180 
     | 
    
         
            +
            	if( RB_TYPE_P(field, T_SYMBOL) ) field = rb_sym_to_s( field );
         
     | 
| 
      
 1181 
     | 
    
         
            +
            	fieldname = StringValueCStr( field );
         
     | 
| 
      
 1182 
     | 
    
         
            +
            	fnum = PQfnumber( result, fieldname );
         
     | 
| 
       1105 
1183 
     | 
    
         | 
| 
       1106 
1184 
     | 
    
         
             
            	if ( fnum < 0 )
         
     | 
| 
       1107 
1185 
     | 
    
         
             
            		rb_raise( rb_eIndexError, "no such field '%s' in result", fieldname );
         
     | 
| 
         @@ -1144,6 +1222,25 @@ pgresult_tuple_values(VALUE self, VALUE index) 
     | 
|
| 
       1144 
1222 
     | 
    
         
             
            	}
         
     | 
| 
       1145 
1223 
     | 
    
         
             
            }
         
     | 
| 
       1146 
1224 
     | 
    
         | 
| 
      
 1225 
     | 
    
         
            +
            static void ensure_init_for_tuple(VALUE self)
         
     | 
| 
      
 1226 
     | 
    
         
            +
            {
         
     | 
| 
      
 1227 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this_safe(self);
         
     | 
| 
      
 1228 
     | 
    
         
            +
             
     | 
| 
      
 1229 
     | 
    
         
            +
            	if( this->field_map == Qnil ){
         
     | 
| 
      
 1230 
     | 
    
         
            +
            		int i;
         
     | 
| 
      
 1231 
     | 
    
         
            +
            		VALUE field_map = rb_hash_new();
         
     | 
| 
      
 1232 
     | 
    
         
            +
             
     | 
| 
      
 1233 
     | 
    
         
            +
            		if( this->nfields == -1 )
         
     | 
| 
      
 1234 
     | 
    
         
            +
            			pgresult_init_fnames( self );
         
     | 
| 
      
 1235 
     | 
    
         
            +
             
     | 
| 
      
 1236 
     | 
    
         
            +
            		for( i = 0; i < this->nfields; i++ ){
         
     | 
| 
      
 1237 
     | 
    
         
            +
            			rb_hash_aset(field_map, this->fnames[i], INT2FIX(i));
         
     | 
| 
      
 1238 
     | 
    
         
            +
            		}
         
     | 
| 
      
 1239 
     | 
    
         
            +
            		rb_obj_freeze(field_map);
         
     | 
| 
      
 1240 
     | 
    
         
            +
            		this->field_map = field_map;
         
     | 
| 
      
 1241 
     | 
    
         
            +
            	}
         
     | 
| 
      
 1242 
     | 
    
         
            +
            }
         
     | 
| 
      
 1243 
     | 
    
         
            +
             
     | 
| 
       1147 
1244 
     | 
    
         
             
            /*
         
     | 
| 
       1148 
1245 
     | 
    
         
             
             *  call-seq:
         
     | 
| 
       1149 
1246 
     | 
    
         
             
             *     res.tuple( n )   -> PG::Tuple
         
     | 
| 
         @@ -1164,19 +1261,7 @@ pgresult_tuple(VALUE self, VALUE index) 
     | 
|
| 
       1164 
1261 
     | 
    
         
             
            	if ( tuple_num < 0 || tuple_num >= num_tuples )
         
     | 
| 
       1165 
1262 
     | 
    
         
             
            		rb_raise( rb_eIndexError, "Index %d is out of range", tuple_num );
         
     | 
| 
       1166 
1263 
     | 
    
         | 
| 
       1167 
     | 
    
         
            -
            	 
     | 
| 
       1168 
     | 
    
         
            -
            		int i;
         
     | 
| 
       1169 
     | 
    
         
            -
            		VALUE field_map = rb_hash_new();
         
     | 
| 
       1170 
     | 
    
         
            -
             
     | 
| 
       1171 
     | 
    
         
            -
            		if( this->nfields == -1 )
         
     | 
| 
       1172 
     | 
    
         
            -
            			pgresult_init_fnames( self );
         
     | 
| 
       1173 
     | 
    
         
            -
             
     | 
| 
       1174 
     | 
    
         
            -
            		for( i = 0; i < this->nfields; i++ ){
         
     | 
| 
       1175 
     | 
    
         
            -
            			rb_hash_aset(field_map, this->fnames[i], INT2FIX(i));
         
     | 
| 
       1176 
     | 
    
         
            -
            		}
         
     | 
| 
       1177 
     | 
    
         
            -
            		rb_obj_freeze(field_map);
         
     | 
| 
       1178 
     | 
    
         
            -
            		this->field_map = field_map;
         
     | 
| 
       1179 
     | 
    
         
            -
            	}
         
     | 
| 
      
 1264 
     | 
    
         
            +
            	ensure_init_for_tuple(self);
         
     | 
| 
       1180 
1265 
     | 
    
         | 
| 
       1181 
1266 
     | 
    
         
             
              return pg_tuple_new(self, tuple_num);
         
     | 
| 
       1182 
1267 
     | 
    
         
             
            }
         
     | 
| 
         @@ -1208,7 +1293,7 @@ pgresult_each(VALUE self) 
     | 
|
| 
       1208 
1293 
     | 
    
         
             
             * call-seq:
         
     | 
| 
       1209 
1294 
     | 
    
         
             
             *    res.fields() -> Array
         
     | 
| 
       1210 
1295 
     | 
    
         
             
             *
         
     | 
| 
       1211 
     | 
    
         
            -
             *  
     | 
| 
      
 1296 
     | 
    
         
            +
             * Depending on #field_name_type= returns an array of strings or symbols representing the names of the fields in the result.
         
     | 
| 
       1212 
1297 
     | 
    
         
             
             */
         
     | 
| 
       1213 
1298 
     | 
    
         
             
            static VALUE
         
     | 
| 
       1214 
1299 
     | 
    
         
             
            pgresult_fields(VALUE self)
         
     | 
| 
         @@ -1307,11 +1392,17 @@ yield_tuple(VALUE self, int ntuples, int nfields) 
     | 
|
| 
       1307 
1392 
     | 
    
         
             
            {
         
     | 
| 
       1308 
1393 
     | 
    
         
             
            	int tuple_num;
         
     | 
| 
       1309 
1394 
     | 
    
         
             
            	t_pg_result *this = pgresult_get_this(self);
         
     | 
| 
       1310 
     | 
    
         
            -
            	VALUE  
     | 
| 
      
 1395 
     | 
    
         
            +
            	VALUE copy;
         
     | 
| 
       1311 
1396 
     | 
    
         
             
            	UNUSED(nfields);
         
     | 
| 
       1312 
1397 
     | 
    
         | 
| 
      
 1398 
     | 
    
         
            +
            	/* make a copy of the base result, that is bound to the PG::Tuple */
         
     | 
| 
      
 1399 
     | 
    
         
            +
            	copy = pg_copy_result(this);
         
     | 
| 
      
 1400 
     | 
    
         
            +
            	/* The copy is now owner of the PGresult and is responsible to PQclear it.
         
     | 
| 
      
 1401 
     | 
    
         
            +
            	 * We clear the pgresult here, so that it's not double freed on error within yield. */
         
     | 
| 
      
 1402 
     | 
    
         
            +
            	this->pgresult = NULL;
         
     | 
| 
      
 1403 
     | 
    
         
            +
             
     | 
| 
       1313 
1404 
     | 
    
         
             
            	for(tuple_num = 0; tuple_num < ntuples; tuple_num++) {
         
     | 
| 
       1314 
     | 
    
         
            -
            		VALUE tuple = pgresult_tuple( 
     | 
| 
      
 1405 
     | 
    
         
            +
            		VALUE tuple = pgresult_tuple(copy, INT2FIX(tuple_num));
         
     | 
| 
       1315 
1406 
     | 
    
         
             
            		rb_yield( tuple );
         
     | 
| 
       1316 
1407 
     | 
    
         
             
            	}
         
     | 
| 
       1317 
1408 
     | 
    
         
             
            }
         
     | 
| 
         @@ -1392,8 +1483,6 @@ pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int)) 
     | 
|
| 
       1392 
1483 
     | 
    
         
             
             *     # do something with each received row of the second query
         
     | 
| 
       1393 
1484 
     | 
    
         
             
             *   end
         
     | 
| 
       1394 
1485 
     | 
    
         
             
             *   conn.get_result  # => nil   (no more results)
         
     | 
| 
       1395 
     | 
    
         
            -
             *
         
     | 
| 
       1396 
     | 
    
         
            -
             * Available since PostgreSQL-9.2
         
     | 
| 
       1397 
1486 
     | 
    
         
             
             */
         
     | 
| 
       1398 
1487 
     | 
    
         
             
            static VALUE
         
     | 
| 
       1399 
1488 
     | 
    
         
             
            pgresult_stream_each(VALUE self)
         
     | 
| 
         @@ -1410,8 +1499,6 @@ pgresult_stream_each(VALUE self) 
     | 
|
| 
       1410 
1499 
     | 
    
         
             
             *
         
     | 
| 
       1411 
1500 
     | 
    
         
             
             * This method works equally to #stream_each , but yields an Array of
         
     | 
| 
       1412 
1501 
     | 
    
         
             
             * values.
         
     | 
| 
       1413 
     | 
    
         
            -
             *
         
     | 
| 
       1414 
     | 
    
         
            -
             * Available since PostgreSQL-9.2
         
     | 
| 
       1415 
1502 
     | 
    
         
             
             */
         
     | 
| 
       1416 
1503 
     | 
    
         
             
            static VALUE
         
     | 
| 
       1417 
1504 
     | 
    
         
             
            pgresult_stream_each_row(VALUE self)
         
     | 
| 
         @@ -1426,21 +1513,81 @@ pgresult_stream_each_row(VALUE self) 
     | 
|
| 
       1426 
1513 
     | 
    
         
             
             * Yields each row of the result set in single row mode.
         
     | 
| 
       1427 
1514 
     | 
    
         
             
             *
         
     | 
| 
       1428 
1515 
     | 
    
         
             
             * This method works equally to #stream_each , but yields a PG::Tuple object.
         
     | 
| 
       1429 
     | 
    
         
            -
             *
         
     | 
| 
       1430 
     | 
    
         
            -
             * Available since PostgreSQL-9.2
         
     | 
| 
       1431 
1516 
     | 
    
         
             
             */
         
     | 
| 
       1432 
1517 
     | 
    
         
             
            static VALUE
         
     | 
| 
       1433 
1518 
     | 
    
         
             
            pgresult_stream_each_tuple(VALUE self)
         
     | 
| 
       1434 
1519 
     | 
    
         
             
            {
         
     | 
| 
      
 1520 
     | 
    
         
            +
            	/* allocate VALUEs that are shared between all streamed tuples */
         
     | 
| 
      
 1521 
     | 
    
         
            +
            	ensure_init_for_tuple(self);
         
     | 
| 
      
 1522 
     | 
    
         
            +
             
     | 
| 
       1435 
1523 
     | 
    
         
             
            	return pgresult_stream_any(self, yield_tuple);
         
     | 
| 
       1436 
1524 
     | 
    
         
             
            }
         
     | 
| 
       1437 
1525 
     | 
    
         | 
| 
      
 1526 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1527 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1528 
     | 
    
         
            +
             *    res.field_name_type = Symbol
         
     | 
| 
      
 1529 
     | 
    
         
            +
             *
         
     | 
| 
      
 1530 
     | 
    
         
            +
             * Set type of field names specific to this result.
         
     | 
| 
      
 1531 
     | 
    
         
            +
             * It can be set to one of:
         
     | 
| 
      
 1532 
     | 
    
         
            +
             * * +:string+ to use String based field names
         
     | 
| 
      
 1533 
     | 
    
         
            +
             * * +:symbol+ to use Symbol based field names
         
     | 
| 
      
 1534 
     | 
    
         
            +
             * * +:static_symbol+ to use pinned Symbol (can not be garbage collected) - Don't use this, it will probably removed in future.
         
     | 
| 
      
 1535 
     | 
    
         
            +
             *
         
     | 
| 
      
 1536 
     | 
    
         
            +
             * The default is retrieved from PG::Connection#field_name_type , which defaults to +:string+ .
         
     | 
| 
      
 1537 
     | 
    
         
            +
             *
         
     | 
| 
      
 1538 
     | 
    
         
            +
             * This setting affects several result methods:
         
     | 
| 
      
 1539 
     | 
    
         
            +
             * * keys of Hash returned by #[] , #each and #stream_each
         
     | 
| 
      
 1540 
     | 
    
         
            +
             * * #fields
         
     | 
| 
      
 1541 
     | 
    
         
            +
             * * #fname
         
     | 
| 
      
 1542 
     | 
    
         
            +
             * * field names used by #tuple and #stream_each_tuple
         
     | 
| 
      
 1543 
     | 
    
         
            +
             *
         
     | 
| 
      
 1544 
     | 
    
         
            +
             * The type of field names can only be changed before any of the affected methods have been called.
         
     | 
| 
      
 1545 
     | 
    
         
            +
             *
         
     | 
| 
      
 1546 
     | 
    
         
            +
             */
         
     | 
| 
      
 1547 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1548 
     | 
    
         
            +
            pgresult_field_name_type_set(VALUE self, VALUE sym)
         
     | 
| 
      
 1549 
     | 
    
         
            +
            {
         
     | 
| 
      
 1550 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this(self);
         
     | 
| 
      
 1551 
     | 
    
         
            +
            	if( this->nfields != -1 ) rb_raise(rb_eArgError, "field names are already materialized");
         
     | 
| 
      
 1552 
     | 
    
         
            +
             
     | 
| 
      
 1553 
     | 
    
         
            +
            	this->flags &= ~PG_RESULT_FIELD_NAMES_MASK;
         
     | 
| 
      
 1554 
     | 
    
         
            +
            	if( sym == sym_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_SYMBOL;
         
     | 
| 
      
 1555 
     | 
    
         
            +
            	else if ( sym == sym_static_symbol ) this->flags |= PG_RESULT_FIELD_NAMES_STATIC_SYMBOL;
         
     | 
| 
      
 1556 
     | 
    
         
            +
            	else if ( sym == sym_string );
         
     | 
| 
      
 1557 
     | 
    
         
            +
            	else rb_raise(rb_eArgError, "invalid argument %+"PRIsVALUE, sym);
         
     | 
| 
      
 1558 
     | 
    
         
            +
             
     | 
| 
      
 1559 
     | 
    
         
            +
            	return sym;
         
     | 
| 
      
 1560 
     | 
    
         
            +
            }
         
     | 
| 
      
 1561 
     | 
    
         
            +
             
     | 
| 
      
 1562 
     | 
    
         
            +
            /*
         
     | 
| 
      
 1563 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 1564 
     | 
    
         
            +
             *    res.field_name_type -> Symbol
         
     | 
| 
      
 1565 
     | 
    
         
            +
             *
         
     | 
| 
      
 1566 
     | 
    
         
            +
             * Get type of field names.
         
     | 
| 
      
 1567 
     | 
    
         
            +
             *
         
     | 
| 
      
 1568 
     | 
    
         
            +
             * See description at #field_name_type=
         
     | 
| 
      
 1569 
     | 
    
         
            +
             */
         
     | 
| 
      
 1570 
     | 
    
         
            +
            static VALUE
         
     | 
| 
      
 1571 
     | 
    
         
            +
            pgresult_field_name_type_get(VALUE self)
         
     | 
| 
      
 1572 
     | 
    
         
            +
            {
         
     | 
| 
      
 1573 
     | 
    
         
            +
            	t_pg_result *this = pgresult_get_this(self);
         
     | 
| 
      
 1574 
     | 
    
         
            +
            	if( this->flags & PG_RESULT_FIELD_NAMES_SYMBOL ){
         
     | 
| 
      
 1575 
     | 
    
         
            +
            		return sym_symbol;
         
     | 
| 
      
 1576 
     | 
    
         
            +
            	} else if( this->flags & PG_RESULT_FIELD_NAMES_STATIC_SYMBOL ){
         
     | 
| 
      
 1577 
     | 
    
         
            +
            		return sym_static_symbol;
         
     | 
| 
      
 1578 
     | 
    
         
            +
            	} else {
         
     | 
| 
      
 1579 
     | 
    
         
            +
            		return sym_string;
         
     | 
| 
      
 1580 
     | 
    
         
            +
            	}
         
     | 
| 
      
 1581 
     | 
    
         
            +
            }
         
     | 
| 
       1438 
1582 
     | 
    
         | 
| 
       1439 
1583 
     | 
    
         
             
            void
         
     | 
| 
       1440 
1584 
     | 
    
         
             
            init_pg_result()
         
     | 
| 
       1441 
1585 
     | 
    
         
             
            {
         
     | 
| 
       1442 
     | 
    
         
            -
            	 
     | 
| 
       1443 
     | 
    
         
            -
            	 
     | 
| 
      
 1586 
     | 
    
         
            +
            	sym_string = ID2SYM(rb_intern("string"));
         
     | 
| 
      
 1587 
     | 
    
         
            +
            	sym_symbol = ID2SYM(rb_intern("symbol"));
         
     | 
| 
      
 1588 
     | 
    
         
            +
            	sym_static_symbol = ID2SYM(rb_intern("static_symbol"));
         
     | 
| 
      
 1589 
     | 
    
         
            +
             
     | 
| 
      
 1590 
     | 
    
         
            +
            	rb_cPGresult = rb_define_class_under( rb_mPG, "Result", rb_cData );
         
     | 
| 
       1444 
1591 
     | 
    
         
             
            	rb_include_module(rb_cPGresult, rb_mEnumerable);
         
     | 
| 
       1445 
1592 
     | 
    
         
             
            	rb_include_module(rb_cPGresult, rb_mPGconstants);
         
     | 
| 
       1446 
1593 
     | 
    
         | 
| 
         @@ -1449,6 +1596,10 @@ init_pg_result() 
     | 
|
| 
       1449 
1596 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "res_status", pgresult_res_status, 1);
         
     | 
| 
       1450 
1597 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "error_message", pgresult_error_message, 0);
         
     | 
| 
       1451 
1598 
     | 
    
         
             
            	rb_define_alias( rb_cPGresult, "result_error_message", "error_message");
         
     | 
| 
      
 1599 
     | 
    
         
            +
            #ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
         
     | 
| 
      
 1600 
     | 
    
         
            +
            	rb_define_method(rb_cPGresult, "verbose_error_message", pgresult_verbose_error_message, 2);
         
     | 
| 
      
 1601 
     | 
    
         
            +
            	rb_define_alias( rb_cPGresult, "result_verbose_error_message", "verbose_error_message");
         
     | 
| 
      
 1602 
     | 
    
         
            +
            #endif
         
     | 
| 
       1452 
1603 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "error_field", pgresult_error_field, 1);
         
     | 
| 
       1453 
1604 
     | 
    
         
             
            	rb_define_alias( rb_cPGresult, "result_error_field", "error_field" );
         
     | 
| 
       1454 
1605 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "clear", pg_result_clear, 0);
         
     | 
| 
         @@ -1496,6 +1647,7 @@ init_pg_result() 
     | 
|
| 
       1496 
1647 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "stream_each", pgresult_stream_each, 0);
         
     | 
| 
       1497 
1648 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "stream_each_row", pgresult_stream_each_row, 0);
         
     | 
| 
       1498 
1649 
     | 
    
         
             
            	rb_define_method(rb_cPGresult, "stream_each_tuple", pgresult_stream_each_tuple, 0);
         
     | 
| 
       1499 
     | 
    
         
            -
            }
         
     | 
| 
       1500 
     | 
    
         
            -
             
     | 
| 
       1501 
1650 
     | 
    
         | 
| 
      
 1651 
     | 
    
         
            +
            	rb_define_method(rb_cPGresult, "field_name_type=", pgresult_field_name_type_set, 1 );
         
     | 
| 
      
 1652 
     | 
    
         
            +
            	rb_define_method(rb_cPGresult, "field_name_type", pgresult_field_name_type_get, 0 );
         
     | 
| 
      
 1653 
     | 
    
         
            +
            }
         
     |