Class: Fb::Connection

Inherits:
Data
  • Object
show all
Defined in:
lib/fb.rb,
ext/fb/fb_ext.c

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#charsetObject

#databaseObject

#downcase_namesObject

#encodingObject

#passwordObject

#roleObject

#usernameObject

Instance Method Details

#closenil

Closes connection to database. All open cursors are dropped.

Returns:

  • (nil)


1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
# File 'ext/fb/fb_ext.c', line 1180

static VALUE connection_close(VALUE self)
{
  struct FbConnection *fb_connection;

  Data_Get_Struct(self, struct FbConnection, fb_connection);

  if (fb_connection->dropped) return Qnil;

  fb_connection_check(fb_connection);
  fb_connection_disconnect(fb_connection);
  fb_connection_drop_cursors(fb_connection);

  return Qnil;
}

#columns(table_name) ⇒ Array

Returns array of objects describing each column of table_name.

Returns:

  • (Array)


2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
# File 'ext/fb/fb_ext.c', line 2557

static VALUE connection_columns(VALUE self, VALUE table_name)
{
    int i;
    struct FbConnection *fb_connection;
    VALUE re_default = rb_reg_new("^\\s*DEFAULT\\s+", strlen("^\\s*DEFAULT\\s+"), IGNORECASE);
    VALUE re_rdb = rb_reg_new("^RDB\\$", strlen("^RDB\\$"), 0);
    VALUE empty = rb_str_new(NULL, 0);
    VALUE columns = rb_ary_new();
    const char *sql = "SELECT r.rdb$field_name NAME, r.rdb$field_source, f.rdb$field_type, f.rdb$field_sub_type, "
                "f.rdb$field_length, f.rdb$field_precision, f.rdb$field_scale SCALE, "
                "COALESCE(r.rdb$default_source, f.rdb$default_source), "
                "COALESCE(r.rdb$null_flag, f.rdb$null_flag) "
                "FROM rdb$relation_fields r "
                "JOIN rdb$fields f ON r.rdb$field_source = f.rdb$field_name "
                "WHERE UPPER(r.rdb$relation_name) = ? "
                "ORDER BY r.rdb$field_position";
    VALUE query = rb_str_new2(sql);
    VALUE upcase_table_name = rb_funcall(table_name, rb_intern("upcase"), 0);
    VALUE query_parms[] = { query, upcase_table_name };
    VALUE rs = connection_query(2, query_parms, self);
    Data_Get_Struct(self, struct FbConnection, fb_connection);
    for (i = 0; i < RARRAY_LEN(rs); i++) {
        VALUE row = rb_ary_entry(rs, i);
        VALUE name = rb_ary_entry(row, 0);
        VALUE domain = rb_ary_entry(row, 1);
        VALUE sql_type = rb_ary_entry(row, 2);
        VALUE sql_subtype = rb_ary_entry(row, 3);
        VALUE length = rb_ary_entry(row, 4);
        VALUE precision = rb_ary_entry(row, 5);
        VALUE scale = rb_ary_entry(row, 6);
        VALUE dflt = rb_ary_entry(row, 7);
        VALUE not_null = rb_ary_entry(row, 8);
        VALUE nullable;
        VALUE column;
        rb_funcall(name, id_rstrip_bang, 0);
        rb_funcall(domain, id_rstrip_bang, 0);
        if (fb_connection->downcase_names && no_lowercase(name)) {
          rb_funcall(name, id_downcase_bang, 0);
        }
        if (rb_funcall(re_rdb, rb_intern("match"), 1, domain) != Qnil) {
            domain = Qnil;
        }
        if (sql_subtype == Qnil) {
            sql_subtype = INT2NUM(0);
        }
        sql_type = sql_type_from_code(self, sql_type, sql_subtype);
        if (dflt != Qnil) {
            rb_funcall(dflt, id_sub_bang, 2, re_default, empty);
        }
        nullable = RTEST(not_null) ? Qfalse : Qtrue;
        column = rb_struct_new(rb_sFbColumn, name, domain, sql_type, sql_subtype, length, precision, scale, dflt, nullable);
        rb_ary_push(columns, column);
    }
    rb_ary_freeze(columns);
    return columns;
}

#commitnil

Commit the current transaction.

Returns:

  • (nil)


1010
1011
1012
1013
1014
1015
1016
1017
# File 'ext/fb/fb_ext.c', line 1010

static VALUE connection_commit(VALUE self)
{
  struct FbConnection *fb_connection;
  Data_Get_Struct(self, struct FbConnection, fb_connection);

  fb_connection_commit(fb_connection);
  return Qnil;
}

