rubyfb 0.5.5 → 0.5.6
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/CHANGELOG +6 -0
- data/Manifest +0 -1
- data/Rakefile +1 -1
- data/ext/AddUser.c +217 -248
- data/ext/AddUser.h +3 -3
- data/ext/Backup.c +337 -404
- data/ext/Backup.h +3 -3
- data/ext/Blob.c +197 -248
- data/ext/Blob.h +30 -31
- data/ext/Common.c +17 -18
- data/ext/Common.h +10 -10
- data/ext/Connection.c +413 -487
- data/ext/Connection.h +18 -19
- data/ext/DataArea.c +172 -189
- data/ext/DataArea.h +11 -11
- data/ext/Database.c +198 -238
- data/ext/Database.h +16 -17
- data/ext/FireRuby.c +118 -142
- data/ext/FireRuby.h +17 -17
- data/ext/FireRubyException.c +68 -138
- data/ext/FireRubyException.h +14 -21
- data/ext/Generator.c +296 -377
- data/ext/Generator.h +17 -18
- data/ext/RemoveUser.c +91 -102
- data/ext/RemoveUser.h +3 -3
- data/ext/Restore.c +353 -423
- data/ext/Restore.h +3 -3
- data/ext/ResultSet.c +423 -456
- data/ext/ResultSet.h +26 -27
- data/ext/Row.c +505 -568
- data/ext/Row.h +27 -28
- data/ext/ServiceManager.c +143 -164
- data/ext/ServiceManager.h +17 -18
- data/ext/Services.c +58 -67
- data/ext/Services.h +3 -3
- data/ext/Statement.c +388 -449
- data/ext/Statement.h +30 -31
- data/ext/Transaction.c +374 -448
- data/ext/Transaction.h +17 -18
- data/ext/TypeMap.c +654 -774
- data/ext/TypeMap.h +17 -17
- data/ext/rfbint.h +3 -3
- data/lib/active_record/connection_adapters/rubyfb_adapter.rb +1 -1
- data/lib/rubyfb_lib.so +0 -0
- data/lib/src.rb +33 -0
- data/rubyfb.gemspec +3 -3
- data/test/ResultSetTest.rb +13 -0
- data/test/RowTest.rb +16 -0
- metadata +4 -5
- data/test/UnitTest.rb +0 -65
data/ext/TypeMap.c
CHANGED
@@ -72,169 +72,149 @@ void populateTimestampField(VALUE, XSQLVAR *);
|
|
72
72
|
*/
|
73
73
|
VALUE toValue(XSQLVAR *entry,
|
74
74
|
isc_db_handle *database,
|
75
|
-
isc_tr_handle *transaction)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
case SQL_VARYING :
|
211
|
-
memcpy(&length, entry->sqldata, 2);
|
212
|
-
if(length >= 0)
|
213
|
-
{
|
214
|
-
array = ALLOC_N(char, length + 1);
|
215
|
-
if(array != NULL)
|
216
|
-
{
|
217
|
-
memset(array, 0, length + 1);
|
218
|
-
memcpy(array, &entry->sqldata[2], length);
|
219
|
-
rb_ary_push(value, rb_str_new2(array));
|
220
|
-
rb_ary_push(value, getColumnType(entry));
|
221
|
-
free(array);
|
222
|
-
}
|
223
|
-
}
|
224
|
-
break;
|
225
|
-
|
226
|
-
default :
|
227
|
-
rb_ary_push(value, Qnil);
|
228
|
-
rb_ary_push(value, Qnil);
|
229
|
-
} /* End of switch. */
|
230
|
-
}
|
231
|
-
else
|
232
|
-
{
|
75
|
+
isc_tr_handle *transaction) {
|
76
|
+
VALUE value = rb_ary_new();
|
77
|
+
|
78
|
+
/* Check for NULL values. */
|
79
|
+
if(!((entry->sqltype & 1) && (*entry->sqlind < 0))) {
|
80
|
+
int type = (entry->sqltype & ~1);
|
81
|
+
char *array = NULL,
|
82
|
+
column[256],
|
83
|
+
table[256];
|
84
|
+
struct tm datetime;
|
85
|
+
short length;
|
86
|
+
double actual;
|
87
|
+
BlobHandle *blob = NULL;
|
88
|
+
VALUE setting = getFireRubySetting("DATE_AS_DATE"),
|
89
|
+
working = Qnil;
|
90
|
+
|
91
|
+
switch(type) {
|
92
|
+
case SQL_ARRAY: /* Type: ARRAY */
|
93
|
+
/* TO BE DONE! */
|
94
|
+
break;
|
95
|
+
|
96
|
+
case SQL_BLOB: /* Type: BLOB */
|
97
|
+
memset(column, 0, 256);
|
98
|
+
memset(table, 0, 256);
|
99
|
+
memcpy(column, entry->sqlname, entry->sqlname_length);
|
100
|
+
memcpy(table, entry->relname, entry->relname_length);
|
101
|
+
blob = openBlob(*(ISC_QUAD *)entry->sqldata, column, table, database,
|
102
|
+
transaction);
|
103
|
+
working = Data_Wrap_Struct(cBlob, NULL, blobFree, blob);
|
104
|
+
rb_ary_push(value, initializeBlob(working));
|
105
|
+
rb_ary_push(value, getColumnType(entry));
|
106
|
+
break;
|
107
|
+
|
108
|
+
case SQL_TYPE_DATE: /* Type: DATE */
|
109
|
+
memset(&datetime, 0, sizeof(struct tm));
|
110
|
+
isc_decode_sql_date((ISC_DATE *)entry->sqldata, &datetime);
|
111
|
+
datetime.tm_sec = 0;
|
112
|
+
datetime.tm_min = 0;
|
113
|
+
datetime.tm_hour = 0;
|
114
|
+
if(setting == Qtrue) {
|
115
|
+
rb_ary_push(value, createDate(&datetime));
|
116
|
+
} else {
|
117
|
+
rb_ary_push(value, createSafeTime(&datetime));
|
118
|
+
}
|
119
|
+
rb_ary_push(value, getColumnType(entry));
|
120
|
+
break;
|
121
|
+
|
122
|
+
case SQL_DOUBLE: /* Type: DOUBLE PRECISION, DECIMAL, NUMERIC */
|
123
|
+
rb_ary_push(value, rb_float_new(*((double *)entry->sqldata)));
|
124
|
+
rb_ary_push(value, getColumnType(entry));
|
125
|
+
break;
|
126
|
+
|
127
|
+
case SQL_FLOAT: /* Type: FLOAT */
|
128
|
+
rb_ary_push(value, rb_float_new(*((float *)entry->sqldata)));
|
129
|
+
rb_ary_push(value, getColumnType(entry));
|
130
|
+
break;
|
131
|
+
|
132
|
+
case SQL_INT64: /* Type: DECIMAL, NUMERIC */
|
133
|
+
if(entry->sqlscale != 0) {
|
134
|
+
double divisor = pow(10, abs(entry->sqlscale));
|
135
|
+
|
136
|
+
actual = *((long long *)entry->sqldata);
|
137
|
+
rb_ary_push(value, rb_float_new(actual / divisor));
|
138
|
+
} else {
|
139
|
+
rb_ary_push(value, LL2NUM(*((long long *)entry->sqldata)));
|
140
|
+
}
|
141
|
+
rb_ary_push(value, getColumnType(entry));
|
142
|
+
break;
|
143
|
+
|
144
|
+
case SQL_LONG: /* Type: INTEGER, DECIMAL, NUMERIC */
|
145
|
+
if(entry->sqlscale != 0) {
|
146
|
+
double divisor = pow(10, abs(entry->sqlscale));
|
147
|
+
|
148
|
+
actual = *((int32_t *)entry->sqldata);
|
149
|
+
rb_ary_push(value, rb_float_new(actual / divisor));
|
150
|
+
} else {
|
151
|
+
rb_ary_push(value, LONG2NUM(*((int32_t *)entry->sqldata)));
|
152
|
+
}
|
153
|
+
rb_ary_push(value, getColumnType(entry));
|
154
|
+
break;
|
155
|
+
|
156
|
+
case SQL_SHORT: /* Type: SMALLINT, DECIMAL, NUMERIC */
|
157
|
+
if(entry->sqlscale != 0) {
|
158
|
+
double divisor = pow(10, abs(entry->sqlscale));
|
159
|
+
|
160
|
+
actual = *((short *)entry->sqldata);
|
161
|
+
rb_ary_push(value, rb_float_new(actual / divisor));
|
162
|
+
} else {
|
163
|
+
rb_ary_push(value, INT2NUM(*((short *)entry->sqldata)));
|
164
|
+
}
|
165
|
+
rb_ary_push(value, getColumnType(entry));
|
166
|
+
break;
|
167
|
+
|
168
|
+
case SQL_TEXT: /* Type: CHAR */
|
169
|
+
array = ALLOC_N(char, entry->sqllen + 1);
|
170
|
+
if(array != NULL) {
|
171
|
+
memset(array, 0, entry->sqllen + 1);
|
172
|
+
memcpy(array, entry->sqldata, entry->sqllen);
|
173
|
+
rb_ary_push(value, rb_str_new2(array));
|
174
|
+
rb_ary_push(value, getColumnType(entry));
|
175
|
+
free(array);
|
176
|
+
}
|
177
|
+
break;
|
178
|
+
|
179
|
+
case SQL_TYPE_TIME: /* Type: TIME */
|
180
|
+
isc_decode_sql_time((ISC_TIME *)entry->sqldata, &datetime);
|
181
|
+
datetime.tm_year = 70;
|
182
|
+
datetime.tm_mon = 0;
|
183
|
+
datetime.tm_mday = 1;
|
184
|
+
rb_ary_push(value, createSafeTime(&datetime));
|
185
|
+
rb_ary_push(value, getColumnType(entry));
|
186
|
+
break;
|
187
|
+
|
188
|
+
case SQL_TIMESTAMP: /* Type: TIMESTAMP */
|
189
|
+
isc_decode_timestamp((ISC_TIMESTAMP *)entry->sqldata, &datetime);
|
190
|
+
rb_ary_push(value, createSafeTime(&datetime));
|
191
|
+
rb_ary_push(value, getColumnType(entry));
|
192
|
+
break;
|
193
|
+
|
194
|
+
case SQL_VARYING:
|
195
|
+
memcpy(&length, entry->sqldata, 2);
|
196
|
+
if(length >= 0) {
|
197
|
+
array = ALLOC_N(char, length + 1);
|
198
|
+
if(array != NULL) {
|
199
|
+
memset(array, 0, length + 1);
|
200
|
+
memcpy(array, &entry->sqldata[2], length);
|
201
|
+
rb_ary_push(value, rb_str_new2(array));
|
202
|
+
rb_ary_push(value, getColumnType(entry));
|
203
|
+
free(array);
|
204
|
+
}
|
205
|
+
}
|
206
|
+
break;
|
207
|
+
|
208
|
+
default:
|
209
|
+
rb_ary_push(value, Qnil);
|
233
210
|
rb_ary_push(value, Qnil);
|
234
|
-
|
235
|
-
|
211
|
+
} /* End of switch. */
|
212
|
+
} else {
|
213
|
+
rb_ary_push(value, Qnil);
|
214
|
+
rb_ary_push(value, getColumnType(entry));
|
215
|
+
}
|
236
216
|
|
237
|
-
|
217
|
+
return(value);
|
238
218
|
}
|
239
219
|
|
240
220
|
|
@@ -248,29 +228,27 @@ VALUE toValue(XSQLVAR *entry,
|
|
248
228
|
* @return A reference to the array containing the row data from the XSQLDA.
|
249
229
|
*
|
250
230
|
*/
|
251
|
-
VALUE toArray(VALUE results)
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
return(array);
|
231
|
+
VALUE toArray(VALUE results) {
|
232
|
+
VALUE array = rb_ary_new(),
|
233
|
+
transaction = rb_iv_get(results, "@transaction"),
|
234
|
+
connection = rb_iv_get(results, "@connection");
|
235
|
+
XSQLVAR *entry = NULL;
|
236
|
+
ConnectionHandle *cHandle = NULL;
|
237
|
+
ResultsHandle *rHandle = NULL;
|
238
|
+
TransactionHandle *tHandle = NULL;
|
239
|
+
int i;
|
240
|
+
|
241
|
+
Data_Get_Struct(connection, ConnectionHandle, cHandle);
|
242
|
+
Data_Get_Struct(results, ResultsHandle, rHandle);
|
243
|
+
Data_Get_Struct(transaction, TransactionHandle, tHandle);
|
244
|
+
entry = rHandle->output->sqlvar;
|
245
|
+
for(i = 0; i < rHandle->output->sqln; i++, entry++) {
|
246
|
+
VALUE value = toValue(entry, &cHandle->handle, &tHandle->handle);
|
247
|
+
|
248
|
+
rb_ary_push(array, value);
|
249
|
+
}
|
250
|
+
|
251
|
+
return(array);
|
274
252
|
}
|
275
253
|
|
276
254
|
|
@@ -288,102 +266,95 @@ VALUE toArray(VALUE results)
|
|
288
266
|
* to get connection and transaction details.
|
289
267
|
*
|
290
268
|
*/
|
291
|
-
void setParameters(XSQLDA *parameters, VALUE array, VALUE source)
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
else
|
381
|
-
{
|
382
|
-
/* Mark the field as a NULL value. */
|
383
|
-
memset(parameter->sqldata, 0, parameter->sqllen);
|
384
|
-
*parameter->sqlind = -1;
|
385
|
-
}
|
386
|
-
}
|
269
|
+
void setParameters(XSQLDA *parameters, VALUE array, VALUE source) {
|
270
|
+
VALUE value;
|
271
|
+
int index,
|
272
|
+
size;
|
273
|
+
XSQLVAR *parameter = NULL;
|
274
|
+
|
275
|
+
/* Check that sufficient parameters have been provided. */
|
276
|
+
value = rb_funcall(array, rb_intern("size"), 0);
|
277
|
+
size = (TYPE(value) == T_FIXNUM ? FIX2INT(value) : NUM2INT(value));
|
278
|
+
parameter = parameters->sqlvar;
|
279
|
+
if(size != parameters->sqld) {
|
280
|
+
rb_raise(rb_eException,
|
281
|
+
"Parameter set mismatch. Too many or too few parameters " \
|
282
|
+
"specified for a SQL statement.");
|
283
|
+
}
|
284
|
+
parameters->sqln = parameters->sqld;
|
285
|
+
parameters->version = 1;
|
286
|
+
|
287
|
+
/* Populate the parameters from the array's contents. */
|
288
|
+
for(index = 0; index < size; index++, parameter++) {
|
289
|
+
int type = (parameter->sqltype & ~1);
|
290
|
+
|
291
|
+
value = rb_ary_entry(array, index);
|
292
|
+
/* Check for nils to indicate null values. */
|
293
|
+
if(value != Qnil) {
|
294
|
+
VALUE name = rb_funcall(value, rb_intern("class"), 0);
|
295
|
+
|
296
|
+
parameter->sqlind = 0;
|
297
|
+
name = rb_funcall(name, rb_intern("name"), 0);
|
298
|
+
switch(type) {
|
299
|
+
case SQL_ARRAY: /* Type: ARRAY */
|
300
|
+
/* TO BE DONE! */
|
301
|
+
break;
|
302
|
+
|
303
|
+
case SQL_BLOB: /* Type: BLOB */
|
304
|
+
populateBlobField(value, parameter, source);
|
305
|
+
break;
|
306
|
+
|
307
|
+
case SQL_DOUBLE: /* Type: DOUBLE PRECISION, DECIMAL, NUMERIC */
|
308
|
+
populateDoubleField(value, parameter);
|
309
|
+
break;
|
310
|
+
|
311
|
+
case SQL_FLOAT: /* Type: FLOAT */
|
312
|
+
populateFloatField(value, parameter);
|
313
|
+
break;
|
314
|
+
|
315
|
+
case SQL_INT64: /* Type: DECIMAL, NUMERIC */
|
316
|
+
populateInt64Field(value, parameter);
|
317
|
+
break;
|
318
|
+
|
319
|
+
case SQL_LONG: /* Type: INTEGER, DECIMAL, NUMERIC */
|
320
|
+
populateLongField(value, parameter);
|
321
|
+
break;
|
322
|
+
|
323
|
+
case SQL_SHORT: /* Type: SMALLINT, DECIMAL, NUMERIC */
|
324
|
+
populateShortField(value, parameter);
|
325
|
+
break;
|
326
|
+
|
327
|
+
case SQL_TEXT: /* Type: CHAR */
|
328
|
+
populateTextField(value, parameter);
|
329
|
+
break;
|
330
|
+
|
331
|
+
case SQL_TYPE_DATE: /* Type: DATE */
|
332
|
+
populateDateField(value, parameter);
|
333
|
+
break;
|
334
|
+
|
335
|
+
case SQL_TYPE_TIME: /* Type: TIME */
|
336
|
+
populateTimeField(value, parameter);
|
337
|
+
break;
|
338
|
+
|
339
|
+
case SQL_TIMESTAMP: /* Type: TIMESTAMP */
|
340
|
+
populateTimestampField(value, parameter);
|
341
|
+
break;
|
342
|
+
|
343
|
+
case SQL_VARYING: /* Type: VARCHAR */
|
344
|
+
populateTextField(value, parameter);
|
345
|
+
break;
|
346
|
+
|
347
|
+
default:
|
348
|
+
rb_raise(rb_eException,
|
349
|
+
"Unknown SQL type encountered in statement parameter " \
|
350
|
+
"set.");
|
351
|
+
} /* End of the switch statement. */
|
352
|
+
} else {
|
353
|
+
/* Mark the field as a NULL value. */
|
354
|
+
memset(parameter->sqldata, 0, parameter->sqllen);
|
355
|
+
*parameter->sqlind = -1;
|
356
|
+
}
|
357
|
+
}
|
387
358
|
}
|
388
359
|
|
389
360
|
|
@@ -395,36 +366,33 @@ void setParameters(XSQLDA *parameters, VALUE array, VALUE source)
|
|
395
366
|
* @return A Ruby Date object.
|
396
367
|
*
|
397
368
|
*/
|
398
|
-
VALUE createDate(const struct tm *date)
|
399
|
-
|
400
|
-
|
401
|
-
klass = Qnil;
|
369
|
+
VALUE createDate(const struct tm *date) {
|
370
|
+
VALUE result = Qnil,
|
371
|
+
klass = Qnil;
|
402
372
|
|
403
|
-
|
373
|
+
klass = getClass("Date");
|
404
374
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
}
|
375
|
+
/* Check if we need to require date. */
|
376
|
+
if(klass == Qnil) {
|
377
|
+
rb_require("date");
|
378
|
+
klass = getClass("Date");
|
379
|
+
}
|
411
380
|
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
VALUE arguments[3];
|
381
|
+
/* Check that we got the Date class. */
|
382
|
+
if(klass != Qnil) {
|
383
|
+
VALUE arguments[3];
|
416
384
|
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
385
|
+
/* Prepare the arguments. */
|
386
|
+
arguments[0] = INT2FIX(date->tm_year + 1900);
|
387
|
+
arguments[1] = INT2FIX(date->tm_mon + 1);
|
388
|
+
arguments[2] = INT2FIX(date->tm_mday);
|
421
389
|
|
422
|
-
|
423
|
-
|
424
|
-
|
390
|
+
/* Create the class instance. */
|
391
|
+
result = rb_funcall2(klass, rb_intern("new"), 3, arguments);
|
392
|
+
}
|
425
393
|
|
426
394
|
|
427
|
-
|
395
|
+
return(result);
|
428
396
|
}
|
429
397
|
|
430
398
|
|
@@ -436,42 +404,39 @@ VALUE createDate(const struct tm *date)
|
|
436
404
|
* @return A Ruby DateTime object.
|
437
405
|
*
|
438
406
|
*/
|
439
|
-
VALUE createDateTime(VALUE dt)
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
}
|
473
|
-
|
474
|
-
return(result);
|
407
|
+
VALUE createDateTime(VALUE dt) {
|
408
|
+
VALUE result = Qnil,
|
409
|
+
klass = Qnil;
|
410
|
+
|
411
|
+
struct tm *datetime;
|
412
|
+
Data_Get_Struct(dt, struct tm, datetime);
|
413
|
+
|
414
|
+
klass = getClass("DateTime");
|
415
|
+
|
416
|
+
/* Check if we need to require date. */
|
417
|
+
if(klass == Qnil) {
|
418
|
+
rb_require("date");
|
419
|
+
klass = getClass("DateTime");
|
420
|
+
}
|
421
|
+
|
422
|
+
/* Check that we got the DateTime class. */
|
423
|
+
if(klass != Qnil) {
|
424
|
+
VALUE arguments[7];
|
425
|
+
|
426
|
+
/* Prepare the arguments. */
|
427
|
+
arguments[0] = INT2FIX(datetime->tm_year + 1900);
|
428
|
+
arguments[1] = INT2FIX(datetime->tm_mon + 1);
|
429
|
+
arguments[2] = INT2FIX(datetime->tm_mday);
|
430
|
+
arguments[3] = INT2FIX(datetime->tm_hour);
|
431
|
+
arguments[4] = INT2FIX(datetime->tm_min);
|
432
|
+
arguments[5] = INT2FIX(datetime->tm_sec);
|
433
|
+
arguments[6] = rb_funcall(rb_funcall(klass, rb_intern("now"), 0), rb_intern("offset"), 0);
|
434
|
+
|
435
|
+
/* Create the class instance. */
|
436
|
+
result = rb_funcall2(klass, rb_intern("new"), 7, arguments);
|
437
|
+
}
|
438
|
+
|
439
|
+
return(result);
|
475
440
|
}
|
476
441
|
|
477
442
|
|
@@ -483,54 +448,51 @@ VALUE createDateTime(VALUE dt)
|
|
483
448
|
* @return A Ruby Time object.
|
484
449
|
*
|
485
450
|
*/
|
486
|
-
VALUE createTime(VALUE dt)
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
return(result);
|
451
|
+
VALUE createTime(VALUE dt) {
|
452
|
+
VALUE result = Qnil,
|
453
|
+
klass = Qnil;
|
454
|
+
|
455
|
+
struct tm *datetime;
|
456
|
+
Data_Get_Struct(dt, struct tm, datetime);
|
457
|
+
|
458
|
+
klass = getClass("Time");
|
459
|
+
|
460
|
+
/* Check that we got the Time class. */
|
461
|
+
if(klass != Qnil) {
|
462
|
+
VALUE arguments[6];
|
463
|
+
|
464
|
+
/* Prepare the arguments. */
|
465
|
+
/*fprintf(stderr, "%d-%d-%d %d:%d:%d\n", datetime->tm_year + 1900,
|
466
|
+
datetime->tm_mon + 1, datetime->tm_mday, datetime->tm_hour,
|
467
|
+
datetime->tm_min, datetime->tm_sec);*/
|
468
|
+
arguments[0] = INT2FIX(datetime->tm_year + 1900);
|
469
|
+
arguments[1] = INT2FIX(datetime->tm_mon + 1);
|
470
|
+
arguments[2] = INT2FIX(datetime->tm_mday);
|
471
|
+
arguments[3] = INT2FIX(datetime->tm_hour);
|
472
|
+
arguments[4] = INT2FIX(datetime->tm_min);
|
473
|
+
arguments[5] = INT2FIX(datetime->tm_sec);
|
474
|
+
|
475
|
+
/* Create the class instance. */
|
476
|
+
result = rb_funcall2(klass, rb_intern("local"), 6, arguments);
|
477
|
+
}
|
478
|
+
|
479
|
+
return(result);
|
517
480
|
}
|
518
481
|
|
519
482
|
/**
|
520
|
-
* This function converts a struct tm to a Ruby Time instance.
|
483
|
+
* This function converts a struct tm to a Ruby Time instance.
|
521
484
|
* If the conversion process results in an out of range error then
|
522
485
|
* it will convert the struct to a DateTime instance.
|
523
486
|
*
|
524
487
|
* @param datetime A structure containing the date/time details.
|
525
488
|
*
|
526
|
-
* @return A Ruby Time object if the arguments are in range, otherwise
|
489
|
+
* @return A Ruby Time object if the arguments are in range, otherwise
|
527
490
|
* a Ruby DateTime object.
|
528
491
|
*
|
529
492
|
*/
|
530
|
-
VALUE createSafeTime(const struct tm *datetime)
|
531
|
-
|
532
|
-
|
533
|
-
return rb_rescue(createTime, dt, createDateTime, dt);
|
493
|
+
VALUE createSafeTime(const struct tm *datetime) {
|
494
|
+
VALUE dt = Data_Wrap_Struct(rb_cObject, NULL, NULL, (void*)datetime);
|
495
|
+
return rb_rescue(createTime, dt, createDateTime, dt);
|
534
496
|
}
|
535
497
|
|
536
498
|
/**
|
@@ -544,29 +506,25 @@ VALUE createSafeTime(const struct tm *datetime)
|
|
544
506
|
* @return A Ruby VALUE representing the constant.
|
545
507
|
*
|
546
508
|
*/
|
547
|
-
VALUE getConstant(const char *name, VALUE module)
|
548
|
-
{
|
509
|
+
VALUE getConstant(const char *name, VALUE module) {
|
549
510
|
VALUE owner = module,
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
511
|
+
constants,
|
512
|
+
exists,
|
513
|
+
entry = Qnil,
|
514
|
+
symbol = ID2SYM(rb_intern(name));
|
554
515
|
|
555
516
|
/* Check that we've got somewhere to look. */
|
556
|
-
if(owner == Qnil)
|
557
|
-
{
|
517
|
+
if(owner == Qnil) {
|
558
518
|
owner = rb_cModule;
|
559
519
|
}
|
560
520
|
|
561
521
|
constants = rb_funcall(owner, rb_intern("constants"), 0),
|
562
522
|
exists = rb_funcall(constants, rb_intern("include?"), 1, symbol);
|
563
|
-
if(exists == Qfalse)
|
564
|
-
{
|
523
|
+
if(exists == Qfalse) {
|
565
524
|
/* 1.8 style lookup */
|
566
525
|
exists = rb_funcall(constants, rb_intern("include?"), 1, rb_str_new2(name));
|
567
526
|
}
|
568
|
-
if(exists != Qfalse)
|
569
|
-
{
|
527
|
+
if(exists != Qfalse) {
|
570
528
|
entry = rb_funcall(owner, rb_intern("const_get"), 1, symbol);
|
571
529
|
}
|
572
530
|
return(entry);
|
@@ -581,21 +539,18 @@ VALUE getConstant(const char *name, VALUE module)
|
|
581
539
|
* module could not be located.
|
582
540
|
*
|
583
541
|
*/
|
584
|
-
VALUE getModule(const char *name)
|
585
|
-
|
586
|
-
VALUE module = getConstant(name, Qnil);
|
542
|
+
VALUE getModule(const char *name) {
|
543
|
+
VALUE module = getConstant(name, Qnil);
|
587
544
|
|
588
|
-
|
589
|
-
|
590
|
-
VALUE type = rb_funcall(module, rb_intern("class"), 0);
|
545
|
+
if(module != Qnil) {
|
546
|
+
VALUE type = rb_funcall(module, rb_intern("class"), 0);
|
591
547
|
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
}
|
548
|
+
if(type != rb_cModule) {
|
549
|
+
module = Qnil;
|
550
|
+
}
|
551
|
+
}
|
597
552
|
|
598
|
-
|
553
|
+
return(module);
|
599
554
|
}
|
600
555
|
|
601
556
|
|
@@ -607,21 +562,18 @@ VALUE getModule(const char *name)
|
|
607
562
|
* could not be found.
|
608
563
|
*
|
609
564
|
*/
|
610
|
-
VALUE getClass(const char *name)
|
611
|
-
|
612
|
-
VALUE klass = getConstant(name, Qnil);
|
565
|
+
VALUE getClass(const char *name) {
|
566
|
+
VALUE klass = getConstant(name, Qnil);
|
613
567
|
|
614
|
-
|
615
|
-
|
616
|
-
VALUE type = rb_funcall(klass, rb_intern("class"), 0);
|
568
|
+
if(klass != Qnil) {
|
569
|
+
VALUE type = rb_funcall(klass, rb_intern("class"), 0);
|
617
570
|
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
}
|
571
|
+
if(type != rb_cClass) {
|
572
|
+
klass = Qnil;
|
573
|
+
}
|
574
|
+
}
|
623
575
|
|
624
|
-
|
576
|
+
return(klass);
|
625
577
|
}
|
626
578
|
|
627
579
|
|
@@ -635,21 +587,18 @@ VALUE getClass(const char *name)
|
|
635
587
|
* not be located.
|
636
588
|
*
|
637
589
|
*/
|
638
|
-
VALUE getModuleInModule(const char *name, VALUE owner)
|
639
|
-
|
640
|
-
VALUE module = getConstant(name, owner);
|
590
|
+
VALUE getModuleInModule(const char *name, VALUE owner) {
|
591
|
+
VALUE module = getConstant(name, owner);
|
641
592
|
|
642
|
-
|
643
|
-
|
644
|
-
VALUE type = rb_funcall(module, rb_intern("class"), 0);
|
593
|
+
if(module != Qnil) {
|
594
|
+
VALUE type = rb_funcall(module, rb_intern("class"), 0);
|
645
595
|
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
}
|
596
|
+
if(type != rb_cModule) {
|
597
|
+
module = Qnil;
|
598
|
+
}
|
599
|
+
}
|
651
600
|
|
652
|
-
|
601
|
+
return(module);
|
653
602
|
}
|
654
603
|
|
655
604
|
|
@@ -663,21 +612,18 @@ VALUE getModuleInModule(const char *name, VALUE owner)
|
|
663
612
|
* not be located.
|
664
613
|
*
|
665
614
|
*/
|
666
|
-
VALUE getClassInModule(const char *name, VALUE owner)
|
667
|
-
|
668
|
-
VALUE klass = getConstant(name, owner);
|
615
|
+
VALUE getClassInModule(const char *name, VALUE owner) {
|
616
|
+
VALUE klass = getConstant(name, owner);
|
669
617
|
|
670
|
-
|
671
|
-
|
672
|
-
VALUE type = rb_funcall(klass, rb_intern("class"), 0);
|
618
|
+
if(klass != Qnil) {
|
619
|
+
VALUE type = rb_funcall(klass, rb_intern("class"), 0);
|
673
620
|
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
}
|
621
|
+
if(type != rb_cClass) {
|
622
|
+
klass = Qnil;
|
623
|
+
}
|
624
|
+
}
|
679
625
|
|
680
|
-
|
626
|
+
return(klass);
|
681
627
|
}
|
682
628
|
|
683
629
|
|
@@ -690,47 +636,41 @@ VALUE getClassInModule(const char *name, VALUE owner)
|
|
690
636
|
* in the order year, month, day of month, hours, minutes and seconds.
|
691
637
|
*
|
692
638
|
*/
|
693
|
-
VALUE toDateTime(VALUE value)
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
else
|
729
|
-
{
|
730
|
-
rb_raise(rb_eException, "Value conversion error.");
|
731
|
-
}
|
732
|
-
|
733
|
-
return(result);
|
639
|
+
VALUE toDateTime(VALUE value) {
|
640
|
+
VALUE result,
|
641
|
+
klass = rb_funcall(value, rb_intern("class"), 0);
|
642
|
+
|
643
|
+
if(klass == rb_cTime) {
|
644
|
+
VALUE data;
|
645
|
+
|
646
|
+
result = rb_ary_new();
|
647
|
+
|
648
|
+
data = rb_funcall(value, rb_intern("year"), 0);
|
649
|
+
rb_ary_push(result, INT2FIX(FIX2INT(data) - 1900));
|
650
|
+
data = rb_funcall(value, rb_intern("month"), 0);
|
651
|
+
rb_ary_push(result, INT2FIX(FIX2INT(data) - 1));
|
652
|
+
rb_ary_push(result, rb_funcall(value, rb_intern("day"), 0));
|
653
|
+
rb_ary_push(result, rb_funcall(value, rb_intern("hour"), 0));
|
654
|
+
rb_ary_push(result, rb_funcall(value, rb_intern("min"), 0));
|
655
|
+
rb_ary_push(result, rb_funcall(value, rb_intern("sec"), 0));
|
656
|
+
} else if(klass == getClass("Date")) {
|
657
|
+
VALUE data;
|
658
|
+
|
659
|
+
result = rb_ary_new();
|
660
|
+
|
661
|
+
data = rb_funcall(value, rb_intern("year"), 0);
|
662
|
+
rb_ary_push(result, INT2FIX(FIX2INT(data) - 1900));
|
663
|
+
data = rb_funcall(value, rb_intern("month"), 0);
|
664
|
+
rb_ary_push(result, INT2FIX(FIX2INT(data) - 1));
|
665
|
+
rb_ary_push(result, rb_funcall(value, rb_intern("mday"), 0));
|
666
|
+
rb_ary_push(result, INT2FIX(0));
|
667
|
+
rb_ary_push(result, INT2FIX(0));
|
668
|
+
rb_ary_push(result, INT2FIX(0));
|
669
|
+
} else {
|
670
|
+
rb_raise(rb_eException, "Value conversion error.");
|
671
|
+
}
|
672
|
+
|
673
|
+
return(result);
|
734
674
|
}
|
735
675
|
|
736
676
|
|
@@ -746,22 +686,21 @@ VALUE toDateTime(VALUE value)
|
|
746
686
|
* raised.
|
747
687
|
*
|
748
688
|
*/
|
749
|
-
VALUE rescueConvert(VALUE arguments, VALUE error)
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
return(rb_funcall(rb_eException, rb_intern("exception"), 1, &message));
|
689
|
+
VALUE rescueConvert(VALUE arguments, VALUE error) {
|
690
|
+
VALUE message,
|
691
|
+
tmp_str1 = Qnil,
|
692
|
+
tmp_str2 = Qnil;
|
693
|
+
char text[512];
|
694
|
+
|
695
|
+
tmp_str1 = rb_ary_entry(arguments, 1);
|
696
|
+
tmp_str2 = rb_ary_entry(arguments, 2);
|
697
|
+
sprintf(text, "Error converting input column %d from a %s to a %s.",
|
698
|
+
FIX2INT(rb_ary_entry(arguments, 0)),
|
699
|
+
StringValuePtr(tmp_str1),
|
700
|
+
StringValuePtr(tmp_str2));
|
701
|
+
message = rb_str_new2(text);
|
702
|
+
|
703
|
+
return(rb_funcall(rb_eException, rb_intern("exception"), 1, &message));
|
765
704
|
}
|
766
705
|
|
767
706
|
|
@@ -782,48 +721,41 @@ VALUE rescueConvert(VALUE arguments, VALUE error)
|
|
782
721
|
void storeBlob(VALUE info,
|
783
722
|
XSQLVAR *field,
|
784
723
|
ConnectionHandle *connection,
|
785
|
-
TransactionHandle *transaction)
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
ISC_STATUS other[20];
|
810
|
-
|
811
|
-
isc_close_blob(other, &handle);
|
812
|
-
rb_fireruby_raise(status, "Error writing blob data.");
|
813
|
-
}
|
814
|
-
|
815
|
-
offset = offset + size;
|
724
|
+
TransactionHandle *transaction) {
|
725
|
+
ISC_STATUS status[ISC_STATUS_LENGTH];
|
726
|
+
isc_blob_handle handle = 0;
|
727
|
+
ISC_QUAD *blobId = (ISC_QUAD *)field->sqldata;
|
728
|
+
VALUE number = rb_funcall(info, rb_intern("length"), 0);
|
729
|
+
long length = 0;
|
730
|
+
char *data = StringValuePtr(info);
|
731
|
+
|
732
|
+
length = TYPE(number) == T_FIXNUM ? FIX2INT(number) : NUM2INT(number);
|
733
|
+
field->sqltype = SQL_BLOB;
|
734
|
+
if(isc_create_blob(status, &connection->handle, &transaction->handle,
|
735
|
+
&handle, blobId) == 0) {
|
736
|
+
long offset = 0;
|
737
|
+
unsigned short size = 0;
|
738
|
+
|
739
|
+
while(offset < length) {
|
740
|
+
char *buffer = &data[offset];
|
741
|
+
|
742
|
+
size = (length - offset) > USHRT_MAX ? USHRT_MAX : length - offset;
|
743
|
+
if(isc_put_segment(status, &handle, size, buffer) != 0) {
|
744
|
+
ISC_STATUS other[20];
|
745
|
+
|
746
|
+
isc_close_blob(other, &handle);
|
747
|
+
rb_fireruby_raise(status, "Error writing blob data.");
|
816
748
|
}
|
817
749
|
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
750
|
+
offset = offset + size;
|
751
|
+
}
|
752
|
+
|
753
|
+
if(isc_close_blob(status, &handle) != 0) {
|
754
|
+
rb_fireruby_raise(status, "Error closing blob.");
|
755
|
+
}
|
756
|
+
} else {
|
757
|
+
rb_fireruby_raise(status, "Error storing blob data.");
|
758
|
+
}
|
827
759
|
}
|
828
760
|
|
829
761
|
|
@@ -836,24 +768,22 @@ void storeBlob(VALUE info,
|
|
836
768
|
* contains the connection and transaction details.
|
837
769
|
*
|
838
770
|
*/
|
839
|
-
void populateBlobField(VALUE value, XSQLVAR *field, VALUE source)
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
storeBlob(value, field, connection, transaction);
|
856
|
-
field->sqltype = SQL_BLOB;
|
771
|
+
void populateBlobField(VALUE value, XSQLVAR *field, VALUE source) {
|
772
|
+
VALUE attribute;
|
773
|
+
ConnectionHandle *connection = NULL;
|
774
|
+
TransactionHandle *transaction = NULL;
|
775
|
+
|
776
|
+
if(TYPE(value) != T_STRING) {
|
777
|
+
rb_fireruby_raise(NULL, "Error converting input parameter to blob.");
|
778
|
+
}
|
779
|
+
|
780
|
+
/* Fetch the connection and transaction details. */
|
781
|
+
attribute = rb_iv_get(source, "@connection");
|
782
|
+
Data_Get_Struct(attribute, ConnectionHandle, connection);
|
783
|
+
attribute = rb_iv_get(source, "@transaction");
|
784
|
+
Data_Get_Struct(attribute, TransactionHandle, transaction);
|
785
|
+
storeBlob(value, field, connection, transaction);
|
786
|
+
field->sqltype = SQL_BLOB;
|
857
787
|
}
|
858
788
|
|
859
789
|
|
@@ -864,23 +794,21 @@ void populateBlobField(VALUE value, XSQLVAR *field, VALUE source)
|
|
864
794
|
* @param field A pointer to the output field to be populated.
|
865
795
|
*
|
866
796
|
*/
|
867
|
-
void populateDateField(VALUE value, XSQLVAR *field)
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
isc_encode_sql_date(&datetime, (ISC_DATE *)field->sqldata);
|
883
|
-
field->sqltype = SQL_TYPE_DATE;
|
797
|
+
void populateDateField(VALUE value, XSQLVAR *field) {
|
798
|
+
struct tm datetime;
|
799
|
+
VALUE arguments = rb_ary_new();
|
800
|
+
|
801
|
+
rb_ary_push(arguments, rb_str_new2("date"));
|
802
|
+
value = rb_rescue(toDateTime, value, rescueConvert, arguments);
|
803
|
+
if(TYPE(value) != T_ARRAY) {
|
804
|
+
VALUE message = rb_funcall(value, rb_intern("message"), 0);
|
805
|
+
rb_fireruby_raise(NULL, StringValuePtr(message));
|
806
|
+
}
|
807
|
+
datetime.tm_year = FIX2INT(rb_ary_entry(value, 0));
|
808
|
+
datetime.tm_mon = FIX2INT(rb_ary_entry(value, 1));
|
809
|
+
datetime.tm_mday = FIX2INT(rb_ary_entry(value, 2));
|
810
|
+
isc_encode_sql_date(&datetime, (ISC_DATE *)field->sqldata);
|
811
|
+
field->sqltype = SQL_TYPE_DATE;
|
884
812
|
}
|
885
813
|
|
886
814
|
|
@@ -891,27 +819,22 @@ void populateDateField(VALUE value, XSQLVAR *field)
|
|
891
819
|
* @param field A pointer to the output field to be populated.
|
892
820
|
*
|
893
821
|
*/
|
894
|
-
void populateDoubleField(VALUE value, XSQLVAR *field)
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
{
|
907
|
-
rb_fireruby_raise(NULL,
|
908
|
-
"Error converting input parameter to double.");
|
909
|
-
}
|
910
|
-
}
|
822
|
+
void populateDoubleField(VALUE value, XSQLVAR *field) {
|
823
|
+
double store;
|
824
|
+
VALUE actual;
|
825
|
+
|
826
|
+
if(TYPE(value) != T_FLOAT) {
|
827
|
+
if(rb_obj_is_kind_of(value, rb_cNumeric) || TYPE(value) == T_STRING) {
|
828
|
+
actual = rb_funcall(value, rb_intern("to_f"), 0);
|
829
|
+
} else {
|
830
|
+
rb_fireruby_raise(NULL,
|
831
|
+
"Error converting input parameter to double.");
|
832
|
+
}
|
833
|
+
}
|
911
834
|
|
912
|
-
|
913
|
-
|
914
|
-
|
835
|
+
store = NUM2DBL(value);
|
836
|
+
memcpy(field->sqldata, &store, field->sqllen);
|
837
|
+
field->sqltype = SQL_DOUBLE;
|
915
838
|
}
|
916
839
|
|
917
840
|
|
@@ -922,29 +845,24 @@ void populateDoubleField(VALUE value, XSQLVAR *field)
|
|
922
845
|
* @param field A pointer to the output field to be populated.
|
923
846
|
*
|
924
847
|
*/
|
925
|
-
void populateFloatField(VALUE value, XSQLVAR *field)
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
{
|
939
|
-
rb_fireruby_raise(NULL,
|
940
|
-
"Error converting input parameter to double.");
|
941
|
-
}
|
942
|
-
}
|
848
|
+
void populateFloatField(VALUE value, XSQLVAR *field) {
|
849
|
+
double full = 0.0;
|
850
|
+
float store = 0.0;
|
851
|
+
VALUE actual;
|
852
|
+
|
853
|
+
if(TYPE(value) != T_FLOAT) {
|
854
|
+
if(rb_obj_is_kind_of(value, rb_cNumeric) || TYPE(value) == T_STRING) {
|
855
|
+
actual = rb_funcall(value, rb_intern("to_f"), 0);
|
856
|
+
} else {
|
857
|
+
rb_fireruby_raise(NULL,
|
858
|
+
"Error converting input parameter to double.");
|
859
|
+
}
|
860
|
+
}
|
943
861
|
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
862
|
+
full = NUM2DBL(value);
|
863
|
+
store = (float)full;
|
864
|
+
memcpy(field->sqldata, &store, field->sqllen);
|
865
|
+
field->sqltype = SQL_FLOAT;
|
948
866
|
}
|
949
867
|
|
950
868
|
|
@@ -956,38 +874,29 @@ void populateFloatField(VALUE value, XSQLVAR *field)
|
|
956
874
|
* @param field A pointer to the XSQLVAR field that the value will go into.
|
957
875
|
*
|
958
876
|
*/
|
959
|
-
void populateInt64Field(VALUE value, XSQLVAR *field)
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
else if(TYPE(value) == T_STRING)
|
979
|
-
{
|
980
|
-
actual = rb_funcall(value, rb_intern("to_i"), 0);
|
981
|
-
}
|
982
|
-
else
|
983
|
-
{
|
984
|
-
rb_fireruby_raise(NULL,
|
985
|
-
"Error converting input parameter to 64 bit integer.");
|
986
|
-
}
|
877
|
+
void populateInt64Field(VALUE value, XSQLVAR *field) {
|
878
|
+
VALUE actual = Qnil;
|
879
|
+
long long store = 0;
|
880
|
+
|
881
|
+
if(rb_obj_is_kind_of(value, rb_cInteger)) {
|
882
|
+
actual = value;
|
883
|
+
} else if(TYPE(value) == T_FLOAT) {
|
884
|
+
double number = NUM2DBL(value);
|
885
|
+
|
886
|
+
if(field->sqlscale != 0) {
|
887
|
+
number = number * pow(10, abs(field->sqlscale));
|
888
|
+
actual = INT2NUM((long)number);
|
889
|
+
}
|
890
|
+
} else if(TYPE(value) == T_STRING) {
|
891
|
+
actual = rb_funcall(value, rb_intern("to_i"), 0);
|
892
|
+
} else {
|
893
|
+
rb_fireruby_raise(NULL,
|
894
|
+
"Error converting input parameter to 64 bit integer.");
|
895
|
+
}
|
987
896
|
|
988
|
-
|
989
|
-
|
990
|
-
|
897
|
+
store = TYPE(actual) == T_FIXNUM ? FIX2INT(actual) : NUM2INT(actual);
|
898
|
+
memcpy(field->sqldata, &store, field->sqllen);
|
899
|
+
field->sqltype = SQL_INT64;
|
991
900
|
}
|
992
901
|
|
993
902
|
|
@@ -999,40 +908,31 @@ void populateInt64Field(VALUE value, XSQLVAR *field)
|
|
999
908
|
* @param field A pointer to the XSQLVAR field that the value will go into.
|
1000
909
|
*
|
1001
910
|
*/
|
1002
|
-
void populateLongField(VALUE value, XSQLVAR *field)
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
else if(TYPE(value) == T_STRING)
|
1023
|
-
{
|
1024
|
-
actual = rb_funcall(value, rb_intern("to_i"), 0);
|
1025
|
-
}
|
1026
|
-
else
|
1027
|
-
{
|
1028
|
-
rb_fireruby_raise(NULL,
|
1029
|
-
"Error converting input parameter to long integer.");
|
1030
|
-
}
|
911
|
+
void populateLongField(VALUE value, XSQLVAR *field) {
|
912
|
+
VALUE actual = Qnil;
|
913
|
+
long long full = 0;
|
914
|
+
long store = 0;
|
915
|
+
|
916
|
+
if(rb_obj_is_kind_of(value, rb_cInteger)) {
|
917
|
+
actual = value;
|
918
|
+
} else if(TYPE(value) == T_FLOAT) {
|
919
|
+
double number = NUM2DBL(value);
|
920
|
+
|
921
|
+
if(field->sqlscale != 0) {
|
922
|
+
number = number * pow(10, abs(field->sqlscale));
|
923
|
+
actual = INT2NUM((long)number);
|
924
|
+
}
|
925
|
+
} else if(TYPE(value) == T_STRING) {
|
926
|
+
actual = rb_funcall(value, rb_intern("to_i"), 0);
|
927
|
+
} else {
|
928
|
+
rb_fireruby_raise(NULL,
|
929
|
+
"Error converting input parameter to long integer.");
|
930
|
+
}
|
1031
931
|
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
932
|
+
full = TYPE(actual) == T_FIXNUM ? FIX2INT(actual) : NUM2INT(actual);
|
933
|
+
store = (long)full;
|
934
|
+
memcpy(field->sqldata, &store, field->sqllen);
|
935
|
+
field->sqltype = SQL_LONG;
|
1036
936
|
}
|
1037
937
|
|
1038
938
|
|
@@ -1044,40 +944,31 @@ void populateLongField(VALUE value, XSQLVAR *field)
|
|
1044
944
|
* @param field A pointer to the XSQLVAR field that the value will go into.
|
1045
945
|
*
|
1046
946
|
*/
|
1047
|
-
void populateShortField(VALUE value, XSQLVAR *field)
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
else if(TYPE(value) == T_STRING)
|
1068
|
-
{
|
1069
|
-
actual = rb_funcall(value, rb_intern("to_i"), 0);
|
1070
|
-
}
|
1071
|
-
else
|
1072
|
-
{
|
1073
|
-
rb_fireruby_raise(NULL,
|
1074
|
-
"Error converting input parameter to short integer.");
|
1075
|
-
}
|
947
|
+
void populateShortField(VALUE value, XSQLVAR *field) {
|
948
|
+
VALUE actual = Qnil;
|
949
|
+
long long full = 0;
|
950
|
+
short store = 0;
|
951
|
+
|
952
|
+
if(rb_obj_is_kind_of(value, rb_cInteger)) {
|
953
|
+
actual = value;
|
954
|
+
} else if(TYPE(value) == T_FLOAT) {
|
955
|
+
double number = NUM2DBL(value);
|
956
|
+
|
957
|
+
if(field->sqlscale != 0) {
|
958
|
+
number = number * pow(10, abs(field->sqlscale));
|
959
|
+
actual = INT2NUM((long)number);
|
960
|
+
}
|
961
|
+
} else if(TYPE(value) == T_STRING) {
|
962
|
+
actual = rb_funcall(value, rb_intern("to_i"), 0);
|
963
|
+
} else {
|
964
|
+
rb_fireruby_raise(NULL,
|
965
|
+
"Error converting input parameter to short integer.");
|
966
|
+
}
|
1076
967
|
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
968
|
+
full = TYPE(actual) == T_FIXNUM ? FIX2INT(actual) : NUM2INT(actual);
|
969
|
+
store = (short)full;
|
970
|
+
memcpy(field->sqldata, &store, field->sqllen);
|
971
|
+
field->sqltype = SQL_SHORT;
|
1081
972
|
}
|
1082
973
|
|
1083
974
|
|
@@ -1089,36 +980,29 @@ void populateShortField(VALUE value, XSQLVAR *field)
|
|
1089
980
|
* @param field A pointer to the XSQLVAR field that the value will go into.
|
1090
981
|
*
|
1091
982
|
*/
|
1092
|
-
void populateTextField(VALUE value, XSQLVAR *field)
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
else
|
1116
|
-
{
|
1117
|
-
memcpy(field->sqldata, &length, sizeof(short));
|
1118
|
-
memcpy(&field->sqldata[sizeof(short)], text, length);
|
1119
|
-
field->sqltype = SQL_VARYING;
|
1120
|
-
}
|
1121
|
-
field->sqllen = length;
|
983
|
+
void populateTextField(VALUE value, XSQLVAR *field) {
|
984
|
+
VALUE actual;
|
985
|
+
char *text = NULL;
|
986
|
+
short length = 0;
|
987
|
+
|
988
|
+
if(TYPE(value) != T_STRING) {
|
989
|
+
actual = value;
|
990
|
+
} else {
|
991
|
+
actual = rb_funcall(value, rb_intern("to_s"), 0);
|
992
|
+
}
|
993
|
+
|
994
|
+
text = StringValuePtr(actual);
|
995
|
+
length = strlen(text) > field->sqllen ? field->sqllen : strlen(text);
|
996
|
+
|
997
|
+
if((field->sqltype & ~1) == SQL_TEXT) {
|
998
|
+
memcpy(field->sqldata, text, length);
|
999
|
+
field->sqltype = SQL_TEXT;
|
1000
|
+
} else {
|
1001
|
+
memcpy(field->sqldata, &length, sizeof(short));
|
1002
|
+
memcpy(&field->sqldata[sizeof(short)], text, length);
|
1003
|
+
field->sqltype = SQL_VARYING;
|
1004
|
+
}
|
1005
|
+
field->sqllen = length;
|
1122
1006
|
}
|
1123
1007
|
|
1124
1008
|
|
@@ -1129,23 +1013,21 @@ void populateTextField(VALUE value, XSQLVAR *field)
|
|
1129
1013
|
* @param field A pointer to the output field to be populated.
|
1130
1014
|
*
|
1131
1015
|
*/
|
1132
|
-
void populateTimeField(VALUE value, XSQLVAR *field)
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
isc_encode_sql_time(&datetime, (ISC_TIME *)field->sqldata);
|
1148
|
-
field->sqltype = SQL_TYPE_TIME;
|
1016
|
+
void populateTimeField(VALUE value, XSQLVAR *field) {
|
1017
|
+
struct tm datetime;
|
1018
|
+
VALUE arguments = rb_ary_new();
|
1019
|
+
|
1020
|
+
rb_ary_push(arguments, rb_str_new2("time"));
|
1021
|
+
value = rb_rescue(toDateTime, value, rescueConvert, arguments);
|
1022
|
+
if(TYPE(value) != T_ARRAY) {
|
1023
|
+
VALUE message = rb_funcall(value, rb_intern("message"), 0);
|
1024
|
+
rb_fireruby_raise(NULL, StringValuePtr(message));
|
1025
|
+
}
|
1026
|
+
datetime.tm_hour = FIX2INT(rb_ary_entry(value, 3));
|
1027
|
+
datetime.tm_min = FIX2INT(rb_ary_entry(value, 4));
|
1028
|
+
datetime.tm_sec = FIX2INT(rb_ary_entry(value, 5));
|
1029
|
+
isc_encode_sql_time(&datetime, (ISC_TIME *)field->sqldata);
|
1030
|
+
field->sqltype = SQL_TYPE_TIME;
|
1149
1031
|
}
|
1150
1032
|
|
1151
1033
|
|
@@ -1156,24 +1038,22 @@ void populateTimeField(VALUE value, XSQLVAR *field)
|
|
1156
1038
|
* @param field A pointer to the output field to be populated.
|
1157
1039
|
*
|
1158
1040
|
*/
|
1159
|
-
void populateTimestampField(VALUE value, XSQLVAR *field)
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
isc_encode_timestamp(&datetime, (ISC_TIMESTAMP *)field->sqldata);
|
1178
|
-
field->sqltype = SQL_TIMESTAMP;
|
1041
|
+
void populateTimestampField(VALUE value, XSQLVAR *field) {
|
1042
|
+
struct tm datetime;
|
1043
|
+
VALUE arguments = rb_ary_new();
|
1044
|
+
|
1045
|
+
rb_ary_push(arguments, rb_str_new2("timestamp"));
|
1046
|
+
value = rb_rescue(toDateTime, value, rescueConvert, arguments);
|
1047
|
+
if(TYPE(value) != T_ARRAY) {
|
1048
|
+
VALUE message = rb_funcall(value, rb_intern("message"), 0);
|
1049
|
+
rb_fireruby_raise(NULL, StringValuePtr(message));
|
1050
|
+
}
|
1051
|
+
datetime.tm_year = FIX2INT(rb_ary_entry(value, 0));
|
1052
|
+
datetime.tm_mon = FIX2INT(rb_ary_entry(value, 1));
|
1053
|
+
datetime.tm_mday = FIX2INT(rb_ary_entry(value, 2));
|
1054
|
+
datetime.tm_hour = FIX2INT(rb_ary_entry(value, 3));
|
1055
|
+
datetime.tm_min = FIX2INT(rb_ary_entry(value, 4));
|
1056
|
+
datetime.tm_sec = FIX2INT(rb_ary_entry(value, 5));
|
1057
|
+
isc_encode_timestamp(&datetime, (ISC_TIMESTAMP *)field->sqldata);
|
1058
|
+
field->sqltype = SQL_TIMESTAMP;
|
1179
1059
|
}
|