kb-activerecord-jdbc-adapter 0.9.7.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. data/History.txt +296 -0
  2. data/LICENSE.txt +21 -0
  3. data/Manifest.txt +139 -0
  4. data/README.txt +219 -0
  5. data/Rakefile +10 -0
  6. data/lib/active_record/connection_adapters/cachedb_adapter.rb +1 -0
  7. data/lib/active_record/connection_adapters/derby_adapter.rb +13 -0
  8. data/lib/active_record/connection_adapters/h2_adapter.rb +13 -0
  9. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +13 -0
  10. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  11. data/lib/active_record/connection_adapters/jdbc_adapter.rb +661 -0
  12. data/lib/active_record/connection_adapters/jdbc_adapter_spec.rb +26 -0
  13. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  14. data/lib/active_record/connection_adapters/mssql_adapter.rb +13 -0
  15. data/lib/active_record/connection_adapters/mysql_adapter.rb +13 -0
  16. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/postgresql_adapter.rb +13 -0
  18. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +13 -0
  19. data/lib/activerecord-jdbc-adapter.rb +6 -0
  20. data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
  21. data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
  22. data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
  23. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +6 -0
  24. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
  25. data/lib/generators/jdbc/jdbc_generator.rb +9 -0
  26. data/lib/jdbc_adapter.rb +27 -0
  27. data/lib/jdbc_adapter/jdbc.rake +122 -0
  28. data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
  29. data/lib/jdbc_adapter/jdbc_cachedb.rb +33 -0
  30. data/lib/jdbc_adapter/jdbc_db2.rb +222 -0
  31. data/lib/jdbc_adapter/jdbc_derby.rb +426 -0
  32. data/lib/jdbc_adapter/jdbc_firebird.rb +109 -0
  33. data/lib/jdbc_adapter/jdbc_hsqldb.rb +221 -0
  34. data/lib/jdbc_adapter/jdbc_informix.rb +147 -0
  35. data/lib/jdbc_adapter/jdbc_mimer.rb +145 -0
  36. data/lib/jdbc_adapter/jdbc_mssql.rb +468 -0
  37. data/lib/jdbc_adapter/jdbc_mysql.rb +260 -0
  38. data/lib/jdbc_adapter/jdbc_oracle.rb +397 -0
  39. data/lib/jdbc_adapter/jdbc_postgre.rb +531 -0
  40. data/lib/jdbc_adapter/jdbc_sqlite3.rb +386 -0
  41. data/lib/jdbc_adapter/jdbc_sybase.rb +50 -0
  42. data/lib/jdbc_adapter/missing_functionality_helper.rb +87 -0
  43. data/lib/jdbc_adapter/railtie.rb +9 -0
  44. data/lib/jdbc_adapter/rake_tasks.rb +10 -0
  45. data/lib/jdbc_adapter/tsql_helper.rb +69 -0
  46. data/lib/jdbc_adapter/version.rb +5 -0
  47. data/lib/pg.rb +4 -0
  48. data/rails_generators/jdbc_generator.rb +15 -0
  49. data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
  50. data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
  51. data/rakelib/compile.rake +23 -0
  52. data/rakelib/package.rake +91 -0
  53. data/rakelib/rails.rake +41 -0
  54. data/rakelib/test.rake +78 -0
  55. data/src/java/jdbc_adapter/JdbcAdapterInternalService.java +53 -0
  56. data/src/java/jdbc_adapter/JdbcConnectionFactory.java +36 -0
  57. data/src/java/jdbc_adapter/JdbcDerbySpec.java +293 -0
  58. data/src/java/jdbc_adapter/JdbcMySQLSpec.java +134 -0
  59. data/src/java/jdbc_adapter/MssqlRubyJdbcConnection.java +71 -0
  60. data/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java +55 -0
  61. data/src/java/jdbc_adapter/RubyJdbcConnection.java +1176 -0
  62. data/src/java/jdbc_adapter/SQLBlock.java +27 -0
  63. data/src/java/jdbc_adapter/Sqlite3RubyJdbcConnection.java +41 -0
  64. data/test/abstract_db_create.rb +107 -0
  65. data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -0
  66. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
  67. data/test/cachedb_simple_test.rb +6 -0
  68. data/test/db/cachedb.rb +9 -0
  69. data/test/db/db2.rb +9 -0
  70. data/test/db/derby.rb +14 -0
  71. data/test/db/h2.rb +11 -0
  72. data/test/db/hsqldb.rb +12 -0
  73. data/test/db/informix.rb +11 -0
  74. data/test/db/jdbc.rb +11 -0
  75. data/test/db/jndi_config.rb +30 -0
  76. data/test/db/logger.rb +3 -0
  77. data/test/db/mssql.rb +9 -0
  78. data/test/db/mysql.rb +10 -0
  79. data/test/db/oracle.rb +34 -0
  80. data/test/db/postgres.rb +9 -0
  81. data/test/db/sqlite3.rb +15 -0
  82. data/test/db2_simple_test.rb +10 -0
  83. data/test/derby_migration_test.rb +21 -0
  84. data/test/derby_multibyte_test.rb +12 -0
  85. data/test/derby_simple_test.rb +21 -0
  86. data/test/generic_jdbc_connection_test.rb +9 -0
  87. data/test/h2_simple_test.rb +6 -0
  88. data/test/has_many_through.rb +79 -0
  89. data/test/helper.rb +5 -0
  90. data/test/hsqldb_simple_test.rb +6 -0
  91. data/test/informix_simple_test.rb +48 -0
  92. data/test/jdbc_adapter/jdbc_db2_test.rb +26 -0
  93. data/test/jdbc_adapter/jdbc_sybase_test.rb +33 -0
  94. data/test/jdbc_common.rb +25 -0
  95. data/test/jndi_callbacks_test.rb +38 -0
  96. data/test/jndi_test.rb +35 -0
  97. data/test/manualTestDatabase.rb +191 -0
  98. data/test/minirunit.rb +109 -0
  99. data/test/minirunit/testConnect.rb +14 -0
  100. data/test/minirunit/testH2.rb +73 -0
  101. data/test/minirunit/testHsqldb.rb +73 -0
  102. data/test/minirunit/testLoadActiveRecord.rb +3 -0
  103. data/test/minirunit/testMysql.rb +83 -0
  104. data/test/minirunit/testRawSelect.rb +24 -0
  105. data/test/models/add_not_null_column_to_table.rb +12 -0
  106. data/test/models/auto_id.rb +18 -0
  107. data/test/models/data_types.rb +28 -0
  108. data/test/models/entry.rb +23 -0
  109. data/test/models/mixed_case.rb +20 -0
  110. data/test/models/reserved_word.rb +18 -0
  111. data/test/models/string_id.rb +18 -0
  112. data/test/models/validates_uniqueness_of_string.rb +19 -0
  113. data/test/mssql_db_create_test.rb +26 -0
  114. data/test/mssql_identity_insert_test.rb +19 -0
  115. data/test/mssql_legacy_types_test.rb +58 -0
  116. data/test/mssql_limit_offset_test.rb +108 -0
  117. data/test/mssql_multibyte_test.rb +18 -0
  118. data/test/mssql_simple_test.rb +49 -0
  119. data/test/mysql_db_create_test.rb +25 -0
  120. data/test/mysql_info_test.rb +62 -0
  121. data/test/mysql_multibyte_test.rb +10 -0
  122. data/test/mysql_nonstandard_primary_key_test.rb +42 -0
  123. data/test/mysql_simple_test.rb +32 -0
  124. data/test/oracle_simple_test.rb +54 -0
  125. data/test/pick_rails_version.rb +3 -0
  126. data/test/postgres_db_create_test.rb +21 -0
  127. data/test/postgres_mixed_case_test.rb +19 -0
  128. data/test/postgres_nonseq_pkey_test.rb +40 -0
  129. data/test/postgres_reserved_test.rb +22 -0
  130. data/test/postgres_schema_search_path_test.rb +46 -0
  131. data/test/postgres_simple_test.rb +13 -0
  132. data/test/simple.rb +494 -0
  133. data/test/sqlite3_simple_test.rb +233 -0
  134. data/test/sybase_jtds_simple_test.rb +6 -0
  135. metadata +230 -0
