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 +8 -0
- data/README +1 -1
- data/ext/ibm_db.c +18 -3
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +358 -133
- data/test/cases/migration_test.rb +120 -108
- metadata +6 -21
- data/test/cases/query_cache_test.rb +0 -124
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
|
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
|
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 =
|
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,
|
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} =
|
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
|
-
|
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
|
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.
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
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
|
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
|
-
|
1356
|
-
|
1357
|
-
|
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
|
-
|
1366
|
-
|
1367
|
-
|
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
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
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
|
-
#
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
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
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
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
|
-
#
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
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
|
-
|
1816
|
-
|
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
|
-
|
560
|
-
|
561
|
-
|
567
|
+
if (!current_adapter?(:IBM_DBAdapter) || @ibm_db_rename_supported)
|
568
|
+
def test_add_rename
|
569
|
+
Person.delete_all
|
562
570
|
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
571
|
+
begin
|
572
|
+
Person.connection.add_column "people", "girlfriend", :string
|
573
|
+
Person.reset_column_information
|
574
|
+
Person.create :girlfriend => 'bobette'
|
567
575
|
|
568
|
-
|
576
|
+
Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
|
569
577
|
|
570
|
-
|
571
|
-
|
578
|
+
Person.reset_column_information
|
579
|
+
bob = Person.find(:first)
|
572
580
|
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
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
|
-
|
587
|
+
end
|
580
588
|
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
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
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
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
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
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
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
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
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
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
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
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
|
-
|
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
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
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
|
-
|
684
|
-
|
685
|
-
|
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
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
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
|
-
|
695
|
-
|
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
|
-
|
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
|
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-
|
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.
|
94
|
+
rubygems_version: 1.3.3
|
110
95
|
signing_key:
|
111
|
-
specification_version:
|
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
|