pg 0.16.0-x64-mingw32 → 0.17.0-x64-mingw32
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 +122 -1
- data/History.rdoc +15 -0
- data/Rakefile +6 -2
- data/Rakefile.cross +1 -1
- data/ext/gvl_wrappers.h +45 -3
- data/ext/pg_connection.c +13 -8
- data/ext/pg_result.c +2 -2
- data/lib/2.0/pg_ext.so +0 -0
- data/lib/pg.rb +3 -1
- data/lib/pg/connection.rb +85 -0
- data/spec/lib/helpers.rb +6 -0
- data/spec/pg/connection_spec.rb +95 -0
- metadata +19 -7
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
|
4
|
-
|
3
|
+
metadata.gz: 21f53fb93db689d13bbec315cbf5190e22581120
|
4
|
+
data.tar.gz: 59fe2cf2c7bedfe9d1295779e434e52812a0cb26
|
5
5
|
SHA512:
|
6
|
-
|
7
|
-
|
6
|
+
metadata.gz: 79f561112dee71eec9cfeb84f94a253f1ac2c9cdfc1e5227a7c96ea1e07a37940a6c35be804d425ebe282cd7a3cf8e2ddfd9fff20ccf67aa5ec099fd2afd1634
|
7
|
+
data.tar.gz: 26ec759a2af8b649ea4a11b3521a99536f2af838da7e94ea77b7c2a4916bcbd209876b58fc50fa3990e7f15fd9e060a8706e7bdcddd4191d6e5168df6765cf32
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/ChangeLog
CHANGED
@@ -1,8 +1,129 @@
|
|
1
|
+
2013-09-16 Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
* .hgtags:
|
4
|
+
Added tag v0.17.0 for changeset 30da9c169efc
|
5
|
+
[46f35f5b396e] [tip]
|
6
|
+
|
7
|
+
* .hgsigs:
|
8
|
+
Added signature for changeset eed93df350a6
|
9
|
+
[30da9c169efc] [v0.17.0]
|
10
|
+
|
11
|
+
* .hoerc:
|
12
|
+
Add the Gemfile to the list of files that don't have to be on the
|
13
|
+
Manifest.
|
14
|
+
[eed93df350a6]
|
15
|
+
|
16
|
+
2013-09-15 Michael Granger <ged@FaerieMUD.org>
|
17
|
+
|
18
|
+
* History.rdoc, lib/pg.rb:
|
19
|
+
Bump minor version
|
20
|
+
[7cdff0a462e5]
|
21
|
+
|
22
|
+
2013-09-14 Lars Kanis <lars@greiz-reinsdorf.de>
|
23
|
+
|
24
|
+
* History.rdoc:
|
25
|
+
Add change of PG::Result#check to History.rdoc.
|
26
|
+
[2b4f876c54f6]
|
27
|
+
|
28
|
+
* spec/lib/helpers.rb:
|
29
|
+
verify_clean_exec_status itself should leave a clean status.
|
30
|
+
[933d0f788047]
|
31
|
+
|
32
|
+
2013-09-13 Lars Kanis <lars@greiz-reinsdorf.de>
|
33
|
+
|
34
|
+
* lib/pg.rb, lib/pg/connection.rb, spec/lib/helpers.rb,
|
35
|
+
spec/pg/connection_spec.rb:
|
36
|
+
Improve Connection#copy_data:
|
37
|
+
- ensure and verify a clean exec status for each test case
|
38
|
+
- add error PG::NotAllCopyDataRetrieved and a spec for this case
|
39
|
+
- fix input/output naming in the specs
|
40
|
+
- use ArgumentError instead of PG::Error in case of non-COPY statement
|
41
|
+
[b0fd97e58a9a]
|
42
|
+
|
43
|
+
* History.rdoc, lib/pg.rb:
|
44
|
+
Bump VERSION to 0.16.1 and prepare History.rdoc for release.
|
45
|
+
[c2bbdcd4ef0f]
|
46
|
+
|
47
|
+
* lib/pg/connection.rb:
|
48
|
+
Fix examples of conn#copy_data and improve the documentation.
|
49
|
+
[53d027b0d064]
|
50
|
+
|
51
|
+
2013-09-07 Lars Kanis <lars@greiz-reinsdorf.de>
|
52
|
+
|
53
|
+
* ext/gvl_wrappers.h, ext/pg_connection.c:
|
54
|
+
Wrap PQisBusy to be called without GVL. It could trigger the notice
|
55
|
+
callback.
|
56
|
+
[d93b3ddc69ff]
|
57
|
+
|
58
|
+
* ext/gvl_wrappers.h, ext/pg_connection.c:
|
59
|
+
Wrap all PQsend* functions to be called without GVL.
|
60
|
+
|
61
|
+
These functions could trigger the notice callback when some notice
|
62
|
+
is yet in the buffer. The notice callback needs to be called without
|
63
|
+
GVL since it always reaquires the GLV. This fixes issue #171.
|
64
|
+
[1fd77c0a4cea]
|
65
|
+
|
66
|
+
2013-08-19 Lars Kanis <lars@greiz-reinsdorf.de>
|
67
|
+
|
68
|
+
* spec/pg/connection_spec.rb:
|
69
|
+
Add #copy_data case for non copy statement
|
70
|
+
[eea6da92b30a]
|
71
|
+
|
72
|
+
* ext/pg_connection.c:
|
73
|
+
Remove copy examples in favour of #copy_data
|
74
|
+
[c549f9878adf]
|
75
|
+
|
76
|
+
2013-08-18 Lars Kanis <lars@greiz-reinsdorf.de>
|
77
|
+
|
78
|
+
* merge tip
|
79
|
+
[90252df3c5c8]
|
80
|
+
|
81
|
+
2013-08-15 Lars Kanis <lars@greiz-reinsdorf.de>
|
82
|
+
|
83
|
+
* Rakefile.cross:
|
84
|
+
Use RbConfig::CONFIG['CC'] instead of ['host'] for determining cross
|
85
|
+
compilation platform.
|
86
|
+
|
87
|
+
This is 'i586-mingw32msvc-gcc' versus 'i586-pc-mingw32msvc'.
|
88
|
+
[fbee9586e8f7]
|
89
|
+
|
90
|
+
2013-08-18 Lars Kanis <lars@greiz-reinsdorf.de>
|
91
|
+
|
92
|
+
* lib/pg/connection.rb, spec/pg/connection_spec.rb:
|
93
|
+
Add PG::Connection#copy_data as a convenience method.
|
94
|
+
[5096385267ab]
|
95
|
+
|
96
|
+
* ext/pg_result.c:
|
97
|
+
Return self from PG::Result#check instead of nil. This allowes to
|
98
|
+
stack method calls.
|
99
|
+
[8255d4f73334]
|
100
|
+
|
101
|
+
2013-08-14 Lars Kanis <lars@greiz-reinsdorf.de>
|
102
|
+
|
103
|
+
* Gemfile, Rakefile:
|
104
|
+
Add Gemfile for compat with rake-compiler-dev-box.
|
105
|
+
|
106
|
+
Increase version of rake-compiler to 0.9. That is needed for the
|
107
|
+
x64-mingw32 build.
|
108
|
+
[355cce5c8566]
|
109
|
+
|
110
|
+
2013-08-13 Lars Kanis <lars@greiz-reinsdorf.de>
|
111
|
+
|
112
|
+
* ext/pg_connection.c:
|
113
|
+
Add usage examples for put_copy_data and get_copy_data.
|
114
|
+
[9959003173b4]
|
115
|
+
|
116
|
+
2013-08-11 Lars Kanis <lars@greiz-reinsdorf.de>
|
117
|
+
|
118
|
+
* Rakefile:
|
119
|
+
Add Lars Kanis to the list of developers in the gemspec.
|
120
|
+
[6d3d18452d99]
|
121
|
+
|
1
122
|
2013-07-23 Michael Granger <ged@FaerieMUD.org>
|
2
123
|
|
3
124
|
* .hgtags:
|
4
125
|
Added tag v0.16.0 for changeset def8f41a7672
|
5
|
-
[315fa9728831]
|
126
|
+
[315fa9728831]
|
6
127
|
|
7
128
|
* .hgsigs:
|
8
129
|
Added signature for changeset 4e0606f5f5aa
|
data/History.rdoc
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
== v0.17.0 [2013-09-15] Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
|
5
|
+
- Fix crash by calling PQsend* and PQisBusy without GVL (#171).
|
6
|
+
|
7
|
+
Enhancements:
|
8
|
+
|
9
|
+
- Add method PG::Connection#copy_data.
|
10
|
+
- Add a Gemfile to allow installation of dependencies with bundler.
|
11
|
+
- Add compatibility with rake-compiler-dev-box.
|
12
|
+
- Return self from PG::Result#check instead of nil. This allows
|
13
|
+
to stack method calls.
|
14
|
+
|
15
|
+
|
1
16
|
== v0.16.0 [2013-07-22] Michael Granger <ged@FaerieMUD.org>
|
2
17
|
|
3
18
|
Bugfixes:
|
data/Rakefile
CHANGED
@@ -38,6 +38,7 @@ CLEAN.include( PKGDIR.to_s, TMPDIR.to_s )
|
|
38
38
|
Hoe.plugin :mercurial
|
39
39
|
Hoe.plugin :signing
|
40
40
|
Hoe.plugin :deveiate
|
41
|
+
Hoe.plugin :bundler
|
41
42
|
|
42
43
|
Hoe.plugins.delete :rubyforge
|
43
44
|
Hoe.plugins.delete :compiler
|
@@ -54,9 +55,12 @@ $hoespec = Hoe.spec 'pg' do
|
|
54
55
|
self.extra_rdoc_files.include( 'ext/*.c' )
|
55
56
|
|
56
57
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
58
|
+
self.developer 'Lars Kanis', 'lars@greiz-reinsdorf.de'
|
57
59
|
|
58
|
-
self.dependency 'rake-compiler', '~> 0.
|
59
|
-
self.dependency
|
60
|
+
self.dependency 'rake-compiler', '~> 0.9', :developer
|
61
|
+
self.dependency 'hoe', '~> 3.5.1', :developer
|
62
|
+
self.dependency 'hoe-deveiate', '~> 0.2', :developer
|
63
|
+
self.dependency 'hoe-bundler', '~> 1.0', :developer
|
60
64
|
|
61
65
|
self.spec_extras[:licenses] = ['BSD', 'Ruby', 'GPL']
|
62
66
|
self.spec_extras[:extensions] = [ 'ext/extconf.rb' ]
|
data/Rakefile.cross
CHANGED
@@ -72,7 +72,7 @@ class CrossLibrary < OpenStruct
|
|
72
72
|
self.host_platform = begin
|
73
73
|
config_file = YAML.load_file(File.expand_path("~/.rake-compiler/config.yml"))
|
74
74
|
_, rbfile = config_file.find{|key, fname| key.start_with?("rbconfig-#{for_platform}-") }
|
75
|
-
IO.read(rbfile).match(/CONFIG\["
|
75
|
+
IO.read(rbfile).match(/CONFIG\["CC"\] = "(.*)"/)[1].sub(/\-gcc/, '')
|
76
76
|
rescue
|
77
77
|
nil
|
78
78
|
end
|
data/ext/gvl_wrappers.h
CHANGED
@@ -168,7 +168,41 @@ void ubf_cancel_running_command(void *c);
|
|
168
168
|
|
169
169
|
#define FOR_EACH_PARAM_OF_PQnotifies(param)
|
170
170
|
|
171
|
-
|
171
|
+
#define FOR_EACH_PARAM_OF_PQsendQuery(param) \
|
172
|
+
param(PGconn *, conn)
|
173
|
+
|
174
|
+
#define FOR_EACH_PARAM_OF_PQsendQueryParams(param) \
|
175
|
+
param(PGconn *, conn) \
|
176
|
+
param(const char *, command) \
|
177
|
+
param(int, nParams) \
|
178
|
+
param(const Oid *, paramTypes) \
|
179
|
+
param(const char *const *, paramValues) \
|
180
|
+
param(const int *, paramLengths) \
|
181
|
+
param(const int *, paramFormats)
|
182
|
+
|
183
|
+
#define FOR_EACH_PARAM_OF_PQsendPrepare(param) \
|
184
|
+
param(PGconn *, conn) \
|
185
|
+
param(const char *, stmtName) \
|
186
|
+
param(const char *, query) \
|
187
|
+
param(int, nParams)
|
188
|
+
|
189
|
+
#define FOR_EACH_PARAM_OF_PQsendQueryPrepared(param) \
|
190
|
+
param(PGconn *, conn) \
|
191
|
+
param(const char *, stmtName) \
|
192
|
+
param(int, nParams) \
|
193
|
+
param(const char *const *, paramValues) \
|
194
|
+
param(const int *, paramLengths) \
|
195
|
+
param(const int *, paramFormats)
|
196
|
+
|
197
|
+
#define FOR_EACH_PARAM_OF_PQsendDescribePrepared(param) \
|
198
|
+
param(PGconn *, conn)
|
199
|
+
|
200
|
+
#define FOR_EACH_PARAM_OF_PQsendDescribePortal(param) \
|
201
|
+
param(PGconn *, conn)
|
202
|
+
|
203
|
+
#define FOR_EACH_PARAM_OF_PQisBusy(param)
|
204
|
+
|
205
|
+
/* function( name, cancel, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
|
172
206
|
#define FOR_EACH_BLOCKING_FUNCTION(function) \
|
173
207
|
function(PQconnectdb, GVL_NONCANCELABLE, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
|
174
208
|
function(PQconnectStart, GVL_NONCANCELABLE, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
|
@@ -186,7 +220,15 @@ void ubf_cancel_running_command(void *c);
|
|
186
220
|
function(PQputCopyData, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, int, nbytes) \
|
187
221
|
function(PQputCopyEnd, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, const char *, errormsg) \
|
188
222
|
function(PQgetCopyData, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, int, async) \
|
189
|
-
function(PQnotifies, GVL_CANCELABLE, GVL_TYPE_NONVOID, PGnotify *, PGconn *, conn)
|
223
|
+
function(PQnotifies, GVL_CANCELABLE, GVL_TYPE_NONVOID, PGnotify *, PGconn *, conn) \
|
224
|
+
function(PQsendQuery, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, const char *, query) \
|
225
|
+
function(PQsendQueryParams, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
226
|
+
function(PQsendPrepare, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, const Oid *, paramTypes) \
|
227
|
+
function(PQsendQueryPrepared, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
228
|
+
function(PQsendDescribePrepared, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, const char *, stmt) \
|
229
|
+
function(PQsendDescribePortal, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, const char *, portal) \
|
230
|
+
function(PQisBusy, GVL_CANCELABLE, GVL_TYPE_NONVOID, int, PGconn *, conn);
|
231
|
+
|
190
232
|
|
191
233
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
|
192
234
|
|
@@ -201,7 +243,7 @@ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
|
|
201
243
|
#define FOR_EACH_PARAM_OF_notice_receiver_proxy(param) \
|
202
244
|
param(void *, arg)
|
203
245
|
|
204
|
-
/* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
|
246
|
+
/* function( name, cancel, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
|
205
247
|
#define FOR_EACH_CALLBACK_FUNCTION(function) \
|
206
248
|
function(notice_processor_proxy,, GVL_TYPE_VOID, void, const char *, message) \
|
207
249
|
function(notice_receiver_proxy,, GVL_TYPE_VOID, void, const PGresult *, result) \
|
data/ext/pg_connection.c
CHANGED
@@ -1610,7 +1610,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1610
1610
|
|
1611
1611
|
/* If called with no parameters, use PQsendQuery */
|
1612
1612
|
if(NIL_P(params)) {
|
1613
|
-
if(
|
1613
|
+
if(gvl_PQsendQuery(conn,StringValuePtr(command)) == 0) {
|
1614
1614
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1615
1615
|
rb_iv_set(error, "@connection", self);
|
1616
1616
|
rb_exc_raise(error);
|
@@ -1683,7 +1683,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
|
|
1683
1683
|
paramFormats[i] = NUM2INT(param_format);
|
1684
1684
|
}
|
1685
1685
|
|
1686
|
-
result =
|
1686
|
+
result = gvl_PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes,
|
1687
1687
|
(const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
|
1688
1688
|
|
1689
1689
|
rb_gc_unregister_address(&gc_array);
|
@@ -1750,7 +1750,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
|
|
1750
1750
|
paramTypes[i] = NUM2INT(param);
|
1751
1751
|
}
|
1752
1752
|
}
|
1753
|
-
result =
|
1753
|
+
result = gvl_PQsendPrepare(conn, StringValuePtr(name), StringValuePtr(command),
|
1754
1754
|
nParams, paramTypes);
|
1755
1755
|
|
1756
1756
|
xfree(paramTypes);
|
@@ -1868,7 +1868,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
|
|
1868
1868
|
paramFormats[i] = NUM2INT(param_format);
|
1869
1869
|
}
|
1870
1870
|
|
1871
|
-
result =
|
1871
|
+
result = gvl_PQsendQueryPrepared(conn, StringValuePtr(name), nParams,
|
1872
1872
|
(const char * const *)paramValues, paramLengths, paramFormats,
|
1873
1873
|
resultFormat);
|
1874
1874
|
|
@@ -1899,7 +1899,7 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
|
|
1899
1899
|
VALUE error;
|
1900
1900
|
PGconn *conn = pg_get_pgconn(self);
|
1901
1901
|
/* returns 0 on failure */
|
1902
|
-
if(
|
1902
|
+
if(gvl_PQsendDescribePrepared(conn,StringValuePtr(stmt_name)) == 0) {
|
1903
1903
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1904
1904
|
rb_iv_set(error, "@connection", self);
|
1905
1905
|
rb_exc_raise(error);
|
@@ -1921,7 +1921,7 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
|
|
1921
1921
|
VALUE error;
|
1922
1922
|
PGconn *conn = pg_get_pgconn(self);
|
1923
1923
|
/* returns 0 on failure */
|
1924
|
-
if(
|
1924
|
+
if(gvl_PQsendDescribePortal(conn,StringValuePtr(portal)) == 0) {
|
1925
1925
|
error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
|
1926
1926
|
rb_iv_set(error, "@connection", self);
|
1927
1927
|
rb_exc_raise(error);
|
@@ -1998,7 +1998,7 @@ static VALUE
|
|
1998
1998
|
pgconn_is_busy(self)
|
1999
1999
|
VALUE self;
|
2000
2000
|
{
|
2001
|
-
return
|
2001
|
+
return gvl_PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
|
2002
2002
|
}
|
2003
2003
|
|
2004
2004
|
/*
|
@@ -2449,6 +2449,9 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
|
|
2449
2449
|
* is in nonblocking mode, and this command would block).
|
2450
2450
|
*
|
2451
2451
|
* Raises an exception if an error occurs.
|
2452
|
+
*
|
2453
|
+
* See also #copy_data.
|
2454
|
+
*
|
2452
2455
|
*/
|
2453
2456
|
static VALUE
|
2454
2457
|
pgconn_put_copy_data(self, buffer)
|
@@ -2513,6 +2516,8 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
|
|
2513
2516
|
* if the copy is done, or +false+ if the call would
|
2514
2517
|
* block (only possible if _async_ is true).
|
2515
2518
|
*
|
2519
|
+
* See also #copy_data.
|
2520
|
+
*
|
2516
2521
|
*/
|
2517
2522
|
static VALUE
|
2518
2523
|
pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
|
@@ -2916,7 +2921,7 @@ pgconn_s_quote_ident(VALUE self, VALUE in_str)
|
|
2916
2921
|
static void *
|
2917
2922
|
get_result_readable(PGconn *conn)
|
2918
2923
|
{
|
2919
|
-
return
|
2924
|
+
return gvl_PQisBusy(conn) ? NULL : (void*)1;
|
2920
2925
|
}
|
2921
2926
|
|
2922
2927
|
|
data/ext/pg_result.c
CHANGED
@@ -74,7 +74,7 @@ pg_result_check( VALUE self )
|
|
74
74
|
#endif
|
75
75
|
case PGRES_EMPTY_QUERY:
|
76
76
|
case PGRES_COMMAND_OK:
|
77
|
-
return
|
77
|
+
return self;
|
78
78
|
case PGRES_BAD_RESPONSE:
|
79
79
|
case PGRES_FATAL_ERROR:
|
80
80
|
case PGRES_NONFATAL_ERROR:
|
@@ -97,7 +97,7 @@ pg_result_check( VALUE self )
|
|
97
97
|
rb_exc_raise( exception );
|
98
98
|
|
99
99
|
/* Not reached */
|
100
|
-
return
|
100
|
+
return self;
|
101
101
|
}
|
102
102
|
|
103
103
|
|
data/lib/2.0/pg_ext.so
CHANGED
Binary file
|
data/lib/pg.rb
CHANGED
@@ -19,11 +19,13 @@ end
|
|
19
19
|
module PG
|
20
20
|
|
21
21
|
# Library version
|
22
|
-
VERSION = '0.
|
22
|
+
VERSION = '0.17.0'
|
23
23
|
|
24
24
|
# VCS revision
|
25
25
|
REVISION = %q$Revision$
|
26
26
|
|
27
|
+
class NotAllCopyDataRetrieved < PG::Error
|
28
|
+
end
|
27
29
|
|
28
30
|
### Get the PG library version. If +include_buildnum+ is +true+, include the build ID.
|
29
31
|
def self::version_string( include_buildnum=false )
|
data/lib/pg/connection.rb
CHANGED
@@ -74,6 +74,91 @@ class PG::Connection
|
|
74
74
|
return connopts.join(' ')
|
75
75
|
end
|
76
76
|
|
77
|
+
# call-seq:
|
78
|
+
# conn.copy_data( sql ) {|sql_result| ... } -> PG::Result
|
79
|
+
#
|
80
|
+
# Execute a copy process for transfering data to or from the server.
|
81
|
+
#
|
82
|
+
# This issues the SQL COPY command via #exec. The response to this
|
83
|
+
# (if there is no error in the command) is a PG::Result object that
|
84
|
+
# is passed to the block, bearing a status code of PGRES_COPY_OUT or
|
85
|
+
# PGRES_COPY_IN (depending on the specified copy direction).
|
86
|
+
# The application should then use #put_copy_data or #get_copy_data
|
87
|
+
# to receive or transmit data rows and should return from the block
|
88
|
+
# when finished.
|
89
|
+
#
|
90
|
+
# #copy_data returns another PG::Result object when the data transfer
|
91
|
+
# is complete. An exception is raised if some problem was encountered,
|
92
|
+
# so it isn't required to make use of any of them.
|
93
|
+
# At this point further SQL commands can be issued via #exec.
|
94
|
+
# (It is not possible to execute other SQL commands using the same
|
95
|
+
# connection while the COPY operation is in progress.)
|
96
|
+
#
|
97
|
+
# This method ensures, that the copy process is properly terminated
|
98
|
+
# in case of client side or server side failures. Therefore, in case
|
99
|
+
# of blocking mode of operation, #copy_data is preferred to raw calls
|
100
|
+
# of #put_copy_data, #get_copy_data and #put_copy_end.
|
101
|
+
#
|
102
|
+
# Example with CSV input format:
|
103
|
+
# conn.exec "create table my_table (a text,b text,c text,d text,e text)"
|
104
|
+
# conn.copy_data "COPY my_table FROM STDOUT CSV" do
|
105
|
+
# conn.put_copy_data "some,csv,data,to,copy\n"
|
106
|
+
# conn.put_copy_data "more,csv,data,to,copy\n"
|
107
|
+
# end
|
108
|
+
# This creates +my_table+ and inserts two rows.
|
109
|
+
#
|
110
|
+
# Example with CSV output format:
|
111
|
+
# conn.copy_data "COPY my_table TO STDOUT CSV" do
|
112
|
+
# while row=conn.get_copy_data
|
113
|
+
# p row
|
114
|
+
# end
|
115
|
+
# end
|
116
|
+
# This prints all rows of +my_table+ to stdout:
|
117
|
+
# "some,csv,data,to,copy\n"
|
118
|
+
# "more,csv,data,to,copy\n"
|
119
|
+
def copy_data( sql )
|
120
|
+
res = exec( sql )
|
121
|
+
|
122
|
+
case res.result_status
|
123
|
+
when PGRES_COPY_IN
|
124
|
+
begin
|
125
|
+
yield res
|
126
|
+
rescue Exception => err
|
127
|
+
errmsg = "%s while copy data: %s" % [ err.class.name, err.message ]
|
128
|
+
put_copy_end( errmsg )
|
129
|
+
get_result
|
130
|
+
raise
|
131
|
+
else
|
132
|
+
put_copy_end
|
133
|
+
get_last_result
|
134
|
+
end
|
135
|
+
|
136
|
+
when PGRES_COPY_OUT
|
137
|
+
begin
|
138
|
+
yield res
|
139
|
+
rescue Exception => err
|
140
|
+
cancel
|
141
|
+
while get_copy_data
|
142
|
+
end
|
143
|
+
while get_result
|
144
|
+
end
|
145
|
+
raise
|
146
|
+
else
|
147
|
+
res = get_last_result
|
148
|
+
if res.result_status != PGRES_COMMAND_OK
|
149
|
+
while get_copy_data
|
150
|
+
end
|
151
|
+
while get_result
|
152
|
+
end
|
153
|
+
raise PG::NotAllCopyDataRetrieved, "Not all COPY data retrieved"
|
154
|
+
end
|
155
|
+
res
|
156
|
+
end
|
157
|
+
|
158
|
+
else
|
159
|
+
raise ArgumentError, "SQL command is no COPY statement: #{sql}"
|
160
|
+
end
|
161
|
+
end
|
77
162
|
|
78
163
|
# Backward-compatibility aliases for stuff that's moved into PG.
|
79
164
|
class << self
|
data/spec/lib/helpers.rb
CHANGED
@@ -254,6 +254,12 @@ module PG::TestingHelpers
|
|
254
254
|
conn_name.should include(app_name[-10..-1])
|
255
255
|
conn_name.length.should <= 64
|
256
256
|
end
|
257
|
+
|
258
|
+
# Ensure the connection is in a clean execution status.
|
259
|
+
def verify_clean_exec_status
|
260
|
+
@conn.send_query( "VALUES (1)" )
|
261
|
+
@conn.get_last_result.values.should == [["1"]]
|
262
|
+
end
|
257
263
|
end
|
258
264
|
|
259
265
|
|
data/spec/pg/connection_spec.rb
CHANGED
@@ -457,6 +457,101 @@ describe PG::Connection do
|
|
457
457
|
rval.should include( '5678', '1234' )
|
458
458
|
end
|
459
459
|
|
460
|
+
it "can process #copy_data output queries" do
|
461
|
+
rows = []
|
462
|
+
res2 = @conn.copy_data( "COPY (SELECT 1 UNION ALL SELECT 2) TO STDOUT" ) do |res|
|
463
|
+
res.result_status.should == PG::PGRES_COPY_OUT
|
464
|
+
res.nfields.should == 1
|
465
|
+
while row=@conn.get_copy_data
|
466
|
+
rows << row
|
467
|
+
end
|
468
|
+
end
|
469
|
+
rows.should == ["1\n", "2\n"]
|
470
|
+
res2.result_status.should == PG::PGRES_COMMAND_OK
|
471
|
+
verify_clean_exec_status
|
472
|
+
end
|
473
|
+
|
474
|
+
it "can handle incomplete #copy_data output queries" do
|
475
|
+
expect {
|
476
|
+
@conn.copy_data( "COPY (SELECT 1 UNION ALL SELECT 2) TO STDOUT" ) do |res|
|
477
|
+
@conn.get_copy_data
|
478
|
+
end
|
479
|
+
}.to raise_error(PG::NotAllCopyDataRetrieved, /Not all/)
|
480
|
+
verify_clean_exec_status
|
481
|
+
end
|
482
|
+
|
483
|
+
it "can handle client errors in #copy_data for output" do
|
484
|
+
expect {
|
485
|
+
@conn.copy_data( "COPY (SELECT 1 UNION ALL SELECT 2) TO STDOUT" ) do
|
486
|
+
raise "boom"
|
487
|
+
end
|
488
|
+
}.to raise_error(RuntimeError, "boom")
|
489
|
+
verify_clean_exec_status
|
490
|
+
end
|
491
|
+
|
492
|
+
it "can handle server errors in #copy_data for output" do
|
493
|
+
@conn.exec "ROLLBACK"
|
494
|
+
@conn.transaction do
|
495
|
+
@conn.exec( "CREATE FUNCTION errfunc() RETURNS int AS $$ BEGIN RAISE 'test-error'; END; $$ LANGUAGE plpgsql;" )
|
496
|
+
expect {
|
497
|
+
@conn.copy_data( "COPY (SELECT errfunc()) TO STDOUT" ) do |res|
|
498
|
+
while @conn.get_copy_data
|
499
|
+
end
|
500
|
+
end
|
501
|
+
}.to raise_error(PG::Error, /test-error/)
|
502
|
+
end
|
503
|
+
verify_clean_exec_status
|
504
|
+
end
|
505
|
+
|
506
|
+
it "can process #copy_data input queries" do
|
507
|
+
@conn.exec( "CREATE TEMP TABLE copytable (col1 TEXT)" )
|
508
|
+
res2 = @conn.copy_data( "COPY copytable FROM STDOUT" ) do |res|
|
509
|
+
res.result_status.should == PG::PGRES_COPY_IN
|
510
|
+
res.nfields.should == 1
|
511
|
+
@conn.put_copy_data "1\n"
|
512
|
+
@conn.put_copy_data "2\n"
|
513
|
+
end
|
514
|
+
res2.result_status.should == PG::PGRES_COMMAND_OK
|
515
|
+
|
516
|
+
verify_clean_exec_status
|
517
|
+
|
518
|
+
res = @conn.exec( "SELECT * FROM copytable ORDER BY col1" )
|
519
|
+
res.values.should == [["1"], ["2"]]
|
520
|
+
end
|
521
|
+
|
522
|
+
it "can handle client errors in #copy_data for input" do
|
523
|
+
@conn.exec "ROLLBACK"
|
524
|
+
@conn.transaction do
|
525
|
+
@conn.exec( "CREATE TEMP TABLE copytable (col1 TEXT)" )
|
526
|
+
expect {
|
527
|
+
@conn.copy_data( "COPY copytable FROM STDOUT" ) do |res|
|
528
|
+
raise "boom"
|
529
|
+
end
|
530
|
+
}.to raise_error(RuntimeError, "boom")
|
531
|
+
end
|
532
|
+
verify_clean_exec_status
|
533
|
+
end
|
534
|
+
|
535
|
+
it "can handle server errors in #copy_data for input" do
|
536
|
+
@conn.exec "ROLLBACK"
|
537
|
+
@conn.transaction do
|
538
|
+
@conn.exec( "CREATE TEMP TABLE copytable (col1 INT)" )
|
539
|
+
expect {
|
540
|
+
@conn.copy_data( "COPY copytable FROM STDOUT" ) do |res|
|
541
|
+
@conn.put_copy_data "xyz\n"
|
542
|
+
end
|
543
|
+
}.to raise_error(PG::Error, /invalid input syntax for integer/)
|
544
|
+
end
|
545
|
+
verify_clean_exec_status
|
546
|
+
end
|
547
|
+
|
548
|
+
it "should raise an error for non copy statements in #copy_data" do
|
549
|
+
expect {
|
550
|
+
@conn.copy_data( "SELECT 1" ){}
|
551
|
+
}.to raise_error(ArgumentError, /no COPY/)
|
552
|
+
|
553
|
+
verify_clean_exec_status
|
554
|
+
end
|
460
555
|
|
461
556
|
it "correctly finishes COPY queries passed to #async_exec" do
|
462
557
|
@conn.async_exec( "COPY (SELECT 1 UNION ALL SELECT 2) TO STDOUT" )
|
metadata
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.0
|
5
5
|
platform: x64-mingw32
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
8
|
+
- Lars Kanis
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain:
|
@@ -30,7 +31,7 @@ cert_chain:
|
|
30
31
|
mMFp4kPUHbWOqCp2mz9gCA==
|
31
32
|
-----END CERTIFICATE-----
|
32
33
|
|
33
|
-
date: 2013-
|
34
|
+
date: 2013-09-16 00:00:00 Z
|
34
35
|
dependencies:
|
35
36
|
- !ruby/object:Gem::Dependency
|
36
37
|
name: hoe-mercurial
|
@@ -69,29 +70,39 @@ dependencies:
|
|
69
70
|
requirements:
|
70
71
|
- - ~>
|
71
72
|
- !ruby/object:Gem::Version
|
72
|
-
version: "0.
|
73
|
+
version: "0.9"
|
73
74
|
type: :development
|
74
75
|
version_requirements: *id004
|
75
76
|
- !ruby/object:Gem::Dependency
|
76
|
-
name: hoe
|
77
|
+
name: hoe
|
77
78
|
prerelease: false
|
78
79
|
requirement: &id005 !ruby/object:Gem::Requirement
|
79
80
|
requirements:
|
80
81
|
- - ~>
|
81
82
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
83
|
+
version: 3.5.1
|
83
84
|
type: :development
|
84
85
|
version_requirements: *id005
|
85
86
|
- !ruby/object:Gem::Dependency
|
86
|
-
name: hoe
|
87
|
+
name: hoe-deveiate
|
87
88
|
prerelease: false
|
88
89
|
requirement: &id006 !ruby/object:Gem::Requirement
|
89
90
|
requirements:
|
90
91
|
- - ~>
|
91
92
|
- !ruby/object:Gem::Version
|
92
|
-
version: "
|
93
|
+
version: "0.2"
|
93
94
|
type: :development
|
94
95
|
version_requirements: *id006
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: hoe-bundler
|
98
|
+
prerelease: false
|
99
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: "1.0"
|
104
|
+
type: :development
|
105
|
+
version_requirements: *id007
|
95
106
|
description: |-
|
96
107
|
Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/].
|
97
108
|
|
@@ -114,6 +125,7 @@ description: |-
|
|
114
125
|
end
|
115
126
|
email:
|
116
127
|
- ged@FaerieMUD.org
|
128
|
+
- lars@greiz-reinsdorf.de
|
117
129
|
executables: []
|
118
130
|
|
119
131
|
extensions: []
|
metadata.gz.sig
CHANGED
Binary file
|