ibm_db 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +5 -0
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +87 -96
- metadata +2 -2
data/CHANGES
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
Change Log
|
2
2
|
==============
|
3
3
|
|
4
|
+
2007/11/30 (IBM_DB adapter 0.9.2, driver 0.9.1):
|
5
|
+
- Lifted index length limitation (18 chars) and fixed multiple index creation
|
6
|
+
- Fixed [#13294] limit/offset breaks subselect in db2 adapter
|
7
|
+
- Fixed error handling for metadata retrieval (tables, columns, indexes)
|
8
|
+
|
4
9
|
2007/11/07 (IBM_DB adapter 0.9.1, driver 0.9.1):
|
5
10
|
- Fixed ibm_db driver VC80 runtime issue on Windows
|
6
11
|
|
@@ -62,13 +62,22 @@ module ActiveRecord
|
|
62
62
|
end
|
63
63
|
update_query << " WHERE #{self.class.primary_key} = #{id}"
|
64
64
|
|
65
|
-
stmt = IBM_DB::prepare(connection.connection, update_query)
|
65
|
+
unless stmt = IBM_DB::prepare(connection.connection, update_query)
|
66
|
+
error_msg = IBM_DB::conn_errormsg ? IBM_DB::conn_errormsg : IBM_DB::stmt_errormsg
|
67
|
+
if error_msg && !error_msg.empty?
|
68
|
+
raise "Failed to rename table due to error: #{error_msg}"
|
69
|
+
else
|
70
|
+
raise StandardError('Unexpected error during update')
|
71
|
+
end
|
72
|
+
end
|
66
73
|
connection.log_query(update_query,'update of LOB/XML field(s)in handle_lobs')
|
67
74
|
|
68
75
|
# rollback any failed LOB/XML field updates (and remove associated marker)
|
69
76
|
unless IBM_DB::execute(stmt, values)
|
70
77
|
connection.execute("ROLLBACK")
|
71
78
|
raise "Failed to insert/update LOB/XML field(s) due to: #{IBM_DB::stmt_errormsg(stmt)}"
|
79
|
+
else
|
80
|
+
IBM_DB::free_result stmt
|
72
81
|
end
|
73
82
|
end # if connection.sql
|
74
83
|
end # if connection.kind_of?
|
@@ -737,25 +746,35 @@ requires credentials: username and password"
|
|
737
746
|
128
|
738
747
|
end
|
739
748
|
|
740
|
-
#
|
749
|
+
# Retrieves table's metadata for a specified shema name
|
741
750
|
def tables(name = nil)
|
742
751
|
# Initializes the tables array
|
743
752
|
tables = []
|
744
|
-
#
|
745
|
-
if stmt = IBM_DB::tables(@connection,
|
746
|
-
nil,
|
753
|
+
# Retrieve table's metadata through IBM_DB driver
|
754
|
+
if stmt = IBM_DB::tables(@connection, nil,
|
747
755
|
@servertype.set_case(@schema))
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
756
|
+
begin
|
757
|
+
# Fetches all the records available
|
758
|
+
while tab = IBM_DB::fetch_assoc(stmt)
|
759
|
+
# Adds the lowercase table name to the array
|
760
|
+
tables << tab["table_name"].downcase
|
761
|
+
end
|
762
|
+
ensure
|
763
|
+
IBM_DB::free_result(stmt) # Free resources associated with the statement
|
764
|
+
end
|
765
|
+
else # Handle driver execution errors
|
766
|
+
error_msg = IBM_DB::conn_errormsg ? IBM_DB::conn_errormsg : IBM_DB::stmt_errormsg
|
767
|
+
if error_msg && !error_msg.empty?
|
768
|
+
raise "Failed to retrieve tables metadata due to error: #{error_msg}"
|
769
|
+
else
|
770
|
+
raise StandardError('Unexpected error during table metadata retrieval')
|
752
771
|
end
|
753
772
|
end
|
754
773
|
# Returns the tables array
|
755
|
-
tables
|
774
|
+
return tables
|
756
775
|
end
|
757
776
|
|
758
|
-
# Returns an array of non-primary key indexes for
|
777
|
+
# Returns an array of non-primary key indexes for a specified table name
|
759
778
|
def indexes(table_name, name = nil)
|
760
779
|
# to_s required because +table_name+ may be a symbol.
|
761
780
|
table_name = table_name.to_s
|
@@ -770,28 +789,35 @@ requires credentials: username and password"
|
|
770
789
|
# "NON_UNIQUE: #{index_stats[3]}"
|
771
790
|
# "INDEX_NAME: #{index_stats[5]}"
|
772
791
|
# "COLUMN_NAME: #{index_stats[8]}"
|
773
|
-
stmt = IBM_DB::statistics( @connection,
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
792
|
+
if stmt = IBM_DB::statistics( @connection, nil,
|
793
|
+
@servertype.set_case(@schema),
|
794
|
+
@servertype.set_case(table_name), 1 )
|
795
|
+
begin
|
796
|
+
while ( index_stats = IBM_DB::fetch_array(stmt) )
|
797
|
+
if index_stats[5] # INDEX_NAME
|
798
|
+
index_name = index_stats[5].downcase
|
799
|
+
# Non-unique index type (not the primary key)
|
800
|
+
unless index_stats[3] == 0 # NON_UNIQUE
|
801
|
+
index_unique = (index_stats[3] == 0)
|
802
|
+
index_columns = index_stats[8].map{|c| c.downcase} # COLUMN_NAME
|
803
|
+
# Create an IndexDefinition object and add to the indexes array
|
804
|
+
indexes << IndexDefinition.new(table_name, index_name, index_unique, index_columns)
|
805
|
+
end
|
806
|
+
end
|
787
807
|
end
|
808
|
+
ensure # Free resources associated with the statement
|
809
|
+
IBM_DB::free_result(stmt) if stmt
|
810
|
+
end
|
811
|
+
else # Handle driver execution errors
|
812
|
+
error_msg = IBM_DB::conn_errormsg ? IBM_DB::conn_errormsg : IBM_DB::stmt_errormsg
|
813
|
+
if error_msg && !error_msg.empty?
|
814
|
+
raise "Failed to retrieve index metadata due to error: #{error_msg}"
|
815
|
+
else
|
816
|
+
raise StandardError('Unexpected error during index retrieval')
|
788
817
|
end
|
789
818
|
end
|
790
819
|
# Returns the indexes array
|
791
820
|
return indexes
|
792
|
-
# Ensures to free the resources associated with the statement
|
793
|
-
ensure
|
794
|
-
IBM_DB::free_result(stmt) if stmt
|
795
821
|
end
|
796
822
|
|
797
823
|
# Returns an array of Column objects for the table specified by +table_name+
|
@@ -804,10 +830,9 @@ requires credentials: username and password"
|
|
804
830
|
# +columns+ will contain the resulting array
|
805
831
|
columns = []
|
806
832
|
# Statement required to access all the columns information
|
807
|
-
if stmt = IBM_DB::columns(@connection,
|
808
|
-
|
809
|
-
|
810
|
-
@servertype.set_case(table_name))
|
833
|
+
if stmt = IBM_DB::columns( @connection, nil,
|
834
|
+
@servertype.set_case(@schema),
|
835
|
+
@servertype.set_case(table_name) )
|
811
836
|
begin
|
812
837
|
# Fetches all the columns and assigns them to col.
|
813
838
|
# +col+ is an hash with keys/value pairs for a column
|
@@ -849,17 +874,26 @@ requires credentials: username and password"
|
|
849
874
|
columns << IBM_DBColumn.new(column_name, column_default_value, column_type, column_nullable)
|
850
875
|
end
|
851
876
|
end
|
852
|
-
rescue StandardError
|
877
|
+
rescue StandardError # Handle driver fetch errors
|
853
878
|
error_msg = IBM_DB::conn_errormsg ? IBM_DB::conn_errormsg : IBM_DB::stmt_errormsg
|
854
879
|
if error_msg && !error_msg.empty?
|
855
|
-
raise "Failed to retrieve column metadata
|
880
|
+
raise "Failed to retrieve column metadata during fetch: #{error_msg}"
|
856
881
|
else
|
857
882
|
raise
|
858
883
|
end
|
884
|
+
ensure # Free resources associated with the statement
|
885
|
+
IBM_DB::free_result(stmt)
|
886
|
+
end
|
887
|
+
else # Handle driver execution errors
|
888
|
+
error_msg = IBM_DB::conn_errormsg ? IBM_DB::conn_errormsg : IBM_DB::stmt_errormsg
|
889
|
+
if error_msg && !error_msg.empty?
|
890
|
+
raise "Failed to retrieve column metadata due to error: #{error_msg}"
|
891
|
+
else
|
892
|
+
raise StandardError('Unexpected error during columns metadata retrieval')
|
859
893
|
end
|
860
894
|
end
|
861
895
|
# Returns the columns array
|
862
|
-
columns
|
896
|
+
return columns
|
863
897
|
end
|
864
898
|
|
865
899
|
# Renames a table.
|
@@ -909,43 +943,6 @@ requires credentials: username and password"
|
|
909
943
|
@servertype.change_column_default(table_name, column_name, default)
|
910
944
|
end
|
911
945
|
|
912
|
-
# Adds a new index to the table. +column_name+ can be a single Symbol, or
|
913
|
-
# an Array of Symbols.
|
914
|
-
#
|
915
|
-
# The index will be named after the table and the first column names,
|
916
|
-
# unless you pass +:name+ as an option.
|
917
|
-
#
|
918
|
-
# When creating an index on multiple columns, the first column is used as a name
|
919
|
-
# for the index. For example, when you specify an index on two columns
|
920
|
-
# [+:first+, +:last+], the DBMS creates an index for both columns as well as an
|
921
|
-
# index for the first colum +:first+. Using just the first name for this index
|
922
|
-
# makes sense, because you will never have to create a singular index with this
|
923
|
-
# name.
|
924
|
-
#
|
925
|
-
# ===== Examples
|
926
|
-
# ====== Creating a simple index
|
927
|
-
# add_index(:suppliers, :name)
|
928
|
-
# generates
|
929
|
-
# CREATE INDEX suppliers_name_index ON suppliers(name)
|
930
|
-
# ====== Creating a unique index
|
931
|
-
# add_index(:accounts, [:branch_id, :party_id], :unique => true)
|
932
|
-
# generates
|
933
|
-
# CREATE UNIQUE INDEX accounts_branch_id_index ON accounts(branch_id, party_id)
|
934
|
-
# ====== Creating a named index
|
935
|
-
# add_index(:accounts, [:branch_id, :party_id], :unique => true, :name => 'by_branch_party')
|
936
|
-
# generates
|
937
|
-
# CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
|
938
|
-
# Overidden to comply to the 18 characters cross-platform limit on index identifiers.
|
939
|
-
def add_index(table_name, column_name, options = {})
|
940
|
-
index_name = index_name(table_name, options)
|
941
|
-
if Hash === options # legacy support, since this param was a string
|
942
|
-
index_type = options[:unique] ? "UNIQUE" : ""
|
943
|
-
else
|
944
|
-
index_type = options
|
945
|
-
end
|
946
|
-
execute("CREATE #{index_type} INDEX #{index_name} ON #{table_name} (#{Array(column_name).join(", ")})")
|
947
|
-
end
|
948
|
-
|
949
946
|
# Remove the given index from the table.
|
950
947
|
#
|
951
948
|
# Remove the suppliers_name_index in the suppliers table (legacy support, use the second or third forms).
|
@@ -962,24 +959,6 @@ requires credentials: username and password"
|
|
962
959
|
def remove_index(table_name, options = {})
|
963
960
|
execute("DROP INDEX #{index_name(table_name, options)}")
|
964
961
|
end
|
965
|
-
|
966
|
-
# Builds an index name from a table_name and column. If an index name has been passed,
|
967
|
-
# the method returns it. Overrides the default method to respect the IBM data servers (cross-platform)
|
968
|
-
# limit on indexes (max of 18 characters)
|
969
|
-
def index_name(table_name, options)
|
970
|
-
if Hash === options and options[:name]
|
971
|
-
# legacy support
|
972
|
-
# If a name has been specified, this is returned
|
973
|
-
options[:name]
|
974
|
-
else
|
975
|
-
# We reverse the table name to reduce the chance of hitting duplicate
|
976
|
-
# index name errors. For e.g. indexes on table names like accounts,
|
977
|
-
# accounts_favorites
|
978
|
-
"ror_#{table_name.to_s.reverse[0,10]}_idx"
|
979
|
-
end
|
980
|
-
end
|
981
|
-
private :index_name
|
982
|
-
|
983
962
|
end # class IBM_DBAdapter
|
984
963
|
|
985
964
|
# This class contains common code across DB's (DB2 LUW, zOS, i5 and IDS)
|
@@ -1093,11 +1072,23 @@ To remove the column, the table must be dropped and recreated without the #{colu
|
|
1093
1072
|
def last_generated_id(stmt)
|
1094
1073
|
# Queries the db to obtain the last ID that was automatically generated
|
1095
1074
|
sql = "SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1"
|
1096
|
-
stmt = IBM_DB::exec(@adapter.connection, sql)
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1075
|
+
if stmt = IBM_DB::exec(@adapter.connection, sql)
|
1076
|
+
begin
|
1077
|
+
# Fetches the only record available (containing the last id)
|
1078
|
+
IBM_DB::fetch_row(stmt)
|
1079
|
+
# Retrieves and returns the result of the query with the last id.
|
1080
|
+
IBM_DB::result(stmt,0)
|
1081
|
+
ensure # Free resources associated with the statement
|
1082
|
+
IBM_DB::free_result stmt
|
1083
|
+
end
|
1084
|
+
else
|
1085
|
+
error_msg = IBM_DB::conn_errormsg ? IBM_DB::conn_errormsg : IBM_DB::stmt_errormsg
|
1086
|
+
if error_msg && !error_msg.empty?
|
1087
|
+
raise "Failed to retrieve last generated id due to error: #{error_msg}"
|
1088
|
+
else
|
1089
|
+
raise StandardError('Unexpected error during last generated id retrieval')
|
1090
|
+
end
|
1091
|
+
end
|
1101
1092
|
end
|
1102
1093
|
|
1103
1094
|
def change_column(table_name, column_name, type, options)
|
@@ -1285,7 +1276,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
1285
1276
|
# a number of records after the specified offset.
|
1286
1277
|
# 'select' or 'SELECT' is replaced with the partial query below that adds the sys_row_num column
|
1287
1278
|
# to select with the condition of this column being between offset+1 and the offset+limit
|
1288
|
-
sql.
|
1279
|
+
sql.sub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
|
1289
1280
|
# The final part of the query is appended to include a WHERE...BETWEEN...AND condition,
|
1290
1281
|
# and retrieve only a LIMIT number of records starting from the OFFSET+1
|
1291
1282
|
sql << ") AS I) AS O WHERE sys_row_num BETWEEN #{offset+1} AND #{last_record}"
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ibm_db
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.9.
|
7
|
-
date: 2007-11-
|
6
|
+
version: 0.9.2
|
7
|
+
date: 2007-11-30 00:00:00 -05:00
|
8
8
|
summary: "Rails Driver and Adapter for IBM Data Servers: {LUW, zOS, i5, IDS}"
|
9
9
|
require_paths:
|
10
10
|
- lib
|