ibm_db 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,5 +1,13 @@
1
1
  Change Log
2
2
  ==============
3
+ 2009/06/17 (IBM_DB adapter 1.1.0, driver 1.1.0) :
4
+ - Support for Activerecord's Query Cache Mechanism
5
+ - rename_column support for DB2 on LUW version 9.7, DB2 on zOS 9 and enhanced rename_column support for Informix Dynamic Server
6
+ - Support for parameterized timestamp datatype feature of DB2 on LUW Version 9.7
7
+ - Enhanced support for Bigint datatype along with support for Bigserial datatype (with client version 9.7 and above) of IDS
8
+ - Callback method handle_lobs enhanced by making it to use prepared statements completely
9
+ - Handling of exceptions during fetch operations enabled
10
+
3
11
  2009/03/24 (IBM_DB adapter 1.0.5, driver 1.0.5) :
4
12
  - Support for Ruby-1.9.1
5
13
  - Support for SQLRowcount in driver
data/README CHANGED
@@ -1,5 +1,5 @@
1
1
  =====================================================================
2
- README for the IBM_DB Adapter (1.0.5) and Driver (1.0.5) (2009/03/24)
2
+ README for the IBM_DB Adapter (1.1.0) and Driver (1.1.0) (2009/06/17)
3
3
  For ActiveRecord Version >= 1.15.5 (and Rails >= 1.2.5)
4
4
  =====================================================================
5
5
 
data/ext/ibm_db.c CHANGED
@@ -12,7 +12,7 @@
12
12
  +----------------------------------------------------------------------+
13
13
  */
14
14
 
15
- #define MODULE_RELEASE "1.0.5"
15
+ #define MODULE_RELEASE "1.1.0"
16
16
 
17
17
  #ifdef HAVE_CONFIG_H
18
18
  #include "config.h"
@@ -3315,10 +3315,25 @@ static int _ruby_ibm_db_bind_data( stmt_handle *stmt_res, param_node *curr, VALU
3315
3315
  }
3316
3316
 