#db_dialectInteger

Returns database dialect.

Returns:

  • (Integer)


1232
1233
1234
1235
1236
1237
1238
1239
1240
# File 'ext/fb/fb_ext.c', line 1232

static VALUE connection_db_dialect(VALUE self)
{
  struct FbConnection *fb_connection;

  Data_Get_Struct(self, struct FbConnection, fb_connection);
  fb_connection_check(fb_connection);

  return INT2FIX(fb_connection->db_dialect);
}

#dialectInteger

Returns dialect of connection.

Returns:

  • (Integer)


1217
1218
1219
1220
1221
1222
1223
1224
1225
# File 'ext/fb/fb_ext.c', line 1217

static VALUE connection_dialect(VALUE self)
{
  struct FbConnection *fb_connection;

  Data_Get_Struct(self, struct FbConnection, fb_connection);
  fb_connection_check(fb_connection);

  return INT2FIX(fb_connection->dialect);
}

#dropnil

Drops connected database. All open cursors are dropped.

Returns:

  • (nil)


1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
# File 'ext/fb/fb_ext.c', line 1200

static VALUE connection_drop(VALUE self)
{
  struct FbConnection *fb_connection;

  Data_Get_Struct(self, struct FbConnection, fb_connection);
  fb_connection->dropped = 1;
  fb_connection_disconnect(fb_connection);
  fb_connection_drop_cursors(fb_connection);

  return Qnil;
}

#execute(sql, *args) ⇒ Cursor #execute(sql, *args) {|cursor| ... } ⇒ Object

Allocates a Cursor and executes the sql statement, matching up the parameters in args with the place holders in the statement, represented by ?‘s.

If the sql statement returns a result set and a block is provided, the cursor is yielded to the block before being automatically closed.

If the sql statement returns a result set and a block is not provided, a Cursor object is returned.

If the sql statement performs an INSERT, UPDATE or DELETE, the number of rows affected is returned. Other statements, such as schema updates, return -1.

*args can be one or more tuples of parameters or an array of tuples (arrays), in which case the statement will be executed once for each tuple of parameters.

If no transaction is currently active, a transaction is automatically started and is closed when the cursor is closed. Note that if additional statements yielding cursors are started before the first cursor is closed, these cursors will also be closed when the first one is closed and its transaction committed.

Overloads:

  • #execute(sql, *args) ⇒ Cursor

    Returns:

  • #execute(sql, *args) {|cursor| ... } ⇒ Object

    Yields:

    • (cursor)


1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
# File 'ext/fb/fb_ext.c', line 1120

static VALUE connection_execute(int argc, VALUE *argv, VALUE self)
{
  VALUE cursor = connection_cursor(self);
  VALUE val = cursor_execute(argc, argv, cursor);

  if (NIL_P(val)) {
    if (rb_block_given_p()) {
      return rb_ensure(rb_yield,cursor,cursor_close,cursor);
      } else {
        HERE("connection_execute Y");
        return cursor;
      }
  } else {
    cursor_drop(cursor);
  }
  return val;
}

#execute_script(sql) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/fb.rb', line 5

def execute_script(sql)
  stmts = []
  delim = ';'
  while sql =~ /\S/
    stmt, sql = sql.split(delim, 2)
    if stmt =~ /^\s*set\s+term\s+(\S+)/i
      delim = $1
    elsif stmt =~ /\S/
      stmts << stmt
    end
  end
  self.transaction do
    stmts.each do |stmt|
      self.execute(stmt)
    end
  end
end

#generator_namesArray

Returns sorted array of generator names in connected database.

Returns:

  • (Array)


2495
2496
2497
2498
2499
2500
2501
# File 'ext/fb/fb_ext.c', line 2495

static VALUE connection_generator_names(VALUE self)
{
  const char *sql = "SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS "
        "WHERE (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG <> 1) "
        "ORDER BY RDB$GENERATOR_NAME";
  return connection_names(self, sql);
}

#indexesHash

Returns a hash of indexes, keyed by index name.

Returns:

  • (Hash)


2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
# File 'ext/fb/fb_ext.c', line 2656

