fb 0.5.5 → 0.5.9

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/README CHANGED
@@ -216,3 +216,17 @@ Change Log
216
216
  2007-12-11
217
217
 
218
218
  * Properly scaled NUMERIC and DECIMAL types when inserting with parameters.
219
+
220
+ 2007-12-13
221
+
222
+ * Rounded instead of flooring NUMERIC and DECIMAL types.
223
+ * Replace deprecated isc_interprete method call for FB2.
224
+
225
+ 2008-04-22
226
+
227
+ * Implement explicit end-of-data flag for cursors to avoid synchronization error in newer Firebird builds.
228
+ * Allocated longer buffers to avoid memory access error reported by valgrind
229
+ * Tightened up C syntax for stricter compilers.
230
+ * Factored symbol and regex creation out to global scope for efficiency.
231
+ * Removed global transaction functions that weren't exposed anyway.
232
+ * Removed remaining global state. This should allow for better concurrency.
data/fb.c CHANGED
@@ -21,6 +21,7 @@
21
21
  */
22
22
 
23
23
  #include "ruby.h"
24
+ #include "re.h"
24
25
  #include <stdio.h>
25
26
  #include <string.h>
26
27
  #include <limits.h>
@@ -48,15 +49,20 @@ static VALUE rb_cFbDatabase;
48
49
  static VALUE rb_cFbConnection;
49
50
  static VALUE rb_cFbCursor;
50
51
  static VALUE rb_cFbSqlType;
51
- static VALUE rb_cFbGlobal;
52
+ /* static VALUE rb_cFbGlobal; */
52
53
  static VALUE rb_eFbError;
53
54
  static VALUE rb_sFbField;
54
55
  static VALUE rb_sFbIndex;
55
56
 
56
57
  static VALUE rb_cDate;
57
58
 
