nuodb 1.0.2 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +11 -6
- data/{CONTRIBUTION.rdoc → CONTRIBUTION.md} +20 -19
- data/Gemfile +1 -1
- data/Gemfile.lock +56 -0
- data/History.txt +3 -0
- data/README.md +43 -0
- data/Rakefile +1 -1
- data/ext/nuodb/nuodb.cpp +440 -790
- data/lib/nuodb/version.rb +1 -1
- data/nuodb.gemspec +1 -1
- data/spec/functional/datatypes_spec.rb +1 -1
- data/spec/functional/generated_keys_spec.rb +7 -4
- data/spec/functional/statement_spec.rb +7 -6
- metadata +57 -28
- checksums.yaml +0 -7
- data/README.rdoc +0 -36
- data/install-nuodb.sh +0 -5
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
3
|
rvm:
|
4
|
+
- 2.0.0
|
4
5
|
- 1.9.3
|
5
6
|
|
6
7
|
env:
|
7
|
-
- NUODB_ROOT=/opt/nuodb
|
8
|
+
- NUODB_ROOT=/opt/nuodb NUODB_VERSION=1.2
|
9
|
+
- NUODB_ROOT=/opt/nuodb NUODB_VERSION=1.1.1
|
10
|
+
- NUODB_ROOT=/opt/nuodb NUODB_VERSION=1.1
|
11
|
+
- NUODB_ROOT=/opt/nuodb NUODB_VERSION=1.0.2
|
12
|
+
- NUODB_ROOT=/opt/nuodb NUODB_VERSION=1.0.1
|
8
13
|
|
9
14
|
notifications:
|
10
15
|
recipients:
|
@@ -13,19 +18,19 @@ notifications:
|
|
13
18
|
- lbayas@nuodb.com
|
14
19
|
|
15
20
|
before_install:
|
16
|
-
- wget http://www.nuodb.com/latest/nuodb
|
21
|
+
- wget http://www.nuodb.com/latest/releases/nuodb-${NUODB_VERSION}.linux.x64.deb --output-document=/var/tmp/nuodb.deb
|
17
22
|
- sudo dpkg -i /var/tmp/nuodb.deb
|
18
23
|
- sleep 2
|
19
24
|
|
20
25
|
before_script:
|
21
26
|
- ${NUODB_ROOT}/bin/nuodb --chorus test --password bar --dba-user dba --dba-password baz --verbose debug --archive /var/tmp/nuodb --initialize --force &
|
22
|
-
- sleep
|
27
|
+
- sleep 4
|
23
28
|
- ${NUODB_ROOT}/bin/nuodb --chorus test --password bar --dba-user dba --dba-password baz &
|
24
|
-
- sleep
|
29
|
+
- sleep 4
|
25
30
|
- echo "create user cloud password 'user';" | ${NUODB_ROOT}/bin/nuosql test@localhost --user dba --password baz
|
26
31
|
|
27
32
|
script:
|
28
|
-
- NUODB_ROOT=/opt/nuodb bundle exec rake spec
|
33
|
+
- NUODB_ROOT=/opt/nuodb bundle exec rake spec
|
29
34
|
|
30
35
|
after_script:
|
31
|
-
- sudo dpkg -r nuodb
|
36
|
+
- sudo dpkg -r nuodb
|
@@ -1,20 +1,20 @@
|
|
1
|
-
|
1
|
+
# Contributing to the Ruby NuoDB Driver
|
2
2
|
|
3
|
-
|
3
|
+
## BUILDING THE GEM
|
4
4
|
|
5
5
|
To compile and test run this command:
|
6
6
|
|
7
7
|
rake clean build rdoc spec
|
8
8
|
|
9
|
-
|
9
|
+
## INSTALLING THE GEM
|
10
10
|
|
11
|
-
NUODB_ROOT=/Users/rbuck/tmp/nuodb gem install nuodb-1.
|
11
|
+
NUODB_ROOT=/Users/rbuck/tmp/nuodb gem install nuodb-1.1.gem
|
12
12
|
|
13
13
|
Or from the source tree:
|
14
14
|
|
15
|
-
NUODB_ROOT=/Users/rbuck/tmp/nuodb gem install pkg/nuodb-1.
|
15
|
+
NUODB_ROOT=/Users/rbuck/tmp/nuodb gem install pkg/nuodb-1.1.gem
|
16
16
|
|
17
|
-
|
17
|
+
## TESTING THE GEM
|
18
18
|
|
19
19
|
Start up a minimal chorus as follows:
|
20
20
|
|
@@ -32,33 +32,34 @@ Run the tests:
|
|
32
32
|
|
33
33
|
rake spec
|
34
34
|
|
35
|
-
|
35
|
+
## PUBLISHING THE GEM
|
36
36
|
|
37
|
-
|
37
|
+
### TAGGING
|
38
38
|
|
39
|
-
Tag the product using tags per the SemVer specification; our tags have a
|
39
|
+
Tag the product using tags per the SemVer specification; our tags have a
|
40
|
+
v-prefix:
|
40
41
|
|
41
|
-
git tag -a v1.
|
42
|
+
git tag -a v1.1 -m "SemVer Version: v1.1"
|
42
43
|
|
43
44
|
If you make a mistake, take it back quickly:
|
44
45
|
|
45
|
-
git tag -d v1.
|
46
|
-
git push origin :refs/tags/v1.
|
46
|
+
git tag -d v1.1
|
47
|
+
git push origin :refs/tags/v1.1
|
47
48
|
|
48
|
-
|
49
|
+
### PUBLISHING
|
49
50
|
|
50
51
|
Here are the commands used to publish:
|
51
52
|
|
52
|
-
gem push pkg/nuodb-1.
|
53
|
+
gem push pkg/nuodb-1.1.gem
|
53
54
|
|
54
|
-
|
55
|
+
## INSPECTING THE GEM
|
55
56
|
|
56
|
-
It is often useful to inspect the contents of a Gem before distribution.
|
57
|
-
|
57
|
+
It is often useful to inspect the contents of a Gem before distribution. To do
|
58
|
+
this you dump the contents of a gem thus:
|
58
59
|
|
59
|
-
gem unpack pkg/nuodb-1.
|
60
|
+
gem unpack pkg/nuodb-1.1.gem
|
60
61
|
|
61
|
-
|
62
|
+
## INSPECTING THE EXPORTED SYMBOLS
|
62
63
|
|
63
64
|
To inspec the symbols on Linux:
|
64
65
|
|
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
nuodb (1.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.1.3)
|
10
|
+
erubis (2.7.0)
|
11
|
+
haml (3.0.25)
|
12
|
+
hanna-nouveau (0.2.7)
|
13
|
+
haml (= 3.0.25)
|
14
|
+
rdoc (~> 3.1)
|
15
|
+
json (1.8.0)
|
16
|
+
multi_json (1.7.9)
|
17
|
+
optiflag (0.7)
|
18
|
+
rake (10.1.0)
|
19
|
+
rdoc (3.12.2)
|
20
|
+
json (~> 1.4)
|
21
|
+
rspec (2.11.0)
|
22
|
+
rspec-core (~> 2.11.0)
|
23
|
+
rspec-expectations (~> 2.11.0)
|
24
|
+
rspec-mocks (~> 2.11.0)
|
25
|
+
rspec-core (2.11.1)
|
26
|
+
rspec-expectations (2.11.3)
|
27
|
+
diff-lcs (~> 1.1.3)
|
28
|
+
rspec-mocks (2.11.3)
|
29
|
+
ruby-prof (0.13.0)
|
30
|
+
rubydoc (0.0.1)
|
31
|
+
optiflag (~> 0.7)
|
32
|
+
sdoc (0.3.20)
|
33
|
+
json (>= 1.1.3)
|
34
|
+
rdoc (~> 3.10)
|
35
|
+
simplecov (0.7.1)
|
36
|
+
multi_json (~> 1.0)
|
37
|
+
simplecov-html (~> 0.7.1)
|
38
|
+
simplecov-html (0.7.1)
|
39
|
+
|
40
|
+
PLATFORMS
|
41
|
+
ruby
|
42
|
+
|
43
|
+
DEPENDENCIES
|
44
|
+
erubis (~> 2.7.0)
|
45
|
+
hanna-nouveau
|
46
|
+
nuodb!
|
47
|
+
rake (~> 10.1.0)
|
48
|
+
rdoc
|
49
|
+
rspec (~> 2.11.0)
|
50
|
+
rspec-core (~> 2.11.0)
|
51
|
+
rspec-expectations (~> 2.11.0)
|
52
|
+
rspec-mocks (~> 2.11.0)
|
53
|
+
ruby-prof
|
54
|
+
rubydoc
|
55
|
+
sdoc
|
56
|
+
simplecov
|
data/History.txt
CHANGED
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Ruby/NuoDB Interface [<img src="https://api.travis-ci.org/nuodb/ruby-nuodb.png?branch=master" alt="Build Status" />](http://travis-ci.org/nuodb/ruby-nuodb) [<img src="https://gemnasium.com/nuodb/ruby-nuodb.png?travis" alt="Dependency Status" />](https://gemnasium.com/nuodb/ruby-nuodb) [<img src="https://codeclimate.com/github/nuodb/ruby-nuodb.png" />](https://codeclimate.com/github/nuodb/ruby-nuodb)
|
2
|
+
|
3
|
+
This is the official Ruby Gem for [NuoDB](http://www.nuodb.com/). It wraps the
|
4
|
+
NuoDB C++ API, providing a natural API for Ruby.
|
5
|
+
|
6
|
+
To use NuoDB with Rails you will also want the [ActiveRecord NuoDB
|
7
|
+
Adapter](https://github.com/nuodb/ruby-activerecord-nuodb-adapter)
|
8
|
+
|
9
|
+
Note: At this time the Ruby/NuoDB Interface does not support Windows.
|
10
|
+
|
11
|
+
## Getting Started
|
12
|
+
|
13
|
+
1. If you haven't already, [Download and Install NuoDB](http://nuodb.com/download-nuodb/)
|
14
|
+
|
15
|
+
2. Install the gem
|
16
|
+
|
17
|
+
gem install nuodb
|
18
|
+
|
19
|
+
3. Use NuoDB in Ruby
|
20
|
+
|
21
|
+
require "nuodb"
|
22
|
+
|
23
|
+
conn = NuoDB::Connection.new(:database => 'test@localhost', :username => 'dba', :password => 'goalie', :schema => 'hockey')
|
24
|
+
stmt = conn.statement
|
25
|
+
stmt.execute("SELECT * FROM hockey")
|
26
|
+
stmt.results.each do |res|
|
27
|
+
puts res.inspect
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
## More Information
|
32
|
+
|
33
|
+
* [Ruby/NuoDB Interface Rdoc](http://nuodb.github.io/ruby-nuodb/rdoc/)
|
34
|
+
* [NuoDB Community Forum](http://www.nuodb.com/community/forum.php)
|
35
|
+
* [NuoDB Online Documentation](http://www.nuodb.com/community/documentation.php)
|
36
|
+
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
See [Contribution](CONTRIBUTION.md) for information about contributing to
|
41
|
+
the Ruby ActiveRecord NuoDB Adapter.
|
42
|
+
|
43
|
+
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/9acbb24d79760ffb071e5e653305e21e "githalytics.com")](http://githalytics.com/nuodb/ruby-nuodb)
|
data/Rakefile
CHANGED
@@ -129,7 +129,7 @@ namespace :nuodb do
|
|
129
129
|
case RUBY_PLATFORM
|
130
130
|
when /linux/i
|
131
131
|
unless File.exists? '/etc/redhat-release'
|
132
|
-
puts %x(wget http://www.nuodb.com/latest/nuodb-1.
|
132
|
+
puts %x(wget http://www.nuodb.com/latest/releases/nuodb-1.1.linux.x64.deb --output-document=/var/tmp/nuodb.deb)
|
133
133
|
puts %x(sudo dpkg -i /var/tmp/nuodb.deb)
|
134
134
|
end
|
135
135
|
else
|
data/ext/nuodb/nuodb.cpp
CHANGED
@@ -36,17 +36,21 @@
|
|
36
36
|
#include <time.h>
|
37
37
|
#include <stdio.h>
|
38
38
|
#include <typeinfo>
|
39
|
+
#include <stdarg.h>
|
40
|
+
|
41
|
+
#define NANOS_PER_SECOND 1000000000
|
42
|
+
#define NANOS_PER_MICRO 1000
|
39
43
|
|
40
44
|
#define HAVE_CXA_DEMANGLE
|
41
45
|
|
42
46
|
#ifdef HAVE_CXA_DEMANGLE
|
43
47
|
#include <cxxabi.h>
|
44
|
-
const char
|
48
|
+
const char* demangle(const char* name)
|
45
49
|
{
|
46
50
|
char buf[1024];
|
47
51
|
size_t size = 1024;
|
48
52
|
int status;
|
49
|
-
char
|
53
|
+
char* res = abi::__cxa_demangle (name,
|
50
54
|
buf, &size, &status);
|
51
55
|
return res;
|
52
56
|
}
|
@@ -121,19 +125,19 @@ static const bool ENABLE_CLOSE_HOOK = true;
|
|
121
125
|
|
122
126
|
enum LogLevel
|
123
127
|
{
|
124
|
-
ERROR,
|
125
|
-
WARN,
|
126
|
-
INFO,
|
127
128
|
TRACE,
|
128
129
|
DEBUG,
|
130
|
+
INFO,
|
131
|
+
WARN,
|
132
|
+
ERROR,
|
129
133
|
NONE
|
130
134
|
};
|
131
135
|
|
132
|
-
static LogLevel logLevel =
|
136
|
+
static LogLevel logLevel = ERROR;
|
133
137
|
|
134
|
-
static char const
|
138
|
+
static char const* log_level_name(LogLevel level)
|
135
139
|
{
|
136
|
-
char const
|
140
|
+
char const* level_name = NULL;
|
137
141
|
switch(level)
|
138
142
|
{
|
139
143
|
case NONE:
|
@@ -158,7 +162,7 @@ static char const * log_level_name(LogLevel level)
|
|
158
162
|
return level_name;
|
159
163
|
}
|
160
164
|
|
161
|
-
static void log(LogLevel level, char const
|
165
|
+
static void log(LogLevel level, char const* message)
|
162
166
|
{
|
163
167
|
if (level >= logLevel)
|
164
168
|
{
|
@@ -166,17 +170,17 @@ static void log(LogLevel level, char const * message)
|
|
166
170
|
}
|
167
171
|
}
|
168
172
|
|
169
|
-
static void trace(char const
|
173
|
+
static void trace(char const* message)
|
170
174
|
{
|
171
175
|
log(TRACE, message);
|
172
176
|
}
|
173
177
|
|
174
|
-
static void print_address(char const
|
178
|
+
static void print_address(char const* context, void* address)
|
175
179
|
{
|
176
180
|
if (DEBUG >= logLevel)
|
177
181
|
{
|
178
182
|
unsigned char *p = (unsigned char *)&address;
|
179
|
-
int i;
|
183
|
+
unsigned int i;
|
180
184
|
printf("%s: ", context);
|
181
185
|
for (i = 0; i < sizeof address; i++)
|
182
186
|
{
|
@@ -187,137 +191,35 @@ static void print_address(char const * context, void * address)
|
|
187
191
|
}
|
188
192
|
|
189
193
|
// ----------------------------------------------------------------------------
|
190
|
-
//
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
/*
|
195
|
-
* GC Notes:
|
196
|
-
*
|
197
|
-
* 1. gc_entities are placed in the Ruby object table and are freed via mark
|
198
|
-
* and sweep.
|
199
|
-
* 2. gc_entities may be freed in any order.
|
200
|
-
* 3. gc_entities may be freed either before shutdown or during shutdown.
|
201
|
-
* 4. gc_entities may no longer be accessed once freed by the garbage
|
202
|
-
* collector; once gc_entities are freed they no longer appear in the
|
203
|
-
* object table. As such, calls to Data_Get_Struct on previously garbage
|
204
|
-
* collected entities will cause the Ruby VM to crash; viz. SIGABRT via
|
205
|
-
* EXC_BAD_ACCESS.
|
206
|
-
*
|
207
|
-
* a. So a general observation of this is thusly: if e.g. with graphs of
|
208
|
-
* child to parent relationships an orderly de-allocation is required,
|
209
|
-
* as parents (gc_entities) may be freed prior to childrens (gc_entities)
|
210
|
-
* it becomes imperative that the logic between freeing gc_entity objects
|
211
|
-
* be kept completely and distinctly apart from the logic of the managed
|
212
|
-
* entities themselves.
|
213
|
-
*/
|
214
|
-
|
215
|
-
typedef void (*callback)(void *);
|
216
|
-
|
217
|
-
/*
|
218
|
-
* Application Rules:
|
219
|
-
*
|
220
|
-
* 1. Assign a callback for the increment and decrement refers counter so that
|
221
|
-
* context specific logging and tracking may be implemented.
|
222
|
-
* 2. Direct access to refers should never occur.
|
223
|
-
* 3. The freed bit indicates that the resources associated to the data_handle
|
224
|
-
* has been freed, and NOT that the os_entity struct has been freed.
|
225
|
-
*
|
226
|
-
* Logic:
|
227
|
-
*
|
228
|
-
* 1. The incr_func is called on a child when it is first created.
|
229
|
-
* 2. The incr_func is called on a parent when its child is first created.
|
230
|
-
* 3. When incr_func is called, ATOMIC_INC increments the refers field.
|
231
|
-
* 4. When decr_func is called, ATOMIC_DEC decrements the refers field.
|
232
|
-
* 5. When the refers field reaches zero (inside decr_func):
|
233
|
-
* 5.1. ATOMIC-CAS the freed bit, if the prior freed bit is not set:
|
234
|
-
* 5.1.1. ATOMIC-OR all parents freed bits and if the result does not have
|
235
|
-
* the freed bit set:
|
236
|
-
* 5.1.1.1. Call the free function, passing the os_entity itself as a parameter.
|
237
|
-
* The free function releases any resources related to the data
|
238
|
-
* handle itself and sets the handle to null.
|
239
|
-
* 5.2. Call the decr_func on its parent (this may act recursively).
|
240
|
-
* 5.3. Call xfree on the os_entity structure itself.
|
241
|
-
* 6. When a user calls finish on an object:
|
242
|
-
* 6.1. ATOMIC-CAS the freed bit, if the prior freed bit is not set
|
243
|
-
* perform operations 5.1.1 through 5.1.1.1.
|
244
|
-
*
|
245
|
-
* Details:
|
246
|
-
*
|
247
|
-
* 1. Regarding 5a, above, we neither want to doubly release an object, nor
|
248
|
-
* call free_function when a parent has already released all the resources.
|
249
|
-
* This optionally is configurable, for cases when parents forcibly close
|
250
|
-
* child resources, or for cases where they don't. This is a behavioral
|
251
|
-
* configuration parameter to the resource manager. But the above documentation
|
252
|
-
* is tailored for cases where parents automatically release child resources
|
253
|
-
* when they themselves are closed.
|
254
|
-
* 2. A race condition may occur between 5.1 and 5.2, above, where a parent
|
255
|
-
* resource is released just after 5.1.1.1 and before 5.2; the result will
|
256
|
-
* be a SEGV. This may prompt the use of a global lock for the reference
|
257
|
-
* manager.
|
258
|
-
*
|
259
|
-
* Interface:
|
260
|
-
*
|
261
|
-
* 1. Structures as defined below.
|
262
|
-
* 2. Function to release a reference:
|
263
|
-
* void rc_decr_refs (void * handle, int * err_code)
|
264
|
-
* 3. Function to acquire a reference:
|
265
|
-
* void rc_incr_refs (void * handle, int * err_code)
|
266
|
-
* 4. Function to wrap an entity:
|
267
|
-
* void * rc_add_object (void * object, int * err_code)
|
268
|
-
* 5. Function to get wrapped pointer:
|
269
|
-
* void * rc_get_object (void * handle, int * err_code)
|
270
|
-
*
|
271
|
-
* Questions:
|
272
|
-
*
|
273
|
-
* 1. Do we go opaque so that the data type definition is malleable? We don't
|
274
|
-
* want this any more type specific than it is.
|
275
|
-
*/
|
276
|
-
struct os_entity
|
277
|
-
{
|
278
|
-
void * data_handle;
|
279
|
-
unsigned int flags;
|
280
|
-
rb_atomic_t refers;
|
281
|
-
|
282
|
-
callback incr_func;
|
283
|
-
callback decr_func;
|
284
|
-
callback free_func;
|
285
|
-
|
286
|
-
os_entity * parent;
|
287
|
-
};
|
194
|
+
// H A N D L E S
|
195
|
+
//
|
196
|
+
//
|
288
197
|
|
289
198
|
/*
|
290
|
-
*
|
199
|
+
* Each nuodb client datatype that we need to expose to ruby will be done via a handle object. The handle contains
|
200
|
+
* two kinds of things, a pointer to a client instance and GC handling information. The GC information is there to
|
201
|
+
* deal with the fact that the nuodb client API requires that things be closed before they are deallocated and that
|
202
|
+
* the closures happen in a very specific order. Namely, that all result sets are closed before their creating
|
203
|
+
* statement can be closed. And that all statements are closed before their creating connection may be closed.
|
204
|
+
* Ruby's GC hooks allow us to hook into the MARK phase so that all objects may mark their parents to prevent that
|
205
|
+
* out-of-order condition. However, ruby guarantees no particular order when freeing objects determined to be
|
206
|
+
* garbage. Therefore the GC thread may invoke free on a statement before it's result set even though both are
|
207
|
+
* garbage and will eventually be freed in the same sweep. Therefore, each handle also has a numUsed reference
|
208
|
+
* count. On creation, a handle increments its parent's numUsed. On free, a handle decrements its parent's numUsed.
|
209
|
+
* A handle cannot be freed if its numUsed is greater than 0. Therefore, it is the responsibility of every child to
|
210
|
+
* check if it needs to clean up its parent.
|
291
211
|
*
|
292
|
-
*
|
293
|
-
*
|
294
|
-
* 2. When the garbage collector frees an object, the decr_function is called
|
295
|
-
* on the entity passing the entity as its parameter.
|
212
|
+
* When a handle has finally been deemed to be free-able, the cleanupFunc needs to be called to actually close out
|
213
|
+
* the handle's client instances.
|
296
214
|
*/
|
297
|
-
struct gc_entity
|
298
|
-
{
|
299
|
-
os_entity * entity;
|
300
|
-
VALUE ** mark_refs;
|
301
|
-
};
|
302
|
-
|
303
|
-
/*
|
304
|
-
* A strict release strategy only permits free calls after the reference count
|
305
|
-
* drops to zero. A lenient release strategy permits free calls at any time,
|
306
|
-
* yet the entity itself is not freed until its reference count drops to zero.
|
307
|
-
*/
|
308
|
-
typedef enum {strict, lenient} free_strategy;
|
309
|
-
|
310
|
-
#endif /* ENABLE_NEXTGEN_GC_INTEGRATION */
|
311
|
-
|
312
|
-
// ----------------------------------------------------------------------------
|
313
|
-
// H A N D L E S
|
314
215
|
|
315
216
|
struct nuodb_handle
|
316
217
|
{
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
218
|
+
bool freePending; //GC wants to free us, but we still have some children outstanding
|
219
|
+
void (*cleanupFunc)(nuodb_handle*); //cleanup function
|
220
|
+
|
221
|
+
int numUsed; //number of surviving children to prevent premature free
|
222
|
+
nuodb_handle* parent;
|
321
223
|
};
|
322
224
|
|
323
225
|
struct nuodb_connection_handle : nuodb_handle
|
@@ -328,128 +230,59 @@ struct nuodb_connection_handle : nuodb_handle
|
|
328
230
|
VALUE schema;
|
329
231
|
VALUE timezone;
|
330
232
|
|
331
|
-
NuoDB::Connection
|
233
|
+
NuoDB::Connection* pointer;
|
332
234
|
};
|
333
235
|
|
334
236
|
struct nuodb_prepared_statement_handle : nuodb_handle
|
335
237
|
{
|
336
|
-
NuoDB::PreparedStatement
|
238
|
+
NuoDB::PreparedStatement* pointer;
|
239
|
+
|
240
|
+
VALUE connection;
|
241
|
+
nuodb_connection_handle* connection_handle;
|
337
242
|
};
|
338
243
|
|
339
244
|
struct nuodb_statement_handle : nuodb_handle
|
340
245
|
{
|
341
|
-
NuoDB::Statement
|
246
|
+
NuoDB::Statement* pointer;
|
247
|
+
|
248
|
+
VALUE connection;
|
249
|
+
nuodb_connection_handle* connection_handle;
|
342
250
|
};
|
343
251
|
|
344
252
|
struct nuodb_result_handle : nuodb_handle
|
345
253
|
{
|
346
|
-
NuoDB::ResultSet
|
347
|
-
NuoDB::Connection
|
254
|
+
NuoDB::ResultSet* pointer;
|
255
|
+
NuoDB::Connection* connection;
|
256
|
+
|
257
|
+
VALUE statement;
|
258
|
+
int columnCount;
|
259
|
+
NuoDB::SqlType* types;
|
260
|
+
NuoDB::ResultSetMetaData* resultMetaData;
|
261
|
+
|
262
|
+
nuodb_prepared_statement_handle* prepStmt;
|
263
|
+
nuodb_statement_handle* stmt;
|
348
264
|
};
|
349
265
|
|
350
266
|
template<typename handle_type>
|
351
|
-
handle_type
|
267
|
+
handle_type* cast_handle(VALUE value)
|
352
268
|
{
|
353
269
|
Check_Type(value, T_DATA);
|
354
270
|
return static_cast<handle_type*>(DATA_PTR(value));
|
355
271
|
}
|
356
272
|
|
357
273
|
template<typename handle_type, typename return_type>
|
358
|
-
return_type
|
274
|
+
return_type* cast_pointer_member(VALUE value)
|
359
275
|
{
|
360
276
|
Check_Type(value, T_DATA);
|
361
277
|
return cast_handle<handle_type>(value)->pointer;
|
362
278
|
}
|
363
279
|
|
364
|
-
static void track_ref_count(char const * context, nuodb_handle * handle)
|
365
|
-
{
|
366
|
-
trace("track_ref_count");
|
367
|
-
|
368
|
-
if (handle != 0)
|
369
|
-
{
|
370
|
-
int parent_count = -10;
|
371
|
-
if (handle->parent_handle != 0)
|
372
|
-
{
|
373
|
-
parent_count = handle->parent_handle->atomic;
|
374
|
-
}
|
375
|
-
if (logLevel <= DEBUG)
|
376
|
-
{
|
377
|
-
nuodb_handle * parent = handle->parent_handle;
|
378
|
-
unsigned char *p = (unsigned char *)&handle;
|
379
|
-
unsigned char *q = (unsigned char *)&parent;
|
380
|
-
int i;
|
381
|
-
printf("[REFERENCE COUNT][%s] (%s @ ", context, demangle(typeid(*handle).name()));
|
382
|
-
for (i = 0; i < sizeof handle; i++)
|
383
|
-
{
|
384
|
-
printf("%02x ", p[i]);
|
385
|
-
}
|
386
|
-
printf("): %d (%s @ ", handle->atomic, demangle(typeid(*parent).name()));
|
387
|
-
for (i = 0; i < sizeof parent; i++)
|
388
|
-
{
|
389
|
-
printf("%02x ", q[i]);
|
390
|
-
}
|
391
|
-
printf("): %d", parent_count);
|
392
|
-
putchar('\n');
|
393
|
-
}
|
394
|
-
}
|
395
|
-
}
|
396
|
-
|
397
|
-
void incr_reference_count(nuodb_handle * handle)
|
398
|
-
{
|
399
|
-
trace("incr_reference_count");
|
400
|
-
|
401
|
-
track_ref_count("I INCR", handle);
|
402
|
-
|
403
|
-
ATOMIC_INC(handle->atomic);
|
404
|
-
if (handle->parent_handle != 0)
|
405
|
-
{
|
406
|
-
log(DEBUG, "incrementing parent");
|
407
|
-
ATOMIC_INC(handle->parent_handle->atomic);
|
408
|
-
}
|
409
|
-
|
410
|
-
track_ref_count("O INCR", handle);
|
411
|
-
}
|
412
|
-
|
413
|
-
void decr_reference_count(nuodb_handle * handle)
|
414
|
-
{
|
415
|
-
trace("decr_reference_count");
|
416
|
-
|
417
|
-
track_ref_count("I DECR", handle);
|
418
|
-
|
419
|
-
if (handle->atomic == 0)
|
420
|
-
{
|
421
|
-
return;
|
422
|
-
}
|
423
|
-
|
424
|
-
if (ATOMIC_DEC(handle->atomic) == 0)
|
425
|
-
{
|
426
|
-
(*(handle->free_func))(handle);
|
427
|
-
if (handle->parent_handle != 0)
|
428
|
-
{
|
429
|
-
log(DEBUG, "decrementing parent");
|
430
|
-
decr_reference_count(handle->parent_handle);
|
431
|
-
handle->parent = Qnil;
|
432
|
-
handle->parent_handle = 0;
|
433
|
-
assert(NIL_P(handle->parent));
|
434
|
-
}
|
435
|
-
track_ref_count("O DECR", handle);
|
436
|
-
|
437
|
-
print_address("[DELETING HANDLE]", handle);
|
438
|
-
xfree(handle);
|
439
|
-
handle = NULL;
|
440
|
-
}
|
441
|
-
else
|
442
|
-
{
|
443
|
-
track_ref_count("O DECR", handle);
|
444
|
-
}
|
445
|
-
}
|
446
|
-
|
447
280
|
//------------------------------------------------------------------------------
|
448
281
|
// exception mapper
|
449
282
|
|
450
283
|
static ID c_error_code_assignment;
|
451
284
|
|
452
|
-
static void rb_raise_nuodb_error(int code, const char
|
285
|
+
static void rb_raise_nuodb_error(int code, const char* fmt, ...)
|
453
286
|
{
|
454
287
|
va_list args;
|
455
288
|
char text[BUFSIZ];
|
@@ -468,60 +301,124 @@ static void rb_raise_nuodb_error(int code, const char * fmt, ...)
|
|
468
301
|
using namespace NuoDB;
|
469
302
|
|
470
303
|
//------------------------------------------------------------------------------
|
304
|
+
//
|
305
|
+
//
|
306
|
+
static
|
307
|
+
void handle_init(nuodb_handle* self, nuodb_handle* parent, int initialChildren, void (*cleaner)(nuodb_handle*))
|
308
|
+
{
|
309
|
+
self->numUsed = 0;
|
310
|
+
self->freePending = false;
|
311
|
+
self->cleanupFunc = NULL;
|
312
|
+
self->parent = parent;
|
313
|
+
self->cleanupFunc = cleaner;
|
314
|
+
}
|
471
315
|
|
316
|
+
/*
|
317
|
+
* Adjusts the parent's reference count
|
318
|
+
*/
|
472
319
|
static
|
473
|
-
|
320
|
+
int add_child(nuodb_handle* parent, nuodb_handle* child)
|
474
321
|
{
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
322
|
+
parent->numUsed++;
|
323
|
+
|
324
|
+
return parent->numUsed;
|
325
|
+
}
|
326
|
+
|
327
|
+
/*
|
328
|
+
* Decrements the parent's reference count. Returns whether or not this child was the last one.
|
329
|
+
* If true, that means the responsibility for freeing the parent rests with the child handle
|
330
|
+
* calling this function.
|
331
|
+
*/
|
332
|
+
static
|
333
|
+
bool remove_from_parent(nuodb_handle* child, nuodb_handle* parent)
|
334
|
+
{
|
335
|
+
//parent may be NULL
|
336
|
+
if (parent) {
|
337
|
+
parent->numUsed--;
|
338
|
+
assert(parent->numUsed >= 0);
|
339
|
+
return parent->numUsed == 0 && parent->freePending;
|
493
340
|
}
|
494
|
-
|
341
|
+
|
342
|
+
return false;
|
495
343
|
}
|
496
344
|
|
345
|
+
/*
|
346
|
+
* Method attempts to free handle and recursively free its parent if necessary. Returns a pointer
|
347
|
+
* to any exception encoundered while executing cleanup functions. Errors do not stop recursion.
|
348
|
+
* An error in the child won't stop this from attempting to free the parent. To do otherwise would
|
349
|
+
* cause a leak.
|
350
|
+
*/
|
497
351
|
static
|
498
|
-
|
352
|
+
NuoDB::SQLException* handle_free(nuodb_handle* handle, nuodb_handle* parent)
|
499
353
|
{
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
354
|
+
if (handle->numUsed == 0) {
|
355
|
+
bool needToRemoveParent = remove_from_parent(handle, parent);
|
356
|
+
|
357
|
+
NuoDB::SQLException* caughtError = NULL;
|
358
|
+
|
359
|
+
try {
|
360
|
+
//clean up ourselves
|
361
|
+
handle->cleanupFunc(handle);
|
362
|
+
} catch (NuoDB::SQLException& err) {
|
363
|
+
caughtError = &err;
|
364
|
+
}
|
365
|
+
|
366
|
+
try {
|
367
|
+
//clean up parent if we're the last ones out
|
368
|
+
if (needToRemoveParent) {
|
369
|
+
handle_free(parent, parent->parent);
|
370
|
+
}
|
371
|
+
} catch (NuoDB::SQLException& err) {
|
372
|
+
if (!caughtError) {
|
373
|
+
caughtError = &err;
|
374
|
+
}
|
508
375
|
}
|
376
|
+
|
377
|
+
//free ourselves
|
378
|
+
trace("freeing object");
|
379
|
+
free(handle);
|
380
|
+
|
381
|
+
return caughtError;
|
382
|
+
} else {
|
383
|
+
handle->freePending = true;
|
384
|
+
return NULL;
|
509
385
|
}
|
510
386
|
}
|
511
387
|
|
512
388
|
static
|
513
|
-
void nuodb_result_mark(void
|
389
|
+
void nuodb_result_mark(void* ptr)
|
514
390
|
{
|
515
391
|
trace("nuodb_result_mark");
|
516
|
-
nuodb_result_handle
|
517
|
-
rb_gc_mark(handle->
|
392
|
+
nuodb_result_handle* handle = static_cast<nuodb_result_handle *>(ptr);
|
393
|
+
rb_gc_mark(handle->statement);
|
518
394
|
}
|
519
395
|
|
520
396
|
static
|
521
|
-
void
|
397
|
+
void nuodb_result_cleanup(nuodb_handle* handle)
|
522
398
|
{
|
523
|
-
|
524
|
-
|
399
|
+
nuodb_result_handle* resultHandle = (nuodb_result_handle*)handle;
|
400
|
+
|
401
|
+
if (resultHandle && resultHandle->pointer) {
|
402
|
+
resultHandle->pointer->close();
|
403
|
+
}
|
404
|
+
}
|
405
|
+
|
406
|
+
static
|
407
|
+
void nuodb_result_free(nuodb_handle* handle)
|
408
|
+
{
|
409
|
+
trace("nuodb_result_free");
|
410
|
+
nuodb_result_handle* result_handle = (nuodb_result_handle*)handle;
|
411
|
+
|
412
|
+
if (result_handle) {
|
413
|
+
NuoDB::SQLException* err = handle_free(handle, (result_handle->prepStmt != NULL ? (nuodb_handle*)result_handle->prepStmt : (nuodb_handle*)result_handle->stmt));
|
414
|
+
|
415
|
+
if (err) {
|
416
|
+
//Not ok to raise an error during GC
|
417
|
+
//rb_raise_nuodb_error(err->getSqlcode(), "Failed to successfully close result set: %s", err->getText());
|
418
|
+
log(ERROR, "Failed to successfully close result set");
|
419
|
+
log(ERROR, err->getText());
|
420
|
+
}
|
421
|
+
}
|
525
422
|
}
|
526
423
|
|
527
424
|
/*
|
@@ -534,49 +431,9 @@ static
|
|
534
431
|
VALUE nuodb_result_finish(VALUE self)
|
535
432
|
{
|
536
433
|
trace("nuodb_result_free_protect");
|
537
|
-
nuodb_result_handle
|
434
|
+
nuodb_result_handle* handle = cast_handle<nuodb_result_handle>(self);
|
538
435
|
nuodb_result_free(handle);
|
539
|
-
// if (handle != NULL)
|
540
|
-
// {
|
541
|
-
// if (handle->pointer != NULL)
|
542
|
-
// {
|
543
|
-
// try
|
544
|
-
// {
|
545
|
-
// //handle->pointer->close();
|
546
|
-
// //handle->pointer = NULL;
|
547
|
-
// }
|
548
|
-
// catch (SQLException & e)
|
549
|
-
// {
|
550
|
-
// rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close result: %s", e.getText());
|
551
|
-
// }
|
552
|
-
// }
|
553
|
-
// }
|
554
436
|
return Qnil;
|
555
|
-
//
|
556
|
-
//
|
557
|
-
//
|
558
|
-
// trace("nuodb_result_finish");
|
559
|
-
// if (ENABLE_CLOSE_HOOK)
|
560
|
-
// {
|
561
|
-
// //nuodb_result_decr_reference_count(cast_handle<nuodb_result_handle>(self));
|
562
|
-
// }
|
563
|
-
// nuodb_result_handle * handle = ;
|
564
|
-
// if (handle != NULL && handle->pointer != NULL)
|
565
|
-
// {
|
566
|
-
// if (ATOMIC_DEC(handle->atomic) == 0)
|
567
|
-
// {
|
568
|
-
// try
|
569
|
-
// {
|
570
|
-
// //handle->pointer->close();
|
571
|
-
// //handle->pointer = NULL;
|
572
|
-
// }
|
573
|
-
// catch (SQLException & e)
|
574
|
-
// {
|
575
|
-
// rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close result set: %s", e.getText());
|
576
|
-
// }
|
577
|
-
// }
|
578
|
-
// }
|
579
|
-
// return Qnil;
|
580
437
|
}
|
581
438
|
|
582
439
|
static
|
@@ -592,6 +449,10 @@ VALUE nuodb_map_sql_type(int type)
|
|
592
449
|
symbol = ID2SYM(rb_intern("integer"));
|
593
450
|
break;
|
594
451
|
|
452
|
+
case NUOSQL_BINARY:
|
453
|
+
symbol = ID2SYM(rb_intern("binary"));
|
454
|
+
break;
|
455
|
+
|
595
456
|
case NUOSQL_FLOAT:
|
596
457
|
case NUOSQL_DOUBLE:
|
597
458
|
symbol = ID2SYM(rb_intern("float"));
|
@@ -628,18 +489,16 @@ VALUE nuodb_map_sql_type(int type)
|
|
628
489
|
symbol = ID2SYM(rb_intern("numeric"));
|
629
490
|
break;
|
630
491
|
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
//
|
492
|
+
case NUOSQL_BLOB:
|
493
|
+
symbol = ID2SYM(rb_intern("blob"));
|
494
|
+
break;
|
635
495
|
// case NUOSQL_CLOB:
|
636
496
|
// symbol = ID2SYM(rb_intern("clob"));
|
637
497
|
// break;
|
638
498
|
|
639
499
|
case NUOSQL_NULL:
|
640
|
-
case NUOSQL_BLOB:
|
500
|
+
//case NUOSQL_BLOB:
|
641
501
|
case NUOSQL_CLOB:
|
642
|
-
case NUOSQL_BINARY:
|
643
502
|
case NUOSQL_LONGVARBINARY:
|
644
503
|
default:
|
645
504
|
rb_raise(rb_eNotImpError, "Unsupported SQL type: %d", type);
|
@@ -647,53 +506,51 @@ VALUE nuodb_map_sql_type(int type)
|
|
647
506
|
return symbol;
|
648
507
|
}
|
649
508
|
static
|
650
|
-
VALUE
|
651
|
-
{
|
652
|
-
trace("
|
653
|
-
nuodb_handle
|
654
|
-
if (parent_handle != NULL)
|
655
|
-
|
656
|
-
nuodb_result_handle
|
657
|
-
handle
|
658
|
-
handle->
|
659
|
-
handle
|
660
|
-
|
509
|
+
VALUE nuodb_result_init(VALUE parent, NuoDB::ResultSet* results, NuoDB::Connection* connection)
|
510
|
+
{
|
511
|
+
trace("nuodb_result_init");
|
512
|
+
nuodb_handle* parent_handle = cast_handle<nuodb_handle>(parent);
|
513
|
+
if (parent_handle != NULL) {
|
514
|
+
trace("alloc result set");
|
515
|
+
nuodb_result_handle* handle = ALLOC(struct nuodb_result_handle);
|
516
|
+
handle_init(handle, parent_handle, 0, nuodb_result_cleanup);
|
517
|
+
handle->statement = parent;
|
518
|
+
add_child(parent_handle, handle);
|
519
|
+
|
520
|
+
handle->prepStmt = NULL;
|
521
|
+
handle->stmt = NULL;
|
522
|
+
handle->columnCount = -1;
|
523
|
+
handle->types = NULL;
|
524
|
+
handle->resultMetaData = NULL;
|
661
525
|
handle->pointer = results;
|
662
526
|
handle->connection = connection;
|
663
|
-
|
664
|
-
VALUE self = Data_Wrap_Struct(nuodb_result_klass, nuodb_result_mark, nuodb_result_decr_reference_count, handle);
|
527
|
+
VALUE self = Data_Wrap_Struct(nuodb_result_klass, nuodb_result_mark, nuodb_result_free, handle);
|
665
528
|
|
666
529
|
rb_iv_set(self, "@columns", Qnil);
|
667
530
|
rb_iv_set(self, "@rows", Qnil);
|
668
531
|
|
669
532
|
if (!rb_block_given_p()) {
|
670
|
-
trace("
|
533
|
+
trace("nuodb_result_init: no block");
|
671
534
|
|
672
535
|
return self;
|
673
536
|
}
|
674
537
|
|
675
|
-
trace("
|
538
|
+
trace("nuodb_result_init: begin block");
|
676
539
|
|
677
540
|
int exception = 0;
|
678
541
|
VALUE result = rb_protect(rb_yield, self, &exception);
|
679
542
|
|
680
|
-
trace("
|
543
|
+
trace("nuodb_result_init: end block");
|
681
544
|
|
682
|
-
|
545
|
+
trace("nuodb_result_init: auto finish");
|
683
546
|
|
684
|
-
|
685
|
-
|
686
|
-
if (exception)
|
687
|
-
{
|
547
|
+
if (exception) {
|
548
|
+
//@TODO - don't we need to free here?
|
688
549
|
rb_jump_tag(exception);
|
689
|
-
}
|
690
|
-
else
|
691
|
-
{
|
550
|
+
} else {
|
692
551
|
return result;
|
693
552
|
}
|
694
|
-
}
|
695
|
-
else
|
696
|
-
{
|
553
|
+
} else {
|
697
554
|
rb_raise(rb_eArgError, "invalid state: statement handle nil");
|
698
555
|
}
|
699
556
|
return Qnil;
|
@@ -708,10 +565,9 @@ nuodb_get_rb_timezone_offset()
|
|
708
565
|
}
|
709
566
|
|
710
567
|
static VALUE
|
711
|
-
nuodb_get_rb_value(int column, SqlType type, ResultSet
|
568
|
+
nuodb_get_rb_value(int column, SqlType type, ResultSet* results)
|
712
569
|
{
|
713
570
|
VALUE value = Qnil;
|
714
|
-
|
715
571
|
switch (type)
|
716
572
|
{
|
717
573
|
case NUOSQL_BIT:
|
@@ -764,11 +620,13 @@ nuodb_get_rb_value(int column, SqlType type, ResultSet * results)
|
|
764
620
|
}
|
765
621
|
break;
|
766
622
|
}
|
767
|
-
|
623
|
+
|
624
|
+
case NUOSQL_BLOB:
|
625
|
+
case NUOSQL_BINARY:
|
768
626
|
case NUOSQL_VARCHAR:
|
769
627
|
case NUOSQL_LONGVARCHAR:
|
770
628
|
{
|
771
|
-
char const
|
629
|
+
char const* field = results->getString(column);
|
772
630
|
if (!results->wasNull())
|
773
631
|
{
|
774
632
|
value = rb_str_new2(field);
|
@@ -777,7 +635,7 @@ nuodb_get_rb_value(int column, SqlType type, ResultSet * results)
|
|
777
635
|
}
|
778
636
|
case NUOSQL_DATE:
|
779
637
|
{
|
780
|
-
NuoDB::Date
|
638
|
+
NuoDB::Date* field = results->getDate(column);
|
781
639
|
if (!results->wasNull())
|
782
640
|
{
|
783
641
|
double secs = (double) field->getSeconds();
|
@@ -789,17 +647,17 @@ nuodb_get_rb_value(int column, SqlType type, ResultSet * results)
|
|
789
647
|
case NUOSQL_TIME:
|
790
648
|
case NUOSQL_TIMESTAMP:
|
791
649
|
{
|
792
|
-
NuoDB::Timestamp
|
650
|
+
NuoDB::Timestamp* field = results->getTimestamp(column);
|
793
651
|
if (!results->wasNull())
|
794
652
|
{
|
795
|
-
double secs = ((double) field->getSeconds()) + (((double) field->getNanos()) /
|
653
|
+
double secs = ((double) field->getSeconds()) + (((double) field->getNanos()) / NANOS_PER_SECOND);
|
796
654
|
value = rb_funcall(rb_cTime, rb_intern("at"), 1, rb_float_new(secs)); // - nuodb_get_rb_timezone_offset()
|
797
655
|
}
|
798
656
|
break;
|
799
657
|
}
|
800
658
|
case NUOSQL_NUMERIC:
|
801
659
|
{
|
802
|
-
char const
|
660
|
+
char const* field = results->getString(column);
|
803
661
|
if (!results->wasNull())
|
804
662
|
{
|
805
663
|
rb_require("bigdecimal");
|
@@ -812,13 +670,23 @@ nuodb_get_rb_value(int column, SqlType type, ResultSet * results)
|
|
812
670
|
}
|
813
671
|
default:
|
814
672
|
{
|
815
|
-
rb_raise(rb_eTypeError, "
|
673
|
+
rb_raise(rb_eTypeError, "Not a supported ruby type: %d", type);
|
816
674
|
break;
|
817
675
|
}
|
818
676
|
}
|
819
677
|
return value;
|
820
678
|
}
|
821
679
|
|
680
|
+
static
|
681
|
+
NuoDB::ResultSetMetaData* getResultMetadata(nuodb_result_handle* result_handle)
|
682
|
+
{
|
683
|
+
if (!result_handle->resultMetaData && result_handle->pointer) {
|
684
|
+
result_handle->resultMetaData = result_handle->pointer->getMetaData();
|
685
|
+
}
|
686
|
+
|
687
|
+
return result_handle->resultMetaData;
|
688
|
+
}
|
689
|
+
|
822
690
|
/*
|
823
691
|
* call-seq:
|
824
692
|
* result.columns -> ary
|
@@ -835,53 +703,26 @@ static VALUE
|
|
835
703
|
nuodb_result_columns(VALUE self)
|
836
704
|
{
|
837
705
|
trace("nuodb_result_columns");
|
838
|
-
nuodb_result_handle
|
839
|
-
if (handle != NULL && handle->pointer != NULL)
|
840
|
-
{
|
706
|
+
nuodb_result_handle* handle = cast_handle<nuodb_result_handle>(self);
|
707
|
+
if (handle != NULL && handle->pointer != NULL) {
|
841
708
|
VALUE columns = rb_iv_get(self, "@columns");
|
842
|
-
|
843
|
-
{
|
844
|
-
try
|
845
|
-
|
846
|
-
ResultSetMetaData * result_metadata = handle->pointer->getMetaData();
|
847
|
-
DatabaseMetaData * database_metadata = handle->connection->getMetaData();
|
709
|
+
|
710
|
+
if (NIL_P(columns)) {
|
711
|
+
try {
|
712
|
+
ResultSetMetaData* result_metadata = getResultMetadata(handle);
|
848
713
|
|
849
714
|
VALUE array = rb_ary_new();
|
850
715
|
rb_require("nuodb/column");
|
851
716
|
VALUE column_klass = rb_const_get(m_nuodb, rb_intern("Column"));
|
852
717
|
|
853
718
|
int column_count = result_metadata->getColumnCount();
|
854
|
-
for (int column_index = 1; column_index < column_count + 1; ++column_index)
|
855
|
-
{
|
856
|
-
char const * schema_name = result_metadata->getSchemaName(column_index);
|
857
|
-
char const * table_name = result_metadata->getTableName(column_index);
|
858
|
-
char const * column_name = result_metadata->getColumnName(column_index);
|
859
|
-
|
860
|
-
// args: [name, default, sql_type, null]
|
719
|
+
for (int column_index = 1; column_index < column_count + 1; ++column_index) {
|
861
720
|
VALUE args[4];
|
862
721
|
|
863
722
|
args[0] = rb_str_new2(result_metadata->getColumnLabel(column_index));
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
if(database_metadata_results->next())
|
869
|
-
{
|
870
|
-
try
|
871
|
-
{
|
872
|
-
args[1] = nuodb_get_rb_value(database_metadata_results->findColumn("COLUMN_DEF"),
|
873
|
-
(SqlType) result_metadata->getColumnType(column_index), database_metadata_results);
|
874
|
-
}
|
875
|
-
catch (SQLException & e)
|
876
|
-
{
|
877
|
-
args[1] = Qnil;
|
878
|
-
}
|
879
|
-
}
|
880
|
-
else
|
881
|
-
{
|
882
|
-
args[1] = Qnil;
|
883
|
-
}
|
884
|
-
database_metadata_results->close();
|
723
|
+
|
724
|
+
//Can't issue database metadata queries as that will close out the current transaction due to a bug
|
725
|
+
args[1] = Qnil;
|
885
726
|
|
886
727
|
args[2] = nuodb_map_sql_type(result_metadata->getColumnType(column_index));
|
887
728
|
args[3] = result_metadata->isNullable(column_index) ? Qtrue : Qfalse;
|
@@ -893,24 +734,40 @@ nuodb_result_columns(VALUE self)
|
|
893
734
|
rb_iv_set(self, "@columns", array);
|
894
735
|
|
895
736
|
return array;
|
896
|
-
}
|
897
|
-
catch (SQLException & e)
|
898
|
-
{
|
737
|
+
} catch (SQLException & e) {
|
899
738
|
rb_raise_nuodb_error(e.getSqlcode(), "Failed to create column info: %s", e.getText());
|
900
739
|
}
|
901
|
-
}
|
902
|
-
else
|
903
|
-
{
|
740
|
+
} else {
|
904
741
|
return columns;
|
905
742
|
}
|
906
|
-
}
|
907
|
-
else
|
908
|
-
{
|
743
|
+
} else {
|
909
744
|
rb_raise(rb_eArgError, "invalid state: result handle nil");
|
910
745
|
}
|
911
746
|
return Qnil;
|
912
747
|
}
|
913
748
|
|
749
|
+
static
|
750
|
+
void nuodb_populate_row_metadata(nuodb_result_handle* result_handle)
|
751
|
+
{
|
752
|
+
if (!result_handle->pointer || result_handle->types != NULL) {
|
753
|
+
return;
|
754
|
+
}
|
755
|
+
trace("populating row metadata");
|
756
|
+
|
757
|
+
NuoDB::ResultSetMetaData* metadata = getResultMetadata(result_handle);
|
758
|
+
assert(metadata != NULL);
|
759
|
+
|
760
|
+
int32_t column_count = metadata->getColumnCount();
|
761
|
+
result_handle->columnCount = column_count;
|
762
|
+
result_handle->types = ALLOC_N(SqlType, column_count);
|
763
|
+
|
764
|
+
for (int32_t column = 1; column < column_count + 1; column++) {
|
765
|
+
SqlType type = (SqlType) metadata->getColumnType(column);
|
766
|
+
result_handle->types[column-1] = type;
|
767
|
+
}
|
768
|
+
|
769
|
+
}
|
770
|
+
|
914
771
|
/*
|
915
772
|
* call-seq:
|
916
773
|
* result.rows -> ary
|
@@ -932,25 +789,24 @@ static VALUE
|
|
932
789
|
nuodb_result_rows(VALUE self)
|
933
790
|
{
|
934
791
|
trace("nuodb_result_rows");
|
935
|
-
nuodb_result_handle
|
936
|
-
|
937
|
-
{
|
792
|
+
nuodb_result_handle* handle = cast_handle<nuodb_result_handle>(self);
|
793
|
+
|
794
|
+
if (handle != NULL && handle->pointer != NULL) {
|
795
|
+
|
938
796
|
VALUE rows = rb_iv_get(self, "@rows");
|
939
|
-
|
940
|
-
{
|
941
|
-
try
|
942
|
-
|
797
|
+
|
798
|
+
if (NIL_P(rows)) {
|
799
|
+
try {
|
800
|
+
nuodb_populate_row_metadata(handle);
|
943
801
|
rows = rb_ary_new();
|
944
802
|
|
945
|
-
while (handle->pointer->next())
|
946
|
-
|
803
|
+
while (handle->pointer->next()) {
|
804
|
+
|
947
805
|
VALUE row = rb_ary_new();
|
948
806
|
|
949
|
-
|
950
|
-
int32_t
|
951
|
-
|
952
|
-
{
|
953
|
-
SqlType type = (SqlType) metadata->getColumnType(column);
|
807
|
+
//remember, SQL result set columns are 1-indexed
|
808
|
+
for (int32_t column = 1; column < handle->columnCount + 1; column++) {
|
809
|
+
SqlType type = handle->types[column - 1];
|
954
810
|
rb_ary_push(row, nuodb_get_rb_value(column, type, handle->pointer));
|
955
811
|
}
|
956
812
|
|
@@ -958,16 +814,12 @@ nuodb_result_rows(VALUE self)
|
|
958
814
|
}
|
959
815
|
|
960
816
|
rb_iv_set(self, "@rows", rows);
|
961
|
-
}
|
962
|
-
catch (SQLException & e)
|
963
|
-
{
|
817
|
+
} catch (SQLException & e) {
|
964
818
|
rb_raise_nuodb_error(e.getSqlcode(), "Failed to create a rows array: %s", e.getText());
|
965
819
|
}
|
966
820
|
}
|
967
821
|
return rows;
|
968
|
-
}
|
969
|
-
else
|
970
|
-
{
|
822
|
+
} else {
|
971
823
|
rb_raise(rb_eArgError, "invalid state: result handle nil");
|
972
824
|
}
|
973
825
|
return Qnil;
|
@@ -992,7 +844,7 @@ static VALUE
|
|
992
844
|
nuodb_result_each(VALUE self)
|
993
845
|
{
|
994
846
|
trace("nuodb_result_each");
|
995
|
-
nuodb_result_handle
|
847
|
+
nuodb_result_handle* handle = cast_handle<nuodb_result_handle>(self);
|
996
848
|
if (handle != NULL && handle->pointer != NULL)
|
997
849
|
{
|
998
850
|
VALUE rows = rb_iv_get(self, "@rows");
|
@@ -1038,59 +890,43 @@ void nuodb_define_result_api()
|
|
1038
890
|
//------------------------------------------------------------------------------
|
1039
891
|
|
1040
892
|
static
|
1041
|
-
|
893
|
+
void nuodb_statement_mark(void* ptr)
|
1042
894
|
{
|
1043
|
-
trace("
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
if (handle->pointer != NULL)
|
1048
|
-
{
|
1049
|
-
try
|
1050
|
-
{
|
1051
|
-
log(INFO, "closing statement");
|
1052
|
-
handle->pointer->close();
|
1053
|
-
handle->pointer = NULL;
|
1054
|
-
}
|
1055
|
-
catch (SQLException & e)
|
1056
|
-
{
|
1057
|
-
rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close statement: %s", e.getText());
|
1058
|
-
}
|
1059
|
-
}
|
1060
|
-
}
|
1061
|
-
return Qnil;
|
895
|
+
trace("nuodb_statement_mark");
|
896
|
+
|
897
|
+
nuodb_statement_handle* handle = static_cast<nuodb_statement_handle *>(ptr);
|
898
|
+
rb_gc_mark(handle->connection);
|
1062
899
|
}
|
1063
900
|
|
1064
901
|
static
|
1065
|
-
void nuodb_statement_free(void
|
902
|
+
void nuodb_statement_free(void* ptr)
|
1066
903
|
{
|
1067
904
|
trace("nuodb_statement_free");
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
{
|
1074
|
-
|
905
|
+
nuodb_statement_handle* handle = (nuodb_statement_handle*)ptr;
|
906
|
+
|
907
|
+
if (handle && handle->pointer) {
|
908
|
+
NuoDB::SQLException* err = handle_free(handle, handle->connection_handle);
|
909
|
+
|
910
|
+
if (err) {
|
911
|
+
//Not ok to raise an error during GC
|
912
|
+
//rb_raise_nuodb_error(err->getSqlcode(), "Failed to successfully close statement: %s", err->getText());
|
913
|
+
log(ERROR, "Failed to successfully close statement");
|
914
|
+
log(ERROR, err->getText());
|
1075
915
|
}
|
1076
916
|
}
|
917
|
+
|
1077
918
|
}
|
1078
919
|
|
1079
920
|
static
|
1080
|
-
void
|
921
|
+
void nuodb_statement_cleanup(nuodb_handle* handle)
|
1081
922
|
{
|
1082
|
-
|
923
|
+
nuodb_statement_handle* statementHandle = (nuodb_statement_handle*)handle;
|
1083
924
|
|
1084
|
-
|
1085
|
-
|
925
|
+
if (statementHandle && statementHandle->pointer) {
|
926
|
+
statementHandle->pointer->close();
|
927
|
+
}
|
1086
928
|
}
|
1087
929
|
|
1088
|
-
static
|
1089
|
-
void nuodb_statement_decr_reference_count(void * ptr)
|
1090
|
-
{
|
1091
|
-
trace("nuodb_statement_decr_reference_count");
|
1092
|
-
decr_reference_count(static_cast<nuodb_statement_handle *>(ptr));
|
1093
|
-
}
|
1094
930
|
|
1095
931
|
/*
|
1096
932
|
* call-seq:
|
@@ -1102,39 +938,9 @@ static
|
|
1102
938
|
VALUE nuodb_statement_finish(VALUE self)
|
1103
939
|
{
|
1104
940
|
trace("nuodb_statement_finish");
|
1105
|
-
nuodb_statement_handle
|
941
|
+
nuodb_statement_handle* handle = cast_handle<nuodb_statement_handle>(self);//reinterpret_cast<nuodb_statement_handle*>(value);
|
1106
942
|
nuodb_statement_free(handle);
|
1107
|
-
// if (handle != NULL)
|
1108
|
-
// {
|
1109
|
-
// if (handle->pointer != NULL)
|
1110
|
-
// {
|
1111
|
-
// try
|
1112
|
-
// {
|
1113
|
-
// log(INFO, "closing statement");
|
1114
|
-
// handle->pointer->close();
|
1115
|
-
// handle->pointer = NULL;
|
1116
|
-
// }
|
1117
|
-
// catch (SQLException & e)
|
1118
|
-
// {
|
1119
|
-
// rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close statement: %s", e.getText());
|
1120
|
-
// }
|
1121
|
-
// }
|
1122
|
-
// }
|
1123
943
|
return Qnil;
|
1124
|
-
//
|
1125
|
-
// if (ENABLE_CLOSE_HOOK)
|
1126
|
-
// {
|
1127
|
-
// nuodb_statement_handle * handle = cast_handle<nuodb_statement_handle>(self);
|
1128
|
-
// if (handle != NULL && handle->pointer != NULL)
|
1129
|
-
// {
|
1130
|
-
// nuodb_statement_decr_reference_count(handle);
|
1131
|
-
// }
|
1132
|
-
// else
|
1133
|
-
// {
|
1134
|
-
// rb_raise(rb_eArgError, "invalid state: statement handle nil");
|
1135
|
-
// }
|
1136
|
-
// }
|
1137
|
-
// return Qnil;
|
1138
944
|
}
|
1139
945
|
|
1140
946
|
static
|
@@ -1142,33 +948,28 @@ VALUE nuodb_statement_initialize(VALUE parent)
|
|
1142
948
|
{
|
1143
949
|
trace("nuodb_statement_initialize");
|
1144
950
|
|
1145
|
-
nuodb_connection_handle
|
1146
|
-
|
1147
|
-
{
|
1148
|
-
NuoDB::Statement
|
1149
|
-
try
|
1150
|
-
{
|
951
|
+
nuodb_connection_handle* parent_handle = cast_handle<nuodb_connection_handle>(parent);
|
952
|
+
|
953
|
+
if (parent_handle != NULL && parent_handle->pointer != NULL) {
|
954
|
+
NuoDB::Statement* statement = NULL;
|
955
|
+
try {
|
1151
956
|
statement = parent_handle->pointer->createStatement();
|
1152
|
-
}
|
1153
|
-
catch (SQLException & e)
|
1154
|
-
{
|
957
|
+
} catch (SQLException & e) {
|
1155
958
|
log(ERROR, "rb_raise");
|
1156
959
|
rb_raise_nuodb_error(e.getSqlcode(), "Failed to create statement: %s", e.getText());
|
1157
960
|
}
|
1158
961
|
|
1159
|
-
|
962
|
+
trace("alloc");
|
963
|
+
nuodb_statement_handle* handle = ALLOC(nuodb_statement_handle);
|
964
|
+
handle_init(handle, parent_handle, 1, nuodb_statement_cleanup);
|
965
|
+
add_child(parent_handle, handle);
|
1160
966
|
|
1161
|
-
handle->
|
1162
|
-
handle->
|
1163
|
-
handle->parent = parent;
|
1164
|
-
handle->parent_handle = parent_handle;
|
967
|
+
handle->connection = parent;
|
968
|
+
handle->connection_handle = parent_handle;
|
1165
969
|
handle->pointer = statement;
|
1166
|
-
|
1167
|
-
assert(handle->atomic = 1);
|
1168
|
-
VALUE self = Data_Wrap_Struct(nuodb_statement_klass, nuodb_statement_mark, nuodb_statement_decr_reference_count, handle);
|
970
|
+
VALUE self = Data_Wrap_Struct(nuodb_statement_klass, nuodb_statement_mark, nuodb_statement_free, handle);
|
1169
971
|
if (!rb_block_given_p()) {
|
1170
972
|
trace("nuodb_statement_initialize: no block");
|
1171
|
-
track_ref_count("ALLOC STMT S", cast_handle<nuodb_handle>(self));
|
1172
973
|
return self;
|
1173
974
|
}
|
1174
975
|
|
@@ -1184,17 +985,13 @@ VALUE nuodb_statement_initialize(VALUE parent)
|
|
1184
985
|
|
1185
986
|
trace("nuodb_statement_initialize: auto finish");
|
1186
987
|
|
1187
|
-
if (exception)
|
1188
|
-
|
988
|
+
if (exception) {
|
989
|
+
//@TODO - don't we need to free memory here?
|
1189
990
|
rb_jump_tag(exception);
|
1190
|
-
}
|
1191
|
-
else
|
1192
|
-
{
|
991
|
+
} else {
|
1193
992
|
return result;
|
1194
993
|
}
|
1195
|
-
}
|
1196
|
-
else
|
1197
|
-
{
|
994
|
+
} else {
|
1198
995
|
rb_raise(rb_eArgError, "invalid state: statement handle nil");
|
1199
996
|
}
|
1200
997
|
return Qnil;
|
@@ -1218,7 +1015,7 @@ VALUE nuodb_statement_execute(VALUE self, VALUE sql)
|
|
1218
1015
|
rb_raise(rb_eTypeError, "wrong sql argument type %s (String expected)", rb_class2name(CLASS_OF(sql)));
|
1219
1016
|
}
|
1220
1017
|
|
1221
|
-
nuodb_statement_handle
|
1018
|
+
nuodb_statement_handle* handle = cast_handle<nuodb_statement_handle>(self);
|
1222
1019
|
if (handle != NULL && handle->pointer != NULL)
|
1223
1020
|
{
|
1224
1021
|
try
|
@@ -1249,7 +1046,7 @@ VALUE nuodb_statement_update_count(VALUE self)
|
|
1249
1046
|
{
|
1250
1047
|
trace("nuodb_statement_update_count");
|
1251
1048
|
|
1252
|
-
nuodb_statement_handle
|
1049
|
+
nuodb_statement_handle* handle = cast_handle<nuodb_statement_handle>(self);
|
1253
1050
|
if (handle != NULL && handle->pointer != NULL)
|
1254
1051
|
{
|
1255
1052
|
try
|
@@ -1278,12 +1075,20 @@ static VALUE nuodb_statement_results(VALUE self)
|
|
1278
1075
|
{
|
1279
1076
|
trace("nuodb_statement_results");
|
1280
1077
|
|
1281
|
-
nuodb_statement_handle
|
1078
|
+
nuodb_statement_handle* handle = cast_handle<nuodb_statement_handle>(self);
|
1282
1079
|
if (handle != NULL && handle->pointer != NULL)
|
1283
1080
|
{
|
1284
1081
|
try
|
1285
1082
|
{
|
1286
|
-
|
1083
|
+
VALUE ruby_handle = nuodb_result_init(self, handle->pointer->getResultSet(), handle->pointer->getConnection());
|
1084
|
+
nuodb_result_handle* our_result_handle = cast_handle<nuodb_result_handle>(ruby_handle);
|
1085
|
+
|
1086
|
+
assert(our_result_handle != NULL);
|
1087
|
+
assert(our_result_handle->prepStmt == NULL);
|
1088
|
+
assert(our_result_handle->stmt == NULL);
|
1089
|
+
|
1090
|
+
our_result_handle->stmt = handle;
|
1091
|
+
return ruby_handle;
|
1287
1092
|
}
|
1288
1093
|
catch (SQLException & e)
|
1289
1094
|
{
|
@@ -1308,26 +1113,27 @@ static VALUE nuodb_statement_generated_keys(VALUE self)
|
|
1308
1113
|
{
|
1309
1114
|
trace("nuodb_statement_generated_keys");
|
1310
1115
|
|
1311
|
-
nuodb_statement_handle
|
1312
|
-
if (handle != NULL && handle->pointer != NULL)
|
1313
|
-
|
1314
|
-
try
|
1315
|
-
{
|
1116
|
+
nuodb_statement_handle* handle = cast_handle<nuodb_statement_handle>(self);
|
1117
|
+
if (handle != NULL && handle->pointer != NULL) {
|
1118
|
+
try {
|
1316
1119
|
// this hack should not have been necessary; it should never have
|
1317
1120
|
// returned null, this is a product defect.
|
1318
|
-
ResultSet
|
1319
|
-
if (results != NULL)
|
1320
|
-
|
1321
|
-
|
1121
|
+
ResultSet* results = handle->pointer->getGeneratedKeys();
|
1122
|
+
if (results != NULL) {
|
1123
|
+
VALUE ruby_handle = nuodb_result_init(self, results, handle->pointer->getConnection());
|
1124
|
+
nuodb_result_handle* our_result_handle = cast_handle<nuodb_result_handle>(ruby_handle);
|
1125
|
+
|
1126
|
+
assert(our_result_handle != NULL);
|
1127
|
+
assert(our_result_handle->prepStmt == NULL);
|
1128
|
+
assert(our_result_handle->stmt == NULL);
|
1129
|
+
|
1130
|
+
our_result_handle->stmt = handle;
|
1131
|
+
return ruby_handle;
|
1322
1132
|
}
|
1323
|
-
}
|
1324
|
-
catch (SQLException & e)
|
1325
|
-
{
|
1133
|
+
} catch (SQLException & e) {
|
1326
1134
|
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get the generated keys for the statement: %s", e.getText());
|
1327
1135
|
}
|
1328
|
-
}
|
1329
|
-
else
|
1330
|
-
{
|
1136
|
+
} else {
|
1331
1137
|
rb_raise(rb_eArgError, "invalid state: statement handle nil");
|
1332
1138
|
}
|
1333
1139
|
return Qnil;
|
@@ -1360,60 +1166,40 @@ void nuodb_define_statement_api()
|
|
1360
1166
|
//------------------------------------------------------------------------------
|
1361
1167
|
|
1362
1168
|
static
|
1363
|
-
|
1169
|
+
void nuodb_prepared_statement_free(void* ptr)
|
1364
1170
|
{
|
1365
|
-
trace("
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
{
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
handle->pointer = NULL;
|
1377
|
-
}
|
1378
|
-
catch (SQLException & e)
|
1379
|
-
{
|
1380
|
-
rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close statement: %s", e.getText());
|
1381
|
-
}
|
1171
|
+
trace("nuodb_prepared_statement_free");
|
1172
|
+
|
1173
|
+
if (ptr != NULL) {
|
1174
|
+
nuodb_prepared_statement_handle* handle = (nuodb_prepared_statement_handle*)ptr;
|
1175
|
+
NuoDB::SQLException* err = handle_free(handle, handle->connection_handle);
|
1176
|
+
|
1177
|
+
if (err) {
|
1178
|
+
//Not ok to raise a ruby error during GC
|
1179
|
+
//rb_raise_nuodb_error(err->getSqlcode(), "Failed to successfully close prepared statement: %s", err->getText());
|
1180
|
+
log(ERROR, "Failed to successfully close prepared statement");
|
1181
|
+
log(ERROR, err->getText());
|
1382
1182
|
}
|
1383
1183
|
}
|
1384
|
-
return Qnil;
|
1385
1184
|
}
|
1386
1185
|
|
1387
1186
|
static
|
1388
|
-
void
|
1187
|
+
void nuodb_prepared_statement_cleanup(nuodb_handle* handle)
|
1389
1188
|
{
|
1390
|
-
|
1189
|
+
nuodb_prepared_statement_handle* prepHandle = (nuodb_prepared_statement_handle*)prepHandle;
|
1391
1190
|
|
1392
|
-
if (
|
1393
|
-
|
1394
|
-
int exception = 0;
|
1395
|
-
rb_protect(nuodb_prepared_statement_free_protect, reinterpret_cast<VALUE>(ptr), &exception);
|
1396
|
-
if (exception)
|
1397
|
-
{
|
1398
|
-
rb_jump_tag(exception);
|
1399
|
-
}
|
1191
|
+
if (prepHandle && prepHandle->pointer) {
|
1192
|
+
prepHandle->pointer->close();
|
1400
1193
|
}
|
1401
1194
|
}
|
1402
1195
|
|
1403
1196
|
static
|
1404
|
-
void nuodb_prepared_statement_mark(void
|
1197
|
+
void nuodb_prepared_statement_mark(void* ptr)
|
1405
1198
|
{
|
1406
1199
|
trace("nuodb_prepared_statement_mark");
|
1407
1200
|
|
1408
|
-
nuodb_prepared_statement_handle
|
1409
|
-
rb_gc_mark(handle->
|
1410
|
-
}
|
1411
|
-
|
1412
|
-
static
|
1413
|
-
void nuodb_prepared_statement_decr_reference_count(nuodb_handle * handle)
|
1414
|
-
{
|
1415
|
-
trace("nuodb_prepared_statement_decr_reference_count");
|
1416
|
-
decr_reference_count(handle);
|
1201
|
+
nuodb_prepared_statement_handle* handle = (nuodb_prepared_statement_handle *)ptr;
|
1202
|
+
rb_gc_mark(handle->connection);
|
1417
1203
|
}
|
1418
1204
|
|
1419
1205
|
/*
|
@@ -1426,41 +1212,9 @@ static
|
|
1426
1212
|
VALUE nuodb_prepared_statement_finish(VALUE self)
|
1427
1213
|
{
|
1428
1214
|
trace("nuodb_prepared_statement_finish");
|
1429
|
-
nuodb_prepared_statement_handle
|
1430
|
-
track_ref_count("FINISH PSTMT", handle);
|
1215
|
+
nuodb_prepared_statement_handle* handle = cast_handle<nuodb_prepared_statement_handle>(self);//reinterpret_cast<nuodb_prepared_statement_handle *>(value);
|
1431
1216
|
nuodb_prepared_statement_free(handle);
|
1432
|
-
// if (handle != NULL)
|
1433
|
-
// {
|
1434
|
-
// if (handle->pointer != NULL)
|
1435
|
-
// {
|
1436
|
-
// try
|
1437
|
-
// {
|
1438
|
-
// track_ref_count("CLOSE PSTMT", handle);
|
1439
|
-
// log(INFO, "closing prepared statement");
|
1440
|
-
// handle->pointer->close();
|
1441
|
-
// handle->pointer = NULL;
|
1442
|
-
// }
|
1443
|
-
// catch (SQLException & e)
|
1444
|
-
// {
|
1445
|
-
// rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close statement: %s", e.getText());
|
1446
|
-
// }
|
1447
|
-
// }
|
1448
|
-
// }
|
1449
1217
|
return Qnil;
|
1450
|
-
//
|
1451
|
-
// if (ENABLE_CLOSE_HOOK)
|
1452
|
-
// {
|
1453
|
-
// nuodb_prepared_statement_handle * handle = cast_handle<nuodb_prepared_statement_handle>(self);
|
1454
|
-
// if (handle != NULL && handle->pointer != NULL)
|
1455
|
-
// {
|
1456
|
-
// nuodb_prepared_statement_decr_reference_count(handle);
|
1457
|
-
// }
|
1458
|
-
// else
|
1459
|
-
// {
|
1460
|
-
// rb_raise(rb_eArgError, "invalid state: prepared statement handle nil");
|
1461
|
-
// }
|
1462
|
-
// }
|
1463
|
-
// return Qnil;
|
1464
1218
|
}
|
1465
1219
|
|
1466
1220
|
static
|
@@ -1468,34 +1222,30 @@ VALUE nuodb_prepared_statement_initialize(VALUE parent, VALUE sql)
|
|
1468
1222
|
{
|
1469
1223
|
trace("nuodb_prepared_statement_initialize");
|
1470
1224
|
|
1471
|
-
if (TYPE(sql) != T_STRING)
|
1472
|
-
{
|
1225
|
+
if (TYPE(sql) != T_STRING) {
|
1473
1226
|
rb_raise(rb_eTypeError, "wrong sql argument type %s (String expected)", rb_class2name(CLASS_OF(sql)));
|
1474
1227
|
}
|
1475
1228
|
|
1476
|
-
nuodb_connection_handle
|
1477
|
-
|
1478
|
-
{
|
1479
|
-
NuoDB::PreparedStatement
|
1480
|
-
try
|
1481
|
-
{
|
1229
|
+
nuodb_connection_handle* parent_handle = cast_handle<nuodb_connection_handle>(parent);
|
1230
|
+
|
1231
|
+
if (parent_handle != NULL && parent_handle->pointer != NULL) {
|
1232
|
+
NuoDB::PreparedStatement* statement = NULL;
|
1233
|
+
try {
|
1482
1234
|
statement = parent_handle->pointer->prepareStatement(StringValueCStr(sql),
|
1483
1235
|
NuoDB::RETURN_GENERATED_KEYS);
|
1484
|
-
}
|
1485
|
-
catch (SQLException & e)
|
1486
|
-
{
|
1236
|
+
} catch (SQLException & e) {
|
1487
1237
|
rb_raise_nuodb_error(e.getSqlcode(), "Failed to create prepared statement (%s): %s", sql, e.getText());
|
1488
1238
|
}
|
1489
1239
|
|
1490
|
-
|
1491
|
-
handle
|
1492
|
-
handle
|
1493
|
-
handle
|
1494
|
-
|
1240
|
+
trace("alloc");
|
1241
|
+
nuodb_prepared_statement_handle* handle = ALLOC(struct nuodb_prepared_statement_handle);
|
1242
|
+
handle_init(handle, parent_handle, 1, nuodb_prepared_statement_cleanup);
|
1243
|
+
add_child(parent_handle, handle);
|
1244
|
+
|
1245
|
+
handle->connection = parent;
|
1246
|
+
handle->connection_handle = parent_handle;
|
1495
1247
|
handle->pointer = statement;
|
1496
|
-
|
1497
|
-
assert(handle->atomic == 1);
|
1498
|
-
VALUE self = Data_Wrap_Struct(nuodb_prepared_statement_klass, nuodb_prepared_statement_mark, nuodb_prepared_statement_decr_reference_count, handle);
|
1248
|
+
VALUE self = Data_Wrap_Struct(nuodb_prepared_statement_klass, nuodb_prepared_statement_mark, nuodb_prepared_statement_free, handle);
|
1499
1249
|
|
1500
1250
|
if (!rb_block_given_p()) {
|
1501
1251
|
trace("nuodb_prepared_statement_initialize: no block");
|
@@ -1515,24 +1265,20 @@ VALUE nuodb_prepared_statement_initialize(VALUE parent, VALUE sql)
|
|
1515
1265
|
|
1516
1266
|
trace("nuodb_prepared_statement_initialize: auto finish");
|
1517
1267
|
|
1518
|
-
if (exception)
|
1519
|
-
|
1268
|
+
if (exception) {
|
1269
|
+
//@TODO - don't we have to free memory?
|
1520
1270
|
rb_jump_tag(exception);
|
1521
|
-
}
|
1522
|
-
else
|
1523
|
-
{
|
1271
|
+
} else {
|
1524
1272
|
return result;
|
1525
1273
|
}
|
1526
|
-
}
|
1527
|
-
else
|
1528
|
-
{
|
1274
|
+
} else {
|
1529
1275
|
rb_raise(rb_eArgError, "invalid state: prepared statement handle nil");
|
1530
1276
|
}
|
1531
1277
|
return Qnil;
|
1532
1278
|
}
|
1533
1279
|
|
1534
1280
|
static
|
1535
|
-
void raise_unsupported_type_at_index(char const
|
1281
|
+
void raise_unsupported_type_at_index(char const* type_name, int32_t index)
|
1536
1282
|
{
|
1537
1283
|
rb_raise(rb_eTypeError, "unsupported type %s at %d", type_name, index);
|
1538
1284
|
}
|
@@ -1559,7 +1305,7 @@ VALUE nuodb_prepared_statement_bind_param(VALUE self, VALUE param, VALUE value)
|
|
1559
1305
|
}
|
1560
1306
|
int32_t index = NUM2UINT(param);
|
1561
1307
|
|
1562
|
-
NuoDB::PreparedStatement
|
1308
|
+
NuoDB::PreparedStatement* statement = cast_pointer_member<
|
1563
1309
|
nuodb_prepared_statement_handle, NuoDB::PreparedStatement>(self);
|
1564
1310
|
|
1565
1311
|
try
|
@@ -1576,7 +1322,7 @@ VALUE nuodb_prepared_statement_bind_param(VALUE self, VALUE param, VALUE value)
|
|
1576
1322
|
case T_STRING: // 0x05
|
1577
1323
|
{
|
1578
1324
|
log(DEBUG, "supported: T_STRING");
|
1579
|
-
char const
|
1325
|
+
char const* real_value = RSTRING_PTR(value);
|
1580
1326
|
statement->setString(index, real_value);
|
1581
1327
|
}
|
1582
1328
|
break;
|
@@ -1614,7 +1360,7 @@ VALUE nuodb_prepared_statement_bind_param(VALUE self, VALUE param, VALUE value)
|
|
1614
1360
|
VALUE sec = rb_funcall(value, rb_intern("tv_sec"), 0);
|
1615
1361
|
//VALUE offset = rb_funcall(value, rb_intern("utc_offset"), 0);
|
1616
1362
|
VALUE usec = rb_funcall(value, rb_intern("tv_usec"), 0);
|
1617
|
-
SqlTimestamp sqlTimestamp(NUM2INT(sec), NUM2INT(usec) *
|
1363
|
+
SqlTimestamp sqlTimestamp(NUM2INT(sec), NUM2INT(usec) * NANOS_PER_MICRO); // + NUM2INT(offset)
|
1618
1364
|
statement->setTimestamp(index, &sqlTimestamp);
|
1619
1365
|
break;
|
1620
1366
|
}
|
@@ -1626,7 +1372,7 @@ VALUE nuodb_prepared_statement_bind_param(VALUE self, VALUE param, VALUE value)
|
|
1626
1372
|
VALUE sec = rb_funcall(time, rb_intern("tv_sec"), 0);
|
1627
1373
|
//VALUE offset = rb_funcall(time, rb_intern("utc_offset"), 0);
|
1628
1374
|
VALUE usec = rb_funcall(time, rb_intern("tv_usec"), 0);
|
1629
|
-
SqlTimestamp sqlTimestamp(NUM2LONG(sec), NUM2INT(usec) *
|
1375
|
+
SqlTimestamp sqlTimestamp(NUM2LONG(sec), NUM2INT(usec) * NANOS_PER_MICRO);// + NUM2INT(offset)
|
1630
1376
|
statement->setTimestamp(index, &sqlTimestamp);
|
1631
1377
|
break;
|
1632
1378
|
}
|
@@ -1711,7 +1457,7 @@ VALUE nuodb_prepared_statement_bind_params(VALUE self, VALUE array)
|
|
1711
1457
|
{
|
1712
1458
|
trace("nuodb_prepared_statement_bind_params");
|
1713
1459
|
|
1714
|
-
nuodb_prepared_statement_handle
|
1460
|
+
nuodb_prepared_statement_handle* handle = cast_handle<nuodb_prepared_statement_handle>(self);
|
1715
1461
|
if (handle != NULL && handle->pointer != NULL)
|
1716
1462
|
{
|
1717
1463
|
for (int i = 0; i < RARRAY_LEN(array); ++i)
|
@@ -1741,7 +1487,7 @@ VALUE nuodb_prepared_statement_execute(VALUE self)
|
|
1741
1487
|
{
|
1742
1488
|
trace("nuodb_prepared_statement_execute");
|
1743
1489
|
|
1744
|
-
nuodb_prepared_statement_handle
|
1490
|
+
nuodb_prepared_statement_handle* handle = cast_handle<nuodb_prepared_statement_handle>(self);
|
1745
1491
|
if (handle != NULL && handle->pointer != NULL)
|
1746
1492
|
{
|
1747
1493
|
try
|
@@ -1771,7 +1517,7 @@ VALUE nuodb_prepared_statement_update_count(VALUE self)
|
|
1771
1517
|
{
|
1772
1518
|
trace("nuodb_prepared_statement_update_count");
|
1773
1519
|
|
1774
|
-
nuodb_prepared_statement_handle
|
1520
|
+
nuodb_prepared_statement_handle* handle = cast_handle<nuodb_prepared_statement_handle>(self);
|
1775
1521
|
if (handle != NULL && handle->pointer != NULL)
|
1776
1522
|
{
|
1777
1523
|
try
|
@@ -1800,20 +1546,22 @@ static VALUE nuodb_prepared_statement_results(VALUE self)
|
|
1800
1546
|
{
|
1801
1547
|
trace("nuodb_prepared_statement_results");
|
1802
1548
|
|
1803
|
-
nuodb_prepared_statement_handle
|
1804
|
-
if (handle != NULL && handle->pointer != NULL)
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1549
|
+
nuodb_prepared_statement_handle* handle = cast_handle<nuodb_prepared_statement_handle>(self);
|
1550
|
+
if (handle != NULL && handle->pointer != NULL) {
|
1551
|
+
try {
|
1552
|
+
VALUE ruby_handle = nuodb_result_init(self, handle->pointer->getResultSet(), handle->pointer->getConnection());
|
1553
|
+
nuodb_result_handle* our_result_handle = cast_handle<nuodb_result_handle>(ruby_handle);
|
1554
|
+
|
1555
|
+
assert(our_result_handle != NULL);
|
1556
|
+
assert(our_result_handle->prepStmt == NULL);
|
1557
|
+
assert(our_result_handle->stmt == NULL);
|
1558
|
+
|
1559
|
+
our_result_handle->prepStmt = handle;
|
1560
|
+
return ruby_handle;
|
1561
|
+
} catch (SQLException & e) {
|
1812
1562
|
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get the result set for the prepared statement: %s", e.getText());
|
1813
1563
|
}
|
1814
|
-
}
|
1815
|
-
else
|
1816
|
-
{
|
1564
|
+
} else {
|
1817
1565
|
rb_raise(rb_eArgError, "invalid state: prepared statement handle nil");
|
1818
1566
|
}
|
1819
1567
|
return Qnil;
|
@@ -1830,26 +1578,27 @@ static VALUE nuodb_prepared_statement_generated_keys(VALUE self)
|
|
1830
1578
|
{
|
1831
1579
|
trace("nuodb_prepared_statement_generated_keys");
|
1832
1580
|
|
1833
|
-
nuodb_prepared_statement_handle
|
1834
|
-
if (handle != NULL && handle->pointer != NULL)
|
1835
|
-
|
1836
|
-
try
|
1837
|
-
{
|
1581
|
+
nuodb_prepared_statement_handle* handle = cast_handle<nuodb_prepared_statement_handle>(self);
|
1582
|
+
if (handle != NULL && handle->pointer != NULL) {
|
1583
|
+
try {
|
1838
1584
|
// this hack should not have been necessary; it should never have
|
1839
1585
|
// returned null, this is a product defect.
|
1840
|
-
ResultSet
|
1841
|
-
if (results != NULL)
|
1842
|
-
|
1843
|
-
|
1586
|
+
ResultSet* results = handle->pointer->getGeneratedKeys();
|
1587
|
+
if (results != NULL) {
|
1588
|
+
VALUE ruby_handle = nuodb_result_init(self, results, handle->pointer->getConnection());
|
1589
|
+
nuodb_result_handle* our_result_handle = cast_handle<nuodb_result_handle>(ruby_handle);
|
1590
|
+
|
1591
|
+
assert(our_result_handle != NULL);
|
1592
|
+
assert(our_result_handle->prepStmt == NULL);
|
1593
|
+
assert(our_result_handle->stmt == NULL);
|
1594
|
+
|
1595
|
+
our_result_handle->prepStmt = handle;
|
1596
|
+
return ruby_handle;
|
1844
1597
|
}
|
1845
|
-
}
|
1846
|
-
catch (SQLException & e)
|
1847
|
-
{
|
1598
|
+
} catch (SQLException & e) {
|
1848
1599
|
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get the generated keys for the prepared statement: %s", e.getText());
|
1849
1600
|
}
|
1850
|
-
}
|
1851
|
-
else
|
1852
|
-
{
|
1601
|
+
} else {
|
1853
1602
|
rb_raise(rb_eArgError, "invalid state: prepared statement handle nil");
|
1854
1603
|
}
|
1855
1604
|
return Qnil;
|
@@ -1888,56 +1637,38 @@ void nuodb_define_prepared_statement_api()
|
|
1888
1637
|
*/
|
1889
1638
|
|
1890
1639
|
static
|
1891
|
-
|
1640
|
+
void nuodb_connection_free(void* ptr)
|
1892
1641
|
{
|
1893
|
-
trace("
|
1642
|
+
trace("nuodb_connection_free");
|
1643
|
+
if (ptr != NULL) {
|
1644
|
+
nuodb_connection_handle* handle = (nuodb_connection_handle*)ptr;
|
1645
|
+
NuoDB::SQLException* err = handle_free(handle, NULL);
|
1894
1646
|
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
if (handle->pointer != NULL)
|
1901
|
-
{
|
1902
|
-
try
|
1903
|
-
{
|
1904
|
-
track_ref_count("CLOSE CONN", handle);
|
1905
|
-
log(INFO, "closing connection");
|
1906
|
-
handle->pointer->close();
|
1907
|
-
handle->pointer = NULL;
|
1908
|
-
}
|
1909
|
-
catch (SQLException & e)
|
1910
|
-
{
|
1911
|
-
log(DEBUG, "rb_raise");
|
1912
|
-
rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close connection: %s", e.getText());
|
1913
|
-
}
|
1647
|
+
if (err) {
|
1648
|
+
//Not ok to raise a ruby exception during GC
|
1649
|
+
//rb_raise_nuodb_error(err->getSqlcode(), "Failed to successfully close connection: %s", err->getText());
|
1650
|
+
log(ERROR, "Failed to successfully close connection");
|
1651
|
+
log(ERROR, err->getText());
|
1914
1652
|
}
|
1915
1653
|
}
|
1916
|
-
return Qnil;
|
1917
1654
|
}
|
1918
1655
|
|
1919
1656
|
static
|
1920
|
-
void
|
1657
|
+
void nuodb_connection_cleanup(nuodb_handle* handle)
|
1921
1658
|
{
|
1922
|
-
|
1923
|
-
|
1924
|
-
{
|
1925
|
-
|
1926
|
-
rb_protect(nuodb_connection_free_protect, reinterpret_cast<VALUE>(ptr), &exception);
|
1927
|
-
if (exception)
|
1928
|
-
{
|
1929
|
-
rb_jump_tag(exception);
|
1930
|
-
}
|
1659
|
+
nuodb_connection_handle* connectionHandle = (nuodb_connection_handle*)handle;
|
1660
|
+
|
1661
|
+
if (connectionHandle && connectionHandle->pointer) {
|
1662
|
+
connectionHandle->pointer->close();
|
1931
1663
|
}
|
1932
1664
|
}
|
1933
1665
|
|
1934
1666
|
static
|
1935
|
-
void nuodb_connection_mark(void
|
1667
|
+
void nuodb_connection_mark(void* ptr)
|
1936
1668
|
{
|
1937
1669
|
trace("nuodb_connection_mark");
|
1938
1670
|
|
1939
|
-
nuodb_connection_handle
|
1940
|
-
track_ref_count("MARK CONN", handle);
|
1671
|
+
nuodb_connection_handle* handle = (nuodb_connection_handle *)ptr;
|
1941
1672
|
|
1942
1673
|
rb_gc_mark(handle->database);
|
1943
1674
|
rb_gc_mark(handle->username);
|
@@ -1945,38 +1676,28 @@ void nuodb_connection_mark(void * ptr)
|
|
1945
1676
|
rb_gc_mark(handle->schema);
|
1946
1677
|
}
|
1947
1678
|
|
1948
|
-
static
|
1949
|
-
void nuodb_connection_decr_reference_count(nuodb_handle * handle)
|
1950
|
-
{
|
1951
|
-
trace("nuodb_connection_decr_reference_count");
|
1952
|
-
decr_reference_count(handle);
|
1953
|
-
}
|
1954
|
-
|
1955
1679
|
static
|
1956
1680
|
VALUE nuodb_connection_alloc(VALUE klass)
|
1957
1681
|
{
|
1958
1682
|
trace("nuodb_connection_alloc");
|
1959
1683
|
|
1960
|
-
|
1684
|
+
trace("alloc");
|
1685
|
+
nuodb_connection_handle* handle = ALLOC(struct nuodb_connection_handle);
|
1686
|
+
handle_init(handle, NULL, 4, nuodb_connection_cleanup);
|
1961
1687
|
handle->database = Qnil;
|
1962
1688
|
handle->username = Qnil;
|
1963
1689
|
handle->password = Qnil;
|
1964
1690
|
handle->schema = Qnil;
|
1965
1691
|
handle->timezone = Qnil;
|
1966
1692
|
|
1967
|
-
handle->free_func = RUBY_DATA_FUNC(&nuodb_connection_free);
|
1968
|
-
handle->atomic = 0;
|
1969
|
-
handle->parent = Qnil;
|
1970
|
-
handle->parent_handle = 0;
|
1971
1693
|
handle->pointer = 0;
|
1972
|
-
incr_reference_count(handle);
|
1973
1694
|
|
1974
1695
|
print_address("[ALLOC] connection", handle);
|
1975
1696
|
|
1976
|
-
return Data_Wrap_Struct(klass, nuodb_connection_mark,
|
1697
|
+
return Data_Wrap_Struct(klass, nuodb_connection_mark, nuodb_connection_free, handle);
|
1977
1698
|
}
|
1978
1699
|
|
1979
|
-
static void internal_connection_connect_or_raise(nuodb_connection_handle
|
1700
|
+
static void internal_connection_connect_or_raise(nuodb_connection_handle* handle)
|
1980
1701
|
{
|
1981
1702
|
trace("internal_connection_connect_or_raise");
|
1982
1703
|
|
@@ -1985,7 +1706,7 @@ static void internal_connection_connect_or_raise(nuodb_connection_handle * handl
|
|
1985
1706
|
try
|
1986
1707
|
{
|
1987
1708
|
handle->pointer = Connection::create();
|
1988
|
-
Properties
|
1709
|
+
Properties* props = handle->pointer->allocProperties();
|
1989
1710
|
props->putValue("user", StringValueCStr(handle->username));
|
1990
1711
|
props->putValue("password", StringValueCStr(handle->password));
|
1991
1712
|
props->putValue("schema", StringValueCStr(handle->schema));
|
@@ -2010,7 +1731,7 @@ static void internal_connection_connect_or_raise(nuodb_connection_handle * handl
|
|
2010
1731
|
try
|
2011
1732
|
{
|
2012
1733
|
handle->pointer = Connection::create();
|
2013
|
-
Properties
|
1734
|
+
Properties* props = handle->pointer->allocProperties();
|
2014
1735
|
props->putValue("user", StringValueCStr(handle->username));
|
2015
1736
|
props->putValue("password", StringValueCStr(handle->password));
|
2016
1737
|
if (!NIL_P(handle->timezone))
|
@@ -2045,7 +1766,7 @@ static VALUE nuodb_connection_commit(VALUE self)
|
|
2045
1766
|
{
|
2046
1767
|
trace("nuodb_connection_commit");
|
2047
1768
|
|
2048
|
-
nuodb_connection_handle
|
1769
|
+
nuodb_connection_handle* handle = cast_handle<nuodb_connection_handle>(self);
|
2049
1770
|
if (handle != NULL && handle->pointer != NULL)
|
2050
1771
|
{
|
2051
1772
|
try
|
@@ -2073,44 +1794,9 @@ static VALUE nuodb_connection_commit(VALUE self)
|
|
2073
1794
|
static VALUE nuodb_connection_disconnect(VALUE self)
|
2074
1795
|
{
|
2075
1796
|
trace("nuodb_connection_disconnect");
|
2076
|
-
nuodb_connection_handle
|
2077
|
-
track_ref_count("CONN DISCONNECT", handle);
|
1797
|
+
nuodb_connection_handle* handle = cast_handle<nuodb_connection_handle>(self);//;
|
2078
1798
|
nuodb_connection_free(handle);
|
2079
|
-
// if (handle != NULL)
|
2080
|
-
// {
|
2081
|
-
// track_ref_count("FREE CONN", handle);
|
2082
|
-
// if (handle->pointer != NULL)
|
2083
|
-
// {
|
2084
|
-
// try
|
2085
|
-
// {
|
2086
|
-
// track_ref_count("CLOSE CONN", handle);
|
2087
|
-
// handle->pointer->close();
|
2088
|
-
// handle->pointer = NULL;
|
2089
|
-
// }
|
2090
|
-
// catch (SQLException & e)
|
2091
|
-
// {
|
2092
|
-
// log(DEBUG, "rb_raise");
|
2093
|
-
// rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close connection: %s", e.getText());
|
2094
|
-
// }
|
2095
|
-
// }
|
2096
|
-
// }
|
2097
1799
|
return Qnil;
|
2098
|
-
//
|
2099
|
-
//
|
2100
|
-
//
|
2101
|
-
// if (ENABLE_CLOSE_HOOK)
|
2102
|
-
// {
|
2103
|
-
// nuodb_connection_handle * handle = cast_handle<nuodb_connection_handle>(self);
|
2104
|
-
// if (handle != NULL && handle->pointer != NULL)
|
2105
|
-
// {
|
2106
|
-
// nuodb_connection_decr_reference_count(handle);
|
2107
|
-
// }
|
2108
|
-
// else
|
2109
|
-
// {
|
2110
|
-
// rb_raise(rb_eArgError, "invalid state: connection handle nil");
|
2111
|
-
// }
|
2112
|
-
// }
|
2113
|
-
// return Qnil;
|
2114
1800
|
}
|
2115
1801
|
|
2116
1802
|
/*
|
@@ -2126,7 +1812,7 @@ static VALUE nuodb_connection_ping(VALUE self)
|
|
2126
1812
|
{
|
2127
1813
|
trace("nuodb_connection_ping");
|
2128
1814
|
|
2129
|
-
nuodb_connection_handle
|
1815
|
+
nuodb_connection_handle* handle = cast_handle<nuodb_connection_handle>(self);
|
2130
1816
|
if (handle != NULL && handle->pointer != NULL)
|
2131
1817
|
{
|
2132
1818
|
try
|
@@ -2197,7 +1883,7 @@ static VALUE nuodb_connection_rollback(VALUE self)
|
|
2197
1883
|
{
|
2198
1884
|
trace("nuodb_connection_rollback");
|
2199
1885
|
|
2200
|
-
nuodb_connection_handle
|
1886
|
+
nuodb_connection_handle* handle = cast_handle<nuodb_connection_handle>(self);
|
2201
1887
|
if (handle != NULL && handle->pointer != NULL)
|
2202
1888
|
{
|
2203
1889
|
try
|
@@ -2234,7 +1920,7 @@ static VALUE nuodb_connection_autocommit_set(VALUE self, VALUE value)
|
|
2234
1920
|
{
|
2235
1921
|
trace("nuodb_connection_autocommit_set");
|
2236
1922
|
|
2237
|
-
nuodb_connection_handle
|
1923
|
+
nuodb_connection_handle* handle = cast_handle<nuodb_connection_handle>(self);
|
2238
1924
|
if (handle != NULL && handle->pointer != NULL)
|
2239
1925
|
{
|
2240
1926
|
bool auto_commit = !(RB_TYPE_P(value, T_FALSE) || RB_TYPE_P(value, T_NIL));
|
@@ -2270,7 +1956,7 @@ static VALUE nuodb_connection_autocommit_get(VALUE self)
|
|
2270
1956
|
{
|
2271
1957
|
trace("nuodb_connection_autocommit_get");
|
2272
1958
|
|
2273
|
-
nuodb_connection_handle
|
1959
|
+
nuodb_connection_handle* handle = cast_handle<nuodb_connection_handle>(self);
|
2274
1960
|
if (handle != NULL && handle->pointer != NULL)
|
2275
1961
|
{
|
2276
1962
|
try
|
@@ -2322,7 +2008,7 @@ static VALUE nuodb_connection_initialize(VALUE self, VALUE hash)
|
|
2322
2008
|
rb_raise(rb_eTypeError, "wrong argument type %s (Hash expected)", rb_class2name(CLASS_OF(hash)));
|
2323
2009
|
}
|
2324
2010
|
|
2325
|
-
nuodb_connection_handle
|
2011
|
+
nuodb_connection_handle* handle = cast_handle<nuodb_connection_handle>(self);
|
2326
2012
|
if (NIL_P(handle->database))
|
2327
2013
|
{
|
2328
2014
|
VALUE value = rb_hash_aref(hash, sym_database);
|
@@ -2417,42 +2103,6 @@ static VALUE nuodb_connection_initialize(VALUE self, VALUE hash)
|
|
2417
2103
|
return Qnil;
|
2418
2104
|
}
|
2419
2105
|
|
2420
|
-
///*
|
2421
|
-
// * call-seq:
|
2422
|
-
// * tables(schema = nil) -> Results
|
2423
|
-
// *
|
2424
|
-
// * Retrieves a result set containing the tables associated to the specified schema,
|
2425
|
-
// * or if the specified schema is nil, return a result set of tables for the schema
|
2426
|
-
// * associated with the connection.
|
2427
|
-
// */
|
2428
|
-
//static VALUE nuodb_connection_tables(VALUE self, VALUE schema)
|
2429
|
-
//{
|
2430
|
-
// trace("nuodb_connection_tables");
|
2431
|
-
//
|
2432
|
-
// nuodb_connection_handle * handle = cast_handle<nuodb_connection_handle>(self);
|
2433
|
-
// if (handle != NULL && handle->pointer != NULL)
|
2434
|
-
// {
|
2435
|
-
// if (schema == Qnil)
|
2436
|
-
// {
|
2437
|
-
// schema = handle->schema;
|
2438
|
-
// }
|
2439
|
-
//// char const * sql = "SELECT tablename FROM system.tables WHERE schema = ?"
|
2440
|
-
//// try
|
2441
|
-
//// {
|
2442
|
-
//// return nuodb_result_alloc(self, handle->pointer->getGeneratedKeys());
|
2443
|
-
//// }
|
2444
|
-
//// catch (SQLException & e)
|
2445
|
-
//// {
|
2446
|
-
//// rb_raise_nuodb_error(e.getSqlcode(), "Failed to get the tables keys for the schema: %s", e.getText());
|
2447
|
-
//// }
|
2448
|
-
// }
|
2449
|
-
// else
|
2450
|
-
// {
|
2451
|
-
// rb_raise(rb_eArgError, "invalid state: connection handle nil");
|
2452
|
-
// }
|
2453
|
-
// return Qnil;
|
2454
|
-
//}
|
2455
|
-
|
2456
2106
|
void nuodb_define_connection_api()
|
2457
2107
|
{
|
2458
2108
|
/*
|