pg 0.17.0 → 0.17.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|