pg 0.16.0-x64-mingw32 → 0.17.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- data.tar.gz: ed7bab2dd53a3ae63b96d2e43b0b94438c1517fb
4
- metadata.gz: dacd22ae85fe3a798d05c1b5b6c2e8544786c7e5
3
+ metadata.gz: 21f53fb93db689d13bbec315cbf5190e22581120
4
+ data.tar.gz: 59fe2cf2c7bedfe9d1295779e434e52812a0cb26
5
5
  SHA512:
6
- data.tar.gz: 50b8196d92f9a8ae7dcaaec73e68fca6d849350b8a3db3826ae7e950e1c1bb4820e1b12d73b65875a6224184c7c0c42890076a2220a4b4159a7c778b43014b86
7
- metadata.gz: a156df14e7ab2ae58d3ed2bc5c0326ffb07ebe968cd843c8e55d48449609c2a8e93f064fbbdd2ee62661ed2e91dab077bff0e03ebc08658bdd0144c03530fb7b
6
+ metadata.gz: 79f561112dee71eec9cfeb84f94a253f1ac2c9cdfc1e5227a7c96ea1e07a37940a6c35be804d425ebe282cd7a3cf8e2ddfd9fff20ccf67aa5ec099fd2afd1634
7
+ data.tar.gz: 26ec759a2af8b649ea4a11b3521a99536f2af838da7e94ea77b7c2a4916bcbd209876b58fc50fa3990e7f15fd9e060a8706e7bdcddd4191d6e5168df6765cf32
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] [tip]
126
+ [315fa9728831]
6
127
 
7
128
  * .hgsigs:
8
129
  Added signature for changeset 4e0606f5f5aa
@@ -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.8', :developer
59
- self.dependency 'hoe-deveiate', '~> 0.2', :developer
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' ]
@@ -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\["host"\] = "(.*)"/)[1]
75
+ IO.read(rbfile).match(/CONFIG\["CC"\] = "(.*)"/)[1].sub(/\-gcc/, '')
76
76
  rescue
77
77
  nil
78
78
  end
@@ -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
- /* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
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) \
@@ -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(PQsendQuery(conn,StringValuePtr(command)) == 0) {
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 = PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes,
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 = PQsendPrepare(conn, StringValuePtr(name), StringValuePtr(command),
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 = PQsendQueryPrepared(conn, StringValuePtr(name), nParams,
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(PQsendDescribePrepared(conn,StringValuePtr(stmt_name)) == 0) {
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(PQsendDescribePortal(conn,StringValuePtr(portal)) == 0) {
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 PQisBusy(pg_get_pgconn(self)) ? Qtrue : Qfalse;
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 PQisBusy(conn) ? NULL : (void*)1;
2924
+ return gvl_PQisBusy(conn) ? NULL : (void*)1;
2920
2925
  }
2921
2926
 
2922
2927
 
@@ -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 Qnil;
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 Qnil;
100
+ return self;
101
101
  }
102
102
 
103
103
 
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.16.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 )
@@ -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
@@ -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
 
@@ -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.16.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-07-23 00:00:00 Z
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.8"
73
+ version: "0.9"
73
74
  type: :development
74
75
  version_requirements: *id004
75
76
  - !ruby/object:Gem::Dependency
76
- name: hoe-deveiate
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: "0.2"
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: "3.6"
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