fb 0.5.10 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/extconf.rb CHANGED
@@ -27,10 +27,10 @@ case RUBY_PLATFORM
27
27
  libs.push "fbclient_ms"
28
28
  when /darwin/
29
29
  hosttype = `uname -m`.chomp
30
- #$CFLAGS += " -DOS_UNIX"
31
- $CFLAGS.gsub!(/-arch (\w+)/) { |m| $1 == hosttype ? m : '' }
32
- $LDFLAGS.gsub!(/-arch (\w+)/) { |m| $1 == hosttype ? m : '' }
33
- CONFIG['LDSHARED'].gsub!(/-arch (\w+)/) { |m| $1 == hosttype ? m : '' }
30
+ $CFLAGS += " -DOS_UNIX"
31
+ # $CFLAGS.gsub!(/-arch (\w+)/) { |m| $1 == hosttype ? m : '' }
32
+ # $LDFLAGS.gsub!(/-arch (\w+)/) { |m| $1 == hosttype ? m : '' }
33
+ # CONFIG['LDSHARED'].gsub!(/-arch (\w+)/) { |m| $1 == hosttype ? m : '' }
34
34
  $CPPFLAGS += " -I/Library/Frameworks/Firebird.framework/Headers"
35
35
  $LDFLAGS += " -framework Firebird"
36
36
  when /linux/
data/fb.c CHANGED
@@ -53,13 +53,14 @@ static VALUE rb_cFbSqlType;
53
53
  static VALUE rb_eFbError;
54
54
  static VALUE rb_sFbField;
55
55
  static VALUE rb_sFbIndex;
56
-
56
+ static VALUE rb_sFbColumn;
57
57
  static VALUE rb_cDate;
58
58
 
59
59
  static ID id_matches;
60
60
  static ID id_downcase_bang;
61
61
  static VALUE re_lowercase;
62
62
  static ID id_rstrip_bang;
63
+ static ID id_sub_bang;
63
64
 
64
65
  /* static char isc_info_stmt[] = { isc_info_sql_stmt_type }; */
65
66
  /* static char isc_info_buff[16]; */
@@ -136,7 +137,7 @@ typedef struct trans_opts
136
137
  #define UPPER(c) (((c) >= 'a' && (c)<= 'z') ? (c) - 'a' + 'A' : (c))
137
138
  #define FREE(p) if (p) { xfree(p); p = 0; }
138
139
  #define SETNULL(p) if (p && strlen(p) == 0) { p = 0; }
139
- /* #define HERE(s) printf("%s\n", s) */
140
+ // #define HERE(s) printf("%s\n", s)
140
141
  #define HERE(s)
141
142
 
142
143
  static long calculate_buffsize(XSQLDA *sqlda)
@@ -207,11 +208,11 @@ struct time_object {
207
208
  #define GetTimeval(obj, tobj) \
208
209
  Data_Get_Struct(obj, struct time_object, tobj)
209
210
 
210
- static VALUE fb_mktime(struct tm *tm)
211
+ static VALUE fb_mktime(struct tm *tm, char *which)
211
212
  {
212
213
  return rb_funcall(
213
- rb_cTime, rb_intern("utc"), 6,
214
- INT2FIX(tm->tm_year), INT2FIX(tm->tm_mon), INT2FIX(tm->tm_mday),
214
+ rb_cTime, rb_intern(which), 6,
215
+ INT2FIX(tm->tm_year), INT2FIX(tm->tm_mon + 1), INT2FIX(tm->tm_mday),
215
216
  INT2FIX(tm->tm_hour), INT2FIX(tm->tm_min), INT2FIX(tm->tm_sec));
216
217
  }
217
218
 
@@ -371,7 +372,17 @@ static VALUE fb_sql_type_from_code(int code, int subtype)
371
372
  return rb_str_new2(sql_type);
372
373
  }
373
374
 