@@ -0,0 +1,221 @@
1
+ module ::JdbcSpec
2
+ module ActiveRecordExtensions
3
+ def hsqldb_connection(config)
4
+ require File.dirname(__FILE__) + "/../active_record/connection_adapters/hsqldb_adapter"
5
+ config[:url] ||= "jdbc:hsqldb:#{config[:database]}"
6
+ config[:driver] ||= "org.hsqldb.jdbcDriver"
7
+ embedded_driver(config)
8
+ end
9
+
10
+ def h2_connection(config)
11
+ require File.dirname(__FILE__) + "/../active_record/connection_adapters/h2_adapter"
12
+ config[:url] ||= "jdbc:h2:#{config[:database]}"
13
+ config[:driver] ||= "org.h2.Driver"
14
+ embedded_driver(config)
15
+ end
16
+ end
17
+
18
+ module HSQLDB
19
+ def self.extended(mod)
20
+ mod.class.class_eval do
21
+ alias_chained_method :insert, :query_dirty, :insert
22
+ end
23
+ end
24
+
25
+ def self.adapter_matcher(name, *)
26
+ name =~ /hsqldb/i ? self : false
27
+ end
28
+
29
+ def self.column_selector
30
+ [/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::JdbcSpec::HSQLDB::Column)}]
31
+ end
32
+
33
+ module Column
34
+ private
35
+ def simplified_type(field_type)
36
+ case field_type
37
+ when /longvarchar/i
38
+ :text
39
+ when /tinyint/i
40
+ :boolean
41
+ when /real/i
42
+ :float
43
+ else
44
+ super(field_type)
45
+ end
46
+ end
47
+
48
+ # Override of ActiveRecord::ConnectionAdapters::Column
49
+ def extract_limit(sql_type)
50
+ # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns, which
51
+ # for AR purposes should be interpreted as "no limit"
52
+ return nil if sql_type =~ /\(0\)/
53
+ super
54
+ end
55
+
56
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
57
+ def default_value(value)
58
+ # jdbc returns column default strings with actual single quotes around the value.
59
+ return $1 if value =~ /^'(.*)'$/
60
+
61
+ value
62
+ end
63
+ end
64
+
65
+ def adapter_name #:nodoc:
66
+ defined?(::Jdbc::H2) ? 'H2' : 'Hsqldb'
67
+ end
68
+
69
+ def modify_types(tp)
70
+ tp[:primary_key] = "INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
71
+ tp[:integer][:limit] = nil
72
+ tp[:boolean][:limit] = nil
73
+ # set text and float limits so we don't see odd scales tacked on
74
+ # in migrations
75
+ tp[:boolean] = { :name => "tinyint" }
76
+ tp[:text][:limit] = nil
77
+ tp[:float][:limit] = 17 if defined?(::Jdbc::H2)
78
+ tp[:string][:limit] = 255
79
+ tp[:datetime] = { :name => "DATETIME" }
80
+ tp[:timestamp] = { :name => "DATETIME" }
81
+ tp[:time] = { :name => "TIME" }
82
+ tp[:date] = { :name => "DATE" }
83
+ tp
84
+ end
85
+
86
+ def quote(value, column = nil) # :nodoc:
87
+ return value.quoted_id if value.respond_to?(:quoted_id)
88
+
89
+ case value
90
+ when String
91
+ if respond_to?(:h2_adapter) && value.empty?
92
+ "''"
93
+ elsif column && column.type == :binary
94
+ "'#{value.unpack("H*")}'"
95
+ elsif column && (column.type == :integer ||
96
+ column.respond_to?(:primary) && column.primary && column.klass != String)
97
+ value.to_i.to_s
98
+ else
99
+ "'#{quote_string(value)}'"
100
+ end
101
+ else
102
+ super
103
+ end
104
+ end
105
+
106
+ def quote_column_name(name) #:nodoc:
107
+ name = name.to_s
108
+ if name =~ /[-]/
109
+ %Q{"#{name.upcase}"}
110
+ else
111
+ name
112
+ end
113
+ end
114
+
115
+ def quote_string(str)
116
+ str.gsub(/'/, "''")
117
+ end
118
+
119
+ def quoted_true
120
+ '1'
121
+ end
122
+
123
+ def quoted_false
124
+ '0'
125
+ end
126
+
127
+ def add_column(table_name, column_name, type, options = {})
128
+ if option_not_null = options[:null] == false
129
+ option_not_null = options.delete(:null)
130
+ end
131
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
132
+ add_column_options!(add_column_sql, options)
133
+ execute(add_column_sql)
134
+ if option_not_null
135
+ alter_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} NOT NULL"
136
+ end
137
+ end
138
+
139
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
140
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
141
+ end
142
+
143
+ def change_column_default(table_name, column_name, default) #:nodoc:
144
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
145
+ end
146
+
147
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
148
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
149
+ end
150
+
151
+ # Maps logical Rails types to MySQL-specific data types.
152
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
153
+ return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
154
+
155
+ type
156
+ end
157
+
158
+ def rename_table(name, new_name)
159
+ execute "ALTER TABLE #{name} RENAME TO #{new_name}"
160
+ end
161
+
162
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
163
+ log(sql,name) do
164
+ @connection.execute_update(sql)
165
+ end
166
+ table = sql.split(" ", 4)[2]
167
+ id_value || last_insert_id(table, nil)
168
+ end
169
+
170
+ def last_insert_id(table, sequence_name)
171
+ Integer(select_value("CALL IDENTITY()"))
172
+ end
173
+
174
+ # Override normal #_execute: See Rubyforge #11567
175
+ def _execute(sql, name = nil)
176
+ if ::ActiveRecord::ConnectionAdapters::JdbcConnection::select?(sql)
177
+ @connection.execute_query(sql)
178
+ elsif ::ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql)
179
+ insert(sql, name)
180
+ else
181
+ @connection.execute_update(sql)
182
+ end
183
+ end
184
+
185
+ def add_limit_offset!(sql, options) #:nodoc:
186
+ offset = options[:offset] || 0
187
+ bef = sql[7..-1]
188
+ if limit = options[:limit]
189
+ sql.replace "select limit #{offset} #{limit} #{bef}"
190
+ elsif offset > 0
191
+ sql.replace "select limit #{offset} 0 #{bef}"
192
+ end
193
+ end
194
+
195
+ # override to filter out system tables that otherwise end
196
+ # up in db/schema.rb during migrations. JdbcConnection#tables
197
+ # now takes an optional block filter so we can screen out
198
+ # rows corresponding to system tables. HSQLDB names its
199
+ # system tables SYSTEM.*, but H2 seems to name them without
200
+ # any kind of convention
201
+ def tables
202
+ @connection.tables.select {|row| row.to_s !~ /^system_/i }
203
+ end
204
+
205
+ def remove_index(table_name, options = {})
206
+ execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
207
+ end
208
+ end
209
+
210
+ module H2
211
+ include HSQLDB
212
+
213
+ def self.adapter_matcher(name, *)
214
+ name =~ /\.h2\./i ? self : false
215
+ end
216
+
217
+ def h2_adapter
218
+ true
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,147 @@
1
+ module ::ActiveRecord
2
+ class Base
3
+ after_save :write_lobs
4
+
5
+ private
6
+ def write_lobs
7
+ if connection.is_a?(JdbcSpec::Informix)
8
+ self.class.columns.each do |c|
9
+ if [:text, :binary].include? c.type
10
+ value = self[c.name]
11
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
12
+
13
+ unless value.nil? || (value == '')
14
+ connection.write_large_object(c.type == :binary,
15
+ c.name,
16
+ self.class.table_name,
17
+ self.class.primary_key,
18
+ quote_value(id),
19
+ value)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ module ::JdbcSpec
29
+ module ActiveRecordExtensions
30
+ def informix_connection(config)
31
+ config[:port] ||= 9088
32
+ config[:url] ||= "jdbc:informix-sqli://#{config[:host]}:#{config[:port]}/#{config[:database]}:INFORMIXSERVER=#{config[:servername]}"
33
+ config[:driver] = 'com.informix.jdbc.IfxDriver'
34
+ jdbc_connection(config)
35
+ end
36
+ end
37
+
38
+ module Informix
39
+ def self.extended(base)
40
+ @@db_major_version = base.select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
41
+ end
42
+
43
+ def self.adapter_matcher(name, *)
44
+ name =~ /informix/i ? self : false
45
+ end
46
+
47
+ def self.column_selector
48
+ [ /informix/i,
49
+ lambda { |cfg, column| column.extend(::JdbcSpec::Informix::Column) } ]
50
+ end
51
+
52
+ module Column
53
+ private
54
+ # TODO: Test all Informix column types.
55
+ def simplified_type(field_type)
56
+ if field_type =~ /serial/i
57
+ :primary_key
58
+ else
59
+ super
60
+ end
61
+ end
62
+ end
63
+
64
+ def modify_types(tp)
65
+ tp[:primary_key] = "SERIAL PRIMARY KEY"
66
+ tp[:string] = { :name => "VARCHAR", :limit => 255 }
67
+ tp[:integer] = { :name => "INTEGER" }
68
+ tp[:float] = { :name => "FLOAT" }
69
+ tp[:decimal] = { :name => "DECIMAL" }
70
+ tp[:datetime] = { :name => "DATETIME YEAR TO FRACTION(5)" }
71
+ tp[:timestamp] = { :name => "DATETIME YEAR TO FRACTION(5)" }
72
+ tp[:time] = { :name => "DATETIME HOUR TO FRACTION(5)" }
73
+ tp[:date] = { :name => "DATE" }
74
+ tp[:binary] = { :name => "BYTE" }
75
+ tp[:boolean] = { :name => "BOOLEAN" }
76
+ tp
77
+ end
78
+
79
+ def prefetch_primary_key?(table_name = nil)
80
+ true
81
+ end
82
+
83
+ def supports_migrations?
84
+ true
85
+ end
86
+
87
+ def default_sequence_name(table, column)
88
+ "#{table}_seq"
89
+ end
90
+
91
+ def add_limit_offset!(sql, options)
92
+ if options[:limit]
93
+ limit = "FIRST #{options[:limit]}"
94
+ # SKIP available only in IDS >= 10
95
+ offset = (@@db_major_version >= 10 && options[:offset]?
96
+ "SKIP #{options[:offset]}" : "")
97
+ sql.sub!(/^select /i, "SELECT #{offset} #{limit} ")
98
+ end
99
+ sql
100
+ end
101
+
102
+ def next_sequence_value(sequence_name)
103
+ select_one("SELECT #{sequence_name}.nextval id FROM systables WHERE tabid=1")['id']
104
+ end
105
+
106
+ # TODO: Add some smart quoting for newlines in string and text fields.
107
+ def quote_string(string)
108
+ string.gsub(/\'/, "''")
109
+ end
110
+
111
+ def quote(value, column = nil)
112
+ if column && [:binary, :text].include?(column.type)
113
+ # LOBs are updated separately by an after_save trigger.
114
+ "NULL"
115
+ elsif column && column.type == :date
116
+ "'#{value.mon}/#{value.day}/#{value.year}'"
117
+ else
118
+ super
119
+ end
120
+ end
121
+
122
+ def create_table(name, options = {})
123
+ super(name, options)
124
+ execute("CREATE SEQUENCE #{name}_seq")
125
+ end
126
+
127
+ def rename_table(name, new_name)
128
+ execute("RENAME TABLE #{name} TO #{new_name}")
129
+ execute("RENAME SEQUENCE #{name}_seq TO #{new_name}_seq")
130
+ end
131
+
132
+ def drop_table(name)
133
+ super(name)
134
+ execute("DROP SEQUENCE #{name}_seq")
135
+ end
136
+
137
+ def remove_index(table_name, options = {})
138
+ @connection.execute_update("DROP INDEX #{index_name(table_name, options)}")
139
+ end
140
+
141
+ private
142
+ def select(sql, name = nil)
143
+ # Informix does not like "= NULL", "!= NULL", or "<> NULL".
144
+ execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), name)
145
+ end
146
+ end # module Informix
147
+ end # module ::JdbcSpec
@@ -0,0 +1,145 @@
1
+ module JdbcSpec
2
+ module Mimer
3
+ def self.extended(mod)
4
+ ActiveRecord::Base.extend JdbcSpec::QuotedPrimaryKeyExtension
5
+ end
6
+
7
+ def self.adapter_matcher(name, *)
8
+ name =~ /mimer/i ? self : false
9
+ end
10
+
11
+ def modify_types(tp)
12
+ tp[:primary_key] = "INTEGER NOT NULL PRIMARY KEY"
13
+ tp[:boolean][:limit] = nil
14
+ tp[:string][:limit] = 255
15
+ tp[:binary] = {:name => "BINARY VARYING", :limit => 4096}
16
+ tp[:text] = {:name => "VARCHAR", :limit => 4096}
17
+ tp[:datetime] = { :name => "TIMESTAMP" }
18
+ tp[:timestamp] = { :name => "TIMESTAMP" }
19
+ tp[:time] = { :name => "TIMESTAMP" }
20
+ tp[:date] = { :name => "TIMESTAMP" }
21
+ tp
22
+ end
23
+
24
+ def default_sequence_name(table, column) #:nodoc:
25
+ "#{table}_seq"
26
+ end
27
+
28
+ def create_table(name, options = {}) #:nodoc:
29
+ super(name, options)
30
+ execute "CREATE SEQUENCE #{name}_seq" unless options[:id] == false
31
+ end
32
+
33
+ def drop_table(name, options = {}) #:nodoc:
34
+ super(name) rescue nil
35
+ execute "DROP SEQUENCE #{name}_seq" rescue nil
36
+ end
37
+
38
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
39
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
40
+ end
41
+
42
+ def change_column_default(table_name, column_name, default) #:nodoc:
43
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
44
+ end
45
+
46
+ def remove_index(table_name, options = {}) #:nodoc:
47
+ execute "DROP INDEX #{index_name(table_name, options)}"
48
+ end
49
+
50
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
51
+ if pk.nil? # Who called us? What does the sql look like? No idea!
52
+ execute sql, name
53
+ elsif id_value # Pre-assigned id
54
+ log(sql, name) { @connection.execute_insert sql,pk }
55
+ else # Assume the sql contains a bind-variable for the id
56
+ id_value = select_one("SELECT NEXT_VALUE OF #{sequence_name} AS val FROM MIMER.ONEROW")['val']
57
+ log(sql, name) {
58
+ execute_prepared_insert(sql,id_value)
59
+ }
60
+ end
61
+ id_value
62
+ end
63
+
64
+ def execute_prepared_insert(sql, id)
65
+ @stmts ||= {}
66
+ @stmts[sql] ||= @connection.ps(sql)
67
+ stmt = @stmts[sql]
68
+ stmt.setLong(1,id)
69
+ stmt.executeUpdate
70
+ id
71
+ end
72
+
73
+ def quote(value, column = nil) #:nodoc:
74
+ return value.quoted_id if value.respond_to?(:quoted_id)
75
+
76
+ if String === value && column && column.type == :binary
77
+ return "X'#{quote_string(value.unpack("C*").collect {|v| v.to_s(16)}.join)}'"
78
+ end
79
+ case value
80
+ when String
81
+ %Q{'#{quote_string(value)}'}
82
+ when NilClass
83
+ 'NULL'
84
+ when TrueClass
85
+ '1'
86
+ when FalseClass
87
+ '0'
88
+ when Numeric
89
+ value.to_s
90
+ when Date, Time
91
+ %Q{TIMESTAMP '#{value.strftime("%Y-%m-%d %H:%M:%S")}'}
92
+ else
93
+ %Q{'#{quote_string(value.to_yaml)}'}
94
+ end
95
+ end
96
+
97
+ def quoted_true
98
+ '1'
99
+ end
100
+
101
+ def quoted_false
102
+ '0'
103
+ end
104
+
105
+ def add_limit_offset!(sql, options) # :nodoc:
106
+ @limit = options[:limit]
107
+ @offset = options[:offset]
108
+ end
109
+
110
+ def select_all(sql, name = nil)
111
+ @offset ||= 0
112
+ if !@limit || @limit == -1
113
+ range = @offset..-1
114
+ else
115
+ range = @offset...(@offset+@limit)
116
+ end
117
+ select(sql, name)[range]
118
+ ensure
119
+ @limit = @offset = nil
120
+ end
121
+
122
+ def select_one(sql, name = nil)
123
+ @offset ||= 0
124
+ select(sql, name)[@offset]
125
+ ensure
126
+ @limit = @offset = nil
127
+ end
128
+
129
+ def _execute(sql, name = nil)
130
+ if sql =~ /^select/i
131
+ @offset ||= 0
132
+ if !@limit || @limit == -1
133
+ range = @offset..-1
134
+ else
135
+ range = @offset...(@offset+@limit)
136
+ end
137
+ @connection.execute_query(sql)[range]
138
+ else
139
+ @connection.execute_update(sql)
140
+ end
141
+ ensure
142
+ @limit = @offset = nil
143
+ end
144
+ end
145
+ end