pg 0.13.2 → 0.14.0.pre.351
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/ChangeLog +178 -2
- data/History.rdoc +28 -0
- data/Manifest.txt +8 -0
- data/Rakefile +7 -1
- data/ext/extconf.rb +6 -0
- data/ext/pg.c +77 -3
- data/ext/pg.h +2 -2
- data/ext/pg_connection.c +197 -82
- data/ext/pg_result.c +78 -59
- data/lib/pg.rb +2 -2
- data/lib/pg/connection.rb +7 -0
- data/sample/async_api.rb +2 -0
- data/sample/check_conn.rb +21 -0
- data/sample/disk_usage_report.rb +186 -0
- data/sample/issue-119.rb +94 -0
- data/sample/minimal-testcase.rb +17 -0
- data/sample/pg_statistics.rb +294 -0
- data/sample/replication_monitor.rb +231 -0
- data/sample/wal_shipper.rb +434 -0
- data/sample/warehouse_partitions.rb +320 -0
- data/spec/lib/helpers.rb +6 -1
- data/spec/pg/connection_spec.rb +205 -141
- data/spec/pg/result_spec.rb +18 -6
- data/spec/pg_spec.rb +9 -0
- metadata +68 -26
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/ChangeLog
CHANGED
@@ -1,8 +1,184 @@
|
|
1
|
+
2012-06-12 Mahlon E. Smith <mahlon@laika.com>
|
2
|
+
|
3
|
+
* sample/warehouse_partitions.rb:
|
4
|
+
Move indexes across tablespaces along with their parents. Remove
|
5
|
+
the 'parent table' option, as we can derive that automatically from
|
6
|
+
the pg_inherits table.
|
7
|
+
[be46f44349bf] [tip]
|
8
|
+
|
9
|
+
2012-05-07 Michael Granger <ged@FaerieMUD.org>
|
10
|
+
|
11
|
+
* Rakefile, ext/pg.c, ext/pg_connection.c, ext/pg_result.c:
|
12
|
+
Documentation fixes.
|
13
|
+
[a965926418dd]
|
14
|
+
|
15
|
+
2012-04-23 Michael Granger <ged@FaerieMUD.org>
|
16
|
+
|
17
|
+
* Manifest.txt:
|
18
|
+
Adding Mahlon's samples to the manifest.
|
19
|
+
[997c3a247f44]
|
20
|
+
|
21
|
+
* .rvm.gems, Rakefile:
|
22
|
+
Updated dev dependencies
|
23
|
+
[cc07b81eaf18]
|
24
|
+
|
25
|
+
2012-04-17 Mahlon E. Smith <mahlon@laika.com>
|
26
|
+
|
27
|
+
* sample/disk_usage_report.rb, sample/minimal-testcase.rb,
|
28
|
+
sample/pg_statistics.rb, sample/replication_monitor.rb,
|
29
|
+
sample/wal_shipper.rb, sample/warehouse_partitions.rb:
|
30
|
+
Add a pile of additional sample scripts that perform various
|
31
|
+
administrative tasks.
|
32
|
+
|
33
|
+
These have all been fairly well battle-tested and are in production
|
34
|
+
use at $DAYJOB, though they were cleaned up for addition to the
|
35
|
+
Ruby-PG repo.
|
36
|
+
|
37
|
+
See the top comments in each script for additional information, or
|
38
|
+
the
|
39
|
+
--help flag on any of them for usage.
|
40
|
+
|
41
|
+
- disk_usage_report
|
42
|
+
|
43
|
+
Quick reporting on the heaviest disk consumers for a
|
44
|
+
database. Nice for cronned/email reporting.
|
45
|
+
|
46
|
+
- pg_statistics
|
47
|
+
|
48
|
+
Continuous polled statistics for a database.
|
49
|
+
Suitable for graphing with gnuplot (example
|
50
|
+
included.)
|
51
|
+
|
52
|
+
- replication_monitor
|
53
|
+
|
54
|
+
A command-line monitor for slave replication lag.
|
55
|
+
Works for both streaming replication and WAL
|
56
|
+
shipping. You should be able to use it as a base to
|
57
|
+
plug into your preferred monitoring system.
|
58
|
+
|
59
|
+
- wal_shipper
|
60
|
+
|
61
|
+
A smart WAL file transfer script, similar to
|
62
|
+
PITRTools.
|
63
|
+
|
64
|
+
- warehouse_partitions
|
65
|
+
|
66
|
+
An automated tablespace migrator for older, date-
|
67
|
+
based partitioned tables.
|
68
|
+
[36ca5b412583]
|
69
|
+
|
70
|
+
2012-04-02 Michael Granger <ged@FaerieMUD.org>
|
71
|
+
|
72
|
+
* sample/issue-119.rb:
|
73
|
+
Add a sample from <<issue 119>>
|
74
|
+
[35d75de3f5a5]
|
75
|
+
|
76
|
+
2012-03-26 Michael Granger <ged@FaerieMUD.org>
|
77
|
+
|
78
|
+
* sample/minimal-testcase.rb:
|
79
|
+
Adding a minimal-testcase sample
|
80
|
+
[87a8dadf1fdd]
|
81
|
+
|
82
|
+
2012-03-10 Michael Granger <ged@faeriemud.org>
|
83
|
+
|
84
|
+
* ext/pg_result.c:
|
85
|
+
Merged in larskanis/ruby-pg (pull request #7)
|
86
|
+
[4050c3412bd7]
|
87
|
+
|
88
|
+
2012-03-10 Lars Kanis <kanis@comcard.de>
|
89
|
+
|
90
|
+
* spec/pg/result_spec.rb:
|
91
|
+
Add checks with binary data for other PG::Result methods
|
92
|
+
[ef981c14a854]
|
93
|
+
|
94
|
+
* ext/pg_result.c:
|
95
|
+
Don't associate encoding with non-text-type fields in
|
96
|
+
PGresult#getvalue. This fixes #104 .
|
97
|
+
[9c90c50ca41a]
|
98
|
+
|
99
|
+
2012-03-09 Michael Granger <ged@FaerieMUD.org>
|
100
|
+
|
101
|
+
* ext/pg_result.c:
|
102
|
+
Avoid use of uninitialized Arrays (fixes #47).
|
103
|
+
|
104
|
+
Instead of declaring an Array at the beginning of fetching results
|
105
|
+
and pushing values onto it to return at the end (which could result
|
106
|
+
in a segfault if the GC runs during a NEWOBJ.
|
107
|
+
[6cea3cea3b2b]
|
108
|
+
|
109
|
+
2012-03-06 Michael Granger <ged@FaerieMUD.org>
|
110
|
+
|
111
|
+
* ext/pg.c, ext/pg_result.c:
|
112
|
+
Fix the guard for PGRES_COPY_BOTH.
|
113
|
+
[4053dfd600e8]
|
114
|
+
|
115
|
+
* ext/pg.c, ext/pg_connection.c, lib/pg/connection.rb,
|
116
|
+
spec/lib/helpers.rb, spec/pg/connection_spec.rb, spec/pg_spec.rb:
|
117
|
+
Factor some library-introspection methods up into the toplevel
|
118
|
+
namespace.
|
119
|
+
|
120
|
+
- PG::Connection.library_version -> PG.library_version
|
121
|
+
- PG::Connection.isthreadsafe -> PG.is_threadsafe? (with backward-
|
122
|
+
compat aliases)
|
123
|
+
- Split up examples by PG version metadata
|
124
|
+
[e24ff9f37b12]
|
125
|
+
|
126
|
+
* Rakefile:
|
127
|
+
Depend on RSpec 2.8 for example metadata
|
128
|
+
[c0b00fdff58a]
|
129
|
+
|
130
|
+
* ext/extconf.rb, ext/pg_result.c:
|
131
|
+
ifdef'ed PGRES_COPY_BOTH
|
132
|
+
[ad4f62c38edf]
|
133
|
+
|
134
|
+
2012-03-06 Michael Granger <ged@faeriemud.org>
|
135
|
+
|
136
|
+
* Merged in krasul/ruby-pg/issue-68 (pull request #6)
|
137
|
+
[dedcce66d5e8]
|
138
|
+
|
139
|
+
2012-03-05 Kashif Rasul <kashif@nomad-labs.com>
|
140
|
+
|
141
|
+
* ext/pg_connection.c, ext/pg_result.c, sample/async_api.rb:
|
142
|
+
Added logic for missing cases.
|
143
|
+
[ae9e73972844] <issue-68>
|
144
|
+
|
145
|
+
2012-03-04 Kashif Rasul <kashif@nomad-labs.com>
|
146
|
+
|
147
|
+
* ext/extconf.rb, ext/pg.c, ext/pg_connection.c,
|
148
|
+
spec/pg/connection_spec.rb:
|
149
|
+
Added server ping() API.
|
150
|
+
[fec045ed060d] <issue-68>
|
151
|
+
|
152
|
+
2012-03-02 Kashif Rasul <kashif@nomad-labs.com>
|
153
|
+
|
154
|
+
* ext/extconf.rb, ext/pg_connection.c:
|
155
|
+
Added library_version() as a singleton method. Removed non-
|
156
|
+
singletons.
|
157
|
+
[f82d969cc755] <issue-68>
|
158
|
+
|
159
|
+
* ext/pg_connection.c:
|
160
|
+
Added missing #def to rb_define_method() calls.
|
161
|
+
[fd22651ae6c5] <issue-68>
|
162
|
+
|
163
|
+
* ext/pg_connection.c, spec/pg/connection_spec.rb,
|
164
|
+
spec/pg/result_spec.rb:
|
165
|
+
Added spec for escape_literal().
|
166
|
+
[1ce12f2fe97c] <issue-68>
|
167
|
+
|
168
|
+
* ext/pg_connection.c:
|
169
|
+
Removed unused variable.
|
170
|
+
[3b52e0e0d421] <issue-68>
|
171
|
+
|
172
|
+
* ext/extconf.rb, ext/pg_connection.c, spec/pg/connection_spec.rb:
|
173
|
+
Added PGconn#escape_literal and PGconn#escape_identifier API and a
|
174
|
+
spec to test for keepalive connection parameters.
|
175
|
+
[3bdbb90eb13b] <issue-68>
|
176
|
+
|
1
177
|
2012-02-22 Michael Granger <ged@FaerieMUD.org>
|
2
178
|
|
3
179
|
* .hgtags:
|
4
180
|
Added tag v0.13.2 for changeset c79cd308363d
|
5
|
-
[d8e73919acb6]
|
181
|
+
[d8e73919acb6]
|
6
182
|
|
7
183
|
* .hgsigs:
|
8
184
|
Added signature for changeset 41e071bdd6ed
|
@@ -130,7 +306,7 @@
|
|
130
306
|
|
131
307
|
* History.rdoc, Manifest.txt, README.rdoc, Rakefile, lib/pg.rb:
|
132
308
|
Updated the History file, Manifest, README, added missing require.
|
133
|
-
[b2cd37832d02]
|
309
|
+
[b2cd37832d02]
|
134
310
|
|
135
311
|
* .rvm.gems:
|
136
312
|
Removed rspec 2.8.1 -- not yet released, and 2.8.0 is now pulled in
|
data/History.rdoc
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
== v0.14.0 [2012-06-17] Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
#47, #104
|
5
|
+
|
6
|
+
|
7
|
+
New Methods for PostgreSQL 9 and async API support:
|
8
|
+
PG
|
9
|
+
- ::library_version
|
10
|
+
|
11
|
+
PG::Connection
|
12
|
+
- ::ping
|
13
|
+
- #escape_literal
|
14
|
+
- #escape_identifier
|
15
|
+
- #set_default_encoding
|
16
|
+
|
17
|
+
PG::Result
|
18
|
+
- #check
|
19
|
+
|
20
|
+
|
21
|
+
New Samples:
|
22
|
+
|
23
|
+
This release also comes with a collection of contributed sample scripts for
|
24
|
+
doing resource-utilization reports, graphing database statistics,
|
25
|
+
monitoring for replication lag, shipping WAL files for replication,
|
26
|
+
automated tablespace partitioning, etc. See the samples/ directory.
|
27
|
+
|
28
|
+
|
1
29
|
== v0.13.2 [2012-02-22] Michael Granger <ged@FaerieMUD.org>
|
2
30
|
|
3
31
|
- Make builds against PostgreSQL earlier than 8.3 fail with a descriptive
|
data/Manifest.txt
CHANGED
@@ -28,12 +28,20 @@ lib/pg/result.rb
|
|
28
28
|
sample/async_api.rb
|
29
29
|
sample/async_copyto.rb
|
30
30
|
sample/async_mixed.rb
|
31
|
+
sample/check_conn.rb
|
31
32
|
sample/copyfrom.rb
|
32
33
|
sample/copyto.rb
|
33
34
|
sample/cursor.rb
|
35
|
+
sample/disk_usage_report.rb
|
36
|
+
sample/issue-119.rb
|
34
37
|
sample/losample.rb
|
38
|
+
sample/minimal-testcase.rb
|
35
39
|
sample/notify_wait.rb
|
40
|
+
sample/pg_statistics.rb
|
41
|
+
sample/replication_monitor.rb
|
36
42
|
sample/test_binary_values.rb
|
43
|
+
sample/wal_shipper.rb
|
44
|
+
sample/warehouse_partitions.rb
|
37
45
|
spec/data/expected_trace.out
|
38
46
|
spec/data/random_binary_data
|
39
47
|
spec/lib/helpers.rb
|
data/Rakefile
CHANGED
@@ -37,6 +37,7 @@ CLEAN.include( PKGDIR.to_s, TMPDIR.to_s )
|
|
37
37
|
# Set up Hoe plugins
|
38
38
|
Hoe.plugin :mercurial
|
39
39
|
Hoe.plugin :signing
|
40
|
+
Hoe.plugin :deveiate
|
40
41
|
|
41
42
|
Hoe.plugins.delete :rubyforge
|
42
43
|
Hoe.plugins.delete :compiler
|
@@ -55,7 +56,7 @@ $hoespec = Hoe.spec 'pg' do
|
|
55
56
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
56
57
|
|
57
58
|
self.dependency 'rake-compiler', '~> 0.7', :developer
|
58
|
-
self.dependency '
|
59
|
+
self.dependency 'hoe-deveiate', '~> 0.1', :developer
|
59
60
|
|
60
61
|
self.spec_extras[:licenses] = ['BSD', 'Ruby', 'GPL']
|
61
62
|
self.spec_extras[:extensions] = [ 'ext/extconf.rb' ]
|
@@ -64,6 +65,11 @@ $hoespec = Hoe.spec 'pg' do
|
|
64
65
|
|
65
66
|
self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
|
66
67
|
self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
|
68
|
+
self.spec_extras[:rdoc_options] = [
|
69
|
+
'-f', 'fivefish',
|
70
|
+
'-t', 'pg: The Ruby Interface to PostgreSQL',
|
71
|
+
'-m', 'README.rdoc',
|
72
|
+
]
|
67
73
|
|
68
74
|
self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
|
69
75
|
end
|
data/ext/extconf.rb
CHANGED
@@ -55,15 +55,21 @@ have_func 'PQprepare'
|
|
55
55
|
have_func 'PQexecParams'
|
56
56
|
have_func 'PQescapeString'
|
57
57
|
have_func 'PQescapeStringConn'
|
58
|
+
have_func 'PQescapeLiteral'
|
59
|
+
have_func 'PQescapeIdentifier'
|
58
60
|
have_func 'PQgetCancel'
|
59
61
|
have_func 'lo_create'
|
60
62
|
have_func 'pg_encoding_to_char'
|
61
63
|
have_func 'pg_char_to_encoding'
|
62
64
|
have_func 'PQsetClientEncoding'
|
65
|
+
have_func 'PQlibVersion'
|
66
|
+
have_func 'PQping'
|
63
67
|
|
64
68
|
have_func 'rb_encdb_alias'
|
65
69
|
have_func 'rb_enc_alias'
|
66
70
|
|
71
|
+
have_const 'PGRES_COPY_BOTH', 'libpq-fe.h'
|
72
|
+
|
67
73
|
$defs.push( "-DHAVE_ST_NOTIFY_EXTRA" ) if
|
68
74
|
have_struct_member 'struct pgNotify', 'extra', 'libpq-fe.h'
|
69
75
|
|
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 a965926418dd 2012/05/07 15:01:03 ged $
|
4
4
|
*
|
5
5
|
* Author/s:
|
6
6
|
*
|
@@ -53,7 +53,7 @@ VALUE rb_mPGconstants;
|
|
53
53
|
|
54
54
|
|
55
55
|
/*
|
56
|
-
* Document-class:
|
56
|
+
* Document-class: PG::Error
|
57
57
|
*
|
58
58
|
* This is the exception class raised when an error is returned from
|
59
59
|
* a libpq API call.
|
@@ -250,6 +250,52 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
|
|
250
250
|
#endif /* M17N_SUPPORTED */
|
251
251
|
|
252
252
|
|
253
|
+
/**************************************************************************
|
254
|
+
* Module Methods
|
255
|
+
**************************************************************************/
|
256
|
+
|
257
|
+
#ifdef HAVE_PQLIBVERSION
|
258
|
+
/*
|
259
|
+
* call-seq:
|
260
|
+
* PG.library_version -> Integer
|
261
|
+
*
|
262
|
+
* Get the version of the libpq library in use. The number is formed by
|
263
|
+
* converting the major, minor, and revision numbers into two-decimal-
|
264
|
+
* digit numbers and appending them together.
|
265
|
+
* For example, version 7.4.2 will be returned as 70402, and version
|
266
|
+
* 8.1 will be returned as 80100 (leading zeroes are not shown). Zero
|
267
|
+
* is returned if the connection is bad.
|
268
|
+
*/
|
269
|
+
static VALUE
|
270
|
+
pg_s_library_version(VALUE self)
|
271
|
+
{
|
272
|
+
UNUSED( self );
|
273
|
+
return INT2NUM(PQlibVersion());
|
274
|
+
}
|
275
|
+
#endif
|
276
|
+
|
277
|
+
|
278
|
+
/*
|
279
|
+
* call-seq:
|
280
|
+
* PG.isthreadsafe -> Boolean
|
281
|
+
* PG.is_threadsafe? -> Boolean
|
282
|
+
* PG.threadsafe? -> Boolean
|
283
|
+
*
|
284
|
+
* Returns +true+ if libpq is thread-safe, +false+ otherwise.
|
285
|
+
*/
|
286
|
+
static VALUE
|
287
|
+
pg_s_threadsafe_p(VALUE self)
|
288
|
+
{
|
289
|
+
UNUSED( self );
|
290
|
+
return PQisthreadsafe() ? Qtrue : Qfalse;
|
291
|
+
}
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
/**************************************************************************
|
296
|
+
* Initializer
|
297
|
+
**************************************************************************/
|
298
|
+
|
253
299
|
void
|
254
300
|
Init_pg_ext()
|
255
301
|
{
|
@@ -257,6 +303,16 @@ Init_pg_ext()
|
|
257
303
|
rb_ePGerror = rb_define_class_under( rb_mPG, "Error", rb_eStandardError );
|
258
304
|
rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" );
|
259
305
|
|
306
|
+
/*************************
|
307
|
+
* PG module methods
|
308
|
+
*************************/
|
309
|
+
#ifdef HAVE_PQLIBVERSION
|
310
|
+
rb_define_singleton_method( rb_mPG, "library_version", pg_s_library_version, 0 );
|
311
|
+
#endif
|
312
|
+
rb_define_singleton_method( rb_mPG, "isthreadsafe", pg_s_threadsafe_p, 0 );
|
313
|
+
SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
|
314
|
+
SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
|
315
|
+
|
260
316
|
/*************************
|
261
317
|
* PG::Error
|
262
318
|
*************************/
|
@@ -285,6 +341,8 @@ Init_pg_ext()
|
|
285
341
|
rb_define_const(rb_mPGconstants, "CONNECTION_SSL_STARTUP", INT2FIX(CONNECTION_SSL_STARTUP));
|
286
342
|
/* Negotiating environment-driven parameter settings. */
|
287
343
|
rb_define_const(rb_mPGconstants, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV));
|
344
|
+
/* Internal state: connect() needed. */
|
345
|
+
rb_define_const(rb_mPGconstants, "CONNECTION_NEEDED", INT2FIX(CONNECTION_NEEDED));
|
288
346
|
|
289
347
|
/****** PG::Connection CLASS CONSTANTS: Nonblocking connection polling status ******/
|
290
348
|
|
@@ -319,6 +377,19 @@ Init_pg_ext()
|
|
319
377
|
/* Verbose error verbosity level (#set_error_verbosity) */
|
320
378
|
rb_define_const(rb_mPGconstants, "PQERRORS_VERBOSE", INT2FIX(PQERRORS_VERBOSE));
|
321
379
|
|
380
|
+
#ifdef HAVE_PQPING
|
381
|
+
/****** PG::Connection CLASS CONSTANTS: Check Server Status ******/
|
382
|
+
|
383
|
+
/* Server is accepting connections. */
|
384
|
+
rb_define_const(rb_mPGconstants, "PQPING_OK", INT2FIX(PQPING_OK));
|
385
|
+
/* Server is alive but rejecting connections. */
|
386
|
+
rb_define_const(rb_mPGconstants, "PQPING_REJECT", INT2FIX(PQPING_REJECT));
|
387
|
+
/* Could not establish connection. */
|
388
|
+
rb_define_const(rb_mPGconstants, "PQPING_NO_RESPONSE", INT2FIX(PQPING_NO_RESPONSE));
|
389
|
+
/* Connection not attempted (bad params). */
|
390
|
+
rb_define_const(rb_mPGconstants, "PQPING_NO_ATTEMPT", INT2FIX(PQPING_NO_ATTEMPT));
|
391
|
+
#endif
|
392
|
+
|
322
393
|
/****** PG::Connection CLASS CONSTANTS: Large Objects ******/
|
323
394
|
|
324
395
|
/* Flag for #lo_creat, #lo_open -- open for writing */
|
@@ -332,7 +403,6 @@ Init_pg_ext()
|
|
332
403
|
/* Flag for #lo_lseek -- seek from object end */
|
333
404
|
rb_define_const(rb_mPGconstants, "SEEK_END", INT2FIX(SEEK_END));
|
334
405
|
|
335
|
-
|
336
406
|
/****** PG::Result CONSTANTS: result status ******/
|
337
407
|
|
338
408
|
/* #result_status constant: The string sent to the server was empty. */
|
@@ -352,6 +422,10 @@ Init_pg_ext()
|
|
352
422
|
rb_define_const(rb_mPGconstants, "PGRES_NONFATAL_ERROR",INT2FIX(PGRES_NONFATAL_ERROR));
|
353
423
|
/* #result_status constant: A fatal error occurred. */
|
354
424
|
rb_define_const(rb_mPGconstants, "PGRES_FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR));
|
425
|
+
/* #result_status constant: Copy In/Out data transfer in progress. */
|
426
|
+
#ifdef HAVE_CONST_PGRES_COPY_BOTH
|
427
|
+
rb_define_const(rb_mPGconstants, "PGRES_COPY_BOTH", INT2FIX(PGRES_COPY_BOTH));
|
428
|
+
#endif
|
355
429
|
|
356
430
|
/****** Result CONSTANTS: result error field codes ******/
|
357
431
|
|
data/ext/pg.h
CHANGED
@@ -107,8 +107,8 @@ void init_pg_result _(( void ));
|
|
107
107
|
|
108
108
|
PGconn *pg_get_pgconn _(( VALUE ));
|
109
109
|
|
110
|
-
VALUE pg_new_result _(( PGresult *,
|
111
|
-
|
110
|
+
VALUE pg_new_result _(( PGresult *, VALUE ));
|
111
|
+
VALUE pg_result_check _(( VALUE ));
|
112
112
|
VALUE pg_result_clear _(( VALUE ));
|
113
113
|
|
114
114
|
#ifdef M17N_SUPPORTED
|
data/ext/pg_connection.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_connection.c - PG::Connection class extension
|
3
|
-
* $Id: pg_connection.c,v
|
3
|
+
* $Id: pg_connection.c,v a3a3177b921c 2012/06/17 17:40:49 ged $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -21,7 +21,7 @@
|
|
21
21
|
* # Equivalent to:
|
22
22
|
* # res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
|
23
23
|
*
|
24
|
-
* See the
|
24
|
+
* See the PG::Result class for information on working with the results of a query.
|
25
25
|
*
|
26
26
|
*/
|
27
27
|
VALUE rb_cPGconn;
|
@@ -31,7 +31,9 @@ static PQnoticeProcessor default_notice_processor = NULL;
|
|
31
31
|
|
32
32
|
static PGconn *pgconn_check( VALUE );
|
33
33
|
static VALUE pgconn_finish( VALUE );
|
34
|
-
|
34
|
+
#ifdef M17N_SUPPORTED
|
35
|
+
static VALUE pgconn_set_default_encoding( VALUE self );
|
36
|
+
#endif
|
35
37
|
|
36
38
|
/*
|
37
39
|
* Global functions
|
@@ -164,10 +166,6 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
164
166
|
PGconn *conn = NULL;
|
165
167
|
VALUE conninfo;
|
166
168
|
VALUE error;
|
167
|
-
#ifdef M17N_SUPPORTED
|
168
|
-
rb_encoding *enc;
|
169
|
-
const char *encname;
|
170
|
-
#endif
|
171
169
|
|
172
170
|
conninfo = rb_funcall2( rb_cPGconn, rb_intern("parse_connect_args"), argc, argv );
|
173
171
|
conn = PQconnectdb(StringValuePtr(conninfo));
|
@@ -185,14 +183,7 @@ pgconn_init(int argc, VALUE *argv, VALUE self)
|
|
185
183
|
}
|
186
184
|
|
187
185
|
#ifdef M17N_SUPPORTED
|
188
|
-
|
189
|
-
* to match */
|
190
|
-
if (( enc = rb_default_internal_encoding() )) {
|
191
|
-
encname = pg_get_rb_encoding_as_pg_encoding( enc );
|
192
|
-
if ( PQsetClientEncoding(conn, encname) != 0 )
|
193
|
-
rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
|
194
|
-
encname, PQerrorMessage(conn) );
|
195
|
-
}
|
186
|
+
pgconn_set_default_encoding( self );
|
196
187
|
#endif
|
197
188
|
|
198
189
|
if (rb_block_given_p()) {
|
@@ -251,6 +242,39 @@ pgconn_s_connect_start( int argc, VALUE *argv, VALUE klass )
|
|
251
242
|
return rb_conn;
|
252
243
|
}
|
253
244
|
|
245
|
+
#ifdef HAVE_PQPING
|
246
|
+
/*
|
247
|
+
* call-seq:
|
248
|
+
* PG::Connection.ping(connection_hash) -> Fixnum
|
249
|
+
* PG::Connection.ping(connection_string) -> Fixnum
|
250
|
+
* PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Fixnum
|
251
|
+
*
|
252
|
+
* Check server status.
|
253
|
+
*
|
254
|
+
* Returns one of:
|
255
|
+
* [+PQPING_OK+]
|
256
|
+
* server is accepting connections
|
257
|
+
* [+PQPING_REJECT+]
|
258
|
+
* server is alive but rejecting connections
|
259
|
+
* [+PQPING_NO_RESPONSE+]
|
260
|
+
* could not establish connection
|
261
|
+
* [+PQPING_NO_ATTEMPT+]
|
262
|
+
* connection not attempted (bad params)
|
263
|
+
*/
|
264
|
+
static VALUE
|
265
|
+
pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
266
|
+
{
|
267
|
+
PGPing ping;
|
268
|
+
VALUE conninfo;
|
269
|
+
VALUE error;
|
270
|
+
|
271
|
+
conninfo = rb_funcall2( klass, rb_intern("parse_connect_args"), argc, argv );
|
272
|
+
ping = PQping( StringValuePtr(conninfo) );
|
273
|
+
|
274
|
+
return INT2FIX((int)ping);
|
275
|
+
}
|
276
|
+
#endif
|
277
|
+
|
254
278
|
/*
|
255
279
|
* call-seq:
|
256
280
|
* PG::Connection.conndefaults() -> Array
|
@@ -336,19 +360,6 @@ pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
|
|
336
360
|
}
|
337
361
|
|
338
362
|
|
339
|
-
/*
|
340
|
-
* call-seq:
|
341
|
-
* PG::Connection.isthreadsafe() -> Boolean
|
342
|
-
*
|
343
|
-
* Returns +true+ if libpq is thread safe, +false+ otherwise.
|
344
|
-
*/
|
345
|
-
static VALUE
|
346
|
-
pgconn_s_isthreadsafe(VALUE self)
|
347
|
-
{
|
348
|
-
UNUSED( self );
|
349
|
-
return PQisthreadsafe() ? Qtrue : Qfalse;
|
350
|
-
}
|
351
|
-
|
352
363
|
/**************************************************************************
|
353
364
|
* PG::Connection INSTANCE METHODS
|
354
365
|
**************************************************************************/
|
@@ -733,12 +744,12 @@ pgconn_connection_used_password(VALUE self)
|
|
733
744
|
|
734
745
|
/*
|
735
746
|
* call-seq:
|
736
|
-
* conn.exec(sql [, params, result_format ] ) ->
|
747
|
+
* conn.exec(sql [, params, result_format ] ) -> PG::Result
|
737
748
|
* conn.exec(sql [, params, result_format ] ) {|pg_result| block }
|
738
749
|
*
|
739
750
|
* Sends SQL query request specified by _sql_ to PostgreSQL.
|
740
|
-
* Returns a
|
741
|
-
* On failure, it raises a
|
751
|
+
* Returns a PG::Result instance on success.
|
752
|
+
* On failure, it raises a PG::Error.
|
742
753
|
*
|
743
754
|
* +params+ is an optional array of the bind parameters for the SQL query.
|
744
755
|
* Each element of the +params+ array may be either:
|
@@ -764,7 +775,7 @@ pgconn_connection_used_password(VALUE self)
|
|
764
775
|
* for binary.
|
765
776
|
*
|
766
777
|
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
767
|
-
* and the
|
778
|
+
* and the PG::Result object will automatically be cleared when the block terminates.
|
768
779
|
* In this instance, <code>conn.exec</code> returns the value of the block.
|
769
780
|
*/
|
770
781
|
static VALUE
|
@@ -793,8 +804,8 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
793
804
|
/* If called with no parameters, use PQexec */
|
794
805
|
if(NIL_P(params)) {
|
795
806
|
result = PQexec(conn, StringValuePtr(command));
|
796
|
-
rb_pgresult = pg_new_result(result,
|
797
|
-
|
807
|
+
rb_pgresult = pg_new_result(result, self);
|
808
|
+
pg_result_check(rb_pgresult);
|
798
809
|
if (rb_block_given_p()) {
|
799
810
|
return rb_ensure(rb_yield, rb_pgresult, pg_result_clear, rb_pgresult);
|
800
811
|
}
|
@@ -876,8 +887,8 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
876
887
|
xfree(paramLengths);
|
877
888
|
xfree(paramFormats);
|
878
889
|
|
879
|
-
rb_pgresult = pg_new_result(result,
|
880
|
-
|
890
|
+
rb_pgresult = pg_new_result(result, self);
|
891
|
+
pg_result_check(rb_pgresult);
|
881
892
|
if (rb_block_given_p()) {
|
882
893
|
return rb_ensure(rb_yield, rb_pgresult,
|
883
894
|
pg_result_clear, rb_pgresult);
|
@@ -887,11 +898,11 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
|
|
887
898
|
|
888
899
|
/*
|
889
900
|
* call-seq:
|
890
|
-
* conn.prepare(stmt_name, sql [, param_types ] ) ->
|
901
|
+
* conn.prepare(stmt_name, sql [, param_types ] ) -> PG::Result
|
891
902
|
*
|
892
903
|
* Prepares statement _sql_ with name _name_ to be executed later.
|
893
|
-
* Returns a
|
894
|
-
* On failure, it raises a
|
904
|
+
* Returns a PG::Result instance on success.
|
905
|
+
* On failure, it raises a PG::Error.
|
895
906
|
*
|
896
907
|
* +param_types+ is an optional parameter to specify the Oids of the
|
897
908
|
* types of the parameters.
|
@@ -939,19 +950,19 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
939
950
|
|
940
951
|
xfree(paramTypes);
|
941
952
|
|
942
|
-
rb_pgresult = pg_new_result(result,
|
943
|
-
|
953
|
+
rb_pgresult = pg_new_result(result, self);
|
954
|
+
pg_result_check(rb_pgresult);
|
944
955
|
return rb_pgresult;
|
945
956
|
}
|
946
957
|
|
947
958
|
/*
|
948
959
|
* call-seq:
|
949
|
-
* conn.exec_prepared(statement_name [, params, result_format ] ) ->
|
960
|
+
* conn.exec_prepared(statement_name [, params, result_format ] ) -> PG::Result
|
950
961
|
* conn.exec_prepared(statement_name [, params, result_format ] ) {|pg_result| block }
|
951
962
|
*
|
952
963
|
* Execute prepared named statement specified by _statement_name_.
|
953
|
-
* Returns a
|
954
|
-
* On failure, it raises a
|
964
|
+
* Returns a PG::Result instance on success.
|
965
|
+
* On failure, it raises a PG::Error.
|
955
966
|
*
|
956
967
|
* +params+ is an array of the optional bind parameters for the
|
957
968
|
* SQL query. Each element of the +params+ array may be either:
|
@@ -970,7 +981,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
|
|
970
981
|
* for binary.
|
971
982
|
*
|
972
983
|
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
973
|
-
* and the
|
984
|
+
* and the PG::Result object will automatically be cleared when the block terminates.
|
974
985
|
* In this instance, <code>conn.exec_prepared</code> returns the value of the block.
|
975
986
|
*/
|
976
987
|
static VALUE
|
@@ -1063,8 +1074,8 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1063
1074
|
xfree(paramLengths);
|
1064
1075
|
xfree(paramFormats);
|
1065
1076
|
|
1066
|
-
rb_pgresult = pg_new_result(result,
|
1067
|
-
|
1077
|
+
rb_pgresult = pg_new_result(result, self);
|
1078
|
+
pg_result_check(rb_pgresult);
|
1068
1079
|
if (rb_block_given_p()) {
|
1069
1080
|
return rb_ensure(rb_yield, rb_pgresult,
|
1070
1081
|
pg_result_clear, rb_pgresult);
|
@@ -1074,7 +1085,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
|
|
1074
1085
|
|
1075
1086
|
/*
|
1076
1087
|
* call-seq:
|
1077
|
-
* conn.describe_prepared( statement_name ) ->
|
1088
|
+
* conn.describe_prepared( statement_name ) -> PG::Result
|
1078
1089
|
*
|
1079
1090
|
* Retrieve information about the prepared statement
|
1080
1091
|
* _statement_name_.
|
@@ -1094,15 +1105,15 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1094
1105
|
stmt = StringValuePtr(stmt_name);
|
1095
1106
|
}
|
1096
1107
|
result = PQdescribePrepared(conn, stmt);
|
1097
|
-
rb_pgresult = pg_new_result(result,
|
1098
|
-
|
1108
|
+
rb_pgresult = pg_new_result(result, self);
|
1109
|
+
pg_result_check(rb_pgresult);
|
1099
1110
|
return rb_pgresult;
|
1100
1111
|
}
|
1101
1112
|
|
1102
1113
|
|
1103
1114
|
/*
|
1104
1115
|
* call-seq:
|
1105
|
-
* conn.describe_portal( portal_name ) ->
|
1116
|
+
* conn.describe_portal( portal_name ) -> PG::Result
|
1106
1117
|
*
|
1107
1118
|
* Retrieve information about the portal _portal_name_.
|
1108
1119
|
*/
|
@@ -1122,17 +1133,17 @@ pgconn_describe_portal(self, stmt_name)
|
|
1122
1133
|
stmt = StringValuePtr(stmt_name);
|
1123
1134
|
}
|
1124
1135
|
result = PQdescribePortal(conn, stmt);
|
1125
|
-
rb_pgresult = pg_new_result(result,
|
1126
|
-
|
1136
|
+
rb_pgresult = pg_new_result(result, self);
|
1137
|
+
pg_result_check(rb_pgresult);
|
1127
1138
|
return rb_pgresult;
|
1128
1139
|
}
|
1129
1140
|
|
1130
1141
|
|
1131
1142
|
/*
|
1132
1143
|
* call-seq:
|
1133
|
-
* conn.make_empty_pgresult( status ) ->
|
1144
|
+
* conn.make_empty_pgresult( status ) -> PG::Result
|
1134
1145
|
*
|
1135
|
-
* Constructs and empty
|
1146
|
+
* Constructs and empty PG::Result with status _status_.
|
1136
1147
|
* _status_ may be one of:
|
1137
1148
|
* * +PGRES_EMPTY_QUERY+
|
1138
1149
|
* * +PGRES_COMMAND_OK+
|
@@ -1142,6 +1153,7 @@ pgconn_describe_portal(self, stmt_name)
|
|
1142
1153
|
* * +PGRES_BAD_RESPONSE+
|
1143
1154
|
* * +PGRES_NONFATAL_ERROR+
|
1144
1155
|
* * +PGRES_FATAL_ERROR+
|
1156
|
+
* * +PGRES_COPY_BOTH+
|
1145
1157
|
*/
|
1146
1158
|
static VALUE
|
1147
1159
|
pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
@@ -1150,8 +1162,8 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
|
|
1150
1162
|
VALUE rb_pgresult;
|
1151
1163
|
PGconn *conn = pg_get_pgconn(self);
|
1152
1164
|
result = PQmakeEmptyPGresult(conn, NUM2INT(status));
|
1153
|
-
rb_pgresult = pg_new_result(result,
|
1154
|
-
|
1165
|
+
rb_pgresult = pg_new_result(result, self);
|
1166
|
+
pg_result_check(rb_pgresult);
|
1155
1167
|
return rb_pgresult;
|
1156
1168
|
}
|
1157
1169
|
|
@@ -1290,13 +1302,79 @@ pgconn_s_unescape_bytea(VALUE self, VALUE str)
|
|
1290
1302
|
return ret;
|
1291
1303
|
}
|
1292
1304
|
|
1305
|
+
#ifdef HAVE_PQESCAPELITERAL
|
1306
|
+
/*
|
1307
|
+
* call-seq:
|
1308
|
+
* conn.escape_literal( str ) -> String
|
1309
|
+
*
|
1310
|
+
* Escape an arbitrary String +str+ as a literal.
|
1311
|
+
*/
|
1312
|
+
static VALUE
|
1313
|
+
pgconn_escape_literal(VALUE self, VALUE string)
|
1314
|
+
{
|
1315
|
+
PGconn *conn = pg_get_pgconn(self);
|
1316
|
+
char *escaped = NULL;
|
1317
|
+
VALUE error;
|
1318
|
+
VALUE result = Qnil;
|
1319
|
+
|
1320
|
+
Check_Type(string, T_STRING);
|
1321
|
+
|
1322
|
+
escaped = PQescapeLiteral(conn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1323
|
+
if (escaped == NULL)
|
1324
|
+
{
|
1325
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
|
1326
|
+
rb_iv_set(error, "@connection", self);
|
1327
|
+
rb_exc_raise(error);
|
1328
|
+
return Qnil;
|
1329
|
+
}
|
1330
|
+
result = rb_str_new2(escaped);
|
1331
|
+
PQfreemem(escaped);
|
1332
|
+
OBJ_INFECT(result, string);
|
1333
|
+
|
1334
|
+
return result;
|
1335
|
+
}
|
1336
|
+
#endif
|
1337
|
+
|
1338
|
+
#ifdef HAVE_PQESCAPEIDENTIFIER
|
1339
|
+
/*
|
1340
|
+
* call-seq:
|
1341
|
+
* conn.escape_identifier( str ) -> String
|
1342
|
+
*
|
1343
|
+
* Escape an arbitrary String +str+ as an identifier.
|
1344
|
+
*/
|
1345
|
+
static VALUE
|
1346
|
+
pgconn_escape_identifier(VALUE self, VALUE string)
|
1347
|
+
{
|
1348
|
+
PGconn *conn = pg_get_pgconn(self);
|
1349
|
+
char *escaped = NULL;
|
1350
|
+
VALUE error;
|
1351
|
+
VALUE result = Qnil;
|
1352
|
+
|
1353
|
+
Check_Type(string, T_STRING);
|
1354
|
+
|
1355
|
+
escaped = PQescapeIdentifier(conn, RSTRING_PTR(string), RSTRING_LEN(string));
|
1356
|
+
if (escaped == NULL)
|
1357
|
+
{
|
1358
|
+
error = rb_exc_new2(rb_ePGerror, PQerrorMessage(conn));
|
1359
|
+
rb_iv_set(error, "@connection", self);
|
1360
|
+
rb_exc_raise(error);
|
1361
|
+
return Qnil;
|
1362
|
+
}
|
1363
|
+
result = rb_str_new2(escaped);
|
1364
|
+
PQfreemem(escaped);
|
1365
|
+
OBJ_INFECT(result, string);
|
1366
|
+
|
1367
|
+
return result;
|
1368
|
+
}
|
1369
|
+
#endif
|
1370
|
+
|
1293
1371
|
/*
|
1294
1372
|
* call-seq:
|
1295
1373
|
* conn.send_query(sql [, params, result_format ] ) -> nil
|
1296
1374
|
*
|
1297
1375
|
* Sends SQL query request specified by _sql_ to PostgreSQL for
|
1298
1376
|
* asynchronous processing, and immediately returns.
|
1299
|
-
* On failure, it raises a
|
1377
|
+
* On failure, it raises a PG::Error.
|
1300
1378
|
*
|
1301
1379
|
* +params+ is an optional array of the bind parameters for the SQL query.
|
1302
1380
|
* Each element of the +params+ array may be either:
|
@@ -1442,7 +1520,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1442
1520
|
*
|
1443
1521
|
* Prepares statement _sql_ with name _name_ to be executed later.
|
1444
1522
|
* Sends prepare command asynchronously, and returns immediately.
|
1445
|
-
* On failure, it raises a
|
1523
|
+
* On failure, it raises a PG::Error.
|
1446
1524
|
*
|
1447
1525
|
* +param_types+ is an optional parameter to specify the Oids of the
|
1448
1526
|
* types of the parameters.
|
@@ -1505,7 +1583,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1505
1583
|
*
|
1506
1584
|
* Execute prepared named statement specified by _statement_name_
|
1507
1585
|
* asynchronously, and returns immediately.
|
1508
|
-
* On failure, it raises a
|
1586
|
+
* On failure, it raises a PG::Error.
|
1509
1587
|
*
|
1510
1588
|
* +params+ is an array of the optional bind parameters for the
|
1511
1589
|
* SQL query. Each element of the +params+ array may be either:
|
@@ -1667,7 +1745,7 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
|
|
1667
1745
|
|
1668
1746
|
/*
|
1669
1747
|
* call-seq:
|
1670
|
-
* conn.get_result() ->
|
1748
|
+
* conn.get_result() -> PG::Result
|
1671
1749
|
* conn.get_result() {|pg_result| block }
|
1672
1750
|
*
|
1673
1751
|
* Blocks waiting for the next result from a call to
|
@@ -1678,7 +1756,7 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
|
|
1678
1756
|
* you will not be able to issue further commands.
|
1679
1757
|
*
|
1680
1758
|
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
1681
|
-
* and the
|
1759
|
+
* and the PG::Result object will automatically be cleared when the block terminates.
|
1682
1760
|
* In this instance, <code>conn.exec</code> returns the value of the block.
|
1683
1761
|
*/
|
1684
1762
|
static VALUE
|
@@ -1691,7 +1769,7 @@ pgconn_get_result(VALUE self)
|
|
1691
1769
|
result = PQgetResult(conn);
|
1692
1770
|
if(result == NULL)
|
1693
1771
|
return Qnil;
|
1694
|
-
rb_pgresult = pg_new_result(result,
|
1772
|
+
rb_pgresult = pg_new_result(result, self);
|
1695
1773
|
if (rb_block_given_p()) {
|
1696
1774
|
return rb_ensure(rb_yield, rb_pgresult,
|
1697
1775
|
pg_result_clear, rb_pgresult);
|
@@ -1797,7 +1875,7 @@ pgconn_isnonblocking(self)
|
|
1797
1875
|
* Returns +true+ if data is successfully flushed, +false+
|
1798
1876
|
* if not (can only return +false+ if connection is
|
1799
1877
|
* nonblocking.
|
1800
|
-
* Raises
|
1878
|
+
* Raises PG::Error if some other failure occurred.
|
1801
1879
|
*/
|
1802
1880
|
static VALUE
|
1803
1881
|
pgconn_flush(self)
|
@@ -2243,7 +2321,7 @@ notice_receiver_proxy(void *arg, const PGresult *result)
|
|
2243
2321
|
* the work in the notice receiver.
|
2244
2322
|
*
|
2245
2323
|
* This function takes a new block to act as the handler, which should
|
2246
|
-
* accept a single parameter that will be a
|
2324
|
+
* accept a single parameter that will be a PG::Result object, and returns
|
2247
2325
|
* the Proc object previously set, or +nil+ if it was previously the default.
|
2248
2326
|
*
|
2249
2327
|
* If you pass no arguments, it will reset the handler to the default.
|
@@ -2387,19 +2465,19 @@ pgconn_transaction(VALUE self)
|
|
2387
2465
|
|
2388
2466
|
if (rb_block_given_p()) {
|
2389
2467
|
result = PQexec(conn, "BEGIN");
|
2390
|
-
rb_pgresult = pg_new_result(result,
|
2391
|
-
|
2468
|
+
rb_pgresult = pg_new_result(result, self);
|
2469
|
+
pg_result_check(rb_pgresult);
|
2392
2470
|
rb_protect(rb_yield, self, &status);
|
2393
2471
|
if(status == 0) {
|
2394
2472
|
result = PQexec(conn, "COMMIT");
|
2395
|
-
rb_pgresult = pg_new_result(result,
|
2396
|
-
|
2473
|
+
rb_pgresult = pg_new_result(result, self);
|
2474
|
+
pg_result_check(rb_pgresult);
|
2397
2475
|
}
|
2398
2476
|
else {
|
2399
2477
|
/* exception occurred, ROLLBACK and re-raise */
|
2400
2478
|
result = PQexec(conn, "ROLLBACK");
|
2401
|
-
rb_pgresult = pg_new_result(result,
|
2402
|
-
|
2479
|
+
rb_pgresult = pg_new_result(result, self);
|
2480
|
+
pg_result_check(rb_pgresult);
|
2403
2481
|
rb_jump_tag(status);
|
2404
2482
|
}
|
2405
2483
|
|
@@ -2664,7 +2742,7 @@ pgconn_block( int argc, VALUE *argv, VALUE self ) {
|
|
2664
2742
|
|
2665
2743
|
/*
|
2666
2744
|
* call-seq:
|
2667
|
-
* conn.get_last_result( ) ->
|
2745
|
+
* conn.get_last_result( ) -> PG::Result
|
2668
2746
|
*
|
2669
2747
|
* This function retrieves all available results
|
2670
2748
|
* on the current connection (from previously issued
|
@@ -2697,8 +2775,8 @@ pgconn_get_last_result(VALUE self)
|
|
2697
2775
|
}
|
2698
2776
|
|
2699
2777
|
if (prev) {
|
2700
|
-
rb_pgresult = pg_new_result(prev,
|
2701
|
-
|
2778
|
+
rb_pgresult = pg_new_result( prev, self );
|
2779
|
+
pg_result_check(rb_pgresult);
|
2702
2780
|
}
|
2703
2781
|
|
2704
2782
|
return rb_pgresult;
|
@@ -2707,7 +2785,7 @@ pgconn_get_last_result(VALUE self)
|
|
2707
2785
|
|
2708
2786
|
/*
|
2709
2787
|
* call-seq:
|
2710
|
-
* conn.async_exec(sql [, params, result_format ] ) ->
|
2788
|
+
* conn.async_exec(sql [, params, result_format ] ) -> PG::Result
|
2711
2789
|
* conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
|
2712
2790
|
*
|
2713
2791
|
* This function has the same behavior as #exec,
|
@@ -2745,7 +2823,7 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
2745
2823
|
* conn.lo_creat( [mode] ) -> Fixnum
|
2746
2824
|
*
|
2747
2825
|
* Creates a large object with mode _mode_. Returns a large object Oid.
|
2748
|
-
* On failure, it raises
|
2826
|
+
* On failure, it raises PG::Error.
|
2749
2827
|
*/
|
2750
2828
|
static VALUE
|
2751
2829
|
pgconn_locreat(int argc, VALUE *argv, VALUE self)
|
@@ -2772,7 +2850,7 @@ pgconn_locreat(int argc, VALUE *argv, VALUE self)
|
|
2772
2850
|
* conn.lo_create( oid ) -> Fixnum
|
2773
2851
|
*
|
2774
2852
|
* Creates a large object with oid _oid_. Returns the large object Oid.
|
2775
|
-
* On failure, it raises
|
2853
|
+
* On failure, it raises PG::Error.
|
2776
2854
|
*/
|
2777
2855
|
static VALUE
|
2778
2856
|
pgconn_locreate(VALUE self, VALUE in_lo_oid)
|
@@ -2794,7 +2872,7 @@ pgconn_locreate(VALUE self, VALUE in_lo_oid)
|
|
2794
2872
|
*
|
2795
2873
|
* Import a file to a large object. Returns a large object Oid.
|
2796
2874
|
*
|
2797
|
-
* On failure, it raises a
|
2875
|
+
* On failure, it raises a PG::Error.
|
2798
2876
|
*/
|
2799
2877
|
static VALUE
|
2800
2878
|
pgconn_loimport(VALUE self, VALUE filename)
|
@@ -3107,9 +3185,8 @@ pgconn_internal_encoding_set(VALUE self, VALUE enc)
|
|
3107
3185
|
* call-seq:
|
3108
3186
|
* conn.external_encoding() -> Encoding
|
3109
3187
|
*
|
3110
|
-
*
|
3111
|
-
*
|
3112
|
-
* - Maps 'SQL_ASCII' to ASCII-8BIT.
|
3188
|
+
* Return the +server_encoding+ of the connected database as a Ruby Encoding object.
|
3189
|
+
* The <tt>SQL_ASCII</tt> encoding is mapped to to <tt>ASCII_8BIT</tt>.
|
3113
3190
|
*/
|
3114
3191
|
static VALUE
|
3115
3192
|
pgconn_external_encoding(VALUE self)
|
@@ -3131,6 +3208,35 @@ pgconn_external_encoding(VALUE self)
|
|
3131
3208
|
return encoding;
|
3132
3209
|
}
|
3133
3210
|
|
3211
|
+
|
3212
|
+
|
3213
|
+
/*
|
3214
|
+
* call-seq:
|
3215
|
+
* conn.set_default_encoding() -> Encoding
|
3216
|
+
*
|
3217
|
+
* If Ruby has its Encoding.default_internal set, set PostgreSQL's client_encoding
|
3218
|
+
* to match. Returns the new Encoding, or +nil+ if the default internal encoding
|
3219
|
+
* wasn't set.
|
3220
|
+
*/
|
3221
|
+
static VALUE
|
3222
|
+
pgconn_set_default_encoding( VALUE self )
|
3223
|
+
{
|
3224
|
+
PGconn *conn = pg_get_pgconn( self );
|
3225
|
+
rb_encoding *enc;
|
3226
|
+
const char *encname;
|
3227
|
+
|
3228
|
+
if (( enc = rb_default_internal_encoding() )) {
|
3229
|
+
encname = pg_get_rb_encoding_as_pg_encoding( enc );
|
3230
|
+
if ( PQsetClientEncoding(conn, encname) != 0 )
|
3231
|
+
rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
|
3232
|
+
encname, PQerrorMessage(conn) );
|
3233
|
+
return rb_enc_from_encoding( enc );
|
3234
|
+
} else {
|
3235
|
+
return Qnil;
|
3236
|
+
}
|
3237
|
+
}
|
3238
|
+
|
3239
|
+
|
3134
3240
|
#endif /* M17N_SUPPORTED */
|
3135
3241
|
|
3136
3242
|
|
@@ -3152,11 +3258,13 @@ init_pg_connection()
|
|
3152
3258
|
SINGLETON_ALIAS(rb_cPGconn, "escape", "escape_string");
|
3153
3259
|
rb_define_singleton_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
|
3154
3260
|
rb_define_singleton_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
|
3155
|
-
rb_define_singleton_method(rb_cPGconn, "isthreadsafe", pgconn_s_isthreadsafe, 0);
|
3156
3261
|
rb_define_singleton_method(rb_cPGconn, "encrypt_password", pgconn_s_encrypt_password, 2);
|
3157
3262
|
rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
|
3158
3263
|
rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
|
3159
3264
|
rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
|
3265
|
+
#ifdef HAVE_PQPING
|
3266
|
+
rb_define_singleton_method(rb_cPGconn, "ping", pgconn_s_ping, -1);
|
3267
|
+
#endif
|
3160
3268
|
|
3161
3269
|
/****** PG::Connection INSTANCE METHODS: Connection Control ******/
|
3162
3270
|
rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
|
@@ -3199,6 +3307,12 @@ init_pg_connection()
|
|
3199
3307
|
rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
|
3200
3308
|
rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
|
3201
3309
|
rb_define_alias(rb_cPGconn, "escape", "escape_string");
|
3310
|
+
#ifdef HAVE_PQESCAPELITERAL
|
3311
|
+
rb_define_method(rb_cPGconn, "escape_literal", pgconn_escape_literal, 1);
|
3312
|
+
#endif
|
3313
|
+
#ifdef HAVE_PQESCAPEIDENTIFIER
|
3314
|
+
rb_define_method(rb_cPGconn, "escape_identifier", pgconn_escape_identifier, 1);
|
3315
|
+
#endif
|
3202
3316
|
rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
|
3203
3317
|
rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
|
3204
3318
|
|
@@ -3281,6 +3395,7 @@ init_pg_connection()
|
|
3281
3395
|
rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0);
|
3282
3396
|
rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1);
|
3283
3397
|
rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0);
|
3398
|
+
rb_define_method(rb_cPGconn, "set_default_encoding", pgconn_set_default_encoding, 0);
|
3284
3399
|
#endif /* M17N_SUPPORTED */
|
3285
3400
|
|
3286
3401
|
}
|