static VALUE connection_indexes(VALUE self)
{
  const char *sql_indexes = "SELECT RDB$INDICES.RDB$RELATION_NAME, RDB$INDICES.RDB$INDEX_NAME, RDB$INDICES.RDB$UNIQUE_FLAG, RDB$INDICES.RDB$INDEX_TYPE "
            "FROM RDB$INDICES "
            "  JOIN RDB$RELATIONS ON RDB$INDICES.RDB$RELATION_NAME = RDB$RELATIONS.RDB$RELATION_NAME "
            "WHERE (RDB$RELATIONS.RDB$SYSTEM_FLAG <> 1 OR RDB$RELATIONS.RDB$SYSTEM_FLAG IS NULL) ";
  VALUE query_indexes = rb_str_new2(sql_indexes);
  VALUE ary_indexes = connection_query(1, &query_indexes, self);
  VALUE indexes = rb_hash_new();
  int i;
  struct FbConnection *fb_connection;
  Data_Get_Struct(self, struct FbConnection, fb_connection);

  for (i = 0; i < RARRAY_LEN(ary_indexes); i++) {
    VALUE index_struct;
    VALUE row = rb_ary_entry(ary_indexes, i);
    VALUE table_name = rb_ary_entry(row, 0);
    VALUE index_name = rb_ary_entry(row, 1);
    VALUE unique = rb_ary_entry(row, 2);
    VALUE descending = rb_ary_entry(row, 3);
    VALUE columns = connection_index_columns(self, index_name);

    rb_funcall(table_name, id_rstrip_bang, 0);
    rb_funcall(index_name, id_rstrip_bang, 0);

    if (fb_connection->downcase_names) {
      if (no_lowercase(table_name)) {
        rb_funcall(table_name, id_downcase_bang, 0);
      }
      if (no_lowercase(index_name)) {
        rb_funcall(index_name, id_downcase_bang, 0);
      }
    }

    rb_str_freeze(table_name);
    rb_str_freeze(index_name);

    unique = (unique == INT2FIX(1)) ? Qtrue : Qfalse;
    descending = (descending == INT2FIX(1)) ? Qtrue : Qfalse;

    index_struct = rb_struct_new(rb_sFbIndex, table_name, index_name, unique, descending, columns);
    rb_hash_aset(indexes, index_name, index_struct);
  }
  return indexes;
}

#open?Boolean

Current connection status.

Returns:

  • (Boolean)


1040
1041
1042
1043
1044
1045
1046
# File 'ext/fb/fb_ext.c', line 1040

static VALUE connection_is_open(VALUE self)
{
  struct FbConnection *fb_connection;

  Data_Get_Struct(self, struct FbConnection, fb_connection);
  return (fb_connection->db == 0) ? Qfalse : Qtrue;
}

#procedure_namesArray

Returns sorted array of stored procedure names in connected database.

Returns:

  • (Array)


2532
2533
2534
2535
2536
2537
# File 'ext/fb/fb_ext.c', line 2532

static VALUE connection_procedure_names(VALUE self)
{
  const char *sql = "SELECT RDB$PROCEDURE_NAME FROM RDB$PROCEDURES "
        "ORDER BY RDB$PROCEDURE_NAME";
  return connection_names(self, sql);
}

#query(: array, sql, *arg) ⇒ Array of Arrays? #query(: hash, sql, *arg) ⇒ Array of Hashes? #query(sql, *args) ⇒ Array of Arrays?

For queries returning a result set, an array is returned, containing either a list of Arrays or Hashes, one for each row.

If the sql statement performs an INSERT, UPDATE or DELETE, the number of rows affected is returned. Other statements, such as schema updates, return -1.

If no transaction is currently active, a transaction is automatically started and committed. Otherwise, the statement executes within the context of the current transaction.

Overloads:

  • #query(: array, sql, *arg) ⇒ Array of Arrays?

    Returns:

    • (Array of Arrays, nil)
  • #query(: hash, sql, *arg) ⇒ Array of Hashes?

    Returns:

    • (Array of Hashes, nil)
  • #query(sql, *args) ⇒ Array of Arrays?

    Returns:

    • (Array of Arrays, nil)


1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
# File 'ext/fb/fb_ext.c', line 1153

static VALUE connection_query(int argc, VALUE *argv, VALUE self)
{
  VALUE format;
  VALUE cursor;
  VALUE result;

  if (argc >= 1 && TYPE(argv[0]) == T_SYMBOL) {
    format = argv[0];
    argc--; argv++;
  } else {
    format = ID2SYM(rb_intern("array"));
  }
  cursor = connection_cursor(self);
  result = cursor_execute(argc, argv, cursor);
  if (NIL_P(result)) {
    result = cursor_fetchall(1, &format, cursor);
    cursor_close(cursor);
  }

  return result;
}

#role_namesArray

Returns sorted array of role names in connected database.

Returns:

  • (Array)


2521
2522
2523
2524
2525
# File 'ext/fb/fb_ext.c', line 2521

