rubyfb 0.5.9 → 0.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 +36 -0
- data/Manifest +1 -0
- data/README +75 -175
- data/Rakefile +1 -1
- data/ext/Blob.c +1 -1
- data/ext/Connection.c +40 -126
- data/ext/FireRubyException.c +27 -41
- data/ext/Generator.c +61 -339
- data/ext/Generator.h +0 -5
- data/ext/ResultSet.c +201 -381
- data/ext/ResultSet.h +8 -9
- data/ext/Statement.c +495 -426
- data/ext/Statement.h +8 -11
- data/ext/Transaction.c +3 -2
- data/ext/TypeMap.c +44 -43
- data/ext/TypeMap.h +1 -1
- data/lib/active_record/connection_adapters/rubyfb_adapter.rb +370 -120
- data/lib/arel/visitors/rubyfb.rb +7 -3
- data/lib/arel/visitors/rubyfb_15compat.rb +8 -4
- data/lib/rubyfb_lib.so +0 -0
- data/lib/src.rb +76 -39
- data/rubyfb.gemspec +3 -3
- data/test/AddRemoveUserTest.rb +7 -0
- data/test/BackupRestoreTest.rb +1 -1
- data/test/BlobTest.rb +5 -5
- data/test/GeneratorTest.rb +8 -8
- data/test/KeyTest.rb +1 -2
- data/test/ResultSetTest.rb +14 -16
- data/test/RoleTest.rb +2 -2
- data/test/RowCountTest.rb +19 -19
- data/test/RowTest.rb +7 -8
- data/test/SQLTest.rb +7 -8
- data/test/StatementTest.rb +18 -24
- data/test/StoredProcedureTest.rb +80 -0
- data/test/TransactionTest.rb +1 -1
- data/test/TypeTest.rb +4 -5
- metadata +5 -5
data/ext/Statement.h
CHANGED
@@ -40,23 +40,20 @@
|
|
40
40
|
typedef struct {
|
41
41
|
isc_stmt_handle handle;
|
42
42
|
int type,
|
43
|
-
inputs
|
43
|
+
inputs,
|
44
|
+
outputs;
|
44
45
|
short dialect;
|
45
|
-
XSQLDA *
|
46
|
+
XSQLDA *output;
|
46
47
|
} StatementHandle;
|
47
48
|
|
48
49
|
/* Function prototypes. */
|
49
|
-
void prepare(isc_db_handle *, isc_tr_handle *, char *, isc_stmt_handle *,
|
50
|
+
/*void prepare(isc_db_handle *, isc_tr_handle *, char *, isc_stmt_handle *,
|
50
51
|
short, int *, int *, int *);
|
51
52
|
void execute(isc_tr_handle *, isc_stmt_handle *, short, XSQLDA *,
|
52
|
-
int, long *)
|
53
|
-
VALUE rb_statement_new(VALUE, VALUE
|
54
|
-
VALUE
|
55
|
-
VALUE rb_execute_statement_for(VALUE, VALUE);
|
56
|
-
VALUE rb_execute_sql(VALUE, VALUE, VALUE);
|
57
|
-
VALUE rb_get_statement_type(VALUE);
|
58
|
-
void rb_statement_close(VALUE);
|
59
|
-
void statementFree(void *);
|
53
|
+
int, long *);*/
|
54
|
+
VALUE rb_statement_new(VALUE, VALUE);
|
55
|
+
VALUE rb_execute_sql(VALUE, VALUE, VALUE, VALUE);
|
60
56
|
void Init_Statement(VALUE);
|
57
|
+
short isCursorStatement(StatementHandle*);
|
61
58
|
|
62
59
|
#endif /* FIRERUBY_STATEMENT_H */
|
data/ext/Transaction.c
CHANGED
@@ -133,7 +133,7 @@ static VALUE commitTransaction(VALUE self) {
|
|
133
133
|
TransactionHandle *transaction = NULL;
|
134
134
|
|
135
135
|
Data_Get_Struct(self, TransactionHandle, transaction);
|
136
|
-
|
136
|
+
|
137
137
|
/* Commit the transaction. */
|
138
138
|
if(transaction->handle != 0) {
|
139
139
|
ISC_STATUS status[ISC_STATUS_LENGTH];
|
@@ -306,7 +306,7 @@ static VALUE executeOnTransaction(VALUE self, VALUE sql) {
|
|
306
306
|
}
|
307
307
|
|
308
308
|
connection = rb_ary_entry(list, 0);
|
309
|
-
return rb_execute_sql(connection,
|
309
|
+
return rb_execute_sql(connection, sql, rb_ary_new(), self);
|
310
310
|
}
|
311
311
|
|
312
312
|
|
@@ -480,6 +480,7 @@ void startTransaction(TransactionHandle *transaction,
|
|
480
480
|
if(teb != NULL) {
|
481
481
|
free(teb);
|
482
482
|
}
|
483
|
+
|
483
484
|
}
|
484
485
|
|
485
486
|
|
data/ext/TypeMap.c
CHANGED
@@ -46,7 +46,7 @@ VALUE getConstant(const char *, VALUE);
|
|
46
46
|
VALUE toDateTime(VALUE);
|
47
47
|
VALUE rescueConvert(VALUE, VALUE);
|
48
48
|
void storeBlob(VALUE, XSQLVAR *, ConnectionHandle *, TransactionHandle *);
|
49
|
-
void populateBlobField(VALUE, XSQLVAR *, VALUE);
|
49
|
+
void populateBlobField(VALUE, XSQLVAR *, VALUE, VALUE);
|
50
50
|
void populateDoubleField(VALUE, XSQLVAR *);
|
51
51
|
void populateFloatField(VALUE, XSQLVAR *);
|
52
52
|
void populateInt64Field(VALUE, XSQLVAR *);
|
@@ -215,15 +215,15 @@ VALUE toValue(XSQLVAR *entry,
|
|
215
215
|
*/
|
216
216
|
VALUE toArray(VALUE results) {
|
217
217
|
VALUE array = rb_ary_new(),
|
218
|
-
transaction =
|
219
|
-
connection =
|
218
|
+
transaction = rb_funcall(results, rb_intern("transaction"), 0),
|
219
|
+
connection = rb_funcall(results, rb_intern("connection"), 0);
|
220
220
|
XSQLVAR *entry = NULL;
|
221
|
-
|
221
|
+
StatementHandle *hStatement = NULL;
|
222
222
|
int i;
|
223
223
|
|
224
|
-
Data_Get_Struct(results,
|
225
|
-
entry =
|
226
|
-
for(i = 0; i <
|
224
|
+
Data_Get_Struct(rb_funcall(results, rb_intern("statement"), 0), StatementHandle, hStatement);
|
225
|
+
entry = hStatement->output->sqlvar;
|
226
|
+
for(i = 0; i < hStatement->output->sqln; i++, entry++) {
|
227
227
|
VALUE value = toValue(entry, connection, transaction);
|
228
228
|
|
229
229
|
rb_ary_push(array, value);
|
@@ -247,7 +247,7 @@ VALUE toArray(VALUE results) {
|
|
247
247
|
* to get connection and transaction details.
|
248
248
|
*
|
249
249
|
*/
|
250
|
-
void setParameters(XSQLDA *parameters, VALUE array, VALUE
|
250
|
+
void setParameters(XSQLDA *parameters, VALUE array, VALUE transaction, VALUE connection) {
|
251
251
|
VALUE value;
|
252
252
|
int index,
|
253
253
|
size;
|
@@ -274,7 +274,7 @@ void setParameters(XSQLDA *parameters, VALUE array, VALUE source) {
|
|
274
274
|
if(value != Qnil) {
|
275
275
|
VALUE name = rb_funcall(value, rb_intern("class"), 0);
|
276
276
|
|
277
|
-
parameter->sqlind = 0;
|
277
|
+
*parameter->sqlind = 0;
|
278
278
|
name = rb_funcall(name, rb_intern("name"), 0);
|
279
279
|
switch(type) {
|
280
280
|
case SQL_ARRAY: /* Type: ARRAY */
|
@@ -282,7 +282,7 @@ void setParameters(XSQLDA *parameters, VALUE array, VALUE source) {
|
|
282
282
|
break;
|
283
283
|
|
284
284
|
case SQL_BLOB: /* Type: BLOB */
|
285
|
-
populateBlobField(value, parameter,
|
285
|
+
populateBlobField(value, parameter, transaction, connection);
|
286
286
|
break;
|
287
287
|
|
288
288
|
case SQL_DOUBLE: /* Type: DOUBLE PRECISION, DECIMAL, NUMERIC */
|
@@ -619,11 +619,15 @@ VALUE getClassInModule(const char *name, VALUE owner) {
|
|
619
619
|
*/
|
620
620
|
VALUE toDateTime(VALUE value) {
|
621
621
|
VALUE result,
|
622
|
-
klass = rb_funcall(value, rb_intern("class"), 0)
|
622
|
+
klass = rb_funcall(value, rb_intern("class"), 0),
|
623
|
+
date_time_class = getClass("DateTime");
|
623
624
|
|
624
|
-
if(klass == rb_cTime) {
|
625
|
+
if((klass == rb_cTime) || (klass == date_time_class)) {
|
625
626
|
VALUE data;
|
626
627
|
|
628
|
+
if (klass == date_time_class) {
|
629
|
+
value = rb_funcall(value, rb_intern("to_time"), 0);
|
630
|
+
}
|
627
631
|
result = rb_ary_new();
|
628
632
|
|
629
633
|
data = rb_funcall(value, rb_intern("year"), 0);
|
@@ -684,6 +688,10 @@ VALUE rescueConvert(VALUE arguments, VALUE error) {
|
|
684
688
|
return(rb_funcall(rb_eException, rb_intern("exception"), 1, &message));
|
685
689
|
}
|
686
690
|
|
691
|
+
long getLongProperty(VALUE obj, const char* name) {
|
692
|
+
VALUE number = rb_funcall(obj, rb_intern(name), 0);
|
693
|
+
return TYPE(number) == T_FIXNUM ? FIX2INT(number) : NUM2INT(number);
|
694
|
+
}
|
687
695
|
|
688
696
|
/**
|
689
697
|
* This function creates a new blob and returns the identifier for it.
|
@@ -707,10 +715,13 @@ void storeBlob(VALUE info,
|
|
707
715
|
isc_blob_handle handle = 0;
|
708
716
|
ISC_QUAD *blobId = (ISC_QUAD *)field->sqldata;
|
709
717
|
char *data = StringValuePtr(info);
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
718
|
+
long dataLength = getLongProperty(info, "length");
|
719
|
+
|
720
|
+
if(Qtrue == rb_funcall(info, rb_intern("respond_to?"), 1, ID2SYM(rb_intern("bytesize")))) {
|
721
|
+
/* 1.9 strings */
|
722
|
+
dataLength = getLongProperty(info, "bytesize");
|
723
|
+
}
|
724
|
+
|
714
725
|
field->sqltype = SQL_BLOB;
|
715
726
|
|
716
727
|
if(isc_create_blob(status, &connection->handle, &transaction->handle,
|
@@ -718,11 +729,10 @@ void storeBlob(VALUE info,
|
|
718
729
|
long offset = 0;
|
719
730
|
unsigned short size = 0;
|
720
731
|
|
721
|
-
while(offset <
|
732
|
+
while(offset < dataLength) {
|
722
733
|
char *buffer = &data[offset];
|
723
734
|
|
724
|
-
size = (
|
725
|
-
size = (size/charSize)*charSize; // align
|
735
|
+
size = (dataLength - offset) > USHRT_MAX ? USHRT_MAX : dataLength - offset;
|
726
736
|
if(isc_put_segment(status, &handle, size, buffer) != 0) {
|
727
737
|
ISC_STATUS other[20];
|
728
738
|
|
@@ -751,21 +761,18 @@ void storeBlob(VALUE info,
|
|
751
761
|
* contains the connection and transaction details.
|
752
762
|
*
|
753
763
|
*/
|
754
|
-
void populateBlobField(VALUE value, XSQLVAR *field, VALUE
|
755
|
-
|
756
|
-
|
757
|
-
TransactionHandle *transaction = NULL;
|
764
|
+
void populateBlobField(VALUE value, XSQLVAR *field, VALUE transaction, VALUE connection) {
|
765
|
+
ConnectionHandle *hConnection = NULL;
|
766
|
+
TransactionHandle *hTransaction = NULL;
|
758
767
|
|
759
768
|
if(TYPE(value) != T_STRING) {
|
760
769
|
rb_fireruby_raise(NULL, "Error converting input parameter to blob.");
|
761
770
|
}
|
762
771
|
|
763
772
|
/* Fetch the connection and transaction details. */
|
764
|
-
|
765
|
-
Data_Get_Struct(
|
766
|
-
|
767
|
-
Data_Get_Struct(attribute, TransactionHandle, transaction);
|
768
|
-
storeBlob(value, field, connection, transaction);
|
773
|
+
Data_Get_Struct(connection, ConnectionHandle, hConnection);
|
774
|
+
Data_Get_Struct(transaction, TransactionHandle, hTransaction);
|
775
|
+
storeBlob(value, field, hConnection, hTransaction);
|
769
776
|
field->sqltype = SQL_BLOB;
|
770
777
|
}
|
771
778
|
|
@@ -858,26 +865,20 @@ void populateFloatField(VALUE value, XSQLVAR *field) {
|
|
858
865
|
*
|
859
866
|
*/
|
860
867
|
void populateInt64Field(VALUE value, XSQLVAR *field) {
|
861
|
-
VALUE actual =
|
868
|
+
VALUE actual = value;
|
862
869
|
long long store = 0;
|
863
870
|
|
864
|
-
if(
|
865
|
-
actual = value;
|
866
|
-
} else if(TYPE(value) == T_FLOAT) {
|
867
|
-
double number = NUM2DBL(value);
|
868
|
-
|
871
|
+
if(TYPE(value) == T_STRING) {
|
869
872
|
if(field->sqlscale != 0) {
|
870
|
-
|
871
|
-
|
873
|
+
actual = rb_funcall(value, rb_intern("to_f"), 0);
|
874
|
+
} else {
|
875
|
+
actual = rb_funcall(value, rb_intern("to_i"), 0);
|
872
876
|
}
|
873
|
-
} else if(TYPE(value) == T_STRING) {
|
874
|
-
actual = rb_funcall(value, rb_intern("to_i"), 0);
|
875
|
-
} else {
|
876
|
-
rb_fireruby_raise(NULL,
|
877
|
-
"Error converting input parameter to 64 bit integer.");
|
878
877
|
}
|
879
|
-
|
880
|
-
|
878
|
+
if(field->sqlscale != 0) {
|
879
|
+
actual = rb_funcall(actual, rb_intern("*"), 1, INT2NUM((long)pow(10, abs(field->sqlscale))));
|
880
|
+
}
|
881
|
+
store = NUM2LL(actual);
|
881
882
|
memcpy(field->sqldata, &store, field->sqllen);
|
882
883
|
field->sqltype = SQL_INT64;
|
883
884
|
}
|
data/ext/TypeMap.h
CHANGED
@@ -41,7 +41,7 @@
|
|
41
41
|
|
42
42
|
/* Function prototypes. */
|
43
43
|
VALUE toArray(VALUE);
|
44
|
-
void setParameters(XSQLDA *, VALUE, VALUE);
|
44
|
+
void setParameters(XSQLDA *, VALUE, VALUE, VALUE);
|
45
45
|
VALUE getModule(const char *);
|
46
46
|
VALUE getClass(const char *);
|
47
47
|
VALUE getClassInModule(const char *, VALUE);
|