pg 0.19.0 → 1.1.0
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data/ChangeLog +218 -1
- data/History.rdoc +106 -0
- data/Manifest.txt +5 -18
- data/README.rdoc +15 -5
- data/Rakefile +8 -9
- data/Rakefile.cross +19 -22
- data/ext/errorcodes.def +17 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +11 -1
- data/ext/extconf.rb +14 -32
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -39
- data/ext/pg.c +19 -48
- data/ext/pg.h +46 -81
- data/ext/pg_binary_decoder.c +69 -6
- data/ext/pg_coder.c +53 -4
- data/ext/pg_connection.c +401 -253
- data/ext/pg_copy_coder.c +10 -5
- data/ext/pg_result.c +359 -131
- data/ext/pg_text_decoder.c +597 -37
- data/ext/pg_text_encoder.c +6 -7
- data/ext/pg_tuple.c +541 -0
- data/ext/pg_type_map.c +14 -7
- data/ext/util.c +6 -6
- data/ext/util.h +2 -2
- data/lib/pg/basic_type_mapping.rb +40 -7
- data/lib/pg/binary_decoder.rb +22 -0
- data/lib/pg/coder.rb +1 -1
- data/lib/pg/connection.rb +27 -7
- data/lib/pg/constants.rb +1 -1
- data/lib/pg/exceptions.rb +1 -1
- data/lib/pg/result.rb +6 -5
- data/lib/pg/text_decoder.rb +19 -23
- data/lib/pg/text_encoder.rb +36 -2
- data/lib/pg/tuple.rb +30 -0
- data/lib/pg/type_map_by_column.rb +1 -1
- data/lib/pg.rb +21 -11
- data/spec/helpers.rb +47 -19
- data/spec/pg/basic_type_mapping_spec.rb +230 -27
- data/spec/pg/connection_spec.rb +402 -275
- data/spec/pg/connection_sync_spec.rb +41 -0
- data/spec/pg/result_spec.rb +59 -17
- data/spec/pg/tuple_spec.rb +280 -0
- data/spec/pg/type_map_by_class_spec.rb +2 -2
- data/spec/pg/type_map_by_column_spec.rb +1 -1
- data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
- data/spec/pg/type_map_by_oid_spec.rb +1 -1
- data/spec/pg/type_map_in_ruby_spec.rb +1 -1
- data/spec/pg/type_map_spec.rb +1 -1
- data/spec/pg/type_spec.rb +184 -12
- data/spec/pg_spec.rb +2 -2
- data.tar.gz.sig +0 -0
- metadata +47 -53
- metadata.gz.sig +0 -0
- data/sample/array_insert.rb +0 -20
- data/sample/async_api.rb +0 -106
- data/sample/async_copyto.rb +0 -39
- data/sample/async_mixed.rb +0 -56
- data/sample/check_conn.rb +0 -21
- data/sample/copyfrom.rb +0 -81
- data/sample/copyto.rb +0 -19
- data/sample/cursor.rb +0 -21
- data/sample/disk_usage_report.rb +0 -186
- data/sample/issue-119.rb +0 -94
- data/sample/losample.rb +0 -69
- data/sample/minimal-testcase.rb +0 -17
- data/sample/notify_wait.rb +0 -72
- data/sample/pg_statistics.rb +0 -294
- data/sample/replication_monitor.rb +0 -231
- data/sample/test_binary_values.rb +0 -33
- data/sample/wal_shipper.rb +0 -434
- data/sample/warehouse_partitions.rb +0 -320
data/ext/errorcodes.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# errcodes.txt
|
3
3
|
# PostgreSQL error codes
|
4
4
|
#
|
5
|
-
# Copyright (c) 2003-
|
5
|
+
# Copyright (c) 2003-2017, PostgreSQL Global Development Group
|
6
6
|
#
|
7
7
|
# This list serves as the basis for generating source files containing error
|
8
8
|
# codes. It is kept in a common format to make sure all these source files have
|
@@ -15,6 +15,9 @@
|
|
15
15
|
# src/pl/plpgsql/src/plerrcodes.h
|
16
16
|
# a list of PL/pgSQL condition names and their SQLSTATE codes
|
17
17
|
#
|
18
|
+
# src/pl/tcl/pltclerrcodes.h
|
19
|
+
# the same, for PL/Tcl
|
20
|
+
#
|
18
21
|
# doc/src/sgml/errcodes-list.sgml
|
19
22
|
# a SGML table of error codes for inclusion in the documentation
|
20
23
|
#
|
@@ -185,6 +188,7 @@ Section: Class 22 - Data Exception
|
|
185
188
|
22004 E ERRCODE_NULL_VALUE_NOT_ALLOWED null_value_not_allowed
|
186
189
|
22002 E ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER null_value_no_indicator_parameter
|
187
190
|
22003 E ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE numeric_value_out_of_range
|
191
|
+
2200H E ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED sequence_generator_limit_exceeded
|
188
192
|
22026 E ERRCODE_STRING_DATA_LENGTH_MISMATCH string_data_length_mismatch
|
189
193
|
22001 E ERRCODE_STRING_DATA_RIGHT_TRUNCATION string_data_right_truncation
|
190
194
|
22011 E ERRCODE_SUBSTRING_ERROR substring_error
|
@@ -229,6 +233,7 @@ Section: Class 25 - Invalid Transaction State
|
|
229
233
|
25007 E ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED schema_and_data_statement_mixing_not_supported
|
230
234
|
25P01 E ERRCODE_NO_ACTIVE_SQL_TRANSACTION no_active_sql_transaction
|
231
235
|
25P02 E ERRCODE_IN_FAILED_SQL_TRANSACTION in_failed_sql_transaction
|
236
|
+
25P03 E ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT idle_in_transaction_session_timeout
|
232
237
|
|
233
238
|
Section: Class 26 - Invalid SQL Statement Name
|
234
239
|
|
@@ -322,6 +327,7 @@ Section: Class 42 - Syntax Error or Access Rule Violation
|
|
322
327
|
42P21 E ERRCODE_COLLATION_MISMATCH collation_mismatch
|
323
328
|
42P22 E ERRCODE_INDETERMINATE_COLLATION indeterminate_collation
|
324
329
|
42809 E ERRCODE_WRONG_OBJECT_TYPE wrong_object_type
|
330
|
+
428C9 E ERRCODE_GENERATED_ALWAYS generated_always
|
325
331
|
|
326
332
|
# Note: for ERRCODE purposes, we divide namable objects into these categories:
|
327
333
|
# databases, schemas, prepared statements, cursors, tables, columns,
|
@@ -413,6 +419,10 @@ Section: Class 58 - System Error (errors external to PostgreSQL itself)
|
|
413
419
|
58P01 E ERRCODE_UNDEFINED_FILE undefined_file
|
414
420
|
58P02 E ERRCODE_DUPLICATE_FILE duplicate_file
|
415
421
|
|
422
|
+
Section: Class 72 - Snapshot Failure
|
423
|
+
# (class borrowed from Oracle)
|
424
|
+
72000 E ERRCODE_SNAPSHOT_TOO_OLD snapshot_too_old
|
425
|
+
|
416
426
|
Section: Class F0 - Configuration File Error
|
417
427
|
|
418
428
|
# (PostgreSQL-specific error class)
|
data/ext/extconf.rb
CHANGED
@@ -60,48 +60,30 @@ abort "Can't find the PostgreSQL client library (libpq)" unless
|
|
60
60
|
have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
|
61
61
|
have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
|
62
62
|
|
63
|
+
if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
64
|
+
# Work around: https://sourceware.org/bugzilla/show_bug.cgi?id=22504
|
65
|
+
checking_for "workaround gcc version with link issue" do
|
66
|
+
`#{RbConfig::MAKEFILE_CONFIG['CC']} --version`.chomp =~ /\s(\d+)\.\d+\.\d+(\s|$)/ &&
|
67
|
+
$1.to_i >= 6 &&
|
68
|
+
have_library(':libpq.lib') # Prefer linking to libpq.lib over libpq.dll if available
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
63
72
|
# optional headers/functions
|
64
|
-
have_func '
|
73
|
+
have_func 'PQsetSingleRowMode' or
|
65
74
|
abort "Your PostgreSQL is too old. Either install an older version " +
|
66
|
-
"of this gem or upgrade your database."
|
67
|
-
have_func 'PQisthreadsafe'
|
68
|
-
have_func 'PQprepare'
|
69
|
-
have_func 'PQexecParams'
|
70
|
-
have_func 'PQescapeString'
|
71
|
-
have_func 'PQescapeStringConn'
|
72
|
-
have_func 'PQescapeLiteral'
|
73
|
-
have_func 'PQescapeIdentifier'
|
74
|
-
have_func 'PQgetCancel'
|
75
|
-
have_func 'lo_create'
|
76
|
-
have_func 'pg_encoding_to_char'
|
77
|
-
have_func 'pg_char_to_encoding'
|
78
|
-
have_func 'PQsetClientEncoding'
|
79
|
-
have_func 'PQlibVersion'
|
80
|
-
have_func 'PQping'
|
81
|
-
have_func 'PQsetSingleRowMode'
|
75
|
+
"of this gem or upgrade your database to at least PostgreSQL-9.2."
|
82
76
|
have_func 'PQconninfo'
|
83
77
|
have_func 'PQsslAttribute'
|
78
|
+
have_func 'PQencryptPasswordConn'
|
79
|
+
have_func 'timegm'
|
80
|
+
have_func 'rb_gc_adjust_memory_usage'
|
84
81
|
|
85
|
-
have_func 'rb_encdb_alias'
|
86
|
-
have_func 'rb_enc_alias'
|
87
|
-
have_func 'rb_thread_call_without_gvl'
|
88
|
-
have_func 'rb_thread_call_with_gvl'
|
89
|
-
have_func 'rb_thread_fd_select'
|
90
|
-
have_func 'rb_w32_wrap_io_handle'
|
91
|
-
have_func 'rb_str_modify_expand'
|
92
|
-
have_func 'rb_hash_dup'
|
93
|
-
|
94
|
-
have_const 'PGRES_COPY_BOTH', 'libpq-fe.h'
|
95
|
-
have_const 'PGRES_SINGLE_TUPLE', 'libpq-fe.h'
|
96
82
|
have_const 'PG_DIAG_TABLE_NAME', 'libpq-fe.h'
|
97
83
|
|
98
|
-
$defs.push( "-DHAVE_ST_NOTIFY_EXTRA" ) if
|
99
|
-
have_struct_member 'struct pgNotify', 'extra', 'libpq-fe.h'
|
100
|
-
|
101
84
|
# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
|
102
85
|
have_header 'unistd.h'
|
103
86
|
have_header 'inttypes.h'
|
104
|
-
have_header 'ruby/st.h' or have_header 'st.h' or abort "pg currently requires the ruby/st.h header"
|
105
87
|
|
106
88
|
checking_for "C99 variable length arrays" do
|
107
89
|
$defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
|
data/ext/gvl_wrappers.c
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
|
6
6
|
#include "pg.h"
|
7
7
|
|
8
|
+
#ifndef HAVE_PQENCRYPTPASSWORDCONN
|
9
|
+
char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm){return NULL;}
|
10
|
+
#endif
|
11
|
+
|
8
12
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
|
9
13
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
|
10
14
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
|
data/ext/gvl_wrappers.h
CHANGED
@@ -15,14 +15,7 @@
|
|
15
15
|
#ifndef __gvl_wrappers_h
|
16
16
|
#define __gvl_wrappers_h
|
17
17
|
|
18
|
-
#
|
19
|
-
extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
|
20
|
-
#endif
|
21
|
-
|
22
|
-
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
23
|
-
extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
24
|
-
rb_unblock_function_t *ubf, void *data2);
|
25
|
-
#endif
|
18
|
+
#include <ruby/thread.h>
|
26
19
|
|
27
20
|
#define DEFINE_PARAM_LIST1(type, name) \
|
28
21
|
name,
|
@@ -53,21 +46,14 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
53
46
|
return NULL; \
|
54
47
|
}
|
55
48
|
|
56
|
-
#
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
}
|
65
|
-
#else
|
66
|
-
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
67
|
-
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
68
|
-
return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
69
|
-
}
|
70
|
-
#endif
|
49
|
+
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
50
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
51
|
+
struct gvl_wrapper_##name##_params params = { \
|
52
|
+
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
|
53
|
+
}; \
|
54
|
+
rb_thread_call_without_gvl(gvl_##name##_skeleton, ¶ms, RUBY_UBF_IO, 0); \
|
55
|
+
when_non_void( return params.retval; ) \
|
56
|
+
}
|
71
57
|
|
72
58
|
#define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
73
59
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
|
@@ -80,21 +66,14 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
80
66
|
return NULL; \
|
81
67
|
}
|
82
68
|
|
83
|
-
#
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}
|
92
|
-
#else
|
93
|
-
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
94
|
-
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
95
|
-
return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
96
|
-
}
|
97
|
-
#endif
|
69
|
+
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
70
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
71
|
+
struct gvl_wrapper_##name##_params params = { \
|
72
|
+
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
|
73
|
+
}; \
|
74
|
+
rb_thread_call_with_gvl(gvl_##name##_skeleton, ¶ms); \
|
75
|
+
when_non_void( return params.retval; ) \
|
76
|
+
}
|
98
77
|
|
99
78
|
#define GVL_TYPE_VOID(string)
|
100
79
|
#define GVL_TYPE_NONVOID(string) string
|
@@ -200,6 +179,11 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
200
179
|
|
201
180
|
#define FOR_EACH_PARAM_OF_PQisBusy(param)
|
202
181
|
|
182
|
+
#define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
|
183
|
+
param(PGconn *, conn) \
|
184
|
+
param(const char *, passwd) \
|
185
|
+
param(const char *, user)
|
186
|
+
|
203
187
|
#define FOR_EACH_PARAM_OF_PQcancel(param) \
|
204
188
|
param(PGcancel *, cancel) \
|
205
189
|
param(char *, errbuf)
|
@@ -231,9 +215,9 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
231
215
|
function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
|
232
216
|
function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
|
233
217
|
function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
218
|
+
function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
|
234
219
|
function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
|
235
220
|
|
236
|
-
|
237
221
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
|
238
222
|
|
239
223
|
|
data/ext/pg.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg.c - Toplevel extension
|
3
|
-
* $Id: pg.c,v
|
3
|
+
* $Id: pg.c,v 0d4acc8a0bc5 2018/08/05 09:07:58 lars $
|
4
4
|
*
|
5
5
|
* Author/s:
|
6
6
|
*
|
@@ -48,6 +48,7 @@
|
|
48
48
|
|
49
49
|
#include "pg.h"
|
50
50
|
|
51
|
+
int pg_skip_deprecation_warning;
|
51
52
|
VALUE rb_mPG;
|
52
53
|
VALUE rb_mPGconstants;
|
53
54
|
|
@@ -69,7 +70,6 @@ VALUE rb_mPGconstants;
|
|
69
70
|
* M17n functions
|
70
71
|
*/
|
71
72
|
|
72
|
-
#ifdef M17N_SUPPORTED
|
73
73
|
/**
|
74
74
|
* The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
|
75
75
|
*/
|
@@ -144,7 +144,7 @@ pg_find_or_create_johab(void)
|
|
144
144
|
|
145
145
|
enc_index = rb_define_dummy_encoding(aliases[0]);
|
146
146
|
for (i = 1; i < sizeof(aliases)/sizeof(aliases[0]); ++i) {
|
147
|
-
|
147
|
+
rb_enc_alias(aliases[i], aliases[0]);
|
148
148
|
}
|
149
149
|
return rb_enc_from_index(enc_index);
|
150
150
|
}
|
@@ -229,8 +229,6 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
|
|
229
229
|
return encname;
|
230
230
|
}
|
231
231
|
|
232
|
-
#endif /* M17N_SUPPORTED */
|
233
|
-
|
234
232
|
|
235
233
|
/*
|
236
234
|
* Ensures that the given string has enough capacity to take expand_len
|
@@ -260,45 +258,26 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
|
|
260
258
|
* rb_str_set_len( string, current_out - RSTRING_PTR(string) );
|
261
259
|
*
|
262
260
|
*/
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
|
273
|
-
curr_ptr = RSTRING_PTR(str) + curr_len;
|
274
|
-
}
|
275
|
-
if( end_ptr )
|
276
|
-
*end_ptr = RSTRING_PTR(str) + rb_str_capacity( str );
|
277
|
-
return curr_ptr;
|
278
|
-
}
|
279
|
-
#else
|
280
|
-
/* Use the more portable version */
|
281
|
-
char *
|
282
|
-
pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
|
283
|
-
{
|
284
|
-
long curr_len = curr_ptr - RSTRING_PTR(str);
|
285
|
-
long curr_capa = RSTRING_LEN( str );
|
286
|
-
if( curr_capa < curr_len + expand_len ){
|
287
|
-
rb_str_resize( str, (curr_len + expand_len) * 2 - curr_capa );
|
288
|
-
curr_ptr = RSTRING_PTR(str) + curr_len;
|
289
|
-
}
|
290
|
-
if( end_ptr )
|
291
|
-
*end_ptr = RSTRING_PTR(str) + RSTRING_LEN(str);
|
292
|
-
return curr_ptr;
|
261
|
+
char *
|
262
|
+
pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
|
263
|
+
{
|
264
|
+
long curr_len = curr_ptr - RSTRING_PTR(str);
|
265
|
+
long curr_capa = rb_str_capacity( str );
|
266
|
+
if( curr_capa < curr_len + expand_len ){
|
267
|
+
rb_str_set_len( str, curr_len );
|
268
|
+
rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
|
269
|
+
curr_ptr = RSTRING_PTR(str) + curr_len;
|
293
270
|
}
|
294
|
-
|
271
|
+
if( end_ptr )
|
272
|
+
*end_ptr = RSTRING_PTR(str) + rb_str_capacity( str );
|
273
|
+
return curr_ptr;
|
274
|
+
}
|
295
275
|
|
296
276
|
|
297
277
|
/**************************************************************************
|
298
278
|
* Module Methods
|
299
279
|
**************************************************************************/
|
300
280
|
|
301
|
-
#ifdef HAVE_PQLIBVERSION
|
302
281
|
/*
|
303
282
|
* call-seq:
|
304
283
|
* PG.library_version -> Integer
|
@@ -316,7 +295,6 @@ pg_s_library_version(VALUE self)
|
|
316
295
|
UNUSED( self );
|
317
296
|
return INT2NUM(PQlibVersion());
|
318
297
|
}
|
319
|
-
#endif
|
320
298
|
|
321
299
|
|
322
300
|
/*
|
@@ -404,15 +382,15 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
|
|
404
382
|
void
|
405
383
|
Init_pg_ext()
|
406
384
|
{
|
385
|
+
pg_skip_deprecation_warning = RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']"));
|
386
|
+
|
407
387
|
rb_mPG = rb_define_module( "PG" );
|
408
388
|
rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" );
|
409
389
|
|
410
390
|
/*************************
|
411
391
|
* PG module methods
|
412
392
|
*************************/
|
413
|
-
#ifdef HAVE_PQLIBVERSION
|
414
393
|
rb_define_singleton_method( rb_mPG, "library_version", pg_s_library_version, 0 );
|
415
|
-
#endif
|
416
394
|
rb_define_singleton_method( rb_mPG, "isthreadsafe", pg_s_threadsafe_p, 0 );
|
417
395
|
SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
|
418
396
|
SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
|
@@ -478,7 +456,6 @@ Init_pg_ext()
|
|
478
456
|
/* Verbose error verbosity level (#set_error_verbosity) */
|
479
457
|
rb_define_const(rb_mPGconstants, "PQERRORS_VERBOSE", INT2FIX(PQERRORS_VERBOSE));
|
480
458
|
|
481
|
-
#ifdef HAVE_PQPING
|
482
459
|
/****** PG::Connection CLASS CONSTANTS: Check Server Status ******/
|
483
460
|
|
484
461
|
/* Server is accepting connections. */
|
@@ -489,7 +466,6 @@ Init_pg_ext()
|
|
489
466
|
rb_define_const(rb_mPGconstants, "PQPING_NO_RESPONSE", INT2FIX(PQPING_NO_RESPONSE));
|
490
467
|
/* Connection not attempted (bad params). */
|
491
468
|
rb_define_const(rb_mPGconstants, "PQPING_NO_ATTEMPT", INT2FIX(PQPING_NO_ATTEMPT));
|
492
|
-
#endif
|
493
469
|
|
494
470
|
/****** PG::Connection CLASS CONSTANTS: Large Objects ******/
|
495
471
|
|
@@ -524,13 +500,9 @@ Init_pg_ext()
|
|
524
500
|
/* #result_status constant: A fatal error occurred. */
|
525
501
|
rb_define_const(rb_mPGconstants, "PGRES_FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR));
|
526
502
|
/* #result_status constant: Copy In/Out data transfer in progress. */
|
527
|
-
#ifdef HAVE_CONST_PGRES_COPY_BOTH
|
528
503
|
rb_define_const(rb_mPGconstants, "PGRES_COPY_BOTH", INT2FIX(PGRES_COPY_BOTH));
|
529
|
-
#endif
|
530
504
|
/* #result_status constant: Single tuple from larger resultset. */
|
531
|
-
#ifdef HAVE_CONST_PGRES_SINGLE_TUPLE
|
532
505
|
rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
|
533
|
-
#endif
|
534
506
|
|
535
507
|
/****** Result CONSTANTS: result error field codes ******/
|
536
508
|
|
@@ -642,9 +614,7 @@ Init_pg_ext()
|
|
642
614
|
/* Add the constants to the toplevel namespace */
|
643
615
|
rb_include_module( rb_mPG, rb_mPGconstants );
|
644
616
|
|
645
|
-
#ifdef M17N_SUPPORTED
|
646
617
|
enc_pg2ruby = st_init_numtable();
|
647
|
-
#endif
|
648
618
|
|
649
619
|
/* Initialize the main extension classes */
|
650
620
|
init_pg_connection();
|
@@ -663,5 +633,6 @@ Init_pg_ext()
|
|
663
633
|
init_pg_binary_encoder();
|
664
634
|
init_pg_binary_decoder();
|
665
635
|
init_pg_copycoder();
|
636
|
+
init_pg_tuple();
|
666
637
|
}
|
667
638
|
|
data/ext/pg.h
CHANGED
@@ -18,89 +18,21 @@
|
|
18
18
|
|
19
19
|
/* Ruby headers */
|
20
20
|
#include "ruby.h"
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#elif HAVE_ST_H
|
24
|
-
# include "st.h"
|
25
|
-
#endif
|
21
|
+
#include "ruby/st.h"
|
22
|
+
#include "ruby/encoding.h"
|
26
23
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
extern int rb_encdb_alias(const char *, const char *);
|
32
|
-
# define ENC_ALIAS(name, orig) rb_encdb_alias((name), (orig))
|
33
|
-
# elif HAVE_RB_ENC_ALIAS
|
34
|
-
extern int rb_enc_alias(const char *, const char *);
|
35
|
-
# define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
|
36
|
-
# else
|
37
|
-
extern int rb_enc_alias(const char *alias, const char *orig); /* declaration missing in Ruby 1.9.1 */
|
38
|
-
# define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
|
39
|
-
# endif
|
40
|
-
|
41
|
-
|
42
|
-
# if !defined(ENCODING_SET_INLINED)
|
43
|
-
/* Rubinius doesn't define ENCODING_SET_INLINED, so we fall back to the more
|
44
|
-
* portable version.
|
45
|
-
*/
|
46
|
-
# define PG_ENCODING_SET_NOCHECK(obj,i) \
|
47
|
-
do { \
|
48
|
-
rb_enc_set_index((obj), (i)); \
|
49
|
-
} while(0)
|
50
|
-
# else
|
51
|
-
# define PG_ENCODING_SET_NOCHECK(obj,i) \
|
24
|
+
/* exported by ruby-1.9.3+ but not declared */
|
25
|
+
extern int rb_enc_alias(const char *, const char *);
|
26
|
+
|
27
|
+
#define PG_ENCODING_SET_NOCHECK(obj,i) \
|
52
28
|
do { \
|
53
29
|
if ((i) < ENCODING_INLINE_MAX) \
|
54
30
|
ENCODING_SET_INLINED((obj), (i)); \
|
55
31
|
else \
|
56
32
|
rb_enc_set_index((obj), (i)); \
|
57
33
|
} while(0)
|
58
|
-
# endif
|
59
|
-
|
60
|
-
#else
|
61
|
-
# define PG_ENCODING_SET_NOCHECK(obj,i) /* nothing */
|
62
|
-
#endif
|
63
34
|
|
64
|
-
#
|
65
|
-
# define RUBY_18_COMPAT
|
66
|
-
#endif
|
67
|
-
|
68
|
-
#ifndef RARRAY_LEN
|
69
|
-
# define RARRAY_LEN(x) RARRAY((x))->len
|
70
|
-
#endif /* RARRAY_LEN */
|
71
|
-
|
72
|
-
#ifndef RSTRING_LEN
|
73
|
-
# define RSTRING_LEN(x) RSTRING((x))->len
|
74
|
-
#endif /* RSTRING_LEN */
|
75
|
-
|
76
|
-
#ifndef RSTRING_PTR
|
77
|
-
# define RSTRING_PTR(x) RSTRING((x))->ptr
|
78
|
-
#endif /* RSTRING_PTR */
|
79
|
-
|
80
|
-
#ifndef StringValuePtr
|
81
|
-
# define StringValuePtr(x) STR2CSTR(x)
|
82
|
-
#endif /* StringValuePtr */
|
83
|
-
|
84
|
-
#ifdef RUBY_18_COMPAT
|
85
|
-
# define rb_io_stdio_file GetWriteFile
|
86
|
-
# include "rubyio.h"
|
87
|
-
#else
|
88
|
-
# include "ruby/io.h"
|
89
|
-
#endif
|
90
|
-
|
91
|
-
#ifdef RUBINIUS
|
92
|
-
/* Workaround for wrong FIXNUM_MAX definition */
|
93
|
-
typedef intptr_t native_int;
|
94
|
-
#endif
|
95
|
-
|
96
|
-
#ifndef RETURN_SIZED_ENUMERATOR
|
97
|
-
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) RETURN_ENUMERATOR((obj), (argc), (argv))
|
98
|
-
#endif
|
99
|
-
|
100
|
-
#ifndef HAVE_RB_HASH_DUP
|
101
|
-
/* Rubinius doesn't define rb_hash_dup() */
|
102
|
-
#define rb_hash_dup(tuple) rb_funcall((tuple), rb_intern("dup"), 0)
|
103
|
-
#endif
|
35
|
+
#include "ruby/io.h"
|
104
36
|
|
105
37
|
#ifndef timeradd
|
106
38
|
#define timeradd(a, b, result) \
|
@@ -145,6 +77,10 @@ typedef long suseconds_t;
|
|
145
77
|
#define PG_MAX_COLUMNS 4000
|
146
78
|
#endif
|
147
79
|
|
80
|
+
#ifndef RARRAY_AREF
|
81
|
+
#define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
|
82
|
+
#endif
|
83
|
+
|
148
84
|
/* The data behind each PG::Connection object */
|
149
85
|
typedef struct {
|
150
86
|
PGconn *pgconn;
|
@@ -168,6 +104,11 @@ typedef struct {
|
|
168
104
|
/* Kind of PG::Coder object for casting COPY rows to ruby values */
|
169
105
|
VALUE decoder_for_get_copy_data;
|
170
106
|
|
107
|
+
/* The connection socket, used for rb_wait_for_single_fd() */
|
108
|
+
int socket;
|
109
|
+
|
110
|
+
/* enable/disable guessing size of PGresult's allocated memory */
|
111
|
+
int guess_result_memsize;
|
171
112
|
} t_pg_connection;
|
172
113
|
|
173
114
|
typedef struct pg_coder t_pg_coder;
|
@@ -198,9 +139,15 @@ typedef struct {
|
|
198
139
|
*/
|
199
140
|
int nfields;
|
200
141
|
|
142
|
+
/* Size of PGresult as published to ruby memory management. */
|
143
|
+
ssize_t result_size;
|
144
|
+
|
201
145
|
/* Prefilled tuple Hash with fnames[] as keys. */
|
202
146
|
VALUE tuple_hash;
|
203
147
|
|
148
|
+
/* Hash with fnames[] to field number mapping. */
|
149
|
+
VALUE field_map;
|
150
|
+
|
204
151
|
/* List of field names as frozen String objects.
|
205
152
|
* Only valid if nfields != -1
|
206
153
|
*/
|
@@ -209,7 +156,7 @@ typedef struct {
|
|
209
156
|
|
210
157
|
|
211
158
|
typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *, int);
|
212
|
-
typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, char *, int, int, int, int);
|
159
|
+
typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, const char *, int, int, int, int);
|
213
160
|
typedef VALUE (* t_pg_fit_to_result)(VALUE, VALUE);
|
214
161
|
typedef VALUE (* t_pg_fit_to_query)(VALUE, VALUE);
|
215
162
|
typedef int (* t_pg_fit_to_copy_get)(VALUE);
|
@@ -217,12 +164,23 @@ typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
|
|
217
164
|
typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
|
218
165
|
typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
|
219
166
|
|
167
|
+
#define PG_CODER_TIMESTAMP_DB_UTC 0x0
|
168
|
+
#define PG_CODER_TIMESTAMP_DB_LOCAL 0x1
|
169
|
+
#define PG_CODER_TIMESTAMP_APP_UTC 0x0
|
170
|
+
#define PG_CODER_TIMESTAMP_APP_LOCAL 0x2
|
171
|
+
#define PG_CODER_FORMAT_ERROR_MASK 0xc
|
172
|
+
#define PG_CODER_FORMAT_ERROR_TO_RAISE 0x4
|
173
|
+
#define PG_CODER_FORMAT_ERROR_TO_STRING 0x8
|
174
|
+
#define PG_CODER_FORMAT_ERROR_TO_PARTIAL 0xc
|
175
|
+
|
220
176
|
struct pg_coder {
|
221
177
|
t_pg_coder_enc_func enc_func;
|
222
178
|
t_pg_coder_dec_func dec_func;
|
223
179
|
VALUE coder_obj;
|
224
180
|
Oid oid;
|
225
181
|
int format;
|
182
|
+
/* OR-ed values out of PG_CODER_* */
|
183
|
+
int flags;
|
226
184
|
};
|
227
185
|
|
228
186
|
typedef struct {
|
@@ -259,6 +217,7 @@ typedef struct {
|
|
259
217
|
* Globals
|
260
218
|
**************************************************************************/
|
261
219
|
|
220
|
+
extern int pg_skip_deprecation_warning;
|
262
221
|
extern VALUE rb_mPG;
|
263
222
|
extern VALUE rb_ePGerror;
|
264
223
|
extern VALUE rb_eServerError;
|
@@ -321,9 +280,10 @@ void init_pg_text_encoder _(( void ));
|
|
321
280
|
void init_pg_text_decoder _(( void ));
|
322
281
|
void init_pg_binary_encoder _(( void ));
|
323
282
|
void init_pg_binary_decoder _(( void ));
|
283
|
+
void init_pg_tuple _(( void ));
|
324
284
|
VALUE lookup_error_class _(( const char * ));
|
325
|
-
VALUE pg_bin_dec_bytea _(( t_pg_coder*, char *, int, int, int, int ));
|
326
|
-
VALUE pg_text_dec_string _(( t_pg_coder*, char *, int, int, int, int ));
|
285
|
+
VALUE pg_bin_dec_bytea _(( t_pg_coder*, const char *, int, int, int, int ));
|
286
|
+
VALUE pg_text_dec_string _(( t_pg_coder*, const char *, int, int, int, int ));
|
327
287
|
int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *, int));
|
328
288
|
int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
|
329
289
|
t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
|
@@ -366,6 +326,7 @@ VALUE pg_new_result_autoclear _(( PGresult *, VALUE ));
|
|
366
326
|
PGresult* pgresult_get _(( VALUE ));
|
367
327
|
VALUE pg_result_check _(( VALUE ));
|
368
328
|
VALUE pg_result_clear _(( VALUE ));
|
329
|
+
VALUE pg_tuple_new _(( VALUE, int ));
|
369
330
|
|
370
331
|
/*
|
371
332
|
* Fetch the data pointer for the result object
|
@@ -373,7 +334,7 @@ VALUE pg_result_clear _(( VALUE ));
|
|
373
334
|
static inline t_pg_result *
|
374
335
|
pgresult_get_this( VALUE self )
|
375
336
|
{
|
376
|
-
t_pg_result *this =
|
337
|
+
t_pg_result *this = RTYPEDDATA_DATA(self);
|
377
338
|
|
378
339
|
if( this == NULL )
|
379
340
|
rb_raise(rb_ePGerror, "result has been cleared");
|
@@ -382,14 +343,18 @@ pgresult_get_this( VALUE self )
|
|
382
343
|
}
|
383
344
|
|
384
345
|
|
385
|
-
#ifdef M17N_SUPPORTED
|
386
346
|
rb_encoding * pg_get_pg_encoding_as_rb_encoding _(( int ));
|
387
347
|
rb_encoding * pg_get_pg_encname_as_rb_encoding _(( const char * ));
|
388
348
|
const char * pg_get_rb_encoding_as_pg_encoding _(( rb_encoding * ));
|
389
349
|
rb_encoding *pg_conn_enc_get _(( PGconn * ));
|
390
|
-
#endif /* M17N_SUPPORTED */
|
391
350
|
|
392
351
|
void notice_receiver_proxy(void *arg, const PGresult *result);
|
393
352
|
void notice_processor_proxy(void *arg, const char *message);
|
394
353
|
|
354
|
+
/* reports if `-W' specified and PG_SKIP_DEPRECATION_WARNING environment variable isn't set */
|
355
|
+
#define pg_deprecated(x) \
|
356
|
+
do { \
|
357
|
+
if( !pg_skip_deprecation_warning ) rb_warning x; \
|
358
|
+
} while(0);
|
359
|
+
|
395
360
|
#endif /* end __pg_h */
|