nuodb 1.0.0.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +8 -0
- data/AUTHORS +4 -0
- data/COPYING +25 -0
- data/Gemfile +9 -0
- data/History.txt +4 -0
- data/LICENSE +26 -0
- data/Manifest.txt +10 -0
- data/README.rdoc +77 -0
- data/Rakefile +146 -0
- data/ext/nuodb/extconf.rb +152 -0
- data/ext/nuodb/nuodb.cpp +1130 -0
- data/lib/nuodb.rb +31 -0
- data/lib/nuodb/error.rb +42 -0
- data/lib/nuodb/version.rb +31 -0
- data/nuodb.gemspec +25 -0
- data/test/test_nuodb.rb +267 -0
- metadata +100 -0
data/ext/nuodb/nuodb.cpp
ADDED
@@ -0,0 +1,1130 @@
|
|
1
|
+
/****************************************************************************
|
2
|
+
* Copyright (c)2012, NuoDB, Inc.
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
7
|
+
*
|
8
|
+
* * Redistributions of source code must retain the above copyright
|
9
|
+
* notice, this list of conditions and the following disclaimer.
|
10
|
+
* * Redistributions in binary form must reproduce the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer in the
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
13
|
+
* * Neither the name of NuoDB, Inc. nor the names of its contributors may
|
14
|
+
* be used to endorse or promote products derived from this software
|
15
|
+
* without specific prior written permission.
|
16
|
+
*
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
18
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20
|
+
* DISCLAIMED. IN NO EVENT SHALL NUODB, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
23
|
+
* OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY OF
|
24
|
+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
25
|
+
* OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
26
|
+
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
****************************************************************************/
|
28
|
+
|
29
|
+
/*
|
30
|
+
* NuoDB Adapter
|
31
|
+
*/
|
32
|
+
|
33
|
+
#include <ruby.h>
|
34
|
+
#include <time.h>
|
35
|
+
#include <stdio.h>
|
36
|
+
|
37
|
+
extern "C" struct timeval rb_time_timeval(VALUE time);
|
38
|
+
|
39
|
+
//------------------------------------------------------------------------------
|
40
|
+
// class building macros
|
41
|
+
|
42
|
+
#define WRAPPER_COMMON(WT, RT) \
|
43
|
+
private: \
|
44
|
+
static VALUE type; \
|
45
|
+
RT* ptr; \
|
46
|
+
public: \
|
47
|
+
WT(RT* arg): ptr(arg) {} \
|
48
|
+
static VALUE getRubyType() { return type; } \
|
49
|
+
static void release(WT* self) \
|
50
|
+
{ \
|
51
|
+
/*delete self->ptr;*/ \
|
52
|
+
delete self; \
|
53
|
+
} \
|
54
|
+
static RT* asPtr(VALUE value) \
|
55
|
+
{ \
|
56
|
+
Check_Type(value, T_DATA); \
|
57
|
+
return ((WT*)DATA_PTR(value))->ptr; \
|
58
|
+
} \
|
59
|
+
static VALUE wrap(RT* value) \
|
60
|
+
{ \
|
61
|
+
if (value == NULL) return Qnil; \
|
62
|
+
WT* w = new WT(value); \
|
63
|
+
VALUE obj = Data_Wrap_Struct(WT::getRubyType(), 0, WT::release, w); \
|
64
|
+
rb_obj_call_init(obj, 0, 0); \
|
65
|
+
return obj; \
|
66
|
+
}
|
67
|
+
|
68
|
+
#define WRAPPER_DEFINITION(WT) \
|
69
|
+
VALUE WT::type = 0;
|
70
|
+
|
71
|
+
#define AS_QBOOL(value)((value)? Qtrue : Qfalse)
|
72
|
+
|
73
|
+
//------------------------------------------------------------------------------
|
74
|
+
// utility function macros
|
75
|
+
|
76
|
+
#define SYMBOL_OF(value) \
|
77
|
+
ID2SYM(rb_intern(#value))
|
78
|
+
|
79
|
+
#define INIT_TYPE(name) \
|
80
|
+
type = rb_define_class_under(module, name, rb_cObject)
|
81
|
+
|
82
|
+
#define DEFINE_SINGLE(func, count) \
|
83
|
+
rb_define_singleton_method(type, #func, RUBY_METHOD_FUNC(func), count)
|
84
|
+
|
85
|
+
#define DEFINE_METHOD(func, count) \
|
86
|
+
rb_define_method(type, #func, RUBY_METHOD_FUNC(func), count)
|
87
|
+
|
88
|
+
//------------------------------------------------------------------------------
|
89
|
+
// exception mapper
|
90
|
+
|
91
|
+
static VALUE m_nuodb, c_nuodb_error;
|
92
|
+
static ID c_error_code_assignment;
|
93
|
+
|
94
|
+
static void rb_raise_nuodb_error(int code, const char * fmt, ...)
|
95
|
+
{
|
96
|
+
va_list args;
|
97
|
+
char text[BUFSIZ];
|
98
|
+
|
99
|
+
va_start(args, fmt);
|
100
|
+
vsnprintf(text, BUFSIZ, fmt, args);
|
101
|
+
va_end(args);
|
102
|
+
|
103
|
+
VALUE error = rb_exc_new2(c_nuodb_error, text);
|
104
|
+
rb_funcall(error, c_error_code_assignment, 1, UINT2NUM(code));
|
105
|
+
rb_exc_raise(error);
|
106
|
+
}
|
107
|
+
|
108
|
+
//------------------------------------------------------------------------------
|
109
|
+
|
110
|
+
#include "Connection.h"
|
111
|
+
#include "BigDecimal.h"
|
112
|
+
#include "Blob.h"
|
113
|
+
#include "Bytes.h"
|
114
|
+
#include "CallableStatement.h"
|
115
|
+
#include "Clob.h"
|
116
|
+
#include "DatabaseMetaData.h"
|
117
|
+
#include "DateClass.h"
|
118
|
+
#include "ParameterMetaData.h"
|
119
|
+
#include "PreparedStatement.h"
|
120
|
+
#include "Properties.h"
|
121
|
+
#include "ResultList.h"
|
122
|
+
#include "ResultSet.h"
|
123
|
+
#include "ResultSetMetaData.h"
|
124
|
+
#include "SQLException.h"
|
125
|
+
#include "Savepoint.h"
|
126
|
+
#include "Statement.h"
|
127
|
+
#include "TimeClass.h"
|
128
|
+
#include "Timestamp.h"
|
129
|
+
#include "SqlTimestamp.h"
|
130
|
+
#include "SqlDate.h"
|
131
|
+
#include "SqlTime.h"
|
132
|
+
|
133
|
+
using namespace NuoDB;
|
134
|
+
|
135
|
+
class WrapDatabaseMetaData
|
136
|
+
{
|
137
|
+
WRAPPER_COMMON(WrapDatabaseMetaData, DatabaseMetaData)
|
138
|
+
|
139
|
+
static void init(VALUE module);
|
140
|
+
static VALUE getDatabaseVersion(VALUE self);
|
141
|
+
static VALUE getIndexInfo(VALUE self, VALUE schemaValue, VALUE tableValue, VALUE uniqueValue, VALUE approxValue);
|
142
|
+
static VALUE getColumns(VALUE self, VALUE schemaValue, VALUE tablePattern);
|
143
|
+
static VALUE getTables(VALUE self, VALUE schemaValue, VALUE table);
|
144
|
+
};
|
145
|
+
|
146
|
+
WRAPPER_DEFINITION(WrapDatabaseMetaData);
|
147
|
+
|
148
|
+
//------------------------------------------------------------------------------
|
149
|
+
|
150
|
+
class WrapResultSetMetaData
|
151
|
+
{
|
152
|
+
WRAPPER_COMMON(WrapResultSetMetaData, ResultSetMetaData);
|
153
|
+
|
154
|
+
static void init(VALUE module);
|
155
|
+
static VALUE getColumnCount(VALUE self);
|
156
|
+
static VALUE getColumnName(VALUE self, VALUE columnValue);
|
157
|
+
static VALUE getScale(VALUE self, VALUE columnValue);
|
158
|
+
static VALUE getPrecision(VALUE self, VALUE columnValue);
|
159
|
+
static VALUE isNullable(VALUE self, VALUE columnValue);
|
160
|
+
static VALUE getColumnTypeName(VALUE self, VALUE columnValue);
|
161
|
+
static VALUE getType(VALUE self, VALUE columnValue);
|
162
|
+
};
|
163
|
+
|
164
|
+
WRAPPER_DEFINITION(WrapResultSetMetaData);
|
165
|
+
|
166
|
+
//------------------------------------------------------------------------------
|
167
|
+
|
168
|
+
class WrapResultSet
|
169
|
+
{
|
170
|
+
WRAPPER_COMMON(WrapResultSet, ResultSet)
|
171
|
+
|
172
|
+
static void init(VALUE module);
|
173
|
+
static VALUE next(VALUE self);
|
174
|
+
static VALUE getColumnCount(VALUE self);
|
175
|
+
static VALUE getMetaData(VALUE self);
|
176
|
+
static VALUE getBoolean(VALUE self, VALUE columnValue);
|
177
|
+
static VALUE getInteger(VALUE self, VALUE columnValue);
|
178
|
+
static VALUE getDouble(VALUE self, VALUE columnValue);
|
179
|
+
static VALUE getString(VALUE self, VALUE columnValue);
|
180
|
+
static VALUE getDate(VALUE self, VALUE columnValue);
|
181
|
+
static VALUE getTime(VALUE self, VALUE columnValue);
|
182
|
+
static VALUE getTimestamp(VALUE self, VALUE columnValue);
|
183
|
+
static VALUE getChar(VALUE self, VALUE columnValue);
|
184
|
+
};
|
185
|
+
|
186
|
+
WRAPPER_DEFINITION(WrapResultSet)
|
187
|
+
|
188
|
+
//------------------------------------------------------------------------------
|
189
|
+
|
190
|
+
class WrapStatement
|
191
|
+
{
|
192
|
+
WRAPPER_COMMON(WrapStatement, Statement);
|
193
|
+
|
194
|
+
static void init(VALUE module);
|
195
|
+
static VALUE close(VALUE self);
|
196
|
+
static VALUE execute(VALUE self, VALUE sqlValue);
|
197
|
+
static VALUE executeQuery(VALUE self, VALUE sqlValue);
|
198
|
+
static VALUE executeUpdate(VALUE self, VALUE sqlValue);
|
199
|
+
static VALUE getResultSet(VALUE self);
|
200
|
+
static VALUE getUpdateCount(VALUE self);
|
201
|
+
static VALUE getGeneratedKeys(VALUE self);
|
202
|
+
};
|
203
|
+
|
204
|
+
WRAPPER_DEFINITION(WrapStatement);
|
205
|
+
|
206
|
+
//------------------------------------------------------------------------------
|
207
|
+
|
208
|
+
class WrapPreparedStatement
|
209
|
+
{
|
210
|
+
WRAPPER_COMMON(WrapPreparedStatement, PreparedStatement);
|
211
|
+
|
212
|
+
static void init(VALUE module);
|
213
|
+
static VALUE close(VALUE self);
|
214
|
+
static VALUE setBoolean(VALUE self, VALUE indexValue, VALUE valueValue);
|
215
|
+
static VALUE setInteger(VALUE self, VALUE indexValue, VALUE valueValue);
|
216
|
+
static VALUE setDouble(VALUE self, VALUE indexValue, VALUE valueValue);
|
217
|
+
static VALUE setString(VALUE self, VALUE indexValue, VALUE valueValue);
|
218
|
+
static VALUE setTime(VALUE self, VALUE indexValue, VALUE valueValue);
|
219
|
+
static VALUE execute(VALUE self);
|
220
|
+
static VALUE executeQuery(VALUE self);
|
221
|
+
static VALUE executeUpdate(VALUE self);
|
222
|
+
static VALUE getResultSet(VALUE self);
|
223
|
+
static VALUE getUpdateCount(VALUE self);
|
224
|
+
static VALUE getGeneratedKeys(VALUE self);
|
225
|
+
};
|
226
|
+
|
227
|
+
WRAPPER_DEFINITION(WrapPreparedStatement);
|
228
|
+
|
229
|
+
//------------------------------------------------------------------------------
|
230
|
+
|
231
|
+
class WrapConnection
|
232
|
+
{
|
233
|
+
WRAPPER_COMMON(WrapConnection, Connection);
|
234
|
+
|
235
|
+
static void init(VALUE module);
|
236
|
+
static VALUE close(VALUE self);
|
237
|
+
static VALUE ping(VALUE self);
|
238
|
+
static VALUE createStatement(VALUE self);
|
239
|
+
static VALUE createPreparedStatement(VALUE self, VALUE sqlValue);
|
240
|
+
static VALUE setAutoCommit(VALUE self, VALUE autoCommitValue);
|
241
|
+
static VALUE hasAutoCommit(VALUE self);
|
242
|
+
static VALUE commit(VALUE self);
|
243
|
+
static VALUE rollback(VALUE self);
|
244
|
+
static VALUE getMetaData(VALUE self);
|
245
|
+
static VALUE getSchema(VALUE self);
|
246
|
+
static VALUE createSqlConnection(VALUE self,
|
247
|
+
VALUE databaseValue,
|
248
|
+
VALUE schemaValue,
|
249
|
+
VALUE usernameValue,
|
250
|
+
VALUE passwordValue);
|
251
|
+
};
|
252
|
+
|
253
|
+
WRAPPER_DEFINITION(WrapConnection);
|
254
|
+
|
255
|
+
//------------------------------------------------------------------------------
|
256
|
+
|
257
|
+
void WrapDatabaseMetaData::init(VALUE module)
|
258
|
+
{
|
259
|
+
INIT_TYPE("DatabaseMetaData");
|
260
|
+
DEFINE_METHOD(getDatabaseVersion, 0);
|
261
|
+
DEFINE_METHOD(getIndexInfo, 4);
|
262
|
+
DEFINE_METHOD(getColumns, 2);
|
263
|
+
DEFINE_METHOD(getTables, 2);
|
264
|
+
}
|
265
|
+
|
266
|
+
VALUE WrapDatabaseMetaData::getDatabaseVersion(VALUE self)
|
267
|
+
{
|
268
|
+
try
|
269
|
+
{
|
270
|
+
return rb_str_new2(asPtr(self)->getDatabaseProductVersion());
|
271
|
+
}
|
272
|
+
catch (SQLException & e)
|
273
|
+
{
|
274
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Get database metadata database version failed: %s", e.getText());
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
VALUE WrapDatabaseMetaData::getIndexInfo(VALUE self, VALUE schemaValue, VALUE tableValue, VALUE uniqueValue, VALUE approxValue)
|
279
|
+
{
|
280
|
+
const char* schema = StringValuePtr(schemaValue);
|
281
|
+
const char* table = StringValuePtr(tableValue);
|
282
|
+
bool unique = !(RB_TYPE_P(uniqueValue, T_FALSE) || RB_TYPE_P(uniqueValue, T_NIL));
|
283
|
+
bool approx = !(RB_TYPE_P(approxValue, T_FALSE) || RB_TYPE_P(approxValue, T_NIL));
|
284
|
+
try
|
285
|
+
{
|
286
|
+
return WrapResultSet::wrap(asPtr(self)->getIndexInfo(NULL, schema, table, unique, approx));
|
287
|
+
}
|
288
|
+
catch (SQLException & e)
|
289
|
+
{
|
290
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Get database metadata index info failed: %s", e.getText());
|
291
|
+
}
|
292
|
+
}
|
293
|
+
|
294
|
+
VALUE WrapDatabaseMetaData::getColumns(VALUE self, VALUE schemaValue, VALUE tableValue)
|
295
|
+
{
|
296
|
+
const char* schema = StringValuePtr(schemaValue);
|
297
|
+
const char* table = StringValuePtr(tableValue);
|
298
|
+
try
|
299
|
+
{
|
300
|
+
return WrapResultSet::wrap(asPtr(self)->getColumns(NULL, schema, table, NULL));
|
301
|
+
}
|
302
|
+
catch (SQLException & e)
|
303
|
+
{
|
304
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Get columns failed: %s", e.getText());
|
305
|
+
}
|
306
|
+
}
|
307
|
+
|
308
|
+
VALUE WrapDatabaseMetaData::getTables(VALUE self, VALUE schemaValue, VALUE tableValue)
|
309
|
+
{
|
310
|
+
const char* schema = StringValuePtr(schemaValue);
|
311
|
+
const char* table = StringValuePtr(tableValue);
|
312
|
+
|
313
|
+
try
|
314
|
+
{
|
315
|
+
return WrapResultSet::wrap(asPtr(self)->getTables(NULL, schema, table, 0, NULL));
|
316
|
+
}
|
317
|
+
catch (SQLException & e)
|
318
|
+
{
|
319
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Get tables failed: %s", e.getText());
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
323
|
+
//------------------------------------------------------------------------------
|
324
|
+
|
325
|
+
void WrapResultSet::init(VALUE module)
|
326
|
+
{
|
327
|
+
INIT_TYPE("ResultSet");
|
328
|
+
DEFINE_METHOD(next, 0);
|
329
|
+
DEFINE_METHOD(getMetaData, 0);
|
330
|
+
DEFINE_METHOD(getBoolean, 1);
|
331
|
+
DEFINE_METHOD(getInteger, 1);
|
332
|
+
DEFINE_METHOD(getDouble, 1);
|
333
|
+
DEFINE_METHOD(getString, 1);
|
334
|
+
DEFINE_METHOD(getDate, 1);
|
335
|
+
DEFINE_METHOD(getTime, 1);
|
336
|
+
DEFINE_METHOD(getTimestamp, 1);
|
337
|
+
DEFINE_METHOD(getChar, 1);
|
338
|
+
}
|
339
|
+
|
340
|
+
VALUE WrapResultSet::next(VALUE self)
|
341
|
+
{
|
342
|
+
try
|
343
|
+
{
|
344
|
+
return AS_QBOOL(asPtr(self)->next());
|
345
|
+
}
|
346
|
+
catch (SQLException & e)
|
347
|
+
{
|
348
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to move the cursor forward one row: %s", e.getText());
|
349
|
+
}
|
350
|
+
}
|
351
|
+
|
352
|
+
VALUE WrapResultSet::getMetaData(VALUE self)
|
353
|
+
{
|
354
|
+
try
|
355
|
+
{
|
356
|
+
return WrapResultSetMetaData::wrap(asPtr(self)->getMetaData());
|
357
|
+
}
|
358
|
+
catch (SQLException & e)
|
359
|
+
{
|
360
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to retrieve number, types, and properties of the result set: %s", e.getText());
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
VALUE WrapResultSet::getBoolean(VALUE self, VALUE columnValue)
|
365
|
+
{
|
366
|
+
int column = NUM2UINT(columnValue);
|
367
|
+
try
|
368
|
+
{
|
369
|
+
bool value = asPtr(self)->getBoolean(column);
|
370
|
+
return AS_QBOOL(value);
|
371
|
+
}
|
372
|
+
catch (SQLException & e)
|
373
|
+
{
|
374
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get boolean value for the designated column (%d): %s", column, e.getText());
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
378
|
+
VALUE WrapResultSet::getInteger(VALUE self, VALUE columnValue)
|
379
|
+
{
|
380
|
+
int column = NUM2UINT(columnValue);
|
381
|
+
try
|
382
|
+
{
|
383
|
+
return INT2NUM(asPtr(self)->getInt(column));
|
384
|
+
}
|
385
|
+
catch (SQLException & e)
|
386
|
+
{
|
387
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get integer value for the designated column (%d): %s", column, e.getText());
|
388
|
+
}
|
389
|
+
}
|
390
|
+
|
391
|
+
VALUE WrapResultSet::getDouble(VALUE self, VALUE columnValue)
|
392
|
+
{
|
393
|
+
int column = NUM2UINT(columnValue);
|
394
|
+
try
|
395
|
+
{
|
396
|
+
return rb_float_new(asPtr(self)->getDouble(column));
|
397
|
+
}
|
398
|
+
catch (SQLException & e)
|
399
|
+
{
|
400
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get double value for the designated column (%d): %s", column, e.getText());
|
401
|
+
}
|
402
|
+
}
|
403
|
+
|
404
|
+
VALUE WrapResultSet::getString(VALUE self, VALUE columnValue)
|
405
|
+
{
|
406
|
+
int column = NUM2UINT(columnValue);
|
407
|
+
try
|
408
|
+
{
|
409
|
+
return rb_str_new2(asPtr(self)->getString(column));
|
410
|
+
}
|
411
|
+
catch (SQLException & e)
|
412
|
+
{
|
413
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get string value for the designated column (%d): %s", column, e.getText());
|
414
|
+
}
|
415
|
+
}
|
416
|
+
VALUE WrapResultSet::getDate(VALUE self, VALUE columnValue)
|
417
|
+
{
|
418
|
+
int column = NUM2UINT(columnValue);
|
419
|
+
try
|
420
|
+
{
|
421
|
+
return rb_str_new2(asPtr(self)->getString(column));
|
422
|
+
//Date* date = asPtr(self)->getDate(column);
|
423
|
+
//SqlDate timestamp(date->getMilliseconds());
|
424
|
+
//struct tm utc;
|
425
|
+
//timestamp.getDate(&utc);
|
426
|
+
//char buffer[250];
|
427
|
+
//::strftime(buffer,sizeof(buffer),"%Y%m%dT%I%M%S+0000",&utc);
|
428
|
+
//return rb_str_new2(buffer);
|
429
|
+
}
|
430
|
+
catch (SQLException & e)
|
431
|
+
{
|
432
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get date value for the designated column (%d): %s", column, e.getText());
|
433
|
+
}
|
434
|
+
}
|
435
|
+
|
436
|
+
VALUE WrapResultSet::getTime(VALUE self, VALUE columnValue)
|
437
|
+
{
|
438
|
+
int column = NUM2UINT(columnValue);
|
439
|
+
try
|
440
|
+
{
|
441
|
+
return rb_str_new2(asPtr(self)->getString(column));
|
442
|
+
//Time* time = asPtr(self)->getTime(column);
|
443
|
+
//SqlTime timestamp(time->getMilliseconds());
|
444
|
+
//struct tm utc;
|
445
|
+
//timestamp.getTime(&utc);
|
446
|
+
//char buffer[250];
|
447
|
+
//::strftime(buffer,sizeof(buffer),"%Y%m%dT%I%M%S+0000",&utc);
|
448
|
+
// Workaround until we fix the Date/Time support
|
449
|
+
// Convert time to local time?
|
450
|
+
//snprintf(buffer, sizeof(buffer), "%u:%u:%u", utc.tm_hour, utc.tm_min, utc.tm_sec);
|
451
|
+
//return rb_str_new2(buffer);
|
452
|
+
}
|
453
|
+
catch (SQLException & e)
|
454
|
+
{
|
455
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get time value for the designated column (%d): %s", column, e.getText());
|
456
|
+
}
|
457
|
+
}
|
458
|
+
|
459
|
+
VALUE WrapResultSet::getTimestamp(VALUE self, VALUE columnValue)
|
460
|
+
{
|
461
|
+
int column = NUM2UINT(columnValue);
|
462
|
+
try
|
463
|
+
{
|
464
|
+
return rb_str_new2(asPtr(self)->getString(column));
|
465
|
+
//Timestamp* ts = asPtr(self)->getTimestamp(column);
|
466
|
+
//SqlTimestamp timestamp(ts->getMilliseconds());
|
467
|
+
//struct tm utc;
|
468
|
+
//timestamp.getTimestamp(&utc);
|
469
|
+
//char buffer[250];
|
470
|
+
//::strftime(buffer,sizeof(buffer),"%Y%m%dT%I%M%S+0000",&utc);
|
471
|
+
//return rb_str_new2(buffer);
|
472
|
+
}
|
473
|
+
catch (SQLException & e)
|
474
|
+
{
|
475
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get timestamp value for the designated column (%d): %s", column, e.getText());
|
476
|
+
}
|
477
|
+
}
|
478
|
+
|
479
|
+
VALUE WrapResultSet::getChar(VALUE self, VALUE columnValue)
|
480
|
+
{
|
481
|
+
int column = NUM2UINT(columnValue);
|
482
|
+
try
|
483
|
+
{
|
484
|
+
return rb_str_new2(asPtr(self)->getString(column));
|
485
|
+
}
|
486
|
+
catch (SQLException & e)
|
487
|
+
{
|
488
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get char value for the designated column (%d): %s", column, e.getText());
|
489
|
+
}
|
490
|
+
}
|
491
|
+
|
492
|
+
//------------------------------------------------------------------------------
|
493
|
+
|
494
|
+
void WrapResultSetMetaData::init(VALUE module)
|
495
|
+
{
|
496
|
+
INIT_TYPE("ResultMetaData");
|
497
|
+
DEFINE_METHOD(getColumnCount, 0);
|
498
|
+
DEFINE_METHOD(getColumnName, 1);
|
499
|
+
DEFINE_METHOD(getType, 1);
|
500
|
+
DEFINE_METHOD(getColumnTypeName, 1);
|
501
|
+
DEFINE_METHOD(getScale, 1);
|
502
|
+
DEFINE_METHOD(getPrecision, 1);
|
503
|
+
DEFINE_METHOD(isNullable, 1);
|
504
|
+
}
|
505
|
+
|
506
|
+
VALUE WrapResultSetMetaData::getColumnCount(VALUE self)
|
507
|
+
{
|
508
|
+
try
|
509
|
+
{
|
510
|
+
return UINT2NUM(asPtr(self)->getColumnCount());
|
511
|
+
}
|
512
|
+
catch (SQLException & e)
|
513
|
+
{
|
514
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get column count from the result set metadata: %s", e.getText());
|
515
|
+
}
|
516
|
+
}
|
517
|
+
|
518
|
+
VALUE WrapResultSetMetaData::getColumnName(VALUE self, VALUE columnValue)
|
519
|
+
{
|
520
|
+
int column = NUM2UINT(columnValue);
|
521
|
+
try
|
522
|
+
{
|
523
|
+
return rb_str_new2(asPtr(self)->getColumnName(column));
|
524
|
+
}
|
525
|
+
catch (SQLException & e)
|
526
|
+
{
|
527
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get column name from the result set metadata: %s", e.getText());
|
528
|
+
}
|
529
|
+
}
|
530
|
+
|
531
|
+
VALUE WrapResultSetMetaData::getScale(VALUE self, VALUE columnValue)
|
532
|
+
{
|
533
|
+
int column = NUM2UINT(columnValue);
|
534
|
+
try
|
535
|
+
{
|
536
|
+
return UINT2NUM(asPtr(self)->getScale(column));
|
537
|
+
}
|
538
|
+
catch (SQLException & e)
|
539
|
+
{
|
540
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get scale from the result set metadata: %s", e.getText());
|
541
|
+
}
|
542
|
+
}
|
543
|
+
|
544
|
+
VALUE WrapResultSetMetaData::getPrecision(VALUE self, VALUE columnValue)
|
545
|
+
{
|
546
|
+
int column = NUM2UINT(columnValue);
|
547
|
+
try
|
548
|
+
{
|
549
|
+
return UINT2NUM(asPtr(self)->getPrecision(column));
|
550
|
+
}
|
551
|
+
catch (SQLException & e)
|
552
|
+
{
|
553
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get precision from the result set metadata: %s", e.getText());
|
554
|
+
}
|
555
|
+
}
|
556
|
+
|
557
|
+
VALUE WrapResultSetMetaData::isNullable(VALUE self, VALUE columnValue)
|
558
|
+
{
|
559
|
+
int column = NUM2UINT(columnValue);
|
560
|
+
try
|
561
|
+
{
|
562
|
+
return AS_QBOOL(asPtr(self)->isNullable(column));
|
563
|
+
}
|
564
|
+
catch (SQLException & e)
|
565
|
+
{
|
566
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to determine nullability from the result set metadata: %s", e.getText());
|
567
|
+
}
|
568
|
+
}
|
569
|
+
|
570
|
+
VALUE WrapResultSetMetaData::getColumnTypeName(VALUE self, VALUE columnValue)
|
571
|
+
{
|
572
|
+
int column = NUM2UINT(columnValue);
|
573
|
+
try
|
574
|
+
{
|
575
|
+
return rb_str_new2(asPtr(self)->getColumnTypeName(column));
|
576
|
+
}
|
577
|
+
catch (SQLException & e)
|
578
|
+
{
|
579
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get column type name from the result set metadata for the designated column (%d): %s", column, e.getText());
|
580
|
+
}
|
581
|
+
}
|
582
|
+
|
583
|
+
VALUE WrapResultSetMetaData::getType(VALUE self, VALUE columnValue)
|
584
|
+
{
|
585
|
+
int column = NUM2UINT(columnValue);
|
586
|
+
SqlType t = (SqlType)asPtr(self)->getColumnType(column);
|
587
|
+
|
588
|
+
switch(t)
|
589
|
+
{
|
590
|
+
case NUOSQL_NULL:
|
591
|
+
return SYMBOL_OF(SQL_NULL);
|
592
|
+
case NUOSQL_BIT:
|
593
|
+
return SYMBOL_OF(SQL_BIT);
|
594
|
+
case NUOSQL_TINYINT:
|
595
|
+
return SYMBOL_OF(SQL_TINYINT);
|
596
|
+
case NUOSQL_SMALLINT:
|
597
|
+
return SYMBOL_OF(SQL_SMALLINT);
|
598
|
+
case NUOSQL_INTEGER:
|
599
|
+
return SYMBOL_OF(SQL_INTEGER);
|
600
|
+
case NUOSQL_BIGINT:
|
601
|
+
return SYMBOL_OF(SQL_BIGINT);
|
602
|
+
case NUOSQL_FLOAT:
|
603
|
+
return SYMBOL_OF(SQL_FLOAT);
|
604
|
+
case NUOSQL_DOUBLE:
|
605
|
+
return SYMBOL_OF(SQL_DOUBLE);
|
606
|
+
case NUOSQL_CHAR:
|
607
|
+
return SYMBOL_OF(SQL_CHAR);
|
608
|
+
case NUOSQL_VARCHAR:
|
609
|
+
return SYMBOL_OF(SQL_STRING);
|
610
|
+
case NUOSQL_LONGVARCHAR:
|
611
|
+
return SYMBOL_OF(SQL_LONGVARCHAR);
|
612
|
+
case NUOSQL_DATE:
|
613
|
+
return SYMBOL_OF(SQL_DATE);
|
614
|
+
case NUOSQL_TIME:
|
615
|
+
return SYMBOL_OF(SQL_TIME);
|
616
|
+
case NUOSQL_TIMESTAMP:
|
617
|
+
return SYMBOL_OF(SQL_TIMESTAMP);
|
618
|
+
case NUOSQL_BLOB:
|
619
|
+
return SYMBOL_OF(SQL_BLOB);
|
620
|
+
case NUOSQL_CLOB:
|
621
|
+
return SYMBOL_OF(SQL_CLOB);
|
622
|
+
case NUOSQL_NUMERIC:
|
623
|
+
return SYMBOL_OF(SQL_NUMERIC);
|
624
|
+
case NUOSQL_DECIMAL:
|
625
|
+
return SYMBOL_OF(SQL_DECIMAL);
|
626
|
+
case NUOSQL_BOOLEAN:
|
627
|
+
return SYMBOL_OF(SQL_BOOLEAN);
|
628
|
+
case NUOSQL_BINARY:
|
629
|
+
return SYMBOL_OF(SQL_BINARY);
|
630
|
+
case NUOSQL_LONGVARBINARY:
|
631
|
+
return SYMBOL_OF(SQL_LONGVARBINARY);
|
632
|
+
default:
|
633
|
+
// raise FEATURE_NOT_YET_IMPLEMENTED for unsupported types
|
634
|
+
rb_raise_nuodb_error(-2, "Invalid SQL type: %d", t);
|
635
|
+
}
|
636
|
+
}
|
637
|
+
|
638
|
+
//------------------------------------------------------------------------------
|
639
|
+
|
640
|
+
void WrapStatement::init(VALUE module)
|
641
|
+
{
|
642
|
+
INIT_TYPE("Statement");
|
643
|
+
DEFINE_METHOD(close, 0);
|
644
|
+
DEFINE_METHOD(execute, 1);
|
645
|
+
DEFINE_METHOD(executeQuery, 1);
|
646
|
+
DEFINE_METHOD(executeUpdate, 1);
|
647
|
+
DEFINE_METHOD(getResultSet, 0);
|
648
|
+
DEFINE_METHOD(getUpdateCount, 0);
|
649
|
+
DEFINE_METHOD(getGeneratedKeys, 0);
|
650
|
+
}
|
651
|
+
|
652
|
+
VALUE WrapStatement::close(VALUE self)
|
653
|
+
{
|
654
|
+
try
|
655
|
+
{
|
656
|
+
asPtr(self)->close();
|
657
|
+
return Qnil;
|
658
|
+
}
|
659
|
+
catch (SQLException & e)
|
660
|
+
{
|
661
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close statement: %s", e.getText());
|
662
|
+
}
|
663
|
+
}
|
664
|
+
|
665
|
+
VALUE WrapStatement::execute(VALUE self, VALUE sqlValue)
|
666
|
+
{
|
667
|
+
const char* sql = StringValuePtr(sqlValue);
|
668
|
+
try
|
669
|
+
{
|
670
|
+
return AS_QBOOL(asPtr(self)->execute(sql, NuoDB::RETURN_GENERATED_KEYS ));
|
671
|
+
}
|
672
|
+
catch (SQLException & e)
|
673
|
+
{
|
674
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to execute SQL statement (\"%s\"): %s", sql, e.getText());
|
675
|
+
}
|
676
|
+
}
|
677
|
+
|
678
|
+
VALUE WrapStatement::executeQuery(VALUE self, VALUE sqlValue)
|
679
|
+
{
|
680
|
+
const char* sql = StringValuePtr(sqlValue);
|
681
|
+
try
|
682
|
+
{
|
683
|
+
return WrapResultSet::wrap(asPtr(self)->executeQuery(sql));
|
684
|
+
}
|
685
|
+
catch (SQLException & e)
|
686
|
+
{
|
687
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to execute SQL query statement (\"%s\"): %s", sql, e.getText());
|
688
|
+
}
|
689
|
+
}
|
690
|
+
|
691
|
+
VALUE WrapStatement::executeUpdate(VALUE self, VALUE sqlValue)
|
692
|
+
{
|
693
|
+
const char* sql = StringValuePtr(sqlValue);
|
694
|
+
try
|
695
|
+
{
|
696
|
+
return INT2NUM(asPtr(self)->executeUpdate(sql));
|
697
|
+
}
|
698
|
+
catch (SQLException & e)
|
699
|
+
{
|
700
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to execute SQL update statement (\"%s\"): %s", sql, e.getText());
|
701
|
+
}
|
702
|
+
}
|
703
|
+
|
704
|
+
VALUE WrapStatement::getResultSet(VALUE self)
|
705
|
+
{
|
706
|
+
try
|
707
|
+
{
|
708
|
+
return WrapResultSet::wrap(asPtr(self)->getResultSet());
|
709
|
+
}
|
710
|
+
catch (SQLException & e)
|
711
|
+
{
|
712
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get statement result set: %s", e.getText());
|
713
|
+
}
|
714
|
+
}
|
715
|
+
|
716
|
+
VALUE WrapStatement::getUpdateCount(VALUE self)
|
717
|
+
{
|
718
|
+
try
|
719
|
+
{
|
720
|
+
return INT2NUM(asPtr(self)->getUpdateCount());
|
721
|
+
}
|
722
|
+
catch (SQLException & e)
|
723
|
+
{
|
724
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get update count for statement: %s", e.getText());
|
725
|
+
}
|
726
|
+
}
|
727
|
+
|
728
|
+
VALUE WrapStatement::getGeneratedKeys(VALUE self)
|
729
|
+
{
|
730
|
+
try
|
731
|
+
{
|
732
|
+
return WrapResultSet::wrap(asPtr(self)->getGeneratedKeys());
|
733
|
+
}
|
734
|
+
catch (SQLException & e)
|
735
|
+
{
|
736
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get generated keys for statement: %s", e.getText());
|
737
|
+
}
|
738
|
+
}
|
739
|
+
|
740
|
+
//------------------------------------------------------------------------------
|
741
|
+
|
742
|
+
void WrapPreparedStatement::init(VALUE module)
|
743
|
+
{
|
744
|
+
INIT_TYPE("PreparedStatement");
|
745
|
+
DEFINE_METHOD(close, 0);
|
746
|
+
DEFINE_METHOD(setBoolean, 2);
|
747
|
+
DEFINE_METHOD(setInteger, 2);
|
748
|
+
DEFINE_METHOD(setDouble, 2);
|
749
|
+
DEFINE_METHOD(setString, 2);
|
750
|
+
DEFINE_METHOD(setTime, 2);
|
751
|
+
DEFINE_METHOD(execute, 0);
|
752
|
+
DEFINE_METHOD(executeQuery, 0);
|
753
|
+
DEFINE_METHOD(executeUpdate, 0);
|
754
|
+
DEFINE_METHOD(getResultSet, 0);
|
755
|
+
DEFINE_METHOD(getUpdateCount, 0);
|
756
|
+
DEFINE_METHOD(getGeneratedKeys, 0);
|
757
|
+
}
|
758
|
+
|
759
|
+
VALUE WrapPreparedStatement::close(VALUE self)
|
760
|
+
{
|
761
|
+
try
|
762
|
+
{
|
763
|
+
asPtr(self)->close();
|
764
|
+
return Qnil;
|
765
|
+
}
|
766
|
+
catch (SQLException & e)
|
767
|
+
{
|
768
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully close prepared statement: %s", e.getText());
|
769
|
+
}
|
770
|
+
}
|
771
|
+
|
772
|
+
VALUE WrapPreparedStatement::setTime(VALUE self, VALUE indexValue, VALUE valueValue)
|
773
|
+
{
|
774
|
+
int32_t index = NUM2UINT(indexValue);
|
775
|
+
struct timeval tv = rb_time_timeval(valueValue);
|
776
|
+
|
777
|
+
SqlDate d( (((int64_t)tv.tv_sec)* 1000)+ (((int64_t)tv.tv_usec)/ 1000));
|
778
|
+
try
|
779
|
+
{
|
780
|
+
asPtr(self)->setDate(index, &d);
|
781
|
+
return Qnil;
|
782
|
+
}
|
783
|
+
catch (SQLException & e)
|
784
|
+
{
|
785
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to set prepared statement setTime(%d, %lld) failed: %s",
|
786
|
+
index, d.getMilliseconds(), e.getText());
|
787
|
+
}
|
788
|
+
}
|
789
|
+
|
790
|
+
VALUE WrapPreparedStatement::setBoolean(VALUE self, VALUE indexValue, VALUE valueValue)
|
791
|
+
{
|
792
|
+
int32_t index = NUM2UINT(indexValue);
|
793
|
+
bool value = valueValue ? true : false;
|
794
|
+
try
|
795
|
+
{
|
796
|
+
asPtr(self)->setInt(index, value);
|
797
|
+
return Qnil;
|
798
|
+
}
|
799
|
+
catch (SQLException & e)
|
800
|
+
{
|
801
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to set prepared statement boolean value (%d, %s): %s",
|
802
|
+
index, (value ? "true" : "false"), e.getText());
|
803
|
+
}
|
804
|
+
}
|
805
|
+
|
806
|
+
VALUE WrapPreparedStatement::setInteger(VALUE self, VALUE indexValue, VALUE valueValue)
|
807
|
+
{
|
808
|
+
int32_t index = NUM2UINT(indexValue);
|
809
|
+
int32_t value = NUM2INT(valueValue);
|
810
|
+
try
|
811
|
+
{
|
812
|
+
asPtr(self)->setInt(index, value);
|
813
|
+
return Qnil;
|
814
|
+
}
|
815
|
+
catch (SQLException & e)
|
816
|
+
{
|
817
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to set prepared statement integer value (%d, %d): %s", index, value, e.getText());
|
818
|
+
}
|
819
|
+
}
|
820
|
+
|
821
|
+
VALUE WrapPreparedStatement::setDouble(VALUE self, VALUE indexValue, VALUE valueValue)
|
822
|
+
{
|
823
|
+
int32_t index = NUM2UINT(indexValue);
|
824
|
+
double value = NUM2DBL(valueValue);
|
825
|
+
try
|
826
|
+
{
|
827
|
+
asPtr(self)->setDouble(index, value);
|
828
|
+
return Qnil;
|
829
|
+
}
|
830
|
+
catch (SQLException & e)
|
831
|
+
{
|
832
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to set prepared statement double value (%d, %g): %s", index, value, e.getText());
|
833
|
+
}
|
834
|
+
}
|
835
|
+
|
836
|
+
VALUE WrapPreparedStatement::setString(VALUE self, VALUE indexValue, VALUE valueValue)
|
837
|
+
{
|
838
|
+
int32_t index = NUM2UINT(indexValue);
|
839
|
+
char const* value = RSTRING_PTR(valueValue);
|
840
|
+
try
|
841
|
+
{
|
842
|
+
asPtr(self)->setString(index, value);
|
843
|
+
return Qnil;
|
844
|
+
}
|
845
|
+
catch (SQLException & e)
|
846
|
+
{
|
847
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to set prepared statement string value (%d, \"%s\"): %s", index, value, e.getText());
|
848
|
+
}
|
849
|
+
}
|
850
|
+
|
851
|
+
VALUE WrapPreparedStatement::execute(VALUE self)
|
852
|
+
{
|
853
|
+
try
|
854
|
+
{
|
855
|
+
return AS_QBOOL(asPtr(self)->execute());
|
856
|
+
}
|
857
|
+
catch (SQLException & e)
|
858
|
+
{
|
859
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to execute SQL prepared statement: %s", e.getText());
|
860
|
+
}
|
861
|
+
}
|
862
|
+
|
863
|
+
VALUE WrapPreparedStatement::executeQuery(VALUE self)
|
864
|
+
{
|
865
|
+
try
|
866
|
+
{
|
867
|
+
return WrapResultSet::wrap(asPtr(self)->executeQuery());
|
868
|
+
}
|
869
|
+
catch (SQLException & e)
|
870
|
+
{
|
871
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to execute SQL query prepared statement: %s", e.getText());
|
872
|
+
}
|
873
|
+
}
|
874
|
+
|
875
|
+
VALUE WrapPreparedStatement::executeUpdate(VALUE self)
|
876
|
+
{
|
877
|
+
try
|
878
|
+
{
|
879
|
+
return INT2NUM(asPtr(self)->executeUpdate());
|
880
|
+
}
|
881
|
+
catch (SQLException & e)
|
882
|
+
{
|
883
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to execute SQL update prepared statement: %s", e.getText());
|
884
|
+
}
|
885
|
+
}
|
886
|
+
|
887
|
+
VALUE WrapPreparedStatement::getResultSet(VALUE self)
|
888
|
+
{
|
889
|
+
try
|
890
|
+
{
|
891
|
+
return WrapResultSet::wrap(asPtr(self)->getResultSet());
|
892
|
+
}
|
893
|
+
catch (SQLException & e)
|
894
|
+
{
|
895
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get the result set for the prepared statement: %s", e.getText());
|
896
|
+
}
|
897
|
+
}
|
898
|
+
|
899
|
+
VALUE WrapPreparedStatement::getUpdateCount(VALUE self)
|
900
|
+
{
|
901
|
+
try
|
902
|
+
{
|
903
|
+
return INT2NUM(asPtr(self)->getUpdateCount());
|
904
|
+
}
|
905
|
+
catch (SQLException & e)
|
906
|
+
{
|
907
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get the update count for the prepared statement: %s", e.getText());
|
908
|
+
}
|
909
|
+
}
|
910
|
+
|
911
|
+
VALUE WrapPreparedStatement::getGeneratedKeys(VALUE self)
|
912
|
+
{
|
913
|
+
try
|
914
|
+
{
|
915
|
+
return WrapResultSet::wrap(asPtr(self)->getGeneratedKeys());
|
916
|
+
}
|
917
|
+
catch (SQLException & e)
|
918
|
+
{
|
919
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get the generated keys for the prepared statement: %s", e.getText());
|
920
|
+
}
|
921
|
+
}
|
922
|
+
|
923
|
+
//------------------------------------------------------------------------------
|
924
|
+
|
925
|
+
void WrapConnection::init(VALUE module)
|
926
|
+
{
|
927
|
+
type = rb_define_class_under(module, "Connection", rb_cObject);
|
928
|
+
|
929
|
+
// DBI
|
930
|
+
|
931
|
+
// todo add .columns, or not? If we did: .columns(table_name)
|
932
|
+
// todo and tie this into the SchemaCache on the Ruby side.
|
933
|
+
rb_define_method(type, "commit", RUBY_METHOD_FUNC(commit), 0);
|
934
|
+
rb_define_method(type, "disconnect", RUBY_METHOD_FUNC(close), 0);
|
935
|
+
rb_define_method(type, "ping", RUBY_METHOD_FUNC(ping), 0);
|
936
|
+
rb_define_method(type, "prepare", RUBY_METHOD_FUNC(createPreparedStatement), 1);
|
937
|
+
rb_define_method(type, "rollback", RUBY_METHOD_FUNC(rollback), 0);
|
938
|
+
// todo add .tables, definitely!
|
939
|
+
|
940
|
+
// NUODB EXTENSIONS
|
941
|
+
|
942
|
+
rb_define_method(type, "autocommit=", RUBY_METHOD_FUNC(setAutoCommit), 1);
|
943
|
+
rb_define_method(type, "autocommit?", RUBY_METHOD_FUNC(hasAutoCommit), 0);
|
944
|
+
|
945
|
+
// DEPRECATED, going away shortly...
|
946
|
+
|
947
|
+
// todo use .new and .initialize instead...
|
948
|
+
DEFINE_SINGLE(createSqlConnection, 4);
|
949
|
+
DEFINE_METHOD(createStatement, 0);
|
950
|
+
DEFINE_METHOD(createPreparedStatement, 1);
|
951
|
+
DEFINE_METHOD(setAutoCommit, 1);
|
952
|
+
DEFINE_METHOD(hasAutoCommit, 0);
|
953
|
+
DEFINE_METHOD(getMetaData, 0);
|
954
|
+
DEFINE_METHOD(close, 0);
|
955
|
+
DEFINE_METHOD(getSchema, 0);
|
956
|
+
}
|
957
|
+
|
958
|
+
VALUE WrapConnection::getSchema(VALUE self)
|
959
|
+
{
|
960
|
+
try
|
961
|
+
{
|
962
|
+
return rb_str_new2(asPtr(self)->getSchema());
|
963
|
+
}
|
964
|
+
catch (SQLException & e)
|
965
|
+
{
|
966
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get schema for connection: %s", e.getText());
|
967
|
+
}
|
968
|
+
}
|
969
|
+
|
970
|
+
VALUE WrapConnection::close(VALUE self)
|
971
|
+
{
|
972
|
+
try
|
973
|
+
{
|
974
|
+
asPtr(self)->close();
|
975
|
+
return Qnil;
|
976
|
+
}
|
977
|
+
catch (SQLException & e)
|
978
|
+
{
|
979
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to successfully disconnect connection: %s", e.getText());
|
980
|
+
}
|
981
|
+
}
|
982
|
+
|
983
|
+
VALUE WrapConnection::ping(VALUE self)
|
984
|
+
{
|
985
|
+
try
|
986
|
+
{
|
987
|
+
asPtr(self)->ping();
|
988
|
+
return Qtrue;
|
989
|
+
}
|
990
|
+
catch (SQLException & e)
|
991
|
+
{
|
992
|
+
return Qfalse;
|
993
|
+
}
|
994
|
+
}
|
995
|
+
|
996
|
+
VALUE WrapConnection::createStatement(VALUE self)
|
997
|
+
{
|
998
|
+
try
|
999
|
+
{
|
1000
|
+
return WrapStatement::wrap(asPtr(self)->createStatement());
|
1001
|
+
}
|
1002
|
+
catch (SQLException & e)
|
1003
|
+
{
|
1004
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to create statement: %s", e.getText());
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
|
1008
|
+
VALUE WrapConnection::createPreparedStatement(VALUE self, VALUE sqlValue)
|
1009
|
+
{
|
1010
|
+
const char * sql = StringValuePtr(sqlValue);
|
1011
|
+
try
|
1012
|
+
{
|
1013
|
+
return WrapPreparedStatement::wrap( asPtr(self)->prepareStatement(sql, NuoDB::RETURN_GENERATED_KEYS));
|
1014
|
+
}
|
1015
|
+
catch (SQLException & e)
|
1016
|
+
{
|
1017
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to create prepared statement (%s): %s", sql, e.getText());
|
1018
|
+
}
|
1019
|
+
}
|
1020
|
+
|
1021
|
+
VALUE WrapConnection::setAutoCommit(VALUE self, VALUE autoCommitValue)
|
1022
|
+
{
|
1023
|
+
bool autoCommit = !(RB_TYPE_P(autoCommitValue, T_FALSE) || RB_TYPE_P(autoCommitValue, T_NIL));
|
1024
|
+
try
|
1025
|
+
{
|
1026
|
+
asPtr(self)->setAutoCommit(autoCommit);
|
1027
|
+
return Qnil;
|
1028
|
+
}
|
1029
|
+
catch (SQLException & e)
|
1030
|
+
{
|
1031
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to set auto-commit (%d) for connection: %s", autoCommit, e.getText());
|
1032
|
+
}
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
VALUE WrapConnection::hasAutoCommit(VALUE self)
|
1036
|
+
{
|
1037
|
+
try
|
1038
|
+
{
|
1039
|
+
return AS_QBOOL(asPtr(self)->getAutoCommit());
|
1040
|
+
}
|
1041
|
+
catch (SQLException & e)
|
1042
|
+
{
|
1043
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to determine auto-commit state for connection: %s", e.getText());
|
1044
|
+
}
|
1045
|
+
}
|
1046
|
+
|
1047
|
+
VALUE WrapConnection::commit(VALUE self)
|
1048
|
+
{
|
1049
|
+
try
|
1050
|
+
{
|
1051
|
+
asPtr(self)->commit();
|
1052
|
+
return Qnil;
|
1053
|
+
}
|
1054
|
+
catch (SQLException & e)
|
1055
|
+
{
|
1056
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to commit transaction: %s", e.getText());
|
1057
|
+
}
|
1058
|
+
}
|
1059
|
+
|
1060
|
+
VALUE WrapConnection::rollback(VALUE self)
|
1061
|
+
{
|
1062
|
+
try
|
1063
|
+
{
|
1064
|
+
asPtr(self)->rollback();
|
1065
|
+
return Qnil;
|
1066
|
+
}
|
1067
|
+
catch (SQLException & e)
|
1068
|
+
{
|
1069
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to rollback transaction: %s", e.getText());
|
1070
|
+
}
|
1071
|
+
}
|
1072
|
+
|
1073
|
+
VALUE WrapConnection::getMetaData(VALUE self)
|
1074
|
+
{
|
1075
|
+
try
|
1076
|
+
{
|
1077
|
+
return WrapDatabaseMetaData::wrap( asPtr(self)->getMetaData());
|
1078
|
+
}
|
1079
|
+
catch (SQLException & e)
|
1080
|
+
{
|
1081
|
+
rb_raise_nuodb_error(e.getSqlcode(), "Failed to get database metadata: %s", e.getText());
|
1082
|
+
}
|
1083
|
+
}
|
1084
|
+
|
1085
|
+
VALUE WrapConnection::createSqlConnection(VALUE self,
|
1086
|
+
VALUE databaseValue,
|
1087
|
+
VALUE schemaValue,
|
1088
|
+
VALUE usernameValue,
|
1089
|
+
VALUE passwordValue)
|
1090
|
+
{
|
1091
|
+
char const* database = StringValuePtr(databaseValue);
|
1092
|
+
char const* schema = StringValuePtr(schemaValue);
|
1093
|
+
char const* username = StringValuePtr(usernameValue);
|
1094
|
+
char const* password = StringValuePtr(passwordValue);
|
1095
|
+
|
1096
|
+
try
|
1097
|
+
{
|
1098
|
+
return WrapConnection::wrap( getDatabaseConnection(database,
|
1099
|
+
username,
|
1100
|
+
password,
|
1101
|
+
1,
|
1102
|
+
"schema",
|
1103
|
+
schema));
|
1104
|
+
}
|
1105
|
+
catch (SQLException & e)
|
1106
|
+
{
|
1107
|
+
rb_raise_nuodb_error(e.getSqlcode(),
|
1108
|
+
"Failed to create database connection (\"%s\", \"%s\", ********, \"%s\"): %s",
|
1109
|
+
database,
|
1110
|
+
username,
|
1111
|
+
schema,
|
1112
|
+
e.getText());
|
1113
|
+
}
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
//------------------------------------------------------------------------------
|
1117
|
+
|
1118
|
+
extern "C" void Init_nuodb(void)
|
1119
|
+
{
|
1120
|
+
m_nuodb = rb_define_module("NuoDB");
|
1121
|
+
c_nuodb_error = rb_const_get(m_nuodb, rb_intern("Error"));
|
1122
|
+
c_error_code_assignment = rb_intern("error_code=");
|
1123
|
+
|
1124
|
+
WrapConnection::init(m_nuodb);
|
1125
|
+
WrapDatabaseMetaData::init(m_nuodb);
|
1126
|
+
WrapStatement::init(m_nuodb);
|
1127
|
+
WrapPreparedStatement::init(m_nuodb);
|
1128
|
+
WrapResultSet::init(m_nuodb);
|
1129
|
+
WrapResultSetMetaData::init(m_nuodb);
|
1130
|
+
}
|