374
- static void fb_error_check(long *isc_status)
375
+ /* call-seq:
376
+ * from_code(code, subtype) -> String
377
+ *
378
+ * Returns the SQL type, such as VARCHAR or INTEGER for a given type code and subtype.
379
+ */
380
+ static VALUE sql_type_from_code(VALUE self, VALUE code, VALUE subtype)
381
+ {
382
+ return fb_sql_type_from_code(NUM2INT(code), NUM2INT(subtype));
383
+ }
384
+
385
+ static void fb_error_check(ISC_STATUS *isc_status)
375
386
  {
376
387
  HERE("fb_error_check");
377
388
  if (isc_status[0] == 1 && isc_status[1]) {
@@ -393,7 +404,7 @@ static void fb_error_check(long *isc_status)
393
404
  HERE("fb_error_check 2");
394
405
  }
395
406
 
396
- static void fb_error_check_warn(long *isc_status)
407
+ static void fb_error_check_warn(ISC_STATUS *isc_status)
397
408
  {
398
409
  short code = isc_sqlcode(isc_status);
399
410
  if (code != 0) {
@@ -1493,7 +1504,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1493
1504
  ratio *= 10;
1494
1505
  obj = double_from_obj(obj);
1495
1506
  dvalue = NUM2DBL(obj) * ratio;
1496
- lvalue = (long)(dvalue + 0.5);
1507
+ lvalue = (ISC_LONG)(dvalue + 0.5);
1497
1508
  } else {
1498
1509
  obj = long_from_obj(obj);
1499
1510
  lvalue = NUM2LONG(obj);
@@ -1514,12 +1525,15 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1514
1525
  ratio *= 10;
1515
1526
  obj = double_from_obj(obj);
1516
1527
  dvalue = NUM2DBL(obj) * ratio;
1517
- lvalue = (long)(dvalue + 0.5);
1528
+ lvalue = (ISC_LONG)(dvalue + 0.5);
1518
1529
  } else {
1519
1530
  obj = long_from_obj(obj);
1520
1531
  lvalue = NUM2LONG(obj);
1521
1532
  }
1522
- *(long *)var->sqldata = lvalue;
1533
+ if (lvalue < -2147483647 || lvalue > 2147483647) {
1534
+ rb_raise(rb_eRangeError, "integer overflow");
1535
+ }
1536
+ *(ISC_LONG *)var->sqldata = lvalue;
1523
1537
  offset += alignment;
1524
1538
  break;
1525
1539
 
@@ -1562,7 +1576,7 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, int argc, VALU
1562
1576
  var->sqldata = (char *)(fb_cursor->i_buffer + offset);
1563
1577
  obj = rb_obj_as_string(obj);
1564
1578
 
1565
- blob_handle = NULL;
1579
+ blob_handle = 0;
1566
1580
  isc_create_blob2(
1567
1581
  fb_connection->isc_status,&fb_connection->db,&fb_connection->transact,
1568
1582
  &blob_handle,&blob_id,0,NULL);
@@ -1869,7 +1883,6 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
1869
1883
  isc_blob_handle blob_handle;
1870
1884
  ISC_QUAD blob_id;
1871
1885
  unsigned short actual_seg_len;
1872
- time_t t;
1873
1886
  static char blob_items[] = {
1874
1887
  isc_info_blob_max_segment,
1875
1888
  isc_info_blob_num_segments,
@@ -1936,10 +1949,10 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
1936
1949
  if (var->sqlscale < 0) {
1937
1950
  ratio = 1;
1938
1951
  for (scnt = 0; scnt > var->sqlscale; scnt--) ratio *= 10;
1939
- dval = (double)*(long*)var->sqldata/ratio;
1952
+ dval = (double)*(ISC_LONG*)var->sqldata/ratio;
1940
1953
  val = rb_float_new(dval);
1941
1954
  } else {
1942
- val = INT2NUM(*(long*)var->sqldata);
1955
+ val = INT2NUM(*(ISC_LONG*)var->sqldata);
1943
1956
  }
1944
1957
  break;
1945
1958
 
@@ -1964,23 +1977,15 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
1964
1977
  #endif
1965
1978
  case SQL_TIMESTAMP:
1966
1979
  isc_decode_timestamp((ISC_TIMESTAMP *)var->sqldata, &tms);
1967
- t = mktime(&tms);
1968
- if (t < 0) t = 0;
1969
- val = rb_time_new(t, 0);
1970
- rb_funcall(val, rb_intern("localtime"), 0);
1980
+ val = fb_mktime(&tms, "local");
1971
1981
  break;
1972
1982
 
1973
1983
  case SQL_TYPE_TIME:
1974
1984
  isc_decode_sql_time((ISC_TIME *)var->sqldata, &tms);
1975
- /*
1976
- t = mktime(&tms);
1977
- if (t < 0) t = t + (24 * 60 * 60);
1978
- val = rb_time_new(t, 0);
1979
- */
1980
1985
  tms.tm_year = 2000;
1981
- tms.tm_mon = 1;
1986
+ tms.tm_mon = 0;
1982
1987
  tms.tm_mday = 1;
1983
- val = fb_mktime(&tms);
1988
+ val = fb_mktime(&tms, "utc");
1984
1989
  break;
1985
1990
 
1986
1991
  case SQL_TYPE_DATE:
@@ -1989,7 +1994,7 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
1989
1994
  break;
1990
1995
 
1991
1996
  case SQL_BLOB:
1992
- blob_handle = NULL;
1997
+ blob_handle = 0;
1993
1998
  blob_id = *(ISC_QUAD *)var->sqldata;
1994
1999
  isc_open_blob2(fb_connection->isc_status, &fb_connection->db, &fb_connection->transact, &blob_handle, &blob_id, 0, NULL);
1995
2000
  fb_error_check(fb_connection->isc_status);
@@ -2642,6 +2647,79 @@ static VALUE connection_procedure_names(VALUE self)
2642
2647
  return connection_names(self, sql);
2643
2648
  }
2644
2649
 
2650
+ /* call-seq:
2651
+ * trigger_names() -> array
2652
+ *
2653
+ * Returns sorted array of trigger names in connected database.
2654
+ */
2655
+ static VALUE connection_trigger_names(VALUE self)
2656
+ {
2657
+ char *sql = "SELECT RDB$TRIGGER_NAME FROM RDB$TRIGGERS "
2658
+ "ORDER BY RDB$TRIGGER_NAME";
2659
+ return connection_names(self, sql);
2660
+ }
2661
+
2662
+ /* call-seq:
2663
+ * columns(table_name) -> array
2664
+ *
2665
+ * Returns array of objects describing each column of table_name.
2666
+ */
2667
+
2668
+ static VALUE connection_columns(VALUE self, VALUE table_name)
2669
+ {
2670
+ int i;
2671
+ struct FbConnection *fb_connection;
2672
+ VALUE re_default = rb_reg_new("^\\s*DEFAULT\\s+", strlen("^\\s*DEFAULT\\s+"), RE_OPTION_IGNORECASE);
2673
+ VALUE re_rdb = rb_reg_new("^RDB\\$", strlen("^RDB\\$"), 0);
2674
+ VALUE empty = rb_str_new(NULL, 0);
2675
+ VALUE columns = rb_ary_new();
2676
+ char *sql = "SELECT r.rdb$field_name NAME, r.rdb$field_source, f.rdb$field_type, f.rdb$field_sub_type, "
2677
+ "f.rdb$field_length, f.rdb$field_precision, f.rdb$field_scale SCALE, "
2678
+ "COALESCE(r.rdb$default_source, f.rdb$default_source), "
2679
+ "COALESCE(r.rdb$null_flag, f.rdb$null_flag) "
2680
+ "FROM rdb$relation_fields r "
2681
+ "JOIN rdb$fields f ON r.rdb$field_source = f.rdb$field_name "
2682
+ "WHERE UPPER(r.rdb$relation_name) = ? "
2683
+ "ORDER BY r.rdb$field_position";
2684
+ VALUE query = rb_str_new2(sql);
2685
+ table_name = rb_funcall(table_name, rb_intern("upcase"), 0);
2686
+ VALUE query_parms[] = { query, table_name };
2687
+ VALUE rs = connection_query(2, query_parms, self);
2688
+ Data_Get_Struct(self, struct FbConnection, fb_connection);
2689
+ for (i = 0; i < RARRAY(rs)->len; i++) {
2690
+ VALUE row = rb_ary_entry(rs, i);
2691
+ VALUE name = rb_ary_entry(row, 0);
2692
+ VALUE domain = rb_ary_entry(row, 1);
2693
+ VALUE sql_type = rb_ary_entry(row, 2);
2694
+ VALUE sql_subtype = rb_ary_entry(row, 3);
2695
+ VALUE length = rb_ary_entry(row, 4);
2696
+ VALUE precision = rb_ary_entry(row, 5);
2697
+ VALUE scale = rb_ary_entry(row, 6);
2698
+ VALUE dflt = rb_ary_entry(row, 7);
2699
+ VALUE not_null = rb_ary_entry(row, 8);
2700
+ rb_funcall(name, id_rstrip_bang, 0);
2701
+ rb_funcall(domain, id_rstrip_bang, 0);
2702
+ if (fb_connection->downcase_names && no_lowercase(name)) {
2703
+ rb_funcall(name, id_downcase_bang, 0);
2704
+ }
2705
+ if (rb_funcall(re_rdb, rb_intern("match"), 1, domain) != Qnil) {
2706
+ domain = Qnil;
2707
+ }
2708
+ if (sql_subtype == Qnil) {
2709
+ sql_subtype = INT2NUM(0);
2710
+ }
2711
+ sql_type = sql_type_from_code(self, sql_type, sql_subtype);
2712
+ if (dflt != Qnil) {
2713
+ rb_funcall(dflt, id_sub_bang, 2, re_default, empty);
2714
+ }
2715
+ VALUE nullable = RTEST(not_null) ? Qfalse : Qtrue;
2716
+ VALUE column = rb_struct_new(rb_sFbColumn, name, domain, sql_type, sql_subtype, length, precision, scale, dflt, nullable);
2717
+ rb_ary_push(columns, column);
2718
+ }
2719
+ rb_ary_freeze(columns);
2720
+ return columns;
2721
+ }
2722
+
2645
2723
  char *p(char *prompt, VALUE s)
2646
2724
  {
2647
2725
  char *sz;
@@ -2730,16 +2808,6 @@ static VALUE connection_indexes(VALUE self)
2730
2808
  return indexes;
2731
2809
  }
2732
2810
 
2733
- /* call-seq:
2734
- * from_code(code, subtype) -> String
2735
- *
2736
- * Returns the SQL type, such as VARCHAR or INTEGER for a given type code and subtype.
2737
- */
2738
- static VALUE sql_type_from_code(VALUE self, VALUE code, VALUE subtype)
2739
- {
2740
- return fb_sql_type_from_code(NUM2INT(code), NUM2INT(subtype));
2741
- }
2742
-
2743
2811
  /*
2744
2812
  static void define_attrs(VALUE klass, char **attrs)
2745
2813
  {
@@ -2911,7 +2979,7 @@ static VALUE database_connect(VALUE self)
2911
2979
  ISC_STATUS isc_status[20];
2912
2980
  char *dbp;
2913
2981
  int length;
2914
- isc_db_handle handle = NULL;
2982
+ isc_db_handle handle = 0;
2915
2983
  VALUE database = rb_iv_get(self, "@database");
2916
2984
 
2917
2985
  Check_Type(database, T_STRING);
@@ -3021,7 +3089,9 @@ void Init_fb()
3021
3089
  rb_define_method(rb_cFbConnection, "view_names", connection_view_names, 0);
3022
3090
  rb_define_method(rb_cFbConnection, "role_names", connection_role_names, 0);
3023
3091
  rb_define_method(rb_cFbConnection, "procedure_names", connection_procedure_names, 0);
3092
+ rb_define_method(rb_cFbConnection, "trigger_names", connection_trigger_names, 0);
3024
3093
  rb_define_method(rb_cFbConnection, "indexes", connection_indexes, 0);
3094
+ rb_define_method(rb_cFbConnection, "columns", connection_columns, 1);
3025
3095
  /* rb_define_method(rb_cFbConnection, "cursor", connection_cursor, 0); */
3026
3096
 
3027
3097
  rb_cFbCursor = rb_define_class_under(rb_mFb, "Cursor", rb_cData);
@@ -3049,7 +3119,8 @@ void Init_fb()
3049
3119
 
3050
3120
  rb_sFbField = rb_struct_define("FbField", "name", "sql_type", "sql_subtype", "display_size", "internal_size", "precision", "scale", "nullable", "type_code", NULL);
3051
3121
  rb_sFbIndex = rb_struct_define("FbIndex", "table_name", "index_name", "unique", "descending", "columns", NULL);
3052
-
3122
+ rb_sFbColumn = rb_struct_define("FbColumn", "name", "domain", "sql_type", "sql_subtype", "length", "precision", "scale", "default", "nullable", NULL);
3123
+
3053
3124
  rb_require("date");
3054
3125
  rb_require("time"); /* Needed as of Ruby 1.8.5 */
3055
3126
  rb_cDate = rb_const_get(rb_cObject, rb_intern("Date"));
@@ -3059,4 +3130,5 @@ void Init_fb()
3059
3130
  re_lowercase = rb_reg_regcomp(rb_str_new2("[[:lower:]]"));
3060
3131
  rb_global_variable(&re_lowercase);
3061
3132
  id_rstrip_bang = rb_intern("rstrip!");
3133
+ id_sub_bang = rb_intern("sub!");
3062
3134
  }
@@ -0,0 +1,21 @@
1
+ module Fb
2
+ class Connection
3
+ def execute_script(sql)
4
+ stmts = []
5
+ delim = ';'
6
+ while sql =~ /\S/
7
+ stmt, sql = sql.split(delim, 2)
8
+ if stmt =~ /^\s*set\s+term\s+(\S+)/i
9
+ delim = $1
10
+ elsif stmt =~ /\S/
11
+ stmts << stmt
12
+ end
13
+ end
14
+ self.transaction do
15
+ stmts.each do |stmt|
16
+ self.execute(stmt)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -381,6 +381,40 @@ class ConnectionTestCases < Test::Unit::TestCase
381
381
  assert_equal 'plusone', names[0]
382
382
  end
383
383
  end
384
+
385
+ def test_trigger_names
386
+ table_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20)); CREATE GENERATOR TEST_SEQ;"
387
+ trigger_schema = <<-END_SQL
388
+ CREATE TRIGGER TEST_INSERT FOR TEST ACTIVE BEFORE INSERT AS
389
+ BEGIN
390
+ IF (NEW.ID IS NULL) THEN
391
+ NEW.ID = CAST(GEN_ID(TEST_SEQ, 1) AS INT);
392
+ END
393
+ END_SQL
394
+ Database.create(@parms) do |connection|
395
+ connection.execute_script(table_schema)
396
+ connection.execute(trigger_schema)
397
+ names = connection.trigger_names
398
+ assert names.include?('TEST_INSERT')
399
+ end
400
+ end
401
+
402
+ def test_trigger_names_downcased
403
+ table_schema = "CREATE TABLE TEST (ID INT, NAME VARCHAR(20)); CREATE GENERATOR TEST_SEQ;"
404
+ trigger_schema = <<-END_SQL
405
+ CREATE TRIGGER TEST_INSERT FOR TEST ACTIVE BEFORE INSERT AS
406
+ BEGIN
407
+ IF (NEW.ID IS NULL) THEN
408
+ NEW.ID = CAST(GEN_ID(TEST_SEQ, 1) AS INT);
409
+ END
410
+ END_SQL
411
+ Database.create(@parms.merge(:downcase_names => true)) do |connection|
412
+ connection.execute_script(table_schema)
413
+ connection.execute(trigger_schema)
414
+ names = connection.trigger_names
415
+ assert names.include?('test_insert')
416
+ end
417
+ end
384
418
 
385
419
  def test_index_names
386
420
  sql_schema = <<-END
@@ -459,4 +493,51 @@ class ConnectionTestCases < Test::Unit::TestCase
459
493
  connection.drop
460
494
  end
461
495
  end
496
+
497
+ def test_columns
498
+ sql_schema = <<-END
499
+ create domain STRING10 as VARCHAR(10);
500
+ create table TEST (
501
+ I INTEGER,
502
+ SI SMALLINT,
503
+ BI BIGINT,
504
+ F FLOAT,
505
+ D DOUBLE PRECISION,
506
+ C CHAR,
507
+ C10 CHAR(10),
508
+ VC VARCHAR(1),
509
+ VC10 STRING10,
510
+ VC10000 VARCHAR(10000),
511
+ DT DATE,
512
+ TM TIME,
513
+ TS TIMESTAMP,
514
+ N92 NUMERIC(9,2),
515
+ D92 DECIMAL(9,2));
516
+ END
517
+ expected = [
518
+ # name, domain, sql_type, sql_subtype, length, precision, scale, default, nullable
519
+ Struct::FbColumn.new("I", nil, "INTEGER", 0, 4, 0, 0, nil, true),
520
+ Struct::FbColumn.new("SI", nil, "SMALLINT", 0, 2, 0, 0, nil, true),
521
+ Struct::FbColumn.new("BI", nil, "BIGINT", 0, 8, 0, 0, nil, true),
522
+ Struct::FbColumn.new("F", nil, "FLOAT", 0, 4, nil, 0, nil, true),
523
+ Struct::FbColumn.new("D", nil, "DOUBLE PRECISION", 0, 8, nil, 0, nil, true),
524
+ Struct::FbColumn.new("C", nil, "CHAR", 0, 1, nil, 0, nil, true),
525
+ Struct::FbColumn.new("C10", nil, "CHAR", 0, 10, nil, 0, nil, true),
526
+ Struct::FbColumn.new("VC", nil, "VARCHAR", 0, 1, nil, 0, nil, true),
527
+ Struct::FbColumn.new("VC10", "STRING10", "VARCHAR", 0, 10, nil, 0, nil, true),
528
+ Struct::FbColumn.new("VC10000", nil, "VARCHAR", 0, 10000, nil, 0, nil, true),
529
+ Struct::FbColumn.new("DT", nil, "DATE", 0, 4, nil, 0, nil, true),
530
+ Struct::FbColumn.new("TM", nil, "TIME", 0, 4, nil, 0, nil, true),
531
+ Struct::FbColumn.new("TS", nil, "TIMESTAMP", 0, 8, nil, 0, nil, true),
532
+ Struct::FbColumn.new("N92", nil, "NUMERIC", 1, 4, 9, -2, nil, true),
533
+ Struct::FbColumn.new("D92", nil, "DECIMAL", 2, 4, 9, -2, nil, true),
534
+ ]
535
+ Database.create(@parms) do |connection|
536
+ connection.execute_script(sql_schema)
537
+ columns = connection.columns('TEST')
538
+ expected.each_with_index do |column, i|
539
+ assert_equal column, columns[i]
540
+ end
541
+ end
542
+ end
462
543
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.10
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brent Rowland
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-26 00:00:00 -07:00
12
+ date: 2009-09-10 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -25,6 +25,7 @@ files:
25
25
  - extconf.rb
26
26
  - fb.c
27
27
  - README
28
+ - fb_extensions.rb
28
29
  - test/ConnectionTestCases.rb
29
30
  - test/CursorTestCases.rb
30
31
  - test/DatabaseTestCases.rb
@@ -33,9 +34,7 @@ files:
33
34
  - test/FbTestSuite.rb
34
35
  - test/TransactionTestCases.rb
35
36
  has_rdoc: true
36
- homepage: http://www.rowlandresearch.com/ruby/
37
- licenses: []
38
-
37
+ homepage: http://github.com/rowland/fb
39
38
  post_install_message:
40
39
  rdoc_options:
41
40
  - --title
@@ -59,11 +58,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
58
  version: "0"
60
59
  version:
61
60
  requirements:
62
- - Firebird client library fbclient.dll
61
+ - Firebird client library fbclient.dll, libfbclient.so or Firebird.framework.
63
62
  rubyforge_project: fblib
64
- rubygems_version: 1.3.3
63
+ rubygems_version: 1.3.1
65
64
  signing_key:
66
- specification_version: 3
65
+ specification_version: 2
67
66
  summary: Firebird and Interbase driver
68
67
  test_files:
69
68
  - test/FbTestSuite.rb