static VALUE connection_role_names(VALUE self)
{
  const char *sql = "SELECT * FROM RDB$ROLES WHERE RDB$SYSTEM_FLAG = 0 ORDER BY RDB$ROLE_NAME";
  return connection_names(self, sql);
}

#rollbacknil

Rollback the current transaction.

Returns:

  • (nil)


1024
1025
1026
1027
1028
1029
1030
1031
# File 'ext/fb/fb_ext.c', line 1024

static VALUE connection_rollback(VALUE self)
{
  struct FbConnection *fb_connection;
  Data_Get_Struct(self, struct FbConnection, fb_connection);

  fb_connection_rollback(fb_connection);
  return Qnil;
}

#table_namesArray

Returns sorted array of table names in connected database.

Returns:

  • (Array)


2482
2483
2484
2485
2486
2487
2488
# File 'ext/fb/fb_ext.c', line 2482

static VALUE connection_table_names(VALUE self)
{
  const char *sql = "SELECT RDB$RELATION_NAME FROM RDB$RELATIONS "
        "WHERE (RDB$SYSTEM_FLAG <> 1 OR RDB$SYSTEM_FLAG IS NULL) AND RDB$VIEW_BLR IS NULL "
        "ORDER BY RDB$RELATION_NAME";
  return connection_names(self, sql);
}

#to_sString

Return current database connection string and either (OPEN) or (CLOSED).

Returns:

  • (String)


1053
1054
1055
1056
1057
1058
1059
1060
# File 'ext/fb/fb_ext.c', line 1053

static VALUE connection_to_s(VALUE self)
{
  VALUE is_open = connection_is_open(self);
  VALUE status = (is_open == Qtrue) ? rb_str_new2(" (OPEN)") : rb_str_new2(" (CLOSED)");
  VALUE database = rb_iv_get(self, "@database");
  VALUE s = rb_str_dup(database);
  return rb_str_concat(s, status);
}

#transaction(options) ⇒ true #transaction(options) { ... } ⇒ Object

Start a transaction for this connection.

Overloads:

  • #transaction(options) ⇒ true

    Returns:

    • (true)
  • #transaction(options) { ... } ⇒ Object

    Yields:



967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
# File 'ext/fb/fb_ext.c', line 967

static VALUE connection_transaction(int argc, VALUE *argv, VALUE self)
{
  struct FbConnection *fb_connection;
  VALUE opt = Qnil;

  rb_scan_args(argc, argv, "01", &opt);
  Data_Get_Struct(self, struct FbConnection, fb_connection);

  fb_connection_transaction_start(fb_connection, opt);

  if (rb_block_given_p()) {
    int state;
    VALUE result = rb_protect(rb_yield, 0, &state);
    if (state) {
      fb_connection_rollback(fb_connection);
      return rb_funcall(rb_mKernel, rb_intern("raise"), 0);
    } else {
      fb_connection_commit(fb_connection);
      return result;
    }
  } else {
    return Qtrue;
    }
}

#transaction_startedBoolean

Returns true if a transaction is currently active.

Returns:

  • (Boolean)


997
998
999
1000
1001
1002
1003
# File 'ext/fb/fb_ext.c', line 997

static VALUE connection_transaction_started(VALUE self)
{
  struct FbConnection *fb_connection;
  Data_Get_Struct(self, struct FbConnection, fb_connection);

  return fb_connection->transact ? Qtrue : Qfalse;
}

#trigger_namesArray

Returns sorted array of trigger names in connected database.

Returns:

  • (Array)


2544
2545
2546
2547
2548
2549
# File 'ext/fb/fb_ext.c', line 2544

static VALUE connection_trigger_names(VALUE self)
{
  const char *sql = "SELECT RDB$TRIGGER_NAME FROM RDB$TRIGGERS "
        "ORDER BY RDB$TRIGGER_NAME";
  return connection_names(self, sql);
}

#view_namesArray

Returns sorted array of view names in connected database.

Returns:

  • (Array)


2508
2509
2510
2511
2512
2513
2514
# File 'ext/fb/fb_ext.c', line 2508

static VALUE connection_view_names(VALUE self)
{
  const char *sql = "SELECT RDB$RELATION_NAME, RDB$OWNER_NAME, RDB$VIEW_SOURCE FROM RDB$RELATIONS "
        "WHERE (RDB$SYSTEM_FLAG <> 1 OR RDB$SYSTEM_FLAG IS NULL) AND NOT RDB$VIEW_BLR IS NULL AND RDB$FLAGS = 1 "
        "ORDER BY RDB$RELATION_ID";
  return connection_names(self, sql);
}