58
- static char isc_info_stmt[] = { isc_info_sql_stmt_type };
59
- static char isc_info_buff[16];
59
+ static ID id_matches;
60
+ static ID id_downcase_bang;
61
+ static VALUE re_lowercase;
62
+ static ID id_rstrip_bang;
63
+
64
+ /* static char isc_info_stmt[] = { isc_info_sql_stmt_type }; */
65
+ /* static char isc_info_buff[16]; */
60
66
  static char isc_tpb_0[] = {
61
67
  isc_tpb_version1, isc_tpb_write,
62
68
  isc_tpb_concurrency, isc_tpb_nowait
@@ -87,13 +93,15 @@ struct FbConnection {
87
93
  unsigned short db_dialect;
88
94
  short downcase_names;
89
95
  int dropped;
90
- struct FbConnection *next;
96
+ ISC_STATUS isc_status[20];
97
+ /* struct FbConnection *next; */
91
98
  };
92
99
 
93
- static struct FbConnection *fb_connection_list;
100
+ /* static struct FbConnection *fb_connection_list; */
94
101
 
95
102
  struct FbCursor {
96
103
  int open;
104
+ int eof;
97
105
  isc_tr_handle auto_transact;
98
106
  isc_stmt_handle stmt;
99
107
  XSQLDA *i_sqlda;
@@ -117,28 +125,33 @@ typedef struct trans_opts
117
125
  } trans_opts;
118
126
 
119
127
  /* global data */
120
- static isc_tr_handle global_transact = 0; /* transaction handle */
121
- static int connection_count = 0;
128
+ /* static isc_tr_handle global_transact = 0; */ /* transaction handle */
129
+ /* static int connection_count = 0; */
122
130
 
123
131
  /* global utilities */
124
132
 
125
133
  #define ALIGN(n, b) ((n + b - 1) & ~(b - 1))
134
+ #define FB_ALIGN(n, b) ((n + b - 1) & ~(b - 1))
135
+ /* #define FB_ALIGN(n,b) ((n+1) & ~1) */
126
136
  #define UPPER(c) (((c) >= 'a' && (c)<= 'z') ? (c) - 'a' + 'A' : (c))
127
137
  #define FREE(p) if (p) { xfree(p); p = 0; }
128
138
  #define SETNULL(p) if (p && strlen(p) == 0) { p = 0; }
139
+ /* #define HERE(s) printf("%s\n", s) */
140
+ #define HERE(s)
129
141
 
130
142
  static long calculate_buffsize(XSQLDA *sqlda)
131
143
  {
132
144
  XSQLVAR *var;
133
145
  long cols;
134
146
  short dtp;
135
- long offset;
147
+ long offset = 0;
136
148
  long alignment;
137
149
  long length;
138
150
  long count;
139
151
 
140
152
  cols = sqlda->sqld;
141
- for (var = sqlda->sqlvar, offset = 0,count = 0; count < cols; var++,count++) {
153
+ var = sqlda->sqlvar;
154
+ for (count = 0; count < cols; var++,count++) {
142
155
  length = alignment = var->sqllen;
143
156
  dtp = var->sqltype & ~1;
144
157
 
@@ -149,21 +162,21 @@ static long calculate_buffsize(XSQLDA *sqlda)
149
162
  alignment = sizeof(short);
150
163
  }
151
164
 
152
- offset = ALIGN(offset, alignment);
165
+ offset = FB_ALIGN(offset, alignment);
153
166
  offset += length;
154
- offset = ALIGN(offset, sizeof(short));
167
+ offset = FB_ALIGN(offset, sizeof(short));
155
168
  offset += sizeof(short);
156
169
  }
157
170
 
158
- return offset;
171
+ return offset + sizeof(short);
159
172
  }
160
173
 
161
174
  #if (FB_API_VER >= 20)
162
175
  static VALUE fb_error_msg(const ISC_STATUS *isc_status)
163
176
  {
164
- char msg[512];
177
+ char msg[1024];
165
178
  VALUE result = rb_str_new(NULL, 0);
166
- while (fb_interpret(msg, 512, &isc_status))
179
+ while (fb_interpret(msg, 1024, &isc_status))
167
180
  {
168
181
  result = rb_str_cat(result, msg, strlen(msg));
169
182
  result = rb_str_cat(result, "\n", strlen("\n"));
@@ -173,7 +186,7 @@ static VALUE fb_error_msg(const ISC_STATUS *isc_status)
173
186
  #else
174
187
  static VALUE fb_error_msg(ISC_STATUS *isc_status)
175
188
  {
176
- char msg[512];
189
+ char msg[1024];
177
190
  VALUE result = rb_str_new(NULL, 0);
178
191
  while (isc_interprete(msg, &isc_status))
179
192
  {
@@ -360,11 +373,11 @@ static VALUE fb_sql_type_from_code(int code, int subtype)
360
373
 
361
374
  static void fb_error_check(long *isc_status)
362
375
  {
363
- short code = isc_sqlcode(isc_status);
364
-
365
- if (code != 0) {
376
+ HERE("fb_error_check");
377
+ if (isc_status[0] == 1 && isc_status[1]) {
366
378
  char buf[1024];
367
379
  VALUE exc, msg, msg1, msg2;
380
+ short code = isc_sqlcode(isc_status);
368
381
 
369
382
  isc_sql_interprete(code, buf, 1024);
370
383
  msg1 = rb_str_new2(buf);
@@ -374,8 +387,10 @@ static void fb_error_check(long *isc_status)
374
387
 
375
388
  exc = rb_exc_new3(rb_eFbError, msg);
376
389
  rb_iv_set(exc, "error_code", INT2FIX(code));
390
+ HERE("fb_error_check 1");
377
391
  rb_exc_raise(exc);
378
392
  }
393
+ HERE("fb_error_check 2");
379
394
  }
380
395
 
381
396
  static void fb_error_check_warn(long *isc_status)
@@ -414,11 +429,13 @@ static void fb_cursor_free();
414
429
  /* connection utilities */
415
430
  static void fb_connection_check(struct FbConnection *fb_connection)
416
431
  {
432
+ HERE("fb_connection_check");
417
433
  if (fb_connection->db == 0) {
418
434
  rb_raise(rb_eFbError, "closed db connection");
419
435
  }
420
436
  }
421
437
 
438
+ /*
422
439
  static void global_close_cursors()
423
440
  {
424
441
  struct FbConnection *list = fb_connection_list;
@@ -431,6 +448,7 @@ static void global_close_cursors()
431
448
  list = list->next;
432
449
  }
433
450
  }
451
+ */
434
452
 
435
453
  static void fb_connection_close_cursors(struct FbConnection *fb_connection)
436
454
  {
@@ -451,6 +469,7 @@ static void fb_connection_drop_cursors(struct FbConnection *fb_connection)
451
469
  RARRAY(fb_connection->cursor)->len = 0;
452
470
  }
453
471
 
472
+ /*
454
473
  static void fb_connection_remove(struct FbConnection *fb_connection)
455
474
  {
456
475
  if (fb_connection_list != NULL) {
@@ -470,35 +489,32 @@ static void fb_connection_remove(struct FbConnection *fb_connection)
470
489
  connection_count--;
471
490
  }
472
491
  }
492
+ */
473
493
 
474
494
  static void fb_connection_disconnect(struct FbConnection *fb_connection)
475
495
  {
476
- long isc_status[20];
477
-
478
496
  if (fb_connection->transact) {
479
- isc_commit_transaction(isc_status, &fb_connection->transact);
480
- fb_error_check(isc_status);
497
+ isc_commit_transaction(fb_connection->isc_status, &fb_connection->transact);
498
+ fb_error_check(fb_connection->isc_status);
481
499
  }
482
500
  if (fb_connection->dropped) {
483
- isc_drop_database(isc_status, &fb_connection->db);
501
+ isc_drop_database(fb_connection->isc_status, &fb_connection->db);
484
502
  } else {
485
- isc_detach_database(isc_status, &fb_connection->db);
503
+ isc_detach_database(fb_connection->isc_status, &fb_connection->db);
486
504
  }
487
- fb_error_check(isc_status);
488
- fb_connection_remove(fb_connection);
505
+ fb_error_check(fb_connection->isc_status);
506
+ /* fb_connection_remove(fb_connection); */
489
507
  }
490
508
 
491
509
  static void fb_connection_disconnect_warn(struct FbConnection *fb_connection)
492
510
  {
493
- long isc_status[20];
494
-
495
511
  if (fb_connection->transact) {
496
- isc_commit_transaction(isc_status, &fb_connection->transact);
497
- fb_error_check_warn(isc_status);
512
+ isc_commit_transaction(fb_connection->isc_status, &fb_connection->transact);
513
+ fb_error_check_warn(fb_connection->isc_status);
498
514
  }
499
- isc_detach_database(isc_status, &fb_connection->db);
500
- fb_error_check_warn(isc_status);
501
- fb_connection_remove(fb_connection);
515
+ isc_detach_database(fb_connection->isc_status, &fb_connection->db);
516
+ fb_error_check_warn(fb_connection->isc_status);
517
+ /* fb_connection_remove(fb_connection); */
502
518
  }
503
519
 
504
520
  static void fb_connection_mark(struct FbConnection *fb_connection)
@@ -514,6 +530,7 @@ static void fb_connection_free(struct FbConnection *fb_connection)
514
530
  xfree(fb_connection);
515
531
  }
516
532
 
533
+ /*
517
534
  static struct FbConnection* fb_connection_check_retrieve(VALUE data)
518
535
  {
519
536
  if (TYPE(data) != T_DATA || RDATA(data)->dfree != (void *)fb_connection_free) {
@@ -523,19 +540,20 @@ static struct FbConnection* fb_connection_check_retrieve(VALUE data)
523
540
  }
524
541
  return (struct FbConnection*)RDATA(data)->data;
525
542
  }
543
+ */
526
544
 
527
545
  static unsigned short fb_connection_db_SQL_Dialect(struct FbConnection *fb_connection)
528
546
  {
529
- long isc_status[20];
530
547
  long dialect;
531
548
  long length;
532
549
  char db_info_command = isc_info_db_SQL_dialect;
550
+ char isc_info_buff[16];
533
551
 
534
552
  /* Get the db SQL Dialect */
535
- isc_database_info(isc_status, &fb_connection->db,
553
+ isc_database_info(fb_connection->isc_status, &fb_connection->db,
536
554
  1, &db_info_command,
537
555
  sizeof(isc_info_buff), isc_info_buff);
538
- fb_error_check(isc_status);
556
+ fb_error_check(fb_connection->isc_status);
539
557
 
540
558
  if (isc_info_buff[0] == isc_info_db_SQL_dialect) {
541
559
  length = isc_vax_integer(&isc_info_buff[1], 2);
@@ -551,56 +569,58 @@ static unsigned short fb_connection_dialect(struct FbConnection *fb_connection)
551
569
  return fb_connection->dialect;
552
570
  }
553
571
 
572
+ /*
554
573
  static unsigned short fb_connection_db_dialect(struct FbConnection *fb_connection)
555
574
  {
556
575
  return fb_connection->db_dialect;
557
576
  }
577
+ */
558
578
 
559
579
  /* Transaction option list */
560
580
 
561
581
  static trans_opts rcom_opt_S[] =
562
582
  {
563
- "NO", "RECORD_VERSION", isc_tpb_no_rec_version, -1, 0,
564
- "RECORD_VERSION", 0, isc_tpb_rec_version, -1, 0,
565
- "*", 0, isc_tpb_no_rec_version, -1, 0,
566
- 0, 0, 0, 0, 0
583
+ {"NO", "RECORD_VERSION", isc_tpb_no_rec_version, -1, 0},
584
+ {"RECORD_VERSION", 0, isc_tpb_rec_version, -1, 0},
585
+ {"*", 0, isc_tpb_no_rec_version, -1, 0},
586
+ {0, 0, 0, 0, 0}
567
587
  };
568
588
 
569
589
 
570
590
  static trans_opts read_opt_S[] =
571
591
  {
572
- "WRITE", 0, isc_tpb_write, 1, 0,
573
- "ONLY", 0, isc_tpb_read, 1, 0,
574
- "COMMITTED", 0, isc_tpb_read_committed, 2, rcom_opt_S,
575
- 0, 0, 0, 0, 0
592
+ {"WRITE", 0, isc_tpb_write, 1, 0},
593
+ {"ONLY", 0, isc_tpb_read, 1, 0},
594
+ {"COMMITTED", 0, isc_tpb_read_committed, 2, rcom_opt_S},
595
+ {0, 0, 0, 0, 0}
576
596
  };
577
597
 
578
598
 
579
599
  static trans_opts snap_opt_S[] =
580
600
  {
581
- "TABLE", "STABILITY", isc_tpb_consistency, 2, 0,
582
- "*", 0, isc_tpb_concurrency, 2, 0,
583
- 0, 0, 0, 0, 0
601
+ {"TABLE", "STABILITY", isc_tpb_consistency, 2, 0},
602
+ {"*", 0, isc_tpb_concurrency, 2, 0},
603
+ {0, 0, 0, 0, 0}
584
604
  };
585
605
 
586
606
 
587
607
  static trans_opts isol_opt_S[] =
588
608
  {
589
- "SNAPSHOT", 0, 0, 0, snap_opt_S,
590
- "READ", "COMMITTED", isc_tpb_read_committed, 2, rcom_opt_S,
591
- 0, 0, 0, 0, 0
609
+ {"SNAPSHOT", 0, 0, 0, snap_opt_S},
610
+ {"READ", "COMMITTED", isc_tpb_read_committed, 2, rcom_opt_S},
611
+ {0, 0, 0, 0, 0}
592
612
  };
593
613
 
594
614
 
595
615
  static trans_opts trans_opt_S[] =
596
616
  {
597
- "READ", 0, 0, 0, read_opt_S,
598
- "WAIT", 0, isc_tpb_wait, 3, 0,
599
- "NO", "WAIT", isc_tpb_nowait, 3, 0,
600
- "ISOLATION", "LEVEL", 0, 0, isol_opt_S,
601
- "SNAPSHOT", 0, 0, 0, snap_opt_S,
602
- "RESERVING", 0, -1, 0, 0,
603
- 0, 0, 0, 0, 0
617
+ {"READ", 0, 0, 0, read_opt_S},
618
+ {"WAIT", 0, isc_tpb_wait, 3, 0},
619
+ {"NO", "WAIT", isc_tpb_nowait, 3, 0},
620
+ {"ISOLATION", "LEVEL", 0, 0, isol_opt_S},
621
+ {"SNAPSHOT", 0, 0, 0, snap_opt_S},
622
+ {"RESERVING", 0, -1, 0, 0},
623
+ {0, 0, 0, 0, 0}
604
624
  };
605
625
 
606
626
  /* Name1 Name2 Option value Position Sub-option */
@@ -627,7 +647,7 @@ static char* trans_parseopts(VALUE opt, int *tpb_len)
627
647
  char check_f[4];
628
648
  char *resv_p;
629
649
  char *resend_p;
630
- char *tblend_p;
650
+ char *tblend_p = 0;
631
651
  int tbl_len;
632
652
  int res_first;
633
653
  int res_count;
@@ -865,6 +885,7 @@ error:
865
885
  rb_raise(rb_eFbError, desc);
866
886
  }
867
887
 
888
+ /*
868
889
  static void set_teb_vec(ISC_TEB *vec, struct FbConnection *fb_connection, char *tpb, int len)
869
890
  {
870
891
  vec->dbb_ptr = &fb_connection->db;
@@ -876,10 +897,12 @@ static void set_teb_vec(ISC_TEB *vec, struct FbConnection *fb_connection, char *
876
897
  vec->tpb_len = 0;
877
898
  }
878
899
  }
900
+ */
879
901
 
902
+ /*
880
903
  static void global_transaction_start(VALUE opt, int argc, VALUE *argv)
881
904
  {
882
- long isc_status[20];
905
+ ISC_STATUS isc_status[20];
883
906
  struct FbConnection *fb_connection;
884
907
  ISC_TEB *teb_vec = ALLOCA_N(ISC_TEB, connection_count);
885
908
  ISC_TEB *vec = teb_vec;
@@ -916,15 +939,17 @@ static void global_transaction_start(VALUE opt, int argc, VALUE *argv)
916
939
  xfree(tpb);
917
940
  fb_error_check(isc_status);
918
941
  }
942
+ */
919
943
 
920
944
  /* call-seq:
921
945
  * commit() -> nil
922
946
  *
923
947
  * Commit the current (global) transaction.
924
948
  */
949
+ /*
925
950
  static VALUE global_commit()
926
951
  {
927
- long isc_status[20];
952
+ ISC_STATUS isc_status[20];
928
953
 
929
954
  if (global_transact) {
930
955
  global_close_cursors();
@@ -933,15 +958,17 @@ static VALUE global_commit()
933
958
  }
934
959
  return Qnil;
935
960
  }
961
+ */
936
962
 
937
963
  /* call-seq:
938
964
  * rollback() -> nil
939
965
  *
940
966
  * Rollback the current (global) transaction.
941
967
  */
968
+ /*
942
969
  static VALUE global_rollback()
943
970
  {
944
- long isc_status[20];
971
+ ISC_STATUS isc_status[20];
945
972
 
946
973
  if (global_transact) {
947
974
  global_close_cursors();
@@ -950,6 +977,7 @@ static VALUE global_rollback()
950
977
  }
951
978
  return Qnil;
952
979
  }
980
+ */
953
981
 
954
982
  /* call-seq:
955
983
  * transaction(options, *connections) -> true
@@ -957,6 +985,7 @@ static VALUE global_rollback()
957
985
  *
958
986
  * Start a (global) transaction.
959
987
  */
988
+ /*
960
989
  static VALUE global_transaction(int argc, VALUE *argv, VALUE self)
961
990
  {
962
991
  VALUE opt = Qnil;
@@ -981,23 +1010,26 @@ static VALUE global_transaction(int argc, VALUE *argv, VALUE self)
981
1010
  return Qtrue;
982
1011
  }
983
1012
  }
1013
+ */
984
1014
 
985
1015
  /* call-seq:
986
1016
  * transaction_started()? -> true or false
987
1017
  *
988
1018
  * Returns true if a transaction is currently active.
989
1019
  */
1020
+ /*
990
1021
  static VALUE global_transaction_started()
991
1022
  {
992
1023
  return global_transact ? Qtrue : Qfalse;
993
1024
  }
1025
+ */
994
1026
 
995
1027
  static void fb_connection_transaction_start(struct FbConnection *fb_connection, VALUE opt)
996
1028
  {
997
- long isc_status[20];
998
1029
  char *tpb = 0;
999
1030
  int tpb_len;
1000
1031
 
1032
+ HERE("fb_connection_transaction_start");
1001
1033
  if (fb_connection->transact) {
1002
1034
  rb_raise(rb_eFbError, "A transaction has been already started");
1003
1035
  }
@@ -1009,31 +1041,34 @@ static void fb_connection_transaction_start(struct FbConnection *fb_connection,
1009
1041
  tpb = NULL;
1010
1042
  }
1011
1043
 
1012
- isc_start_transaction(isc_status, &fb_connection->transact, 1, &fb_connection->db, tpb_len, tpb);
1044
+ isc_start_transaction(fb_connection->isc_status, &fb_connection->transact, 1, &fb_connection->db, tpb_len, tpb);
1013
1045
  xfree(tpb);
1014
- fb_error_check(isc_status);
1046
+ fb_error_check(fb_connection->isc_status);
1047
+ HERE("fb_connection_transaction_start Z");
1015
1048
  }
1016
1049
 
1017
1050
  static void fb_connection_commit(struct FbConnection *fb_connection)
1018
1051
  {
1019
- long isc_status[20];
1052
+ HERE("fb_connection_commit");
1020
1053
 
1021
1054
  if (fb_connection->transact) {
1022
1055
  fb_connection_close_cursors(fb_connection);
1023
- isc_commit_transaction(isc_status, &fb_connection->transact);
1024
- fb_error_check(isc_status);
1056
+ isc_commit_transaction(fb_connection->isc_status, &fb_connection->transact);
1057
+ fb_error_check(fb_connection->isc_status);
1025
1058
  }
1059
+ HERE("fb_connection_commit Z");
1026
1060
  }
1027
1061
 
1028
1062
  static void fb_connection_rollback(struct FbConnection *fb_connection)
1029
1063
  {
1030
- long isc_status[20];
1064
+ HERE("fb_connection_rollback");
1031
1065
 
1032
1066
  if (fb_connection->transact) {
1033
1067
  fb_connection_close_cursors(fb_connection);
1034
- isc_rollback_transaction(isc_status, &fb_connection->transact);
1035
- fb_error_check(isc_status);
1068
+ isc_rollback_transaction(fb_connection->isc_status, &fb_connection->transact);
1069
+ fb_error_check(fb_connection->isc_status);
1036
1070
  }
1071
+ HERE("fb_connection_rollback Z");
1037
1072
  }
1038
1073
 
1039
1074
  /* call-seq:
@@ -1145,11 +1180,11 @@ static VALUE connection_to_s(VALUE self)
1145
1180
  */
1146
1181
  static VALUE connection_cursor(VALUE self)
1147
1182
  {
1148
- long isc_status[20];
1149
1183
  VALUE c;
1150
1184
  struct FbConnection *fb_connection;
1151
1185
  struct FbCursor *fb_cursor;
1152
1186
 
1187
+ HERE("connection_cursor");
1153
1188
  Data_Get_Struct(self, struct FbConnection, fb_connection);
1154
1189
  fb_connection_check(fb_connection);
1155
1190
 
@@ -1158,6 +1193,7 @@ static VALUE connection_cursor(VALUE self)
1158
1193
  fb_cursor->fields_ary = Qnil;
1159
1194
  fb_cursor->fields_hash = Qnil;
1160
1195
  fb_cursor->open = Qfalse;
1196
+ fb_cursor->eof = Qfalse;
1161
1197
  fb_cursor->stmt = 0;
1162
1198
  fb_cursor->i_sqlda = sqlda_alloc(SQLDA_COLSINIT);
1163
1199
  fb_cursor->o_sqlda = sqlda_alloc(SQLDA_COLSINIT);
@@ -1165,8 +1201,9 @@ static VALUE connection_cursor(VALUE self)
1165
1201
  fb_cursor->i_buffer_size = 0;
1166
1202
  fb_cursor->o_buffer = NULL;
1167
1203
  fb_cursor->o_buffer_size = 0;
1168
- isc_dsql_alloc_statement2(isc_status, &fb_connection->db, &fb_cursor->stmt);
1169
- fb_error_check(isc_status);
1204
+ isc_dsql_alloc_statement2(fb_connection->isc_status, &fb_connection->db, &fb_cursor->stmt);
1205
+ fb_error_check(fb_connection->isc_status);
1206
+ HERE("connection_cursor Z");
1170
1207
 
1171
1208
  return c;
1172
1209
  }
@@ -1197,6 +1234,7 @@ static VALUE connection_cursor(VALUE self)
1197
1234
  */
1198
1235
  static VALUE connection_execute(int argc, VALUE *argv, VALUE self)
1199
1236
  {
1237
+ HERE("connection_execute");
1200
1238
  VALUE cursor = connection_cursor(self);
1201
1239
  VALUE val = cursor_execute(argc, argv, cursor);
1202
1240
 
@@ -1204,11 +1242,13 @@ static VALUE connection_execute(int argc, VALUE *argv, VALUE self)
1204
1242
  if (rb_block_given_p()) {
1205
1243
  return rb_ensure(rb_yield,cursor,cursor_close,cursor);
1206
1244
  } else {
1207
- return cursor;
1245
+ HERE("connection_execute Y");
1246
+ return cursor;
1208
1247
  }
1209
1248
  } else {
1210
1249
  cursor_drop(cursor);
1211
1250
  }
1251
+ HERE("connection_execute Z");
1212
1252
  return val;
1213
1253
  }
1214
1254
 
@@ -1233,6 +1273,7 @@ static VALUE connection_query(int argc, VALUE *argv, VALUE self)
1233
1273
  VALUE cursor;
1234
1274
  VALUE result;
1235
1275
 
1276
+ HERE("connection_query");
1236
1277
  if (argc >= 1 && TYPE(argv[0]) == T_SYMBOL) {
1237
1278
  format = argv[0];
1238
1279
  argc--; argv++;
@@ -1245,6 +1286,7 @@ static VALUE connection_query(int argc, VALUE *argv, VALUE self)
1245
1286
  result = cursor_fetchall(1, &format, cursor);
1246
1287
  cursor_close(cursor);
1247
1288
  }
1289
+ HERE("connection_query Z");
1248
1290
 
1249
1291
  return result;
1250
1292
  }
@@ -1328,7 +1370,7 @@ static void fb_cursor_check(struct FbCursor *fb_cursor)
1328
1370
 
1329
1371
  static void fb_cursor_drop(struct FbCursor *fb_cursor)
1330
1372
  {
1331
- long isc_status[20];
1373
+ ISC_STATUS isc_status[20];
1332
1374
  if (fb_cursor->open) {
1333
1375
  isc_dsql_free_statement(isc_status, &fb_cursor->stmt, DSQL_close);
1334
1376
  fb_error_check(isc_status);
@@ -1339,7 +1381,7 @@ static void fb_cursor_drop(struct FbCursor *fb_cursor)
1339
1381
 
1340
1382
  static void fb_cursor_drop_warn(struct FbCursor *fb_cursor)
1341
1383
  {
1342
- long isc_status[20];
1384
+ ISC_STATUS isc_status[20];
1343
1385
  if (fb_cursor->open) {
1344
1386
  isc_dsql_free_statement(isc_status, &fb_cursor->stmt, DSQL_close);
1345
1387
  fb_error_check_warn(isc_status);
@@ -1386,15 +1428,13 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1386
1428
 
1387
1429
  isc_blob_handle blob_handle;
1388
1430
  ISC_QUAD blob_id;
1389
- static char blob_items[] = { isc_info_blob_max_segment };
1390
- char blob_info[16];
1431
+ /* static char blob_items[] = { isc_info_blob_max_segment }; */
1432
+ /* char blob_info[16]; */
1391
1433
  char *p;
1392
1434
  long length;
1393
- struct time_object *tobj;
1435
+ /* struct time_object *tobj; */
1394
1436
  struct tm tms;
1395
1437
 
1396
- long isc_status[20];
1397
-
1398
1438
  Data_Get_Struct(fb_cursor->connection, struct FbConnection, fb_connection);
1399
1439
 
1400
1440
  /* Check the number of parameters */
@@ -1417,7 +1457,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1417
1457
  switch (dtp) {
1418
1458
  case SQL_TEXT :
1419
1459
  alignment = 1;
1420
- offset = ALIGN(offset, alignment);
1460
+ offset = FB_ALIGN(offset, alignment);
1421
1461
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1422
1462
  obj = rb_obj_as_string(obj);
1423
1463
  if (RSTRING(obj)->len > var->sqllen) {
@@ -1431,7 +1471,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1431
1471
 
1432
1472
  case SQL_VARYING :
1433
1473
  alignment = sizeof(short);
1434
- offset = ALIGN(offset, alignment);
1474
+ offset = FB_ALIGN(offset, alignment);
1435
1475
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1436
1476
  vary = (VARY *)var->sqldata;
1437
1477
  obj = rb_obj_as_string(obj);
@@ -1445,7 +1485,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1445
1485
  break;
1446
1486
 
1447
1487
  case SQL_SHORT :
1448
- offset = ALIGN(offset, alignment);
1488
+ offset = FB_ALIGN(offset, alignment);
1449
1489
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1450
1490
  if (var->sqlscale < 0) {
1451
1491
  ratio = 1;
@@ -1466,7 +1506,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1466
1506
  break;
1467
1507
 
1468
1508
  case SQL_LONG :
1469
- offset = ALIGN(offset, alignment);
1509
+ offset = FB_ALIGN(offset, alignment);
1470
1510
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1471
1511
  if (var->sqlscale < 0) {
1472
1512
  ratio = 1;
@@ -1484,7 +1524,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1484
1524
  break;
1485
1525
 
1486
1526
  case SQL_FLOAT :
1487
- offset = ALIGN(offset, alignment);
1527
+ offset = FB_ALIGN(offset, alignment);
1488
1528
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1489
1529
  obj = double_from_obj(obj);
1490
1530
  dvalue = NUM2DBL(obj);
@@ -1501,7 +1541,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1501
1541
  break;
1502
1542
 
1503
1543
  case SQL_DOUBLE :
1504
- offset = ALIGN(offset, alignment);
1544
+ offset = FB_ALIGN(offset, alignment);
1505
1545
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1506
1546
  obj = double_from_obj(obj);
1507
1547
  dvalue = NUM2DBL(obj);
@@ -1510,7 +1550,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1510
1550
  break;
1511
1551
  #if HAVE_LONG_LONG
1512
1552
  case SQL_INT64 :
1513
- offset = ALIGN(offset, alignment);
1553
+ offset = FB_ALIGN(offset, alignment);
1514
1554
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1515
1555
  obj = ll_from_obj(obj);
1516
1556
  *(ISC_INT64 *)var->sqldata = NUM2LL(obj);
@@ -1518,36 +1558,36 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1518
1558
  break;
1519
1559
  #endif
1520
1560
  case SQL_BLOB :
1521
- offset = ALIGN(offset, alignment);
1561
+ offset = FB_ALIGN(offset, alignment);
1522
1562
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1523
1563
  obj = rb_obj_as_string(obj);
1524
1564
 
1525
1565
  blob_handle = NULL;
1526
1566
  isc_create_blob2(
1527
- isc_status,&fb_connection->db,&fb_connection->transact,
1567
+ fb_connection->isc_status,&fb_connection->db,&fb_connection->transact,
1528
1568
  &blob_handle,&blob_id,0,NULL);
1529
- fb_error_check(isc_status);
1569
+ fb_error_check(fb_connection->isc_status);
1530
1570
  length = RSTRING(obj)->len;
1531
1571
  p = RSTRING(obj)->ptr;
1532
1572
  while (length >= 4096) {
1533
- isc_put_segment(isc_status,&blob_handle,4096,p);
1534
- fb_error_check(isc_status);
1573
+ isc_put_segment(fb_connection->isc_status,&blob_handle,4096,p);
1574
+ fb_error_check(fb_connection->isc_status);
1535
1575
  p += 4096;
1536
1576
  length -= 4096;
1537
1577
  }
1538
1578
  if (length) {
1539
- isc_put_segment(isc_status,&blob_handle,length,p);
1540
- fb_error_check(isc_status);
1579
+ isc_put_segment(fb_connection->isc_status,&blob_handle,length,p);
1580
+ fb_error_check(fb_connection->isc_status);
1541
1581
  }
1542
- isc_close_blob(isc_status,&blob_handle);
1543
- fb_error_check(isc_status);
1582
+ isc_close_blob(fb_connection->isc_status,&blob_handle);
1583
+ fb_error_check(fb_connection->isc_status);
1544
1584
 
1545
1585
  *(ISC_QUAD *)var->sqldata = blob_id;
1546
1586
  offset += alignment;
1547
1587
  break;
1548
1588
 
1549
1589
  case SQL_TIMESTAMP :
1550
- offset = ALIGN(offset, alignment);
1590
+ offset = FB_ALIGN(offset, alignment);
1551
1591
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1552
1592
  tm_from_timestamp(&tms, obj);
1553
1593
  isc_encode_timestamp(&tms, (ISC_TIMESTAMP *)var->sqldata);
@@ -1555,7 +1595,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1555
1595
  break;
1556
1596
 
1557
1597
  case SQL_TYPE_TIME :
1558
- offset = ALIGN(offset, alignment);
1598
+ offset = FB_ALIGN(offset, alignment);
1559
1599
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1560
1600
  tm_from_timestamp(&tms, obj);
1561
1601
  isc_encode_sql_time(&tms, (ISC_TIME *)var->sqldata);
@@ -1563,7 +1603,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1563
1603
  break;
1564
1604
 
1565
1605
  case SQL_TYPE_DATE :
1566
- offset = ALIGN(offset, alignment);
1606
+ offset = FB_ALIGN(offset, alignment);
1567
1607
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1568
1608
  tm_from_date(&tms, obj);
1569
1609
  isc_encode_sql_date(&tms, (ISC_DATE *)var->sqldata);
@@ -1573,7 +1613,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1573
1613
  #if 0
1574
1614
  case SQL_ARRAY :
1575
1615
  /* Not supported now
1576
- offset = ALIGN(offset, alignment);
1616
+ offset = FB_ALIGN(offset, alignment);
1577
1617
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1578
1618
  if (get_arrayvalue(self, type, obj, var))
1579
1619
  return(STATUS_ABNORMAL);
@@ -1589,14 +1629,14 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1589
1629
  }
1590
1630
 
1591
1631
  if (var->sqltype & 1) {
1592
- offset = ALIGN(offset, sizeof(short));
1632
+ offset = FB_ALIGN(offset, sizeof(short));
1593
1633
  var->sqlind = (short *)(fb_cursor->i_buffer + offset);
1594
1634
  *var->sqlind = 0;
1595
1635
  offset += sizeof(short);
1596
1636
  }
1597
1637
  } else if (var->sqltype & 1) {
1598
1638
  var->sqldata = 0;
1599
- offset = ALIGN(offset, sizeof(short));
1639
+ offset = FB_ALIGN(offset, sizeof(short));
1600
1640
  var->sqlind = (short *)(fb_cursor->i_buffer + offset);
1601
1641
  *var->sqlind = -1;
1602
1642
  offset += sizeof(short);
@@ -1609,7 +1649,6 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1609
1649
  static void fb_cursor_execute_withparams(struct FbCursor *fb_cursor, int argc, VALUE *argv)
1610
1650
  {
1611
1651
  struct FbConnection *fb_connection;
1612
- long isc_status[20];
1613
1652
 
1614
1653
  Data_Get_Struct(fb_cursor->connection, struct FbConnection, fb_connection);
1615
1654
  /* Check the first object type of the parameters */
@@ -1631,8 +1670,8 @@ static void fb_cursor_execute_withparams(struct FbCursor *fb_cursor, int argc, V
1631
1670
  fb_cursor_set_inputparams(fb_cursor, RARRAY(obj)->len, RARRAY(obj)->ptr);
1632
1671
 
1633
1672
  /* Execute SQL statement */
1634
- isc_dsql_execute2(isc_status, &fb_connection->transact, &fb_cursor->stmt, SQLDA_VERSION1, fb_cursor->i_sqlda, NULL);
1635
- fb_error_check(isc_status);
1673
+ isc_dsql_execute2(fb_connection->isc_status, &fb_connection->transact, &fb_cursor->stmt, SQLDA_VERSION1, fb_cursor->i_sqlda, NULL);
1674
+ fb_error_check(fb_connection->isc_status);
1636
1675
  }
1637
1676
  }
1638
1677
  } else {
@@ -1640,8 +1679,8 @@ static void fb_cursor_execute_withparams(struct FbCursor *fb_cursor, int argc, V
1640
1679
  fb_cursor_set_inputparams(fb_cursor, argc, argv);
1641
1680
 
1642
1681
  /* Execute SQL statement */
1643
- isc_dsql_execute2(isc_status, &fb_connection->transact, &fb_cursor->stmt, SQLDA_VERSION1, fb_cursor->i_sqlda, NULL);
1644
- fb_error_check(isc_status);
1682
+ isc_dsql_execute2(fb_connection->isc_status, &fb_connection->transact, &fb_cursor->stmt, SQLDA_VERSION1, fb_cursor->i_sqlda, NULL);
1683
+ fb_error_check(fb_connection->isc_status);
1645
1684
  }
1646
1685
  }
1647
1686
 
@@ -1690,27 +1729,29 @@ static VALUE precision_from_sqlvar(XSQLVAR *sqlvar)
1690
1729
  return Qnil;
1691
1730
  }
1692
1731
 
1732
+ static int no_lowercase(VALUE value)
1733
+ {
1734
+ HERE("no_lowercase");
1735
+ value = StringValue(value);
1736
+ int result = rb_funcall(re_lowercase, id_matches, 1, value) == Qnil;
1737
+ HERE("no_lowercase Z");
1738
+ return result;
1739
+ }
1740
+
1693
1741
  static VALUE fb_cursor_fields_ary(XSQLDA *sqlda, short downcase_names)
1694
1742
  {
1743
+ HERE("fb_cursor_fields_ary");
1695
1744
  long cols;
1696
1745
  long count;
1697
1746
  XSQLVAR *var;
1698
1747
  short dtp;
1699
1748
  VALUE ary;
1700
- VALUE re_lowercase;
1701
- ID id_matches, id_downcase_bang;
1702
1749
 
1703
1750
  cols = sqlda->sqld;
1704
1751
  if (cols == 0) {
1705
1752
  return Qnil;
1706
1753
  }
1707
1754
 
1708
- if (downcase_names) {
1709
- re_lowercase = rb_reg_regcomp(rb_str_new2("[[:lower:]]"));
1710
- id_matches = rb_intern("=~");
1711
- id_downcase_bang = rb_intern("downcase!");
1712
- }
1713
-
1714
1755
  ary = rb_ary_new();
1715
1756
  for (count = 0; count < cols; count++) {
1716
1757
  VALUE field;
@@ -1724,7 +1765,7 @@ static VALUE fb_cursor_fields_ary(XSQLDA *sqlda, short downcase_names)
1724
1765
  } else {
1725
1766
  name = rb_tainted_str_new(var->sqlname, var->sqlname_length);
1726
1767
  }
1727
- if (downcase_names && rb_funcall(re_lowercase, id_matches, 1, name) == Qnil) {
1768
+ if (downcase_names && no_lowercase(name)) {
1728
1769
  rb_funcall(name, id_downcase_bang, 0);
1729
1770
  }
1730
1771
  rb_str_freeze(name);
@@ -1745,11 +1786,13 @@ static VALUE fb_cursor_fields_ary(XSQLDA *sqlda, short downcase_names)
1745
1786
  rb_ary_push(ary, field);
1746
1787
  }
1747
1788
  rb_ary_freeze(ary);
1789
+ HERE("fb_cursor_fields_ary Z");
1748
1790
  return ary;
1749
1791
  }
1750
1792
 
1751
1793
  static VALUE fb_cursor_fields_hash(VALUE fields_ary)
1752
1794
  {
1795
+ HERE("fb_cursor_fields_hash");
1753
1796
  int i;
1754
1797
  VALUE hash = rb_hash_new();
1755
1798
 
@@ -1759,6 +1802,7 @@ static VALUE fb_cursor_fields_hash(VALUE fields_ary)
1759
1802
  rb_hash_aset(hash, name, field);
1760
1803
  }
1761
1804
 
1805
+ HERE("fb_cursor_fields_hash Z");
1762
1806
  return hash;
1763
1807
  }
1764
1808
 
@@ -1772,7 +1816,6 @@ static void fb_cursor_fetch_prep(struct FbCursor *fb_cursor)
1772
1816
  long length;
1773
1817
  long alignment;
1774
1818
  long offset;
1775
- long isc_status[20];
1776
1819
 
1777
1820
  fb_cursor_check(fb_cursor);
1778
1821
 
@@ -1781,11 +1824,11 @@ static void fb_cursor_fetch_prep(struct FbCursor *fb_cursor)
1781
1824
 
1782
1825
  /* Check if open cursor */
1783
1826
  if (!fb_cursor->open) {
1784
- rb_raise(rb_eFbError, "The cursor has not been open. Use execute(query)");
1827
+ rb_raise(rb_eFbError, "The cursor has not been opened. Use execute(query)");
1785
1828
  }
1786
1829
  /* Describe output SQLDA */
1787
- isc_dsql_describe(isc_status, &fb_cursor->stmt, 1, fb_cursor->o_sqlda);
1788
- fb_error_check(isc_status);
1830
+ isc_dsql_describe(fb_connection->isc_status, &fb_cursor->stmt, 1, fb_cursor->o_sqlda);
1831
+ fb_error_check(fb_connection->isc_status);
1789
1832
 
1790
1833
  /* Set the output SQLDA */
1791
1834
  cols = fb_cursor->o_sqlda->sqld;
@@ -1799,10 +1842,10 @@ static void fb_cursor_fetch_prep(struct FbCursor *fb_cursor)
1799
1842
  length += sizeof(short);
1800
1843
  alignment = sizeof(short);
1801
1844
  }
1802
- offset = ALIGN(offset, alignment);
1845
+ offset = FB_ALIGN(offset, alignment);
1803
1846
  var->sqldata = (char*)(fb_cursor->o_buffer + offset);
1804
1847
  offset += length;
1805
- offset = ALIGN(offset, sizeof(short));
1848
+ offset = FB_ALIGN(offset, sizeof(short));
1806
1849
  var->sqlind = (short*)(fb_cursor->o_buffer + offset);
1807
1850
  offset += sizeof(short);
1808
1851
  }
@@ -1835,20 +1878,22 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
1835
1878
  char blob_info[32];
1836
1879
  char *p, item;
1837
1880
  short length;
1838
- unsigned short max_segment;
1839
- ISC_LONG num_segments;
1840
- ISC_LONG total_length;
1841
-
1842
- long isc_status[20];
1881
+ unsigned short max_segment = 0;
1882
+ ISC_LONG num_segments = 0;
1883
+ ISC_LONG total_length = 0;
1843
1884
 
1844
1885
  Data_Get_Struct(fb_cursor->connection, struct FbConnection, fb_connection);
1845
1886
  fb_connection_check(fb_connection);
1846
1887
 
1888
+ if (fb_cursor->eof) {
1889
+ rb_raise(rb_eFbError, "Cursor is past end of data.");
1890
+ }
1847
1891
  /* Fetch one row */
1848
- if (isc_dsql_fetch(isc_status, &fb_cursor->stmt, 1, fb_cursor->o_sqlda) == SQLCODE_NOMORE) {
1892
+ if (isc_dsql_fetch(fb_connection->isc_status, &fb_cursor->stmt, 1, fb_cursor->o_sqlda) == SQLCODE_NOMORE) {
1893
+ fb_cursor->eof = Qtrue;
1849
1894
  return Qnil;
1850
1895
  }
1851
- fb_error_check(isc_status);
1896
+ fb_error_check(fb_connection->isc_status);
1852
1897
 
1853
1898
  /* Create the result tuple object */
1854
1899
  cols = fb_cursor->o_sqlda->sqld;
@@ -1915,8 +1960,9 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
1915
1960
  case SQL_TIMESTAMP:
1916
1961
  isc_decode_timestamp((ISC_TIMESTAMP *)var->sqldata, &tms);
1917
1962
  t = mktime(&tms);
1918
- if (t < 0) t = 0;
1919
- val = rb_time_new(t, 0);
1963
+ if (t < 0) t = 0;
1964
+ val = rb_time_new(t, 0);
1965
+ rb_funcall(val, rb_intern("localtime"), 0);
1920
1966
  break;
1921
1967
 
1922
1968
  case SQL_TYPE_TIME:
@@ -1940,13 +1986,13 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
1940
1986
  case SQL_BLOB:
1941
1987
  blob_handle = NULL;
1942
1988
  blob_id = *(ISC_QUAD *)var->sqldata;
1943
- isc_open_blob2(isc_status, &fb_connection->db, &fb_connection->transact, &blob_handle, &blob_id, 0, NULL);
1944
- fb_error_check(isc_status);
1989
+ isc_open_blob2(fb_connection->isc_status, &fb_connection->db, &fb_connection->transact, &blob_handle, &blob_id, 0, NULL);
1990
+ fb_error_check(fb_connection->isc_status);
1945
1991
  isc_blob_info(
1946
- isc_status, &blob_handle,
1992
+ fb_connection->isc_status, &blob_handle,
1947
1993
  sizeof(blob_items), blob_items,
1948
1994
  sizeof(blob_info), blob_info);
1949
- fb_error_check(isc_status);
1995
+ fb_error_check(fb_connection->isc_status);
1950
1996
  for (p = blob_info; *p != isc_info_end; p += length) {
1951
1997
  item = *p++;
1952
1998
  length = (short) isc_vax_integer(p,2);
@@ -1965,11 +2011,11 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
1965
2011
  }
1966
2012
  val = rb_tainted_str_new(NULL,total_length);
1967
2013
  for (p = RSTRING(val)->ptr; num_segments > 0; num_segments--, p += actual_seg_len) {
1968
- isc_get_segment(isc_status, &blob_handle, &actual_seg_len, max_segment, p);
1969
- fb_error_check(isc_status);
2014
+ isc_get_segment(fb_connection->isc_status, &blob_handle, &actual_seg_len, max_segment, p);
2015
+ fb_error_check(fb_connection->isc_status);
1970
2016
  }
1971
- isc_close_blob(isc_status, &blob_handle);
1972
- fb_error_check(isc_status);
2017
+ isc_close_blob(fb_connection->isc_status, &blob_handle);
2018
+ fb_error_check(fb_connection->isc_status);
1973
2019
  break;
1974
2020
 
1975
2021
  case SQL_ARRAY:
@@ -1993,7 +2039,7 @@ static long cursor_rows_affected(struct FbCursor *fb_cursor, long statement_type
1993
2039
  long inserted = 0, selected = 0, updated = 0, deleted = 0;
1994
2040
  char request[] = { isc_info_sql_records };
1995
2041
  char response[64], *r;
1996
- long isc_status[20];
2042
+ ISC_STATUS isc_status[20];
1997
2043
 
1998
2044
  isc_dsql_sql_info(isc_status, &fb_cursor->stmt, sizeof(request), request, sizeof(response), response);
1999
2045
  fb_error_check(isc_status);
@@ -2036,6 +2082,7 @@ static long cursor_rows_affected(struct FbCursor *fb_cursor, long statement_type
2036
2082
  */
2037
2083
  static VALUE cursor_execute2(VALUE args)
2038
2084
  {
2085
+ HERE("cursor_execute2");
2039
2086
  struct FbCursor *fb_cursor;
2040
2087
  struct FbConnection *fb_connection;
2041
2088
  char *sql;
@@ -2045,7 +2092,8 @@ static VALUE cursor_execute2(VALUE args)
2045
2092
  long cols;
2046
2093
  long rows_affected;
2047
2094
  VALUE result = Qnil;
2048
- long isc_status[20];
2095
+ char isc_info_buff[16];
2096
+ char isc_info_stmt[] = { isc_info_sql_stmt_type };
2049
2097
 
2050
2098
  VALUE self = rb_ary_pop(args);
2051
2099
  Data_Get_Struct(self, struct FbCursor, fb_cursor);
@@ -2054,14 +2102,14 @@ static VALUE cursor_execute2(VALUE args)
2054
2102
  sql = STR2CSTR(rb_ary_shift(args));
2055
2103
 
2056
2104
  /* Prepare query */
2057
- isc_dsql_prepare(isc_status, &fb_connection->transact, &fb_cursor->stmt, 0, sql, fb_connection_dialect(fb_connection), fb_cursor->o_sqlda);
2058
- fb_error_check(isc_status);
2105
+ isc_dsql_prepare(fb_connection->isc_status, &fb_connection->transact, &fb_cursor->stmt, 0, sql, fb_connection_dialect(fb_connection), fb_cursor->o_sqlda);
2106
+ fb_error_check(fb_connection->isc_status);
2059
2107
 
2060
2108
  /* Get the statement type */
2061
- isc_dsql_sql_info(isc_status, &fb_cursor->stmt,
2109
+ isc_dsql_sql_info(fb_connection->isc_status, &fb_cursor->stmt,
2062
2110
  sizeof(isc_info_stmt), isc_info_stmt,
2063
2111
  sizeof(isc_info_buff), isc_info_buff);
2064
- fb_error_check(isc_status);
2112
+ fb_error_check(fb_connection->isc_status);
2065
2113
 
2066
2114
  if (isc_info_buff[0] == isc_info_sql_stmt_type) {
2067
2115
  length = isc_vax_integer(&isc_info_buff[1], 2);
@@ -2070,11 +2118,11 @@ static VALUE cursor_execute2(VALUE args)
2070
2118
  statement = 0;
2071
2119
  }
2072
2120
  /* Describe the parameters */
2073
- isc_dsql_describe_bind(isc_status, &fb_cursor->stmt, 1, fb_cursor->i_sqlda);
2074
- fb_error_check(isc_status);
2121
+ isc_dsql_describe_bind(fb_connection->isc_status, &fb_cursor->stmt, 1, fb_cursor->i_sqlda);
2122
+ fb_error_check(fb_connection->isc_status);
2075
2123
 
2076
- isc_dsql_describe(isc_status, &fb_cursor->stmt, 1, fb_cursor->o_sqlda);
2077
- fb_error_check(isc_status);
2124
+ isc_dsql_describe(fb_connection->isc_status, &fb_cursor->stmt, 1, fb_cursor->o_sqlda);
2125
+ fb_error_check(fb_connection->isc_status);
2078
2126
 
2079
2127
  /* Get the number of parameters and reallocate the SQLDA */
2080
2128
  in_params = fb_cursor->i_sqlda->sqld;
@@ -2082,8 +2130,8 @@ static VALUE cursor_execute2(VALUE args)
2082
2130
  xfree(fb_cursor->i_sqlda);
2083
2131
  fb_cursor->i_sqlda = sqlda_alloc(in_params);
2084
2132
  /* Describe again */
2085
- isc_dsql_describe_bind(isc_status, &fb_cursor->stmt, 1, fb_cursor->i_sqlda);
2086
- fb_error_check(isc_status);
2133
+ isc_dsql_describe_bind(fb_connection->isc_status, &fb_cursor->stmt, 1, fb_cursor->i_sqlda);
2134
+ fb_error_check(fb_connection->isc_status);
2087
2135
  }
2088
2136
 
2089
2137
  /* Get the size of parameters buffer and reallocate it */
@@ -2106,8 +2154,8 @@ static VALUE cursor_execute2(VALUE args)
2106
2154
  } else if (in_params) {
2107
2155
  fb_cursor_execute_withparams(fb_cursor, RARRAY(args)->len, RARRAY(args)->ptr);
2108
2156
  } else {
2109
- isc_dsql_execute2(isc_status, &fb_connection->transact, &fb_cursor->stmt, SQLDA_VERSION1, NULL, NULL);
2110
- fb_error_check(isc_status);
2157
+ isc_dsql_execute2(fb_connection->isc_status, &fb_connection->transact, &fb_cursor->stmt, SQLDA_VERSION1, NULL, NULL);
2158
+ fb_error_check(fb_connection->isc_status);
2111
2159
  }
2112
2160
  rows_affected = cursor_rows_affected(fb_cursor, statement);
2113
2161
  result = INT2NUM(rows_affected);
@@ -2119,8 +2167,8 @@ static VALUE cursor_execute2(VALUE args)
2119
2167
  xfree(fb_cursor->o_sqlda);
2120
2168
  fb_cursor->o_sqlda = sqlda_alloc(cols);
2121
2169
  /* Describe again */
2122
- isc_dsql_describe(isc_status, &fb_cursor->stmt, 1, fb_cursor->o_sqlda);
2123
- fb_error_check(isc_status);
2170
+ isc_dsql_describe(fb_connection->isc_status, &fb_cursor->stmt, 1, fb_cursor->o_sqlda);
2171
+ fb_error_check(fb_connection->isc_status);
2124
2172
  }
2125
2173
 
2126
2174
  if (in_params) {
@@ -2128,8 +2176,8 @@ static VALUE cursor_execute2(VALUE args)
2128
2176
  }
2129
2177
 
2130
2178
  /* Open cursor */
2131
- isc_dsql_execute2(isc_status, &fb_connection->transact, &fb_cursor->stmt, SQLDA_VERSION1, in_params ? fb_cursor->i_sqlda : NULL, NULL);
2132
- fb_error_check(isc_status);
2179
+ isc_dsql_execute2(fb_connection->isc_status, &fb_connection->transact, &fb_cursor->stmt, SQLDA_VERSION1, in_params ? fb_cursor->i_sqlda : NULL, NULL);
2180
+ fb_error_check(fb_connection->isc_status);
2133
2181
  fb_cursor->open = Qtrue;
2134
2182
 
2135
2183
  /* Get the size of results buffer and reallocate it */
@@ -2142,7 +2190,9 @@ static VALUE cursor_execute2(VALUE args)
2142
2190
  /* Set the description attributes */
2143
2191
  fb_cursor->fields_ary = fb_cursor_fields_ary(fb_cursor->o_sqlda, fb_connection->downcase_names);
2144
2192
  fb_cursor->fields_hash = fb_cursor_fields_hash(fb_cursor->fields_ary);
2193
+ HERE("cursor_execute2 Z");
2145
2194
  }
2195
+ HERE("cursor_execute2 Z");
2146
2196
  return result;
2147
2197
  }
2148
2198
 
@@ -2153,9 +2203,9 @@ static VALUE cursor_execute2(VALUE args)
2153
2203
  */
2154
2204
  static VALUE cursor_execute(int argc, VALUE* argv, VALUE self)
2155
2205
  {
2206
+ HERE("cursor_execute");
2156
2207
  struct FbCursor *fb_cursor;
2157
2208
  struct FbConnection *fb_connection;
2158
- long isc_status[20];
2159
2209
  VALUE args;
2160
2210
 
2161
2211
  if (argc < 1) {
@@ -2170,8 +2220,8 @@ static VALUE cursor_execute(int argc, VALUE* argv, VALUE self)
2170
2220
  fb_connection_check(fb_connection);
2171
2221
 
2172
2222
  if (fb_cursor->open) {
2173
- isc_dsql_free_statement(isc_status, &fb_cursor->stmt, DSQL_close);
2174
- fb_error_check(isc_status);
2223
+ isc_dsql_free_statement(fb_connection->isc_status, &fb_cursor->stmt, DSQL_close);
2224
+ fb_error_check(fb_connection->isc_status);
2175
2225
  fb_cursor->open = Qfalse;
2176
2226
  }
2177
2227
 
@@ -2188,11 +2238,14 @@ static VALUE cursor_execute(int argc, VALUE* argv, VALUE self)
2188
2238
  return rb_funcall(rb_mKernel, rb_intern("raise"), 0);
2189
2239
  } else if (result != Qnil) {
2190
2240
  fb_connection_commit(fb_connection);
2241
+ HERE("cursor_execute X");
2191
2242
  return result;
2192
2243
  } else {
2244
+ HERE("cursor_execute Y");
2193
2245
  return result;
2194
2246
  }
2195
2247
  } else {
2248
+ HERE("cursor_execute Z");
2196
2249
  return cursor_execute2(args);
2197
2250
  }
2198
2251
  }
@@ -2291,7 +2344,7 @@ static VALUE cursor_fetchall(int argc, VALUE* argv, VALUE self)
2291
2344
  */
2292
2345
  static VALUE cursor_each(int argc, VALUE* argv, VALUE self)
2293
2346
  {
2294
- VALUE ary, row;
2347
+ VALUE row;
2295
2348
  struct FbCursor *fb_cursor;
2296
2349
 
2297
2350
  int hash_rows = hash_format(argc, argv);
@@ -2321,7 +2374,6 @@ static VALUE cursor_close(VALUE self)
2321
2374
  {
2322
2375
  struct FbCursor *fb_cursor;
2323
2376
  struct FbConnection *fb_connection;
2324
- long isc_status[20];
2325
2377
 
2326
2378
  Data_Get_Struct(self, struct FbCursor, fb_cursor);
2327
2379
  Data_Get_Struct(fb_cursor->connection, struct FbConnection, fb_connection);
@@ -2329,15 +2381,15 @@ static VALUE cursor_close(VALUE self)
2329
2381
 
2330
2382
  /* Close the cursor */
2331
2383
  if (fb_cursor->stmt) {
2332
- isc_dsql_free_statement(isc_status, &fb_cursor->stmt, DSQL_close);
2333
- fb_error_check_warn(isc_status);
2334
- isc_dsql_free_statement(isc_status, &fb_cursor->stmt, DSQL_drop);
2335
- fb_error_check(isc_status);
2384
+ isc_dsql_free_statement(fb_connection->isc_status, &fb_cursor->stmt, DSQL_close);
2385
+ fb_error_check_warn(fb_connection->isc_status);
2386
+ isc_dsql_free_statement(fb_connection->isc_status, &fb_cursor->stmt, DSQL_drop);
2387
+ fb_error_check(fb_connection->isc_status);
2336
2388
  fb_cursor->open = Qfalse;
2337
2389
  if (fb_connection->transact == fb_cursor->auto_transact) {
2338
- isc_commit_transaction(isc_status, &fb_connection->transact);
2339
- fb_error_check(isc_status);
2390
+ isc_commit_transaction(fb_connection->isc_status, &fb_connection->transact);
2340
2391
  fb_cursor->auto_transact = fb_connection->transact;
2392
+ fb_error_check(fb_connection->isc_status);
2341
2393
  }
2342
2394
  }
2343
2395
  fb_cursor->fields_ary = Qnil;
@@ -2476,10 +2528,11 @@ static VALUE connection_create(isc_db_handle handle, VALUE db)
2476
2528
  fb_connection->db = handle;
2477
2529
  fb_connection->transact = 0;
2478
2530
  fb_connection->cursor = rb_ary_new();
2531
+ /*
2479
2532
  connection_count++;
2480
2533
  fb_connection->next = fb_connection_list;
2481
2534
  fb_connection_list = fb_connection;
2482
-
2535
+ */
2483
2536
  dialect = SQL_DIALECT_CURRENT;
2484
2537
  db_dialect = fb_connection_db_SQL_Dialect(fb_connection);
2485
2538
 
@@ -2493,7 +2546,7 @@ static VALUE connection_create(isc_db_handle handle, VALUE db)
2493
2546
  downcase_names = rb_iv_get(db, "@downcase_names");
2494
2547
  fb_connection->downcase_names = RTEST(downcase_names);
2495
2548
 
2496
- for (i = 0; parm = CONNECTION_PARMS[i]; i++) {
2549
+ for (i = 0; (parm = CONNECTION_PARMS[i]); i++) {
2497
2550
  rb_iv_set(connection, parm, rb_iv_get(db, parm));
2498
2551
  }
2499
2552
 
@@ -2506,21 +2559,12 @@ static VALUE connection_names(VALUE self, char *sql)
2506
2559
  VALUE query = rb_str_new2(sql);
2507
2560
  VALUE cursor = connection_execute(1, &query, self);
2508
2561
  VALUE names = rb_ary_new();
2509
- ID id_rstrip_bang = rb_intern("rstrip!");
2510
2562
  struct FbConnection *fb_connection;
2511
- VALUE re_lowercase;
2512
- ID id_matches, id_downcase_bang;
2513
2563
  Data_Get_Struct(self, struct FbConnection, fb_connection);
2514
2564
 
2515
- if (fb_connection->downcase_names) {
2516
- re_lowercase = rb_reg_regcomp(rb_str_new2("[[:lower:]]"));
2517
- id_matches = rb_intern("=~");
2518
- id_downcase_bang = rb_intern("downcase!");
2519
- }
2520
-
2521
2565
  while ((row = cursor_fetch(0, NULL, cursor)) != Qnil) {
2522
2566
  VALUE name = rb_ary_entry(row, 0);
2523
- if (fb_connection->downcase_names && rb_funcall(re_lowercase, id_matches, 1, name) == Qnil) {
2567
+ if (fb_connection->downcase_names && no_lowercase(name)) {
2524
2568
  rb_funcall(name, id_downcase_bang, 0);
2525
2569
  }
2526
2570
  rb_funcall(name, id_rstrip_bang, 0);
@@ -2610,28 +2654,19 @@ static VALUE connection_index_columns(VALUE self, VALUE index_name)
2610
2654
  "FROM RDB$INDEX_SEGMENTS "
2611
2655
  "WHERE RDB$INDEX_SEGMENTS.RDB$INDEX_NAME = ? "
2612
2656
  "ORDER BY RDB$INDEX_SEGMENTS.RDB$FIELD_POSITION";
2613
- ID id_rstrip_bang = rb_intern("rstrip!");
2614
2657
  VALUE query_columns = rb_str_new2(sql_columns);
2615
2658
  VALUE query_parms[] = { query_columns, index_name };
2616
2659
  VALUE result = connection_query(2, query_parms, self);
2617
2660
  VALUE columns = rb_ary_new();
2618
- VALUE re_lowercase;
2619
- ID id_matches, id_downcase_bang;
2620
2661
  int i;
2621
2662
  struct FbConnection *fb_connection;
2622
2663
  Data_Get_Struct(self, struct FbConnection, fb_connection);
2623
2664
 
2624
- if (fb_connection->downcase_names) {
2625
- re_lowercase = rb_reg_regcomp(rb_str_new2("[[:lower:]]"));
2626
- id_matches = rb_intern("=~");
2627
- id_downcase_bang = rb_intern("downcase!");
2628
- }
2629
-
2630
2665
  for (i = 0; i < RARRAY(result)->len; i++) {
2631
2666
  VALUE row = rb_ary_entry(result, i);
2632
2667
  VALUE name = rb_ary_entry(row, 1);
2633
2668
  rb_funcall(name, id_rstrip_bang, 0);
2634
- if (fb_connection->downcase_names && rb_funcall(re_lowercase, id_matches, 1, name) == Qnil) {
2669
+ if (fb_connection->downcase_names && no_lowercase(name)) {
2635
2670
  rb_funcall(name, id_downcase_bang, 0);
2636
2671
  }
2637
2672
  rb_ary_push(columns, name);
@@ -2650,22 +2685,13 @@ static VALUE connection_indexes(VALUE self)
2650
2685
  "FROM RDB$INDICES "
2651
2686
  " JOIN RDB$RELATIONS ON RDB$INDICES.RDB$RELATION_NAME = RDB$RELATIONS.RDB$RELATION_NAME "
2652
2687
  "WHERE (RDB$RELATIONS.RDB$SYSTEM_FLAG <> 1 OR RDB$RELATIONS.RDB$SYSTEM_FLAG IS NULL) ";
2653
- ID id_rstrip_bang = rb_intern("rstrip!");
2654
2688
  VALUE query_indexes = rb_str_new2(sql_indexes);
2655
2689
  VALUE ary_indexes = connection_query(1, &query_indexes, self);
2656
2690
  VALUE indexes = rb_hash_new();
2657
- VALUE re_lowercase;
2658
- ID id_matches, id_downcase_bang;
2659
2691
  int i;
2660
2692
  struct FbConnection *fb_connection;
2661
2693
  Data_Get_Struct(self, struct FbConnection, fb_connection);
2662
2694
 
2663
- if (fb_connection->downcase_names) {
2664
- re_lowercase = rb_reg_regcomp(rb_str_new2("[[:lower:]]"));
2665
- id_matches = rb_intern("=~");
2666
- id_downcase_bang = rb_intern("downcase!");
2667
- }
2668
-
2669
2695
  for (i = 0; i < RARRAY(ary_indexes)->len; i++) {
2670
2696
  VALUE index_struct;
2671
2697
  VALUE row = rb_ary_entry(ary_indexes, i);
@@ -2679,10 +2705,10 @@ static VALUE connection_indexes(VALUE self)
2679
2705
  rb_funcall(index_name, id_rstrip_bang, 0);
2680
2706
 
2681
2707
  if (fb_connection->downcase_names) {
2682
- if (rb_funcall(re_lowercase, id_matches, 1, table_name) == Qnil) {
2708
+ if (no_lowercase(table_name)) {
2683
2709
  rb_funcall(table_name, id_downcase_bang, 0);
2684
2710
  }
2685
- if (rb_funcall(re_lowercase, id_matches, 1, index_name) == Qnil) {
2711
+ if (no_lowercase(index_name)) {
2686
2712
  rb_funcall(index_name, id_downcase_bang, 0);
2687
2713
  }
2688
2714
  }
@@ -2709,15 +2735,17 @@ static VALUE sql_type_from_code(VALUE self, VALUE code, VALUE subtype)
2709
2735
  return fb_sql_type_from_code(NUM2INT(code), NUM2INT(subtype));
2710
2736
  }
2711
2737
 
2738
+ /*
2712
2739
  static void define_attrs(VALUE klass, char **attrs)
2713
2740
  {
2714
2741
  char *parm;
2715
- while (parm = *attrs)
2742
+ while ((parm = *attrs))
2716
2743
  {
2717
2744
  rb_define_attr(klass, parm+1, 1, 1);
2718
2745
  attrs++;
2719
2746
  }
2720
2747
  }
2748
+ */
2721
2749
 
2722
2750
  static VALUE default_string(VALUE hash, char *key, char *def)
2723
2751
  {
@@ -2813,7 +2841,7 @@ static VALUE database_initialize(int argc, VALUE *argv, VALUE self)
2813
2841
  */
2814
2842
  static VALUE database_create(VALUE self)
2815
2843
  {
2816
- long isc_status[20];
2844
+ ISC_STATUS isc_status[20];
2817
2845
  isc_db_handle handle = 0;
2818
2846
  isc_tr_handle local_transact = 0;
2819
2847
  VALUE parms, fmt, stmt;
@@ -2880,6 +2908,7 @@ static VALUE database_connect(VALUE self)
2880
2908
  int length;
2881
2909
  isc_db_handle handle = NULL;
2882
2910
  VALUE database = rb_iv_get(self, "@database");
2911
+
2883
2912
  Check_Type(database, T_STRING);
2884
2913
  dbp = connection_create_dbp(self, &length);
2885
2914
  isc_attach_database(isc_status, 0, STR2CSTR(database), &handle, length, dbp);
@@ -2919,14 +2948,13 @@ static VALUE database_s_connect(int argc, VALUE *argv, VALUE klass)
2919
2948
  */
2920
2949
  static VALUE database_drop(VALUE self)
2921
2950
  {
2922
- long isc_status[20];
2923
2951
  struct FbConnection *fb_connection;
2924
2952
 
2925
2953
  VALUE connection = database_connect(self);
2926
2954
  Data_Get_Struct(connection, struct FbConnection, fb_connection);
2927
- isc_drop_database(isc_status, &fb_connection->db);
2928
- fb_error_check(isc_status);
2929
- fb_connection_remove(fb_connection);
2955
+ isc_drop_database(fb_connection->isc_status, &fb_connection->db);
2956
+ fb_error_check(fb_connection->isc_status);
2957
+ /* fb_connection_remove(fb_connection); */
2930
2958
  return Qnil;
2931
2959
  }
2932
2960
 
@@ -2944,6 +2972,7 @@ static VALUE database_s_drop(int argc, VALUE *argv, VALUE klass)
2944
2972
 
2945
2973
  void Init_fb()
2946
2974
  {
2975
+ HERE("Init_fb");
2947
2976
  rb_mFb = rb_define_module("Fb");
2948
2977
 
2949
2978
  rb_cFbDatabase = rb_define_class_under(rb_mFb, "Database", rb_cData);
@@ -2988,10 +3017,10 @@ void Init_fb()
2988
3017
  rb_define_method(rb_cFbConnection, "role_names", connection_role_names, 0);
2989
3018
  rb_define_method(rb_cFbConnection, "procedure_names", connection_procedure_names, 0);
2990
3019
  rb_define_method(rb_cFbConnection, "indexes", connection_indexes, 0);
2991
- //rb_define_method(rb_cFbConnection, "cursor", connection_cursor, 0);
3020
+ /* rb_define_method(rb_cFbConnection, "cursor", connection_cursor, 0); */
2992
3021
 
2993
3022
  rb_cFbCursor = rb_define_class_under(rb_mFb, "Cursor", rb_cData);
2994
- //rb_define_method(rb_cFbCursor, "execute", cursor_execute, -1);
3023
+ /* rb_define_method(rb_cFbCursor, "execute", cursor_execute, -1); */
2995
3024
  rb_define_method(rb_cFbCursor, "fields", cursor_fields, -1);
2996
3025
  rb_define_method(rb_cFbCursor, "fetch", cursor_fetch, -1);
2997
3026
  rb_define_method(rb_cFbCursor, "fetchall", cursor_fetchall, -1);
@@ -3019,4 +3048,10 @@ void Init_fb()
3019
3048
  rb_require("date");
3020
3049
  rb_require("time"); /* Needed as of Ruby 1.8.5 */
3021
3050
  rb_cDate = rb_const_get(rb_cObject, rb_intern("Date"));
3051
+
3052
+ id_matches = rb_intern("=~");
3053
+ id_downcase_bang = rb_intern("downcase!");
3054
+ re_lowercase = rb_reg_regcomp(rb_str_new2("[[:lower:]]"));
3055
+ rb_global_variable(&re_lowercase);
3056
+ id_rstrip_bang = rb_intern("rstrip!");
3022
3057
  }