swift-db-postgres 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.2.6 (2012-11-14)
2
+
3
+ * Ruby 2.x build fixes.
4
+ * Pause GC around execute() with bind values.
5
+
1
6
  == 0.2.5 (2012-09-26)
2
7
 
3
8
  * allow more than 99 placeholders. contributor: @filterfish
@@ -5,6 +5,7 @@
5
5
  #include <stdio.h>
6
6
  #include "adapter.h"
7
7
  #include "typecast.h"
8
+ #include "gvl.h"
8
9
 
9
10
  /* declaration */
10
11
  VALUE cDPA, sUser;
@@ -111,14 +112,15 @@ VALUE db_postgres_adapter_initialize(VALUE self, VALUE options) {
111
112
  return self;
112
113
  }
113
114
 
114
- VALUE nogvl_pq_exec(void *ptr) {
115
+ GVL_NOLOCK_RETURN_TYPE nogvl_pq_exec(void *ptr) {
115
116
  Query *q = (Query *)ptr;
116
- return (VALUE)PQexec(q->connection, q->command);
117
+ return (GVL_NOLOCK_RETURN_TYPE)PQexec(q->connection, q->command);
117
118
  }
118
119
 
119
- VALUE nogvl_pq_exec_params(void *ptr) {
120
+ GVL_NOLOCK_RETURN_TYPE nogvl_pq_exec_params(void *ptr) {
120
121
  Query *q = (Query *)ptr;
121
- return (VALUE)PQexecParams(q->connection, q->command, q->n_args, 0, (const char * const *)q->data, q->size, q->format, 0);
122
+ PGresult * r = PQexecParams(q->connection, q->command, q->n_args, 0, (const char * const *)q->data, q->size, q->format, 0);
123
+ return (GVL_NOLOCK_RETURN_TYPE)r;
122
124
  }
123
125
 
124
126
  VALUE db_postgres_adapter_execute(int argc, VALUE *argv, VALUE self) {
@@ -132,12 +134,13 @@ VALUE db_postgres_adapter_execute(int argc, VALUE *argv, VALUE self) {
132
134
  if (!a->native)
133
135
  sql = db_postgres_normalized_sql(sql);
134
136
 
137
+ rb_gc_register_address(&sql);
138
+ rb_gc_register_address(&bind);
135
139
  if (RARRAY_LEN(bind) > 0) {
136
140
  bind_args_size = (int *) malloc(sizeof(int) * RARRAY_LEN(bind));
137
141
  bind_args_fmt = (int *) malloc(sizeof(int) * RARRAY_LEN(bind));
138
142
  bind_args_data = (char **) malloc(sizeof(char *) * RARRAY_LEN(bind));
139
143
 
140
- rb_gc_register_address(&bind);
141
144
  for (n = 0; n < RARRAY_LEN(bind); n++) {
142
145
  data = rb_ary_entry(bind, n);
143
146
  if (NIL_P(data)) {
@@ -153,7 +156,7 @@ VALUE db_postgres_adapter_execute(int argc, VALUE *argv, VALUE self) {
153
156
 
154
157
  data = typecast_to_string(data);
155
158
  bind_args_size[n] = RSTRING_LEN(data);
156
- bind_args_data[n] = RSTRING_PTR(data);
159
+ bind_args_data[n] = CSTRING_PTR(data);
157
160
  }
158
161
  }
159
162
 
@@ -166,17 +169,21 @@ VALUE db_postgres_adapter_execute(int argc, VALUE *argv, VALUE self) {
166
169
  .format = bind_args_fmt
167
170
  };
168
171
 
169
- result = (PGresult *)rb_thread_blocking_region(nogvl_pq_exec_params, &q, RUBY_UBF_IO, 0);
170
- rb_gc_unregister_address(&bind);
172
+ result = (PGresult *)GVL_NOLOCK(nogvl_pq_exec_params, &q, RUBY_UBF_IO, 0);
173
+ for (n = 0; n < RARRAY_LEN(bind); n++)
174
+ if (bind_args_data[n])
175
+ free(bind_args_data[n]);
171
176
  free(bind_args_size);
172
177
  free(bind_args_data);
173
178
  free(bind_args_fmt);
174
179
  }
175
180
  else {
176
181
  Query q = {.connection = a->connection, .command = CSTRING(sql)};
177
- result = (PGresult *)rb_thread_blocking_region(nogvl_pq_exec, &q, RUBY_UBF_IO, 0);
182
+ result = (PGresult *)GVL_NOLOCK(nogvl_pq_exec, &q, RUBY_UBF_IO, 0);
178
183
  }
179
184
 
185
+ rb_gc_unregister_address(&sql);
186
+ rb_gc_unregister_address(&bind);
180
187
  db_postgres_check_result(result);
181
188
  return db_postgres_result_load(db_postgres_result_allocate(cDPR), result);
182
189
  }
@@ -3,8 +3,15 @@
3
3
  // (c) Bharanee Rathna 2012
4
4
 
5
5
  #include "common.h"
6
+ #include <math.h>
6
7
  #include <uuid/uuid.h>
7
8
 
9
+ char* CSTRING_PTR(VALUE value) {
10
+ char* result = malloc(RSTRING_LEN(value) + 1);
11
+ memcpy(result, RSTRING_PTR(value), RSTRING_LEN(value) + 1);
12
+ return result;
13
+ }
14
+
8
15
  VALUE rb_uuid_string() {
9
16
  size_t n;
10
17
  uuid_t uuid;
@@ -18,25 +25,21 @@ VALUE rb_uuid_string() {
18
25
  return rb_str_new(uuid_hex, sizeof(uuid_t) * 2 + 1);
19
26
  }
20
27
 
21
- /* TODO: very naive, a better ragel based replace thingamajigy */
28
+ /* NOTE: very naive, no regex etc. */
22
29
  VALUE db_postgres_normalized_sql(VALUE sql) {
23
30
  VALUE result;
24
- int i = 0, j = 0, n = 1, size;
25
- char *normalized, *ptr = RSTRING_PTR(sql);
26
-
27
- size = RSTRING_LEN(sql) * 2;
28
- normalized = (char *)malloc(size);
31
+ int i = 0, j = 0, n = 1, size = RSTRING_LEN(sql) * 2, digits;
32
+ char *ptr = RSTRING_PTR(sql), *normalized = malloc(size);
29
33
 
30
34
  while (i < RSTRING_LEN(sql)) {
31
35
  if (*ptr == '?')
32
- j += snprintf(normalized + j, 6, "$%d", n++);
36
+ j += sprintf(normalized + j, "$%d", n++);
33
37
  else
34
38
  normalized[j++] = *ptr;
35
39
 
36
- if (j >= size - 6) {
37
- size = size * 2;
38
- normalized = (char *)realloc(normalized, size);
39
- }
40
+ digits = (int)floor(log10(n)) + 2;
41
+ if (j + digits >= size)
42
+ normalized = realloc(normalized, size += 4096);
40
43
 
41
44
  ptr++;
42
45
  i++;
@@ -22,6 +22,7 @@ extern VALUE cDPA, cDPS, cDPR;
22
22
  extern VALUE eSwiftError, eSwiftArgumentError, eSwiftRuntimeError, eSwiftConnectionError;
23
23
  extern VALUE cStringIO;
24
24
 
25
+ DLL_PRIVATE char* CSTRING_PTR(VALUE);
25
26
  DLL_PRIVATE VALUE rb_uuid_string();
26
27
  DLL_PRIVATE VALUE db_postgres_normalized_sql(VALUE);
27
28
  DLL_PRIVATE void db_postgres_check_result(PGresult *);
@@ -0,0 +1,18 @@
1
+ // vim:ts=4:sts=4:sw=4:expandtab
2
+
3
+ // (c) Bharanee Rathna 2012
4
+
5
+ #pragma once
6
+
7
+ #include "ruby/ruby.h"
8
+ #include "ruby/intern.h"
9
+ #include "ruby/version.h"
10
+
11
+ #if RUBY_API_VERSION_MAJOR >= 2
12
+ #include "ruby/thread.h"
13
+ #define GVL_NOLOCK rb_thread_call_without_gvl
14
+ #define GVL_NOLOCK_RETURN_TYPE void*
15
+ #else
16
+ #define GVL_NOLOCK rb_thread_blocking_region
17
+ #define GVL_NOLOCK_RETURN_TYPE VALUE
18
+ #endif
@@ -5,6 +5,7 @@
5
5
  #include "statement.h"
6
6
  #include "adapter.h"
7
7
  #include "typecast.h"
8
+ #include "gvl.h"
8
9
 
9
10
  /* declaration */
10
11
 
@@ -88,9 +89,10 @@ VALUE db_postgres_statement_release(VALUE self) {
88
89
  return Qfalse;
89
90
  }
90
91
 
91
- VALUE nogvl_pq_exec_prepared(void *ptr) {
92
+ GVL_NOLOCK_RETURN_TYPE nogvl_pq_exec_prepared(void *ptr) {
92
93
  Query *q = (Query *)ptr;
93
- return (VALUE)PQexecPrepared(q->connection, q->command, q->n_args, (const char * const *)q->data, q->size, q->format, 0);
94
+ PGresult *r = PQexecPrepared(q->connection, q->command, q->n_args, (const char * const *)q->data, q->size, q->format, 0);
95
+ return (GVL_NOLOCK_RETURN_TYPE)r;
94
96
  }
95
97
 
96
98
  VALUE db_postgres_statement_execute(int argc, VALUE *argv, VALUE self) {
@@ -105,12 +107,12 @@ VALUE db_postgres_statement_execute(int argc, VALUE *argv, VALUE self) {
105
107
 
106
108
  rb_scan_args(argc, argv, "00*", &bind);
107
109
 
110
+ rb_gc_register_address(&bind);
108
111
  if (RARRAY_LEN(bind) > 0) {
109
112
  bind_args_size = (int *) malloc(sizeof(int) * RARRAY_LEN(bind));
110
113
  bind_args_fmt = (int *) malloc(sizeof(int) * RARRAY_LEN(bind));
111
114
  bind_args_data = (char **) malloc(sizeof(char *) * RARRAY_LEN(bind));
112
115
 
113
- rb_gc_register_address(&bind);
114
116
  for (n = 0; n < RARRAY_LEN(bind); n++) {
115
117
  data = rb_ary_entry(bind, n);
116
118
  if (NIL_P(data)) {
@@ -125,7 +127,7 @@ VALUE db_postgres_statement_execute(int argc, VALUE *argv, VALUE self) {
125
127
  bind_args_fmt[n] = 0;
126
128
  data = typecast_to_string(data);
127
129
  bind_args_size[n] = RSTRING_LEN(data);
128
- bind_args_data[n] = RSTRING_PTR(data);
130
+ bind_args_data[n] = CSTRING_PTR(data);
129
131
  }
130
132
  }
131
133
 
@@ -138,8 +140,10 @@ VALUE db_postgres_statement_execute(int argc, VALUE *argv, VALUE self) {
138
140
  .format = bind_args_fmt
139
141
  };
140
142
 
141
- result = (PGresult *)rb_thread_blocking_region(nogvl_pq_exec_prepared, &q, RUBY_UBF_IO, 0);
142
- rb_gc_unregister_address(&bind);
143
+ result = (PGresult *)GVL_NOLOCK(nogvl_pq_exec_prepared, &q, RUBY_UBF_IO, 0);
144
+ for (n = 0; n < RARRAY_LEN(bind); n++)
145
+ if (bind_args_data[n])
146
+ free(bind_args_data[n]);
143
147
  free(bind_args_fmt);
144
148
  free(bind_args_size);
145
149
  free(bind_args_data);
@@ -153,9 +157,10 @@ VALUE db_postgres_statement_execute(int argc, VALUE *argv, VALUE self) {
153
157
  .size = 0,
154
158
  .format = 0
155
159
  };
156
- result = (PGresult *)rb_thread_blocking_region(nogvl_pq_exec_prepared, &q, RUBY_UBF_IO, 0);
160
+ result = (PGresult *)GVL_NOLOCK(nogvl_pq_exec_prepared, &q, RUBY_UBF_IO, 0);
157
161
  }
158
162
 
163
+ rb_gc_unregister_address(&bind);
159
164
  db_postgres_check_result(result);
160
165
  return db_postgres_result_load(db_postgres_result_allocate(cDPR), result);
161
166
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swift-db-postgres
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-26 00:00:00.000000000 Z
12
+ date: 2012-11-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -37,17 +37,18 @@ extra_rdoc_files: []
37
37
  files:
38
38
  - ext/swift/db/postgres/datetime.c
39
39
  - ext/swift/db/postgres/result.c
40
+ - ext/swift/db/postgres/common.c
40
41
  - ext/swift/db/postgres/adapter.c
41
- - ext/swift/db/postgres/statement.c
42
42
  - ext/swift/db/postgres/typecast.c
43
- - ext/swift/db/postgres/common.c
43
+ - ext/swift/db/postgres/statement.c
44
44
  - ext/swift/db/postgres/main.c
45
45
  - ext/swift/db/postgres/typecast.h
46
- - ext/swift/db/postgres/common.h
47
46
  - ext/swift/db/postgres/datetime.h
48
47
  - ext/swift/db/postgres/result.h
48
+ - ext/swift/db/postgres/gvl.h
49
49
  - ext/swift/db/postgres/statement.h
50
50
  - ext/swift/db/postgres/adapter.h
51
+ - ext/swift/db/postgres/common.h
51
52
  - ext/swift/db/postgres/extconf.rb
52
53
  - test/test_ssl.rb
53
54
  - test/test_adapter.rb
@@ -84,4 +85,3 @@ signing_key:
84
85
  specification_version: 3
85
86
  summary: Swift postgres adapter
86
87
  test_files: []
87
- has_rdoc: