pg 0.17.0 → 0.17.1
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 +1 -2
- data/ChangeLog +77 -2
- data/History.rdoc +16 -0
- data/ext/gvl_wrappers.c +0 -6
- data/ext/gvl_wrappers.h +42 -42
- data/ext/pg_connection.c +15 -19
- data/lib/pg.rb +2 -2
- data/lib/pg/connection.rb +8 -0
- data/spec/pg/connection_spec.rb +24 -1
- metadata +3 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76e0a053a21b6714395f5ccf1bd43c9caa235584
|
4
|
+
data.tar.gz: 6d1021ba6991c151049c33f0963f22c5c1262a75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b91c230861ffd1e08fd835ce16245f9abe9344f435f558fbd8987cf6db81255473445a0ea7c1cbb8f602f2eb6bd2ea1ac446cfba484939bb9635ba67ef4060b
|
7
|
+
data.tar.gz: 3219c6f4aaebb9ba597e1ae772b74edb19e27b80f1f60c16537a85f4790e427d040ebfdd46d8e44a626994a5599cdbf9fc82ce3ab269c5f3b7b77b5a80fccc3c
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
2
|
2
|
-
|7^`�^6�ui��&�ه^(K���E�;R�ZO1V�>�g�L4=�ZL���Zřw�[�\7h�B���)l/��J;F�X�V�"�+Py\�Ė&�g��b&<Qj8.Ū��SY
|
1
|
+
��8�2vp��֜W��j�х��"a�GiN�
|
data/ChangeLog
CHANGED
@@ -1,8 +1,83 @@
|
|
1
|
+
2013-12-17 Lars Kanis <kanis@comcard.de>
|
2
|
+
|
3
|
+
* History.rdoc:
|
4
|
+
Update History file
|
5
|
+
[ebd0e140f78d] [tip]
|
6
|
+
|
7
|
+
2013-12-16 larskanis <lars@greiz-reinsdorf.de>
|
8
|
+
|
9
|
+
* Close branch revert_query_cancel_on_ubf
|
10
|
+
[cddad8917d19] <revert_query_cancel_on_ubf>
|
11
|
+
|
12
|
+
* Merged in larskanis/ruby-pg/revert_query_cancel_on_ubf (pull request
|
13
|
+
#18)
|
14
|
+
|
15
|
+
Revert commit e0492d4 "Ensure a query is canceled, if a thread is
|
16
|
+
about to be killed."
|
17
|
+
[93a8aedecd05]
|
18
|
+
|
19
|
+
2013-12-09 Lars Kanis <kanis@comcard.de>
|
20
|
+
|
21
|
+
* spec/pg/connection_spec.rb:
|
22
|
+
Add test case for compatibility with signal handlers. See 97c3ec2.
|
23
|
+
[1e974a370012] <revert_query_cancel_on_ubf>
|
24
|
+
|
25
|
+
* ext/gvl_wrappers.c, ext/gvl_wrappers.h, ext/pg_connection.c,
|
26
|
+
spec/pg/connection_spec.rb:
|
27
|
+
Revert commit e0492d4 "Ensure a query is canceled, if a thread is
|
28
|
+
about to be killed."
|
29
|
+
|
30
|
+
This is due to this discussion: https://groups.google.com/d/topic
|
31
|
+
/ruby-pg/5_ylGmog1S4/discussion
|
32
|
+
|
33
|
+
We were using rb_thread_call_without_gvl() with an ubf which
|
34
|
+
canceled the query currently being processed. This turned out to be
|
35
|
+
incompatible with possibly registered signal handlers (by
|
36
|
+
Signal.trap). A ubf is unconditionally invoked if ANY signal fires
|
37
|
+
on a process (eg even: USR1 or PROF) and Ruby has handlers
|
38
|
+
registered. Cancelling queries in those conditions does no make
|
39
|
+
sense.
|
40
|
+
|
41
|
+
This commit re-enables Connection#async_exec based on the async API
|
42
|
+
for all ruby versions, because async_exec allowes cancelation of
|
43
|
+
queries by signals like Control+C.
|
44
|
+
|
45
|
+
Thanks to Sam Saffron for highlighting this issue.
|
46
|
+
[97c3ec224be9] <revert_query_cancel_on_ubf>
|
47
|
+
|
48
|
+
2013-09-23 Michael Granger <ged@FaerieMUD.org>
|
49
|
+
|
50
|
+
* ext/pg_connection.c, lib/pg/connection.rb:
|
51
|
+
Fix documentation for PG::Connection::conndefaults.
|
52
|
+
[9812218e0654] [github/master]
|
53
|
+
|
54
|
+
2013-09-20 Lars Kanis <lars@greiz-reinsdorf.de>
|
55
|
+
|
56
|
+
* ext/gvl_wrappers.h, ext/pg_connection.c:
|
57
|
+
Wrap PQcancel to be called without GVL. It internally waits for
|
58
|
+
close of the connection to be canceled.
|
59
|
+
[0ed6451d10a5]
|
60
|
+
|
61
|
+
2013-09-16 Michael Granger <ged@FaerieMUD.org>
|
62
|
+
|
63
|
+
* .hgtags:
|
64
|
+
Added tag v0.17.0 for changeset 30da9c169efc
|
65
|
+
[46f35f5b396e]
|
66
|
+
|
67
|
+
* .hgsigs:
|
68
|
+
Added signature for changeset eed93df350a6
|
69
|
+
[30da9c169efc] [v0.17.0]
|
70
|
+
|
71
|
+
* .hoerc:
|
72
|
+
Add the Gemfile to the list of files that don't have to be on the
|
73
|
+
Manifest.
|
74
|
+
[eed93df350a6]
|
75
|
+
|
1
76
|
2013-09-15 Michael Granger <ged@FaerieMUD.org>
|
2
77
|
|
3
78
|
* History.rdoc, lib/pg.rb:
|
4
79
|
Bump minor version
|
5
|
-
[7cdff0a462e5]
|
80
|
+
[7cdff0a462e5]
|
6
81
|
|
7
82
|
2013-09-14 Lars Kanis <lars@greiz-reinsdorf.de>
|
8
83
|
|
@@ -79,7 +154,7 @@
|
|
79
154
|
compilation platform.
|
80
155
|
|
81
156
|
This is 'i586-mingw32msvc-gcc' versus 'i586-pc-mingw32msvc'.
|
82
|
-
[fbee9586e8f7]
|
157
|
+
[fbee9586e8f7]
|
83
158
|
|
84
159
|
2013-08-14 Lars Kanis <lars@greiz-reinsdorf.de>
|
85
160
|
|
data/History.rdoc
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== v0.17.1 [2013-12-18] Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
|
5
|
+
- Fix compatibility with signal handlers defined in Ruby. This reverts
|
6
|
+
cancelation of queries running on top of the blocking libpq API (like
|
7
|
+
Connection#exec) in case of signals. As an alternative the #async_exec
|
8
|
+
can be used, which is reverted to use the non-blocking API, again.
|
9
|
+
- Wrap PQcancel to be called without GVL. It internally waits for
|
10
|
+
the canceling connection.
|
11
|
+
|
12
|
+
Documentation fixes:
|
13
|
+
|
14
|
+
- Fix documentation for PG::Connection::conndefaults.
|
15
|
+
|
16
|
+
|
1
17
|
== v0.17.0 [2013-09-15] Michael Granger <ged@FaerieMUD.org>
|
2
18
|
|
3
19
|
Bugfixes:
|
data/ext/gvl_wrappers.c
CHANGED
@@ -11,9 +11,3 @@ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
|
|
11
11
|
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
|
12
12
|
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_SKELETON );
|
13
13
|
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB );
|
14
|
-
|
15
|
-
void ubf_cancel_running_command(void *c)
|
16
|
-
{
|
17
|
-
PGconn *conn = (PGconn*) c;
|
18
|
-
PQrequestCancel(conn);
|
19
|
-
}
|
data/ext/gvl_wrappers.h
CHANGED
@@ -24,8 +24,6 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
24
24
|
rb_unblock_function_t *ubf, void *data2);
|
25
25
|
#endif
|
26
26
|
|
27
|
-
void ubf_cancel_running_command(void *c);
|
28
|
-
|
29
27
|
#define DEFINE_PARAM_LIST1(type, name) \
|
30
28
|
name,
|
31
29
|
|
@@ -38,7 +36,7 @@ void ubf_cancel_running_command(void *c);
|
|
38
36
|
#define DEFINE_PARAM_DECL(type, name) \
|
39
37
|
type name;
|
40
38
|
|
41
|
-
#define DEFINE_GVL_WRAPPER_STRUCT(name,
|
39
|
+
#define DEFINE_GVL_WRAPPER_STRUCT(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
42
40
|
struct gvl_wrapper_##name##_params { \
|
43
41
|
struct { \
|
44
42
|
FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_DECL) \
|
@@ -47,7 +45,7 @@ void ubf_cancel_running_command(void *c);
|
|
47
45
|
when_non_void( rettype retval; ) \
|
48
46
|
};
|
49
47
|
|
50
|
-
#define DEFINE_GVL_SKELETON(name,
|
48
|
+
#define DEFINE_GVL_SKELETON(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
51
49
|
static void * gvl_##name##_skeleton( void *data ){ \
|
52
50
|
struct gvl_wrapper_##name##_params *p = (struct gvl_wrapper_##name##_params*)data; \
|
53
51
|
when_non_void( p->retval = ) \
|
@@ -56,25 +54,25 @@ void ubf_cancel_running_command(void *c);
|
|
56
54
|
}
|
57
55
|
|
58
56
|
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
59
|
-
#define DEFINE_GVL_STUB(name,
|
57
|
+
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
60
58
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
61
59
|
struct gvl_wrapper_##name##_params params = { \
|
62
60
|
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
|
63
61
|
}; \
|
64
|
-
rb_thread_call_without_gvl(gvl_##name##_skeleton, ¶ms,
|
62
|
+
rb_thread_call_without_gvl(gvl_##name##_skeleton, ¶ms, RUBY_UBF_IO, 0); \
|
65
63
|
when_non_void( return params.retval; ) \
|
66
64
|
}
|
67
65
|
#else
|
68
|
-
#define DEFINE_GVL_STUB(name,
|
66
|
+
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
69
67
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
70
68
|
return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
71
69
|
}
|
72
70
|
#endif
|
73
71
|
|
74
|
-
#define DEFINE_GVL_STUB_DECL(name,
|
72
|
+
#define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
75
73
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
|
76
74
|
|
77
|
-
#define DEFINE_GVLCB_SKELETON(name,
|
75
|
+
#define DEFINE_GVLCB_SKELETON(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
78
76
|
static void * gvl_##name##_skeleton( void *data ){ \
|
79
77
|
struct gvl_wrapper_##name##_params *p = (struct gvl_wrapper_##name##_params*)data; \
|
80
78
|
when_non_void( p->retval = ) \
|
@@ -83,7 +81,7 @@ void ubf_cancel_running_command(void *c);
|
|
83
81
|
}
|
84
82
|
|
85
83
|
#if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
|
86
|
-
#define DEFINE_GVLCB_STUB(name,
|
84
|
+
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
87
85
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
88
86
|
struct gvl_wrapper_##name##_params params = { \
|
89
87
|
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
|
@@ -92,7 +90,7 @@ void ubf_cancel_running_command(void *c);
|
|
92
90
|
when_non_void( return params.retval; ) \
|
93
91
|
}
|
94
92
|
#else
|
95
|
-
#define DEFINE_GVLCB_STUB(name,
|
93
|
+
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
96
94
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
97
95
|
return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
98
96
|
}
|
@@ -101,9 +99,6 @@ void ubf_cancel_running_command(void *c);
|
|
101
99
|
#define GVL_TYPE_VOID(string)
|
102
100
|
#define GVL_TYPE_NONVOID(string) string
|
103
101
|
|
104
|
-
#define GVL_CANCELABLE ubf_cancel_running_command, conn
|
105
|
-
#define GVL_NONCANCELABLE RUBY_UBF_IO, 0
|
106
|
-
|
107
102
|
|
108
103
|
/*
|
109
104
|
* Definitions of blocking functions and their parameters
|
@@ -202,32 +197,37 @@ void ubf_cancel_running_command(void *c);
|
|
202
197
|
|
203
198
|
#define FOR_EACH_PARAM_OF_PQisBusy(param)
|
204
199
|
|
205
|
-
|
200
|
+
#define FOR_EACH_PARAM_OF_PQcancel(param) \
|
201
|
+
param(PGcancel *, cancel) \
|
202
|
+
param(char *, errbuf)
|
203
|
+
|
204
|
+
/* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
|
206
205
|
#define FOR_EACH_BLOCKING_FUNCTION(function) \
|
207
|
-
function(PQconnectdb,
|
208
|
-
function(PQconnectStart,
|
209
|
-
function(PQconnectPoll,
|
210
|
-
function(PQreset,
|
211
|
-
function(PQresetStart,
|
212
|
-
function(PQresetPoll,
|
213
|
-
function(PQexec,
|
214
|
-
function(PQexecParams,
|
215
|
-
function(PQexecPrepared,
|
216
|
-
function(PQprepare,
|
217
|
-
function(PQdescribePrepared,
|
218
|
-
function(PQdescribePortal,
|
219
|
-
function(PQgetResult,
|
220
|
-
function(PQputCopyData,
|
221
|
-
function(PQputCopyEnd,
|
222
|
-
function(PQgetCopyData,
|
223
|
-
function(PQnotifies,
|
224
|
-
function(PQsendQuery,
|
225
|
-
function(PQsendQueryParams,
|
226
|
-
function(PQsendPrepare,
|
227
|
-
function(PQsendQueryPrepared,
|
228
|
-
function(PQsendDescribePrepared,
|
229
|
-
function(PQsendDescribePortal,
|
230
|
-
function(PQisBusy,
|
206
|
+
function(PQconnectdb, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
|
207
|
+
function(PQconnectStart, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
|
208
|
+
function(PQconnectPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
|
209
|
+
function(PQreset, GVL_TYPE_VOID, void, PGconn *, conn) \
|
210
|
+
function(PQresetStart, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
211
|
+
function(PQresetPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
|
212
|
+
function(PQexec, GVL_TYPE_NONVOID, PGresult *, const char *, command) \
|
213
|
+
function(PQexecParams, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
|
214
|
+
function(PQexecPrepared, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
|
215
|
+
function(PQprepare, GVL_TYPE_NONVOID, PGresult *, const Oid *, paramTypes) \
|
216
|
+
function(PQdescribePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
|
217
|
+
function(PQdescribePortal, GVL_TYPE_NONVOID, PGresult *, const char *, portalName) \
|
218
|
+
function(PQgetResult, GVL_TYPE_NONVOID, PGresult *, PGconn *, conn) \
|
219
|
+
function(PQputCopyData, GVL_TYPE_NONVOID, int, int, nbytes) \
|
220
|
+
function(PQputCopyEnd, GVL_TYPE_NONVOID, int, const char *, errormsg) \
|
221
|
+
function(PQgetCopyData, GVL_TYPE_NONVOID, int, int, async) \
|
222
|
+
function(PQnotifies, GVL_TYPE_NONVOID, PGnotify *, PGconn *, conn) \
|
223
|
+
function(PQsendQuery, GVL_TYPE_NONVOID, int, const char *, query) \
|
224
|
+
function(PQsendQueryParams, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
225
|
+
function(PQsendPrepare, GVL_TYPE_NONVOID, int, const Oid *, paramTypes) \
|
226
|
+
function(PQsendQueryPrepared, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
227
|
+
function(PQsendDescribePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
|
228
|
+
function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
|
229
|
+
function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
230
|
+
function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
|
231
231
|
|
232
232
|
|
233
233
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
|
@@ -243,10 +243,10 @@ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
|
|
243
243
|
#define FOR_EACH_PARAM_OF_notice_receiver_proxy(param) \
|
244
244
|
param(void *, arg)
|
245
245
|
|
246
|
-
/* function( name,
|
246
|
+
/* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
|
247
247
|
#define FOR_EACH_CALLBACK_FUNCTION(function) \
|
248
|
-
function(notice_processor_proxy
|
249
|
-
function(notice_receiver_proxy
|
248
|
+
function(notice_processor_proxy, GVL_TYPE_VOID, void, const char *, message) \
|
249
|
+
function(notice_receiver_proxy, GVL_TYPE_VOID, void, const PGresult *, result) \
|
250
250
|
|
251
251
|
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_STUB_DECL );
|
252
252
|
|
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 97c3ec224be9 2013/12/09 16:34:26 kanis $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -292,7 +292,10 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
|
|
292
292
|
}
|
293
293
|
#endif
|
294
294
|
|
295
|
+
|
295
296
|
/*
|
297
|
+
* Document-method: conndefaults
|
298
|
+
*
|
296
299
|
* call-seq:
|
297
300
|
* PG::Connection.conndefaults() -> Array
|
298
301
|
*
|
@@ -503,6 +506,7 @@ pgconn_reset_poll(VALUE self)
|
|
503
506
|
return INT2FIX((int)status);
|
504
507
|
}
|
505
508
|
|
509
|
+
|
506
510
|
/*
|
507
511
|
* call-seq:
|
508
512
|
* conn.db()
|
@@ -838,6 +842,13 @@ static VALUE pgconn_exec_params( int, VALUE *, VALUE );
|
|
838
842
|
* If the optional code block is given, it will be passed <i>result</i> as an argument,
|
839
843
|
* and the PG::Result object will automatically be cleared when the block terminates.
|
840
844
|
* In this instance, <code>conn.exec</code> returns the value of the block.
|
845
|
+
*
|
846
|
+
* #exec is implemented on the synchronous command processing API of libpq, whereas
|
847
|
+
* #async_exec is implemented on the asynchronous API.
|
848
|
+
* #exec is somewhat faster that #async_exec, but blocks any signals to be processed until
|
849
|
+
* the query is finished. This is most notably visible by a delayed reaction to Control+C.
|
850
|
+
* Both methods ensure that other threads can process while waiting for the server to
|
851
|
+
* complete the request.
|
841
852
|
*/
|
842
853
|
static VALUE
|
843
854
|
pgconn_exec(int argc, VALUE *argv, VALUE self)
|
@@ -2103,7 +2114,7 @@ pgconn_cancel(VALUE self)
|
|
2103
2114
|
if(cancel == NULL)
|
2104
2115
|
rb_raise(rb_ePGerror,"Invalid connection!");
|
2105
2116
|
|
2106
|
-
ret =
|
2117
|
+
ret = gvl_PQcancel(cancel, errbuf, 256);
|
2107
2118
|
if(ret == 1)
|
2108
2119
|
retval = Qnil;
|
2109
2120
|
else
|
@@ -3010,22 +3021,14 @@ pgconn_get_last_result(VALUE self)
|
|
3010
3021
|
return rb_pgresult;
|
3011
3022
|
}
|
3012
3023
|
|
3013
|
-
#if !defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
3014
|
-
|
3015
3024
|
/*
|
3016
3025
|
* call-seq:
|
3017
3026
|
* conn.async_exec(sql [, params, result_format ] ) -> PG::Result
|
3018
3027
|
* conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
|
3019
3028
|
*
|
3020
3029
|
* This function has the same behavior as #exec,
|
3021
|
-
* but
|
3022
|
-
*
|
3023
|
-
*
|
3024
|
-
* On Ruby platforms with native threads (MRI-1.9+ and all others)
|
3025
|
-
* this method is an alias to #exec.
|
3026
|
-
*
|
3027
|
-
* On MRI-1.8 it's implemented using asynchronous command
|
3028
|
-
* processing and ruby's +rb_thread_select+ .
|
3030
|
+
* but is implemented using the asynchronous command
|
3031
|
+
* processing API of libpq.
|
3029
3032
|
*/
|
3030
3033
|
static VALUE
|
3031
3034
|
pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
@@ -3046,8 +3049,6 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
|
|
3046
3049
|
return rb_pgresult;
|
3047
3050
|
}
|
3048
3051
|
|
3049
|
-
#endif
|
3050
|
-
|
3051
3052
|
/**************************************************************************
|
3052
3053
|
* LARGE OBJECT SUPPORT
|
3053
3054
|
**************************************************************************/
|
@@ -3508,7 +3509,6 @@ init_pg_connection()
|
|
3508
3509
|
rb_define_method(rb_cPGconn, "reset", pgconn_reset, 0);
|
3509
3510
|
rb_define_method(rb_cPGconn, "reset_start", pgconn_reset_start, 0);
|
3510
3511
|
rb_define_method(rb_cPGconn, "reset_poll", pgconn_reset_poll, 0);
|
3511
|
-
rb_define_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
|
3512
3512
|
rb_define_alias(rb_cPGconn, "close", "finish");
|
3513
3513
|
|
3514
3514
|
/****** PG::Connection INSTANCE METHODS: Connection Status ******/
|
@@ -3600,11 +3600,7 @@ init_pg_connection()
|
|
3600
3600
|
rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1);
|
3601
3601
|
rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify");
|
3602
3602
|
rb_define_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
|
3603
|
-
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
3604
|
-
rb_define_alias(rb_cPGconn, "async_exec", "exec");
|
3605
|
-
#else
|
3606
3603
|
rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
|
3607
|
-
#endif
|
3608
3604
|
rb_define_alias(rb_cPGconn, "async_query", "async_exec");
|
3609
3605
|
rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
|
3610
3606
|
|
data/lib/pg.rb
CHANGED
data/lib/pg/connection.rb
CHANGED
@@ -164,6 +164,14 @@ class PG::Connection
|
|
164
164
|
class << self
|
165
165
|
define_method( :isthreadsafe, &PG.method(:isthreadsafe) )
|
166
166
|
end
|
167
|
+
|
168
|
+
|
169
|
+
### Returns an array of Hashes with connection defaults. See ::conndefaults
|
170
|
+
### for details.
|
171
|
+
def conndefaults
|
172
|
+
return self.class.conndefaults
|
173
|
+
end
|
174
|
+
|
167
175
|
end # class PG::Connection
|
168
176
|
|
169
177
|
# Backward-compatible alias
|
data/spec/pg/connection_spec.rb
CHANGED
@@ -262,7 +262,7 @@ describe PG::Connection do
|
|
262
262
|
error.should == true
|
263
263
|
end
|
264
264
|
|
265
|
-
it "can stop a thread that runs a blocking query" do
|
265
|
+
it "can stop a thread that runs a blocking query with async_exec" do
|
266
266
|
start = Time.now
|
267
267
|
t = Thread.new do
|
268
268
|
@conn.async_exec( 'select pg_sleep(10)' )
|
@@ -274,6 +274,29 @@ describe PG::Connection do
|
|
274
274
|
(Time.now - start).should < 10
|
275
275
|
end
|
276
276
|
|
277
|
+
it "should work together with signal handlers" do
|
278
|
+
signal_received = false
|
279
|
+
trap 'USR1' do
|
280
|
+
signal_received = true
|
281
|
+
end
|
282
|
+
|
283
|
+
Thread.new do
|
284
|
+
sleep 0.1
|
285
|
+
Process.kill("USR1", Process.pid)
|
286
|
+
end
|
287
|
+
@conn.exec("select pg_sleep(0.3)")
|
288
|
+
signal_received.should be_true
|
289
|
+
|
290
|
+
signal_received = false
|
291
|
+
Thread.new do
|
292
|
+
sleep 0.1
|
293
|
+
Process.kill("USR1", Process.pid)
|
294
|
+
end
|
295
|
+
@conn.async_exec("select pg_sleep(0.3)")
|
296
|
+
signal_received.should be_true
|
297
|
+
end
|
298
|
+
|
299
|
+
|
277
300
|
it "automatically rolls back a transaction started with Connection#transaction if an exception " +
|
278
301
|
"is raised" do
|
279
302
|
# abort the per-example transaction so we can test our own
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.17.
|
4
|
+
version: 0.17.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
6mKCwjpegytE0oifXfF8k75A9105cBnNiMZOe1tXiqYc/exCgWvbggurzDOcRkZu
|
32
32
|
/YSusaiDXHKU2O3Akc3htA==
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date: 2013-
|
34
|
+
date: 2013-12-19 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: hoe-mercurial
|
@@ -259,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
259
259
|
version: '0'
|
260
260
|
requirements: []
|
261
261
|
rubyforge_project: pg
|
262
|
-
rubygems_version: 2.
|
262
|
+
rubygems_version: 2.1.11
|
263
263
|
signing_key:
|
264
264
|
specification_version: 4
|
265
265
|
summary: Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/]
|
metadata.gz.sig
CHANGED
Binary file
|