3317
3317
  switch(TYPE(*bind_data)) {
3318
+ case T_BIGNUM:
3319
+ curr->svalue = rb_str2cstr(rb_big2str(*bind_data,10), &curr->ivalue);
3320
+ rc = SQLBindParameter(stmt_res->hstmt, curr->param_num,
3321
+ curr->param_type, SQL_C_CHAR, curr->data_type,
3322
+ curr->param_size, curr->scale, curr->svalue, 0, NULL);
3323
+ if ( rc == SQL_ERROR ) {
3324
+ _ruby_ibm_db_check_sql_errors(stmt_res->hstmt, SQL_HANDLE_STMT, rc, 1, NULL, -1, 1);
3325
+ }
3326
+ break;
3327
+
3318
3328
  case T_FIXNUM:
3319
- curr->ivalue = FIX2INT(*bind_data);
3329
+ curr->ivalue = FIX2LONG(*bind_data);
3330
+ if(curr->data_type == SQL_BIGINT) {
3331
+ valueType = SQL_C_DEFAULT;
3332
+ } else {
3333
+ valueType = SQL_C_LONG;
3334
+ }
3320
3335
  rc = SQLBindParameter(stmt_res->hstmt, curr->param_num,
3321
- curr->param_type, SQL_C_LONG, curr->data_type,
3336
+ curr->param_type, valueType, curr->data_type,
3322
3337
  curr->param_size, curr->scale, &curr->ivalue, 0, NULL);
3323
3338
  if ( rc == SQL_ERROR ) {
3324
3339
  _ruby_ibm_db_check_sql_errors(stmt_res->hstmt, SQL_HANDLE_STMT, rc, 1, NULL, -1, 1);
@@ -64,7 +64,8 @@ module ActiveRecord
64
64
  update_query << "(" + params.join(',') + ")"
65
65
  end
66
66
 
67
- update_query << " WHERE #{self.class.primary_key} = '#{self[self.class.primary_key.downcase]}'"
67
+ update_query << " WHERE #{self.class.primary_key} = ?"
68
+ values << self[self.class.primary_key.downcase]
68
69
 
69
70
  unless stmt = IBM_DB.prepare(connection.connection, update_query)
70
71
  error_msg = IBM_DB.conn_errormsg
@@ -441,7 +442,12 @@ module ActiveRecord
441
442
  server_info = IBM_DB.server_info( @connection )
442
443
  case server_info.DBMS_NAME
443
444
  when /DB2\//i # DB2 for Linux, Unix and Windows (LUW)
444
- @servertype = IBM_DB2_LUW.new(self)
445
+ case server_info.DBMS_VER
446
+ when /09.07/i # DB2 Version 9.7 (Cobra)
447
+ @servertype = IBM_DB2_LUW_COBRA.new(self)
448
+ else # DB2 Version 9.5 or below
449
+ @servertype = IBM_DB2_LUW.new(self)
450
+ end
445
451
  when /DB2/i # DB2 for zOS
446
452
  case server_info.DBMS_VER
447
453
  when /09/ # DB2 for zOS version 9
@@ -612,7 +618,7 @@ module ActiveRecord
612
618
  # Returns an array of hashes with the column names as keys and
613
619
  # column values as values. +sql+ is the select query,
614
620
  # and +name+ is an optional description for logging
615
- def select_all(sql, name = nil)
621
+ def select(sql, name = nil)
616
622
  # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
617
623
  sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
618
624
 
@@ -621,7 +627,15 @@ module ActiveRecord
621
627
  # IBM_DB.Statement is returned from which results can be fetched
622
628
  if stmt = execute(sql, name)
623
629
  begin
624
- @servertype.select_all(sql, name, stmt, results)
630
+ @servertype.select(sql, name, stmt, results)
631
+ rescue StandardError # Handle driver fetch errors
632
+ error_msg = IBM_DB.conn_errormsg
633
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
634
+ if error_msg && !error_msg.empty?
635
+ raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
636
+ else
637
+ raise "An unexpected error occurred during data retrieval"
638
+ end
625
639
  ensure
626
640
  # Ensures to free the resources associated with the statement
627
641
  IBM_DB.free_result stmt
@@ -644,6 +658,14 @@ module ActiveRecord
644
658
  if stmt = execute(sql, name)
645
659
  begin
646
660
  @servertype.select_rows(sql, name, stmt, results)
661
+ rescue StandardError # Handle driver fetch errors
662
+ error_msg = IBM_DB.conn_errormsg
663
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
664
+ if error_msg && !error_msg.empty?
665
+ raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
666
+ else
667
+ raise "An unexpected error occurred during data retrieval"
668
+ end
647
669
  ensure
648
670
  # Ensures to free the resources associated with the statement
649
671
  IBM_DB.free_result stmt
@@ -729,7 +751,9 @@ module ActiveRecord
729
751
  @sql = []
730
752
  @handle_lobs_triggered = false
731
753
  end
732
-
754
+
755
+ clear_query_cache if defined? clear_query_cache
756
+
733
757
  if stmt = execute(sql, name)
734
758
  begin
735
759
  @sql << sql
@@ -757,6 +781,8 @@ module ActiveRecord
757
781
  @sql = []
758
782
  @handle_lobs_triggered = false
759
783
  end
784
+
785
+ clear_query_cache if defined? clear_query_cache
760
786
 
761
787
  # Make sure the WHERE clause handles NULL's correctly
762
788
  sqlarray = sql.split(/\s*WHERE\s*/)
@@ -984,7 +1010,7 @@ module ActiveRecord
984
1010
  return super if limit.nil?
985
1011
 
986
1012
  # strip off limits on data types not supporting them
987
- if [:integer, :double, :date, :time, :timestamp, :xml].include? type.to_sym
1013
+ if @servertype.limit_not_supported_types.include? type.to_sym
988
1014
  return native_database_types[type.to_sym][:name].to_s
989
1015
  elsif type.to_sym == :boolean
990
1016
  return "smallint"
@@ -1014,6 +1040,14 @@ module ActiveRecord
1014
1040
  tables << tab["table_name"].downcase
1015
1041
  end
1016
1042
  end
1043
+ rescue StandardError # Handle driver fetch errors
1044
+ error_msg = IBM_DB.conn_errormsg
1045
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1046
+ if error_msg && !error_msg.empty?
1047
+ raise "Failed to retrieve table metadata during fetch: #{error_msg}"
1048
+ else
1049
+ raise "An unexpected error occurred during retrieval of table metadata"
1050
+ end
1017
1051
  ensure
1018
1052
  IBM_DB.free_result(stmt) # Free resources associated with the statement
1019
1053
  end
@@ -1050,7 +1084,7 @@ module ActiveRecord
1050
1084
  if stmt = IBM_DB.primary_keys( @connection, nil,
1051
1085
  @servertype.set_case(@schema),
1052
1086
  @servertype.set_case(table_name))
1053
- begin
1087
+ begin
1054
1088
  while ( pk_index_row = IBM_DB.fetch_array(stmt) )
1055
1089
  if pk_index_row[5]
1056
1090
  pk_index_name = pk_index_row[5].downcase
@@ -1062,7 +1096,15 @@ module ActiveRecord
1062
1096
  end
1063
1097
  end
1064
1098
  end
1065
- ensure # Free resources associated with the statement
1099
+ rescue StandardError # Handle driver fetch errors
1100
+ error_msg = IBM_DB.conn_errormsg
1101
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1102
+ if error_msg && !error_msg.empty?
1103
+ raise "Failed to retrieve primarykey metadata during fetch: #{error_msg}"
1104
+ else
1105
+ raise "An unexpected error occurred during retrieval of primary metadata"
1106
+ end
1107
+ ensure # Free resources associated with the statement
1066
1108
  IBM_DB.free_result(stmt) if stmt
1067
1109
  end
1068
1110
  else # Handle driver execution errors
@@ -1084,33 +1126,41 @@ module ActiveRecord
1084
1126
  if stmt = IBM_DB.statistics( @connection, nil,
1085
1127
  @servertype.set_case(@schema),
1086
1128
  @servertype.set_case(table_name), 1 )
1087
- begin
1088
- while ( index_stats = IBM_DB.fetch_array(stmt) )
1089
- is_composite = false
1090
- if index_stats[5] # INDEX_NAME
1091
- index_name = index_stats[5].downcase
1092
- index_unique = (index_stats[3] == 0)
1093
- index_columns = [index_stats[8].downcase] # COLUMN_NAME
1094
- index_qualifier = index_stats[4].downcase #Index_Qualifier
1095
- # Create an IndexDefinition object and add to the indexes array
1096
- i = 0;
1097
- indexes.each do |index|
1098
- if index.name == index_name && index_schema[i] == index_qualifier
1099
- index.columns = index.columns + index_columns
1100
- is_composite = true
1129
+ begin
1130
+ while ( index_stats = IBM_DB.fetch_array(stmt) )
1131
+ is_composite = false
1132
+ if index_stats[5] # INDEX_NAME
1133
+ index_name = index_stats[5].downcase
1134
+ index_unique = (index_stats[3] == 0)
1135
+ index_columns = [index_stats[8].downcase] # COLUMN_NAME
1136
+ index_qualifier = index_stats[4].downcase #Index_Qualifier
1137
+ # Create an IndexDefinition object and add to the indexes array
1138
+ i = 0;
1139
+ indexes.each do |index|
1140
+ if index.name == index_name && index_schema[i] == index_qualifier
1141
+ index.columns = index.columns + index_columns
1142
+ is_composite = true
1143
+ end
1144
+ i = i+1
1145
+ end
1146
+
1147
+ unless is_composite
1148
+ indexes << IndexDefinition.new(table_name, index_name, index_unique, index_columns)
1149
+ index_schema << index_qualifier
1101
1150
  end
1102
- i = i+1
1103
1151
  end
1104
-
1105
- unless is_composite
1106
- indexes << IndexDefinition.new(table_name, index_name, index_unique, index_columns)
1107
- index_schema << index_qualifier
1108
- end
1109
1152
  end
1153
+ rescue StandardError # Handle driver fetch errors
1154
+ error_msg = IBM_DB.conn_errormsg
1155
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1156
+ if error_msg && !error_msg.empty?
1157
+ raise "Failed to retrieve index metadata during fetch: #{error_msg}"
1158
+ else
1159
+ raise "An unexpected error occurred during retrieval of index metadata"
1160
+ end
1161
+ ensure # Free resources associated with the statement
1162
+ IBM_DB.free_result(stmt) if stmt
1110
1163
  end
1111
- ensure # Free resources associated with the statement
1112
- IBM_DB.free_result(stmt) if stmt
1113
- end
1114
1164
  else # Handle driver execution errors
1115
1165
  error_msg = IBM_DB.conn_errormsg
1116
1166
  error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
@@ -1348,13 +1398,25 @@ To remove the column, the table must be dropped and recreated without the #{colu
1348
1398
  end
1349
1399
  end
1350
1400
 
1351
- def select_all(sql, name, stmt, results)
1401
+ def select(sql, name, stmt, results)
1352
1402
  # Fetches all the results available. IBM_DB.fetch_assoc(stmt) returns
1353
1403
  # an hash for each single record.
1354
1404
  # The loop stops when there aren't any more valid records to fetch
1355
- while single_hash = IBM_DB.fetch_assoc(stmt)
1356
- # Add the record to the +results+ array
1357
- results << single_hash
1405
+ begin
1406
+ while single_hash = IBM_DB.fetch_assoc(stmt)
1407
+ # Add the record to the +results+ array
1408
+ results << single_hash
1409
+ end
1410
+ rescue StandardError # Handle driver fetch errors
1411
+ error_msg = IBM_DB.conn_errormsg
1412
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1413
+ if error_msg && !error_msg.empty?
1414
+ raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
1415
+ else
1416
+ raise "An unexpected error occurred during data retrieval"
1417
+ end
1418
+ ensure # Free resources associated with the statement
1419
+ IBM_DB.free_result(stmt)
1358
1420
  end
1359
1421
  end
1360
1422
 
@@ -1362,9 +1424,21 @@ To remove the column, the table must be dropped and recreated without the #{colu
1362
1424
  # Fetches all the results available. IBM_DB.fetch_array(stmt) returns
1363
1425
  # an array representing a row in a result set.
1364
1426
  # The loop stops when there aren't any more valid records to fetch
1365
- while single_array = IBM_DB.fetch_array(stmt)
1366
- #Add the array to results array
1367
- results << single_array
1427
+ begin
1428
+ while single_array = IBM_DB.fetch_array(stmt)
1429
+ #Add the array to results array
1430
+ results << single_array
1431
+ end
1432
+ rescue StandardError # Handle driver fetch errors
1433
+ error_msg = IBM_DB.conn_errormsg
1434
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1435
+ if error_msg && !error_msg.empty?
1436
+ raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
1437
+ else
1438
+ raise "An unexpected error occurred during data retrieval"
1439
+ end
1440
+ ensure # Free resources associated with the statement
1441
+ IBM_DB.free_result(stmt)
1368
1442
  end
1369
1443
  end
1370
1444
 
@@ -1418,6 +1492,10 @@ To remove the column, the table must be dropped and recreated without the #{colu
1418
1492
 
1419
1493
  def set_case(value)
1420
1494
  end
1495
+
1496
+ def limit_not_supported_types
1497
+ [:integer, :double, :date, :time, :timestamp, :xml]
1498
+ end
1421
1499
  end # class IBM_DataServer
1422
1500
 
1423
1501
  class IBM_DB2 < IBM_DataServer
@@ -1441,8 +1519,16 @@ To remove the column, the table must be dropped and recreated without the #{colu
1441
1519
  IBM_DB.fetch_row(stmt)
1442
1520
  # Retrieves and returns the result of the query with the last id.
1443
1521
  IBM_DB.result(stmt,0)
1522
+ rescue StandardError # Handle driver fetch errors
1523
+ error_msg = IBM_DB.conn_errormsg
1524
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1525
+ if error_msg && !error_msg.empty?
1526
+ raise "Failed to retrieve last generated id: #{error_msg}"
1527
+ else
1528
+ raise "An unexpected error occurred during retrieval of last generated id"
1529
+ end
1444
1530
  ensure # Free resources associated with the statement
1445
- IBM_DB.free_result stmt
1531
+ IBM_DB.free_result(stmt) if stmt
1446
1532
  end
1447
1533
  else
1448
1534
  error_msg = IBM_DB.conn_errormsg
@@ -1494,7 +1580,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1494
1580
  if !default.nil?
1495
1581
  change_column_default(table_name, column_name, default)
1496
1582
  end
1497
- reorg_table(table_name)
1583
+ #reorg_table(table_name)
1498
1584
  if !null.nil?
1499
1585
  if null
1500
1586
  change_column_sql = "ALTER TABLE #{table_name} ALTER #{column_name} DROP NOT NULL"
@@ -1528,117 +1614,139 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1528
1614
  # Fetches all the results available. IBM_DB.fetch_assoc(stmt) returns
1529
1615
  # an hash for each single record.
1530
1616
  # The loop stops when there aren't any more valid records to fetch
1531
- def select_all(sql, name, stmt, results)
1532
- if (!@offset.nil? && @offset >= 0) || (!@limit.nil? && @limit > 0)
1533
- # We know at this point that there is an offset and/or a limit
1534
- # Check if the cursor type is set correctly
1535
- cursor_type = IBM_DB.get_option stmt, IBM_DB::SQL_ATTR_CURSOR_TYPE, 0
1536
- @offset = 0 if @offset.nil?
1537
- if (cursor_type == IBM_DB::SQL_CURSOR_STATIC)
1538
- index = 0
1539
- # Get @limit rows starting at @offset
1540
- while (index < @limit)
1541
- # We increment the offset by 1 because for DB2 the offset of the initial row is 1 instead of 0
1542
- if single_hash = IBM_DB.fetch_assoc(stmt, @offset + index + 1)
1543
- # Add the record to the +results+ array
1544
- results << single_hash
1545
- index = index + 1
1546
- else
1547
- # break from the while loop
1548
- break
1549
- end
1550
- end
1551
- else # cursor != IBM_DB::SQL_CURSOR_STATIC
1552
- # If the result set contains a LOB, the cursor type will never be SQL_CURSOR_STATIC
1553
- # because DB2 does not allow this. We can't use the offset mechanism because the cursor
1554
- # is not scrollable. In this case, ignore first @offset rows and return rows starting
1555
- # at @offset to @offset + @limit
1556
- index = 0
1557
- while (index < @offset + @limit)
1558
- if single_hash = IBM_DB.fetch_assoc(stmt)
1559
- # Add the record to the +results+ array only from row @offset to @offset + @limit
1560
- if (index >= @offset)
1617
+ def select(sql, name, stmt, results)
1618
+ begin
1619
+ if (!@offset.nil? && @offset >= 0) || (!@limit.nil? && @limit > 0)
1620
+ # We know at this point that there is an offset and/or a limit
1621
+ # Check if the cursor type is set correctly
1622
+ cursor_type = IBM_DB.get_option stmt, IBM_DB::SQL_ATTR_CURSOR_TYPE, 0
1623
+ @offset = 0 if @offset.nil?
1624
+ if (cursor_type == IBM_DB::SQL_CURSOR_STATIC)
1625
+ index = 0
1626
+ # Get @limit rows starting at @offset
1627
+ while (index < @limit)
1628
+ # We increment the offset by 1 because for DB2 the offset of the initial row is 1 instead of 0
1629
+ if single_hash = IBM_DB.fetch_assoc(stmt, @offset + index + 1)
1630
+ # Add the record to the +results+ array
1561
1631
  results << single_hash
1632
+ index = index + 1
1633
+ else
1634
+ # break from the while loop
1635
+ break
1636
+ end
1637
+ end
1638
+ else # cursor != IBM_DB::SQL_CURSOR_STATIC
1639
+ # If the result set contains a LOB, the cursor type will never be SQL_CURSOR_STATIC
1640
+ # because DB2 does not allow this. We can't use the offset mechanism because the cursor
1641
+ # is not scrollable. In this case, ignore first @offset rows and return rows starting
1642
+ # at @offset to @offset + @limit
1643
+ index = 0
1644
+ while (index < @offset + @limit)
1645
+ if single_hash = IBM_DB.fetch_assoc(stmt)
1646
+ # Add the record to the +results+ array only from row @offset to @offset + @limit
1647
+ if (index >= @offset)
1648
+ results << single_hash
1649
+ end
1650
+ index = index + 1
1651
+ else
1652
+ # break from the while loop
1653
+ break
1562
1654
  end
1563
- index = index + 1
1564
- else
1565
- # break from the while loop
1566
- break
1567
1655
  end
1568
1656
  end
1657
+ # This is the case where limit is set to zero
1658
+ # Simply return an empty +results+
1659
+ elsif (!@limit.nil? && @limit == 0)
1660
+ results
1661
+ # No limits or offsets specified
1662
+ else
1663
+ while single_hash = IBM_DB.fetch_assoc(stmt)
1664
+ # Add the record to the +results+ array
1665
+ results << single_hash
1666
+ end
1569
1667
  end
1570
- # This is the case where limit is set to zero
1571
- # Simply return an empty +results+
1572
- elsif (!@limit.nil? && @limit == 0)
1573
- results
1574
- # No limits or offsets specified
1575
- else
1576
- while single_hash = IBM_DB.fetch_assoc(stmt)
1577
- # Add the record to the +results+ array
1578
- results << single_hash
1668
+ rescue StandardError # Handle driver fetch errors
1669
+ error_msg = IBM_DB.conn_errormsg
1670
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1671
+ if error_msg && !error_msg.empty?
1672
+ raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
1673
+ else
1674
+ raise "An unexpected error occurred during data retrieval"
1579
1675
  end
1676
+ ensure
1677
+ # Assign the instance variables to nil. We will not be using them again
1678
+ @offset = nil
1679
+ @limit = nil
1580
1680
  end
1581
- # Assign the instance variables to nil. We will not be using them again
1582
- @offset = nil
1583
- @limit = nil
1584
1681
  end
1585
1682
 
1586
1683
  # Fetches all the results available. IBM_DB.fetch_array(stmt) returns
1587
1684
  # an array for each single record.
1588
1685
  # The loop stops when there aren't any more valid records to fetch
1589
1686
  def select_rows(sql, name, stmt, results)
1590
- if (!@offset.nil? && @offset >= 0) || (!@limit.nil? && @limit > 0)
1591
- # We know at this point that there is an offset and/or a limit
1592
- # Check if the cursor type is set correctly
1593
- cursor_type = IBM_DB.get_option stmt, IBM_DB::SQL_ATTR_CURSOR_TYPE, 0
1594
- @offset = 0 if @offset.nil?
1595
- if (cursor_type == IBM_DB::SQL_CURSOR_STATIC)
1596
- index = 0
1597
- # Get @limit rows starting at @offset
1598
- while (index < @limit)
1599
- # We increment the offset by 1 because for DB2 the offset of the initial row is 1 instead of 0
1600
- if single_array = IBM_DB.fetch_array(stmt, @offset + index + 1)
1601
- # Add the array to the +results+ array
1602
- results << single_array
1603
- index = index + 1
1604
- else
1605
- # break from the while loop
1606
- break
1607
- end
1608
- end
1609
- else # cursor != IBM_DB::SQL_CURSOR_STATIC
1610
- # If the result set contains a LOB, the cursor type will never be SQL_CURSOR_STATIC
1611
- # because DB2 does not allow this. We can't use the offset mechanism because the cursor
1612
- # is not scrollable. In this case, ignore first @offset rows and return rows starting
1613
- # at @offset to @offset + @limit
1614
- index = 0
1615
- while (index < @offset + @limit)
1616
- if single_array = IBM_DB.fetch_array(stmt)
1617
- # Add the array to the +results+ array only from row @offset to @offset + @limit
1618
- if (index >= @offset)
1687
+ begin
1688
+ if (!@offset.nil? && @offset >= 0) || (!@limit.nil? && @limit > 0)
1689
+ # We know at this point that there is an offset and/or a limit
1690
+ # Check if the cursor type is set correctly
1691
+ cursor_type = IBM_DB.get_option stmt, IBM_DB::SQL_ATTR_CURSOR_TYPE, 0
1692
+ @offset = 0 if @offset.nil?
1693
+ if (cursor_type == IBM_DB::SQL_CURSOR_STATIC)
1694
+ index = 0
1695
+ # Get @limit rows starting at @offset
1696
+ while (index < @limit)
1697
+ # We increment the offset by 1 because for DB2 the offset of the initial row is 1 instead of 0
1698
+ if single_array = IBM_DB.fetch_array(stmt, @offset + index + 1)
1699
+ # Add the array to the +results+ array
1619
1700
  results << single_array
1701
+ index = index + 1
1702
+ else
1703
+ # break from the while loop
1704
+ break
1620
1705
  end
1621
- index = index + 1
1622
- else
1623
- # break from the while loop
1624
- break
1625
1706
  end
1707
+ else # cursor != IBM_DB::SQL_CURSOR_STATIC
1708
+ # If the result set contains a LOB, the cursor type will never be SQL_CURSOR_STATIC
1709
+ # because DB2 does not allow this. We can't use the offset mechanism because the cursor
1710
+ # is not scrollable. In this case, ignore first @offset rows and return rows starting
1711
+ # at @offset to @offset + @limit
1712
+ index = 0
1713
+ while (index < @offset + @limit)
1714
+ if single_array = IBM_DB.fetch_array(stmt)
1715
+ # Add the array to the +results+ array only from row @offset to @offset + @limit
1716
+ if (index >= @offset)
1717
+ results << single_array
1718
+ end
1719
+ index = index + 1
1720
+ else
1721
+ # break from the while loop
1722
+ break
1723
+ end
1724
+ end
1725
+ end
1726
+ # This is the case where limit is set to zero
1727
+ # Simply return an empty +results+
1728
+ elsif (!@limit.nil? && @limit == 0)
1729
+ results
1730
+ # No limits or offsets specified
1731
+ else
1732
+ while single_array = IBM_DB.fetch_array(stmt)
1733
+ # Add the array to the +results+ array
1734
+ results << single_array
1626
1735
  end
1627
1736
  end
1628
- # This is the case where limit is set to zero
1629
- # Simply return an empty +results+
1630
- elsif (!@limit.nil? && @limit == 0)
1631
- results
1632
- # No limits or offsets specified
1633
- else
1634
- while single_array = IBM_DB.fetch_array(stmt)
1635
- # Add the array to the +results+ array
1636
- results << single_array
1737
+ rescue StandardError # Handle driver fetch errors
1738
+ error_msg = IBM_DB.conn_errormsg
1739
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1740
+ if error_msg && !error_msg.empty?
1741
+ raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
1742
+ else
1743
+ raise "An unexpected error occurred during data retrieval"
1637
1744
  end
1745
+ ensure
1746
+ # Assign the instance variables to nil. We will not be using them again
1747
+ @offset = nil
1748
+ @limit = nil
1638
1749
  end
1639
- # Assign the instance variables to nil. We will not be using them again
1640
- @offset = nil
1641
- @limit = nil
1642
1750
  end
1643
1751
 
1644
1752
  def execute(sql, name = nil)
@@ -1734,6 +1842,51 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1734
1842
  end
1735
1843
  end # class IBM_DB2_LUW
1736
1844
 
1845
+ class IBM_DB2_LUW_COBRA < IBM_DB2_LUW
1846
+ # Cobra supports parameterised timestamp,
1847
+ # hence overriding following method to allow timestamp datatype to be parameterised
1848
+ def limit_not_supported_types
1849
+ [:integer, :double, :date, :time, :xml]
1850
+ end
1851
+
1852
+ # Alter table column for renaming a column
1853
+ # This feature is supported for against DB2 V97 and above only
1854
+ def rename_column(table_name, column_name, new_column_name)
1855
+ _table_name = table_name.to_s
1856
+ _column_name = column_name.to_s
1857
+ _new_column_name = new_column_name.to_s
1858
+
1859
+ nil_condition = _table_name.nil? || _column_name.nil? || _new_column_name.nil?
1860
+ empty_condition = _table_name.empty? ||
1861
+ _column_name.empty? ||
1862
+ _new_column_name.empty? unless nil_condition
1863
+
1864
+ if nil_condition || empty_condition
1865
+ raise ArgumentError,"One of the arguments passed to rename_column is empty or nil"
1866
+ end
1867
+
1868
+ begin
1869
+ rename_column_sql = "ALTER TABLE #{_table_name} RENAME COLUMN #{_column_name} \
1870
+ TO #{_new_column_name}"
1871
+
1872
+ unless stmt = execute(rename_column_sql)
1873
+ error_msg = IBM_DB.conn_errormsg
1874
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1875
+ if error_msg && !error_msg.empty?
1876
+ raise "Rename column failed : #{error_msg}"
1877
+ else
1878
+ raise StandardError.new('An unexpected error occurred during renaming the column')
1879
+ end
1880
+ end
1881
+
1882
+ reorg_table(_table_name)
1883
+
1884
+ ensure
1885
+ IBM_DB.free_stmt stmt if stmt
1886
+ end #End of begin
1887
+ end # End of rename_column
1888
+ end #IBM_DB2_LUW_COBRA
1889
+
1737
1890
  module HostedDataServer
1738
1891
  require 'pathname'
1739
1892
  #find DB2-i5-zOS rezerved words file relative path
@@ -1763,6 +1916,42 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1763
1916
  "remove_column is not supported by the DB2 for zOS data server"
1764
1917
  end
1765
1918
 
1919
+ #Alter table column for renaming a column
1920
+ def rename_column(table_name, column_name, new_column_name)
1921
+ _table_name = table_name.to_s
1922
+ _column_name = column_name.to_s
1923
+ _new_column_name = new_column_name.to_s
1924
+
1925
+ nil_condition = _table_name.nil? || _column_name.nil? || _new_column_name.nil?
1926
+ empty_condition = _table_name.empty? ||
1927
+ _column_name.empty? ||
1928
+ _new_column_name.empty? unless nil_condition
1929
+
1930
+ if nil_condition || empty_condition
1931
+ raise ArgumentError,"One of the arguments passed to rename_column is empty or nil"
1932
+ end
1933
+
1934
+ begin
1935
+ rename_column_sql = "ALTER TABLE #{_table_name} RENAME COLUMN #{_column_name} \
1936
+ TO #{_new_column_name}"
1937
+
1938
+ unless stmt = execute(rename_column_sql)
1939
+ error_msg = IBM_DB.conn_errormsg
1940
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1941
+ if error_msg && !error_msg.empty?
1942
+ raise "Rename column failed : #{error_msg}"
1943
+ else
1944
+ raise StandardError.new('An unexpected error occurred during renaming the column')
1945
+ end
1946
+ end
1947
+
1948
+ reorg_table(_table_name)
1949
+
1950
+ ensure
1951
+ IBM_DB.free_stmt stmt if stmt
1952
+ end #End of begin
1953
+ end # End of rename_column
1954
+
1766
1955
  # DB2 z/OS only allows NULL or "" (empty) string as DEFAULT value for a BLOB column.
1767
1956
  # For non-empty string and non-NULL values, the server returns error
1768
1957
  def set_binary_default(value)
@@ -1795,6 +1984,10 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1795
1984
  execute "SET CURRENT RULES = 'STD'"
1796
1985
  end
1797
1986
 
1987
+ def rename_column(table_name, column_name, new_column_name)
1988
+ raise NotImplementedError, "rename_column is not implemented for DB2 on zOS 8"
1989
+ end
1990
+
1798
1991
  def change_column_default(table_name, column_name, default)
1799
1992
  raise NotImplementedError,
1800
1993
  "DB2 for zOS data server version 8 does not support changing the column default"
@@ -1811,9 +2004,41 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1811
2004
  def set_schema(schema)
1812
2005
  end
1813
2006
 
2007
+ # IDS specific ALTER TABLE statement to rename a column
1814
2008
  def rename_column(table_name, column_name, new_column_name)
1815
- execute "RENAME COLUMN #{table_name}.#{column_name} TO #{new_column_name}"
1816
- end
2009
+ _table_name = table_name.to_s
2010
+ _column_name = column_name.to_s
2011
+ _new_column_name = new_column_name.to_s
2012
+
2013
+ nil_condition = _table_name.nil? || _column_name.nil? || _new_column_name.nil?
2014
+ empty_condition = _table_name.empty? ||
2015
+ _column_name.empty? ||
2016
+ _new_column_name.empty? unless nil_condition
2017
+
2018
+ if nil_condition || empty_condition
2019
+ raise ArgumentError,"One of the arguments passed to rename_column is empty or nil"
2020
+ end
2021
+
2022
+ begin
2023
+ rename_column_sql = "RENAME COLUMN #{table_name}.#{column_name} TO \
2024
+ #{new_column_name}"
2025
+
2026
+ unless stmt = execute(rename_column_sql)
2027
+ error_msg = IBM_DB.conn_errormsg
2028
+ error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
2029
+ if error_msg && !error_msg.empty?
2030
+ raise "Rename column failed : #{error_msg}"
2031
+ else
2032
+ raise StandardError.new('An unexpected error occurred during renaming the column')
2033
+ end
2034
+ end
2035
+
2036
+ reorg_table(_table_name)
2037
+
2038
+ ensure
2039
+ IBM_DB.free_stmt stmt if stmt
2040
+ end #End of begin
2041
+ end # End of rename_column
1817
2042
 
1818
2043
  def primary_key
1819
2044
  return "SERIAL(100) PRIMARY KEY"
@@ -28,6 +28,14 @@ if ActiveRecord::Base.connection.supports_migrations?
28
28
  class MigrationTest < ActiveRecord::TestCase
29
29
  self.use_transactional_fixtures = false
30
30
 
31
+ if (current_adapter?(:IBM_DBAdapter))
32
+ #Rename is supported only for server zOS 9 , DB2 COBRA and Informix
33
+ server_type = ActiveRecord::Base.connection.servertype.class.name
34
+ @ibm_db_rename_supported = server_type.include?('::IBM_DB2_LUW_COBRA') ||
35
+ server_type.class.name.include?('::IBM_IDS') ||
36
+ (server_type.include?('IBM_DB2_ZOS') && !server_type.include?('IBM_DB2_ZOS_8'))
37
+ end
38
+
31
39
  fixtures :people
32
40
 
33
41
  def setup
@@ -556,109 +564,111 @@ if ActiveRecord::Base.connection.supports_migrations?
556
564
  assert !Person.column_methods_hash.include?(:last_name)
557
565
  end
558
566
 
559
- unless current_adapter?(:IBM_DBAdapter) # rename not supported
560
- def test_add_rename
561
- Person.delete_all
567
+ if (!current_adapter?(:IBM_DBAdapter) || @ibm_db_rename_supported)
568
+ def test_add_rename
569
+ Person.delete_all
562
570
 
563
- begin
564
- Person.connection.add_column "people", "girlfriend", :string
565
- Person.reset_column_information
566
- Person.create :girlfriend => 'bobette'
571
+ begin
572
+ Person.connection.add_column "people", "girlfriend", :string
573
+ Person.reset_column_information
574
+ Person.create :girlfriend => 'bobette'
567
575
 
568
- Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
576
+ Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
569
577
 
570
- Person.reset_column_information
571
- bob = Person.find(:first)
578
+ Person.reset_column_information
579
+ bob = Person.find(:first)
572
580
 
573
- assert_equal "bobette", bob.exgirlfriend
574
- ensure
575
- Person.connection.remove_column("people", "girlfriend") rescue nil
576
- Person.connection.remove_column("people", "exgirlfriend") rescue nil
577
- end
581
+ assert_equal "bobette", bob.exgirlfriend
582
+ ensure
583
+ Person.connection.remove_column("people", "girlfriend") rescue nil
584
+ Person.connection.remove_column("people", "exgirlfriend") rescue nil
585
+ end
578
586
 
579
- end
587
+ end
580
588
 
581
- def test_rename_column_using_symbol_arguments
582
- begin
583
- names_before = Person.find(:all).map(&:first_name)
584
- Person.connection.rename_column :people, :first_name, :nick_name
585
- Person.reset_column_information
586
- assert Person.column_names.include?("nick_name")
587
- assert_equal names_before, Person.find(:all).map(&:nick_name)
588
- ensure
589
- Person.connection.remove_column("people","nick_name")
590
- Person.connection.add_column("people","first_name", :string)
589
+ def test_rename_column_using_symbol_arguments
590
+ begin
591
+ names_before = Person.find(:all).map(&:first_name)
592
+ Person.connection.rename_column :people, :first_name, :nick_name
593
+ Person.reset_column_information
594
+ assert Person.column_names.include?("nick_name")
595
+ assert_equal names_before, Person.find(:all).map(&:nick_name)
596
+ ensure
597
+ Person.connection.remove_column("people","nick_name")
598
+ Person.connection.add_column("people","first_name", :string)
599
+ end
591
600
  end
592
- end
593
601
 
594
- def test_rename_column
595
- begin
596
- names_before = Person.find(:all).map(&:first_name)
597
- Person.connection.rename_column "people", "first_name", "nick_name"
598
- Person.reset_column_information
599
- assert Person.column_names.include?("nick_name")
600
- assert_equal names_before, Person.find(:all).map(&:nick_name)
601
- ensure
602
- Person.connection.remove_column("people","nick_name")
603
- Person.connection.add_column("people","first_name", :string)
602
+ def test_rename_column
603
+ begin
604
+ names_before = Person.find(:all).map(&:first_name)
605
+ Person.connection.rename_column "people", "first_name", "nick_name"
606
+ Person.reset_column_information
607
+ assert Person.column_names.include?("nick_name")
608
+ assert_equal names_before, Person.find(:all).map(&:nick_name)
609
+ ensure
610
+ Person.connection.remove_column("people","nick_name")
611
+ Person.connection.add_column("people","first_name", :string)
612
+ end
604
613
  end
605
- end
606
614
 
607
- def test_rename_column_preserves_default_value_not_null
608
- begin
609
- default_before = Developer.connection.columns("developers").find { |c| c.name == "salary" }.default
610
- assert_equal 70000, default_before
611
- Developer.connection.rename_column "developers", "salary", "anual_salary"
612
- Developer.reset_column_information
613
- assert Developer.column_names.include?("anual_salary")
614
- default_after = Developer.connection.columns("developers").find { |c| c.name == "anual_salary" }.default
615
- assert_equal 70000, default_after
616
- ensure
617
- Developer.connection.rename_column "developers", "anual_salary", "salary"
618
- Developer.reset_column_information
615
+ def test_rename_column_preserves_default_value_not_null
616
+ begin
617
+ default_before = Developer.connection.columns("developers").find { |c| c.name == "salary" }.default
618
+ assert_equal 70000, default_before
619
+ Developer.connection.rename_column "developers", "salary", "anual_salary"
620
+ Developer.reset_column_information
621
+ assert Developer.column_names.include?("anual_salary")
622
+ default_after = Developer.connection.columns("developers").find { |c| c.name == "anual_salary" }.default
623
+ assert_equal 70000, default_after
624
+ ensure
625
+ Developer.connection.rename_column "developers", "anual_salary", "salary"
626
+ Developer.reset_column_information
627
+ end
619
628
  end
620
- end
621
629
 
622
- def test_rename_nonexistent_column
623
- ActiveRecord::Base.connection.create_table(:hats) do |table|
624
- table.column :hat_name, :string, :default => nil
625
- end
626
- exception = if current_adapter?(:PostgreSQLAdapter)
627
- ActiveRecord::StatementInvalid
628
- else
629
- ActiveRecord::ActiveRecordError
630
- end
631
- assert_raise(exception) do
632
- Person.connection.rename_column "hats", "nonexistent", "should_fail"
630
+ def test_rename_nonexistent_column
631
+ ActiveRecord::Base.connection.create_table(:hats) do |table|
632
+ table.column :hat_name, :string, :default => nil
633
+ end
634
+ exception = if current_adapter?(:PostgreSQLAdapter)
635
+ ActiveRecord::StatementInvalid
636
+ else
637
+ ActiveRecord::ActiveRecordError
638
+ end
639
+ assert_raise(exception) do
640
+ Person.connection.rename_column "hats", "nonexistent", "should_fail"
641
+ end
642
+ ensure
643
+ ActiveRecord::Base.connection.drop_table(:hats)
633
644
  end
634
- ensure
635
- ActiveRecord::Base.connection.drop_table(:hats)
636
- end
637
645
 
638
- def test_rename_column_with_sql_reserved_word
639
- begin
640
- assert_nothing_raised { Person.connection.rename_column "people", "first_name", "group" }
641
- Person.reset_column_information
642
- assert Person.column_names.include?("group")
643
- ensure
644
- Person.connection.remove_column("people", "group") rescue nil
645
- Person.connection.add_column("people", "first_name", :string) rescue nil
646
+ def test_rename_column_with_sql_reserved_word
647
+ begin
648
+ assert_nothing_raised { Person.connection.rename_column "people", "first_name", "group" }
649
+ Person.reset_column_information
650
+ assert Person.column_names.include?("group")
651
+ ensure
652
+ Person.connection.remove_column("people", "group") rescue nil
653
+ Person.connection.add_column("people", "first_name", :string) rescue nil
654
+ end
646
655
  end
647
656
  end
648
657
 
649
- def test_rename_column_with_an_index
650
- ActiveRecord::Base.connection.create_table(:hats) do |table|
651
- table.column :hat_name, :string, :limit => 100
652
- table.column :hat_size, :integer
653
- end
654
- Person.connection.add_index :hats, :hat_name
655
- assert_nothing_raised do
656
- Person.connection.rename_column "hats", "hat_name", "name"
658
+ unless (current_adapter?(:IBM_DBAdapter)) #Cannot alter a object when there is another object depending on it
659
+ def test_rename_column_with_an_index
660
+ ActiveRecord::Base.connection.create_table(:hats) do |table|
661
+ table.column :hat_name, :string, :limit => 100
662
+ table.column :hat_size, :integer
663
+ end
664
+ Person.connection.add_index :hats, :hat_name
665
+ assert_nothing_raised do
666
+ Person.connection.rename_column "hats", "hat_name", "name"
667
+ end
668
+ ensure
669
+ ActiveRecord::Base.connection.drop_table(:hats)
657
670
  end
658
- ensure
659
- ActiveRecord::Base.connection.drop_table(:hats)
660
- end
661
- end
671
+ end
662
672
 
663
673
  def test_remove_column_with_index
664
674
  ActiveRecord::Base.connection.create_table(:hats) do |table|
@@ -672,30 +682,32 @@ if ActiveRecord::Base.connection.supports_migrations?
672
682
  ActiveRecord::Base.connection.drop_table(:hats)
673
683
  end
674
684
 
675
- def test_remove_column_with_multi_column_index
676
- ActiveRecord::Base.connection.create_table(:hats) do |table|
677
- table.column :hat_name, :string, :limit => 100
678
- table.column :hat_size, :integer
679
- table.column :hat_style, :string, :limit => 100
680
- end
681
- ActiveRecord::Base.connection.add_index "hats", ["hat_style", "hat_size"], :unique => true
685
+ unless (current_adapter?(:IBM_DBAdapter)) #Cannot alter a object when there is another object depending on it
686
+ def test_remove_column_with_multi_column_index
687
+ ActiveRecord::Base.connection.create_table(:hats) do |table|
688
+ table.column :hat_name, :string, :limit => 100
689
+ table.column :hat_size, :integer
690
+ table.column :hat_style, :string, :limit => 100
691
+ end
692
+ ActiveRecord::Base.connection.add_index "hats", ["hat_style", "hat_size"], :unique => true
682
693
 
683
- assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
684
- ensure
685
- ActiveRecord::Base.connection.drop_table(:hats)
694
+ assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
695
+ ensure
696
+ ActiveRecord::Base.connection.drop_table(:hats)
697
+ end
686
698
  end
687
699
 
688
- unless current_adapter?(:IBM_DBAdapter) #incompatible types changes
689
- def test_change_type_of_not_null_column
690
- assert_nothing_raised do
691
- Topic.connection.change_column "topics", "written_on", :datetime, :null => false
692
- Topic.reset_column_information
700
+ unless current_adapter?(:IBM_DBAdapter) #incompatible types changes
701
+ def test_change_type_of_not_null_column
702
+ assert_nothing_raised do
703
+ Topic.connection.change_column "topics", "written_on", :datetime, :null => false
704
+ Topic.reset_column_information
693
705
 
694
- Topic.connection.change_column "topics", "written_on", :datetime, :null => false
695
- Topic.reset_column_information
706
+ Topic.connection.change_column "topics", "written_on", :datetime, :null => false
707
+ Topic.reset_column_information
708
+ end
696
709
  end
697
- end
698
- end
710
+ end
699
711
 
700
712
  def test_rename_table
701
713
  begin
@@ -844,7 +856,7 @@ if ActiveRecord::Base.connection.supports_migrations?
844
856
  assert_equal false, person_klass.columns_hash["wealth"].null
845
857
 
846
858
  # rename column to see that column doesn't lose its not null and/or default definition
847
- unless current_adapter?(:IBM_DBAdapter) #rename_column is not implemented in IBM_DBAdapetr
859
+ if (!current_adapter?(:IBM_DBAdapter) || @ibm_db_rename_supported)
848
860
  person_klass.connection.rename_column "testings", "wealth", "money"
849
861
  person_klass.reset_column_information
850
862
  assert_nil person_klass.columns_hash["wealth"]
@@ -853,7 +865,7 @@ if ActiveRecord::Base.connection.supports_migrations?
853
865
  end
854
866
 
855
867
  # change column
856
- unless current_adapter?(:IBM_DBAdapter)
868
+ unless (current_adapter?(:IBM_DBAdapter) && !@ibm_db_rename_supported)
857
869
  person_klass.connection.change_column "testings", "money", :integer, :null => false, :default => 1000
858
870
  person_klass.reset_column_information
859
871
  assert_equal 1000, person_klass.columns_hash["money"].default
@@ -866,7 +878,7 @@ if ActiveRecord::Base.connection.supports_migrations?
866
878
  end
867
879
 
868
880
  # change column, make it nullable and clear default
869
- unless current_adapter?(:IBM_DBAdapter)
881
+ unless (current_adapter?(:IBM_DBAdapter) && !@ibm_db_rename_supported)
870
882
  person_klass.connection.change_column "testings", "money", :integer, :null => true, :default => nil
871
883
  person_klass.reset_column_information
872
884
  assert_nil person_klass.columns_hash["money"].default
@@ -879,7 +891,7 @@ if ActiveRecord::Base.connection.supports_migrations?
879
891
  end
880
892
 
881
893
  # change_column_null, make it not nullable and set null values to a default value
882
- unless current_adapter?(:IBM_DBAdapter)
894
+ unless (current_adapter?(:IBM_DBAdapter) && !@ibm_db_rename_supported)
883
895
  person_klass.connection.execute('UPDATE testings SET money = NULL')
884
896
  person_klass.connection.change_column_null "testings", "money", false, 2000
885
897
  person_klass.reset_column_information
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ibm_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - IBM
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-24 00:00:00 +05:30
12
+ date: 2009-06-16 00:00:00 +05:30
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -34,48 +34,31 @@ extra_rdoc_files:
34
34
  - MANIFEST
35
35
  files:
36
36
  - README
37
- - lib
38
- - lib/active_record
39
- - lib/active_record/connection_adapters
40
37
  - lib/active_record/connection_adapters/ibm_db_adapter.rb
41
- - lib/active_record/vendor
42
38
  - lib/active_record/vendor/db2-i5-zOS.yaml
43
39
  - lib/IBM_DB.rb
44
- - test
45
- - test/connections
46
- - test/connections/native_ibm_db
47
40
  - test/connections/native_ibm_db/connection.rb
48
- - test/models
49
41
  - test/models/warehouse_thing.rb
50
- - test/cases
51
42
  - test/cases/finder_test.rb
52
43
  - test/cases/attribute_methods_test.rb
53
44
  - test/cases/schema_dumper_test.rb
54
45
  - test/cases/validations_test.rb
55
46
  - test/cases/fixtures_test.rb
56
47
  - test/cases/calculations_test.rb
57
- - test/cases/query_cache_test.rb
58
48
  - test/cases/migration_test.rb
59
49
  - test/cases/base_test.rb
60
- - test/cases/associations
61
50
  - test/cases/associations/has_many_through_associations_test.rb
62
51
  - test/cases/associations/has_and_belongs_to_many_associations_test.rb
63
52
  - test/cases/associations/eager_test.rb
64
53
  - test/cases/associations/cascaded_eager_loading_test.rb
65
54
  - test/cases/associations/join_model_test.rb
66
55
  - test/cases/adapter_test.rb
67
- - test/schema
68
- - test/schema/zOS
69
56
  - test/schema/zOS/ibm_db_specific_schema.rb
70
- - test/schema/ids
71
57
  - test/schema/ids/ibm_db_specific_schema.rb
72
- - test/schema/i5
73
58
  - test/schema/i5/ibm_db_specific_schema.rb
74
59
  - test/schema/schema.rb
75
- - test/schema/luw
76
60
  - test/schema/luw/ibm_db_specific_schema.rb
77
61
  - test/ibm_db_test.rb
78
- - ext
79
62
  - ext/ruby_ibm_db.h
80
63
  - ext/Makefile.nt32
81
64
  - ext/extconf.rb
@@ -86,6 +69,8 @@ files:
86
69
  - MANIFEST
87
70
  has_rdoc: true
88
71
  homepage: http://rubyforge.org/projects/rubyibm/
72
+ licenses: []
73
+
89
74
  post_install_message:
90
75
  rdoc_options: []
91
76
 
@@ -106,9 +91,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
91
  requirements:
107
92
  - ActiveRecord, at least 1.15.1
108
93
  rubyforge_project: rubyibm
109
- rubygems_version: 1.3.1
94
+ rubygems_version: 1.3.3
110
95
  signing_key:
111
- specification_version: 2
96
+ specification_version: 3
112
97
  summary: "Rails Driver and Adapter for IBM Data Servers: {DB2 on Linux/Unix/Windows, DB2 on zOS, DB2 on i5/OS, Informix (IDS)}"
113
98
  test_files:
114
99
  - test/ibm_db_test.rb
@@ -1,124 +0,0 @@
1
- require "cases/helper"
2
- require 'models/topic'
3
- require 'models/reply'
4
- require 'models/task'
5
- require 'models/course'
6
- require 'models/category'
7
- require 'models/post'
8
-
9
- unless current_adapter?(:IBM_DBAdapter)
10
- class QueryCacheTest < ActiveRecord::TestCase
11
- fixtures :tasks, :topics, :categories, :posts, :categories_posts
12
-
13
- def test_find_queries
14
- assert_queries(2) { Task.find(1); Task.find(1) }
15
- end
16
-
17
- def test_find_queries_with_cache
18
- Task.cache do
19
- assert_queries(1) { Task.find(1); Task.find(1) }
20
- end
21
- end
22
-
23
- def test_count_queries_with_cache
24
- Task.cache do
25
- assert_queries(1) { Task.count; Task.count }
26
- end
27
- end
28
-
29
- def test_query_cache_dups_results_correctly
30
- Task.cache do
31
- now = Time.now.utc
32
- task = Task.find 1
33
- assert_not_equal now, task.starting
34
- task.starting = now
35
- task.reload
36
- assert_not_equal now, task.starting
37
- end
38
- end
39
-
40
- def test_cache_is_flat
41
- Task.cache do
42
- Topic.columns # don't count this query
43
- assert_queries(1) { Topic.find(1); Topic.find(1); }
44
- end
45
-
46
- ActiveRecord::Base.cache do
47
- assert_queries(1) { Task.find(1); Task.find(1) }
48
- end
49
- end
50
-
51
- def test_cache_does_not_wrap_string_results_in_arrays
52
- Task.cache do
53
- assert_instance_of String, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
54
- end
55
- end
56
- end
57
-
58
- class QueryCacheExpiryTest < ActiveRecord::TestCase
59
- fixtures :tasks, :posts, :categories, :categories_posts
60
-
61
- def test_find
62
- Task.connection.expects(:clear_query_cache).times(1)
63
-
64
- assert !Task.connection.query_cache_enabled
65
- Task.cache do
66
- assert Task.connection.query_cache_enabled
67
- Task.find(1)
68
-
69
- Task.uncached do
70
- assert !Task.connection.query_cache_enabled
71
- Task.find(1)
72
- end
73
-
74
- assert Task.connection.query_cache_enabled
75
- end
76
- assert !Task.connection.query_cache_enabled
77
- end
78
-
79
- def test_update
80
- Task.connection.expects(:clear_query_cache).times(2)
81
-
82
- Task.cache do
83
- task = Task.find(1)
84
- task.starting = Time.now.utc
85
- task.save!
86
- end
87
- end
88
-
89
- def test_destroy
90
- Task.connection.expects(:clear_query_cache).times(2)
91
-
92
- Task.cache do
93
- Task.find(1).destroy
94
- end
95
- end
96
-
97
- def test_insert
98
- ActiveRecord::Base.connection.expects(:clear_query_cache).times(2)
99
-
100
- Task.cache do
101
- Task.create!
102
- end
103
- end
104
-
105
- def test_cache_is_expired_by_habtm_update
106
- ActiveRecord::Base.connection.expects(:clear_query_cache).times(2)
107
- ActiveRecord::Base.cache do
108
- c = Category.find(:first)
109
- p = Post.find(:first)
110
- p.categories << c
111
- end
112
- end
113
-
114
- def test_cache_is_expired_by_habtm_delete
115
- ActiveRecord::Base.connection.expects(:clear_query_cache).times(2)
116
- ActiveRecord::Base.cache do
117
- c = Category.find(1)
118
- p = Post.find(1)
119
- assert p.categories.any?
120
- p.categories.delete_all
121
- end
122
- end
123
- end
124
- end