activerecord-jdbc-adapter-onsite 1.2.2

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 (228) hide show
  1. data/.gitignore +22 -0
  2. data/.travis.yml +14 -0
  3. data/Appraisals +16 -0
  4. data/Gemfile +11 -0
  5. data/Gemfile.lock +45 -0
  6. data/History.txt +488 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.rdoc +214 -0
  9. data/Rakefile +62 -0
  10. data/activerecord-jdbc-adapter.gemspec +23 -0
  11. data/bench/bench_attributes.rb +13 -0
  12. data/bench/bench_attributes_new.rb +14 -0
  13. data/bench/bench_create.rb +12 -0
  14. data/bench/bench_find_all.rb +12 -0
  15. data/bench/bench_find_all_mt.rb +25 -0
  16. data/bench/bench_model.rb +85 -0
  17. data/bench/bench_new.rb +12 -0
  18. data/bench/bench_new_valid.rb +12 -0
  19. data/bench/bench_valid.rb +13 -0
  20. data/gemfiles/rails23.gemfile +10 -0
  21. data/gemfiles/rails23.gemfile.lock +38 -0
  22. data/gemfiles/rails30.gemfile +9 -0
  23. data/gemfiles/rails30.gemfile.lock +33 -0
  24. data/gemfiles/rails31.gemfile +9 -0
  25. data/gemfiles/rails31.gemfile.lock +35 -0
  26. data/gemfiles/rails32.gemfile +9 -0
  27. data/gemfiles/rails32.gemfile.lock +35 -0
  28. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  31. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  32. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
  33. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  34. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  35. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  36. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  37. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  38. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  39. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  40. data/lib/activerecord-jdbc-adapter.rb +8 -0
  41. data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
  42. data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
  43. data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
  44. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +15 -0
  45. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
  46. data/lib/arel/engines/sql/compilers/mssql_compiler.rb +46 -0
  47. data/lib/arel/visitors/compat.rb +13 -0
  48. data/lib/arel/visitors/db2.rb +17 -0
  49. data/lib/arel/visitors/derby.rb +32 -0
  50. data/lib/arel/visitors/firebird.rb +24 -0
  51. data/lib/arel/visitors/hsqldb.rb +26 -0
  52. data/lib/arel/visitors/sql_server.rb +46 -0
  53. data/lib/arjdbc.rb +24 -0
  54. data/lib/arjdbc/db2.rb +2 -0
  55. data/lib/arjdbc/db2/adapter.rb +541 -0
  56. data/lib/arjdbc/derby.rb +7 -0
  57. data/lib/arjdbc/derby/adapter.rb +358 -0
  58. data/lib/arjdbc/derby/connection_methods.rb +19 -0
  59. data/lib/arjdbc/discover.rb +92 -0
  60. data/lib/arjdbc/firebird.rb +2 -0
  61. data/lib/arjdbc/firebird/adapter.rb +140 -0
  62. data/lib/arjdbc/h2.rb +4 -0
  63. data/lib/arjdbc/h2/adapter.rb +54 -0
  64. data/lib/arjdbc/h2/connection_methods.rb +13 -0
  65. data/lib/arjdbc/hsqldb.rb +4 -0
  66. data/lib/arjdbc/hsqldb/adapter.rb +184 -0
  67. data/lib/arjdbc/hsqldb/connection_methods.rb +15 -0
  68. data/lib/arjdbc/informix.rb +3 -0
  69. data/lib/arjdbc/informix/adapter.rb +142 -0
  70. data/lib/arjdbc/informix/connection_methods.rb +11 -0
  71. data/lib/arjdbc/jdbc.rb +2 -0
  72. data/lib/arjdbc/jdbc/adapter.rb +356 -0
  73. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  74. data/lib/arjdbc/jdbc/base_ext.rb +15 -0
  75. data/lib/arjdbc/jdbc/callbacks.rb +44 -0
  76. data/lib/arjdbc/jdbc/column.rb +47 -0
  77. data/lib/arjdbc/jdbc/compatibility.rb +51 -0
  78. data/lib/arjdbc/jdbc/connection.rb +134 -0
  79. data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
  80. data/lib/arjdbc/jdbc/core_ext.rb +24 -0
  81. data/lib/arjdbc/jdbc/discover.rb +18 -0
  82. data/lib/arjdbc/jdbc/driver.rb +35 -0
  83. data/lib/arjdbc/jdbc/extension.rb +47 -0
  84. data/lib/arjdbc/jdbc/java.rb +14 -0
  85. data/lib/arjdbc/jdbc/jdbc.rake +131 -0
  86. data/lib/arjdbc/jdbc/missing_functionality_helper.rb +88 -0
  87. data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
  88. data/lib/arjdbc/jdbc/railtie.rb +9 -0
  89. data/lib/arjdbc/jdbc/rake_tasks.rb +10 -0
  90. data/lib/arjdbc/jdbc/require_driver.rb +16 -0
  91. data/lib/arjdbc/jdbc/type_converter.rb +126 -0
  92. data/lib/arjdbc/mimer.rb +2 -0
  93. data/lib/arjdbc/mimer/adapter.rb +142 -0
  94. data/lib/arjdbc/mssql.rb +4 -0
  95. data/lib/arjdbc/mssql/adapter.rb +477 -0
  96. data/lib/arjdbc/mssql/connection_methods.rb +31 -0
  97. data/lib/arjdbc/mssql/limit_helpers.rb +101 -0
  98. data/lib/arjdbc/mssql/lock_helpers.rb +72 -0
  99. data/lib/arjdbc/mssql/tsql_helper.rb +61 -0
  100. data/lib/arjdbc/mysql.rb +4 -0
  101. data/lib/arjdbc/mysql/adapter.rb +505 -0
  102. data/lib/arjdbc/mysql/connection_methods.rb +28 -0
  103. data/lib/arjdbc/oracle.rb +3 -0
  104. data/lib/arjdbc/oracle/adapter.rb +432 -0
  105. data/lib/arjdbc/oracle/connection_methods.rb +12 -0
  106. data/lib/arjdbc/postgresql.rb +4 -0
  107. data/lib/arjdbc/postgresql/adapter.rb +861 -0
  108. data/lib/arjdbc/postgresql/connection_methods.rb +23 -0
  109. data/lib/arjdbc/sqlite3.rb +4 -0
  110. data/lib/arjdbc/sqlite3/adapter.rb +389 -0
  111. data/lib/arjdbc/sqlite3/connection_methods.rb +35 -0
  112. data/lib/arjdbc/sybase.rb +2 -0
  113. data/lib/arjdbc/sybase/adapter.rb +46 -0
  114. data/lib/arjdbc/version.rb +8 -0
  115. data/lib/generators/jdbc/USAGE +10 -0
  116. data/lib/generators/jdbc/jdbc_generator.rb +9 -0
  117. data/lib/jdbc_adapter.rb +2 -0
  118. data/lib/jdbc_adapter/rake_tasks.rb +3 -0
  119. data/lib/jdbc_adapter/version.rb +3 -0
  120. data/lib/pg.rb +26 -0
  121. data/pom.xml +57 -0
  122. data/rails_generators/jdbc_generator.rb +15 -0
  123. data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
  124. data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
  125. data/rakelib/bundler_ext.rb +11 -0
  126. data/rakelib/compile.rake +23 -0
  127. data/rakelib/db.rake +39 -0
  128. data/rakelib/rails.rake +41 -0
  129. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +69 -0
  130. data/src/java/arjdbc/derby/DerbyModule.java +324 -0
  131. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +70 -0
  132. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +74 -0
  133. data/src/java/arjdbc/jdbc/AdapterJavaService.java +68 -0
  134. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +36 -0
  135. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1346 -0
  136. data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
  137. data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +127 -0
  138. data/src/java/arjdbc/mysql/MySQLModule.java +134 -0
  139. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +161 -0
  140. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +85 -0
  141. data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +82 -0
  142. data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +126 -0
  143. data/test/abstract_db_create.rb +135 -0
  144. data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -0
  145. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
  146. data/test/activerecord/jall.sh +7 -0
  147. data/test/activerecord/jtest.sh +3 -0
  148. data/test/db/db2.rb +11 -0
  149. data/test/db/derby.rb +12 -0
  150. data/test/db/h2.rb +11 -0
  151. data/test/db/hsqldb.rb +13 -0
  152. data/test/db/informix.rb +11 -0
  153. data/test/db/jdbc.rb +12 -0
  154. data/test/db/jndi_config.rb +40 -0
  155. data/test/db/logger.rb +3 -0
  156. data/test/db/mssql.rb +9 -0
  157. data/test/db/mysql.rb +10 -0
  158. data/test/db/oracle.rb +34 -0
  159. data/test/db/postgres.rb +18 -0
  160. data/test/db/sqlite3.rb +11 -0
  161. data/test/db2_reset_column_information_test.rb +8 -0
  162. data/test/db2_simple_test.rb +66 -0
  163. data/test/derby_migration_test.rb +68 -0
  164. data/test/derby_multibyte_test.rb +12 -0
  165. data/test/derby_reset_column_information_test.rb +8 -0
  166. data/test/derby_row_locking_test.rb +9 -0
  167. data/test/derby_simple_test.rb +139 -0
  168. data/test/generic_jdbc_connection_test.rb +29 -0
  169. data/test/h2_change_column_test.rb +68 -0
  170. data/test/h2_simple_test.rb +41 -0
  171. data/test/has_many_through.rb +79 -0
  172. data/test/helper.rb +108 -0
  173. data/test/hsqldb_simple_test.rb +6 -0
  174. data/test/informix_simple_test.rb +48 -0
  175. data/test/jdbc_common.rb +28 -0
  176. data/test/jndi_callbacks_test.rb +36 -0
  177. data/test/jndi_test.rb +25 -0
  178. data/test/manualTestDatabase.rb +191 -0
  179. data/test/models/add_not_null_column_to_table.rb +9 -0
  180. data/test/models/auto_id.rb +15 -0
  181. data/test/models/custom_pk_name.rb +14 -0
  182. data/test/models/data_types.rb +30 -0
  183. data/test/models/entry.rb +40 -0
  184. data/test/models/mixed_case.rb +22 -0
  185. data/test/models/reserved_word.rb +15 -0
  186. data/test/models/string_id.rb +17 -0
  187. data/test/models/thing.rb +16 -0
  188. data/test/models/validates_uniqueness_of_string.rb +19 -0
  189. data/test/mssql_db_create_test.rb +26 -0
  190. data/test/mssql_identity_insert_test.rb +19 -0
  191. data/test/mssql_ignore_system_views_test.rb +27 -0
  192. data/test/mssql_legacy_types_test.rb +58 -0
  193. data/test/mssql_limit_offset_test.rb +136 -0
  194. data/test/mssql_multibyte_test.rb +18 -0
  195. data/test/mssql_null_test.rb +14 -0
  196. data/test/mssql_reset_column_information_test.rb +8 -0
  197. data/test/mssql_row_locking_sql_test.rb +159 -0
  198. data/test/mssql_row_locking_test.rb +9 -0
  199. data/test/mssql_simple_test.rb +55 -0
  200. data/test/mysql_db_create_test.rb +27 -0
  201. data/test/mysql_index_length_test.rb +58 -0
  202. data/test/mysql_info_test.rb +123 -0
  203. data/test/mysql_multibyte_test.rb +10 -0
  204. data/test/mysql_nonstandard_primary_key_test.rb +42 -0
  205. data/test/mysql_reset_column_information_test.rb +8 -0
  206. data/test/mysql_simple_test.rb +125 -0
  207. data/test/oracle_reset_column_information_test.rb +8 -0
  208. data/test/oracle_simple_test.rb +18 -0
  209. data/test/oracle_specific_test.rb +83 -0
  210. data/test/postgres_db_create_test.rb +32 -0
  211. data/test/postgres_drop_db_test.rb +16 -0
  212. data/test/postgres_information_schema_leak_test.rb +29 -0
  213. data/test/postgres_mixed_case_test.rb +29 -0
  214. data/test/postgres_native_type_mapping_test.rb +93 -0
  215. data/test/postgres_nonseq_pkey_test.rb +38 -0
  216. data/test/postgres_reserved_test.rb +22 -0
  217. data/test/postgres_reset_column_information_test.rb +8 -0
  218. data/test/postgres_schema_search_path_test.rb +48 -0
  219. data/test/postgres_simple_test.rb +168 -0
  220. data/test/postgres_table_alias_length_test.rb +15 -0
  221. data/test/postgres_type_conversion_test.rb +34 -0
  222. data/test/row_locking.rb +90 -0
  223. data/test/simple.rb +731 -0
  224. data/test/sqlite3_reset_column_information_test.rb +8 -0
  225. data/test/sqlite3_simple_test.rb +316 -0
  226. data/test/sybase_jtds_simple_test.rb +28 -0
  227. data/test/sybase_reset_column_information_test.rb +8 -0
  228. metadata +288 -0
@@ -0,0 +1,2 @@
1
+ require 'arjdbc/jdbc'
2
+ require 'arjdbc/firebird/adapter'
@@ -0,0 +1,140 @@
1
+ module ::ArJdbc
2
+ module FireBird
3
+
4
+ def self.extended(mod)
5
+ unless @lob_callback_added
6
+ ActiveRecord::Base.class_eval do
7
+ def after_save_with_firebird_blob
8
+ self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |c|
9
+ value = self[c.name]
10
+ if respond_to?(:unserializable_attribute?)
11
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
12
+ else
13
+ value = value.to_yaml if value.is_a?(Hash)
14
+ end
15
+ next if value.nil?
16
+ connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
17
+ end
18
+ end
19
+ end
20
+
21
+ ActiveRecord::Base.after_save :after_save_with_firebird_blob
22
+ @lob_callback_added = true
23
+ end
24
+ end
25
+
26
+ def adapter_name
27
+ 'Firebird'
28
+ end
29
+
30
+ def self.arel2_visitors(config)
31
+ require 'arel/visitors/firebird'
32
+ {}.tap {|v| %w(firebird firebirdsql).each {|a| v[a] = ::Arel::Visitors::Firebird } }
33
+ end
34
+
35
+ def modify_types(tp)
36
+ tp[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
37
+ tp[:string][:limit] = 252
38
+ tp[:integer][:limit] = nil
39
+ tp
40
+ end
41
+
42
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) # :nodoc:
43
+ execute(sql, name, binds)
44
+ id_value
45
+ end
46
+
47
+ def add_limit_offset!(sql, options) # :nodoc:
48
+ if options[:limit]
49
+ limit_string = "FIRST #{options[:limit]}"
50
+ limit_string << " SKIP #{options[:offset]}" if options[:offset]
51
+ sql.sub!(/\A(\s*SELECT\s)/i, '\&' + limit_string + ' ')
52
+ end
53
+ end
54
+
55
+ def prefetch_primary_key?(table_name = nil)
56
+ true
57
+ end
58
+
59
+ def default_sequence_name(table_name, primary_key) # :nodoc:
60
+ "#{table_name}_seq"
61
+ end
62
+
63
+ def next_sequence_value(sequence_name)
64
+ select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"]
65
+ end
66
+
67
+ def create_table(name, options = {}) #:nodoc:
68
+ super(name, options)
69
+ execute "CREATE GENERATOR #{name}_seq"
70
+ end
71
+
72
+ def rename_table(name, new_name) #:nodoc:
73
+ execute "RENAME #{name} TO #{new_name}"
74
+ execute "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name}_seq' WHERE RDB$GENERATOR_NAME='#{name}_seq'" rescue nil
75
+ end
76
+
77
+ def drop_table(name, options = {}) #:nodoc:
78
+ super(name)
79
+ execute "DROP GENERATOR #{name}_seq" rescue nil
80
+ end
81
+
82
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
83
+ execute "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, options[:limit])}"
84
+ end
85
+
86
+ def rename_column(table_name, column_name, new_column_name)
87
+ execute "ALTER TABLE #{table_name} ALTER #{column_name} TO #{new_column_name}"
88
+ end
89
+
90
+ def remove_index(table_name, options) #:nodoc:
91
+ execute "DROP INDEX #{index_name(table_name, options)}"
92
+ end
93
+
94
+ def quote(value, column = nil) # :nodoc:
95
+ return value.quoted_id if value.respond_to?(:quoted_id)
96
+
97
+ # BLOBs are updated separately by an after_save trigger.
98
+ return value.nil? ? "NULL" : "'#{quote_string(value[0..1])}'" if column && [:binary, :text].include?(column.type)
99
+
100
+ if [Time, DateTime].include?(value.class)
101
+ "CAST('#{value.strftime("%Y-%m-%d %H:%M:%S")}' AS TIMESTAMP)"
102
+ else
103
+ if column && column.type == :primary_key
104
+ return value.to_s
105
+ end
106
+ super
107
+ end
108
+ end
109
+
110
+ def quote_string(string) # :nodoc:
111
+ string.gsub(/'/, "''")
112
+ end
113
+
114
+ def quote_column_name(column_name) # :nodoc:
115
+ %Q("#{ar_to_fb_case(column_name)}")
116
+ end
117
+
118
+ def quoted_true # :nodoc:
119
+ quote(1)
120
+ end
121
+
122
+ def quoted_false # :nodoc:
123
+ quote(0)
124
+ end
125
+
126
+ private
127
+
128
+ # Maps uppercase Firebird column names to lowercase for ActiveRecord;
129
+ # mixed-case columns retain their original case.
130
+ def fb_to_ar_case(column_name)
131
+ column_name =~ /[[:lower:]]/ ? column_name : column_name.to_s.downcase
132
+ end
133
+
134
+ # Maps lowercase ActiveRecord column names to uppercase for Fierbird;
135
+ # mixed-case columns retain their original case.
136
+ def ar_to_fb_case(column_name)
137
+ column_name =~ /[[:upper:]]/ ? column_name : column_name.to_s.upcase
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,4 @@
1
+ require 'arjdbc/jdbc'
2
+ jdbc_require_driver 'jdbc/h2'
3
+ require 'arjdbc/h2/connection_methods'
4
+ require 'arjdbc/h2/adapter'
@@ -0,0 +1,54 @@
1
+ require 'arjdbc/hsqldb/adapter'
2
+
3
+ module ArJdbc
4
+ module H2
5
+ include HSQLDB
6
+
7
+ def self.jdbc_connection_class
8
+ ::ActiveRecord::ConnectionAdapters::H2JdbcConnection
9
+ end
10
+
11
+ def adapter_name #:nodoc:
12
+ 'H2'
13
+ end
14
+
15
+ def self.arel2_visitors(config)
16
+ v = HSQLDB.arel2_visitors(config)
17
+ v.merge({}.tap {|v| %w(h2 jdbch2).each {|a| v[a] = ::Arel::Visitors::HSQLDB } })
18
+ end
19
+
20
+ def h2_adapter
21
+ true
22
+ end
23
+
24
+ def tables
25
+ @connection.tables(nil, h2_schema)
26
+ end
27
+
28
+ def columns(table_name, name=nil)
29
+ @connection.columns_internal(table_name.to_s, name, h2_schema)
30
+ end
31
+
32
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
33
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
34
+ change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
35
+ change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
36
+ end
37
+
38
+ private
39
+ def change_column_null(table_name, column_name, null, default = nil)
40
+ if !null && !default.nil?
41
+ execute("UPDATE #{table_name} SET #{column_name}=#{quote(default)} WHERE #{column_name} IS NULL")
42
+ end
43
+ if null
44
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NULL"
45
+ else
46
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NOT NULL"
47
+ end
48
+ end
49
+
50
+ def h2_schema
51
+ @config[:schema] || ''
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,13 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ def h2_connection(config)
5
+ config[:url] ||= "jdbc:h2:#{config[:database]}"
6
+ config[:driver] ||= "org.h2.Driver"
7
+ config[:adapter_spec] = ::ArJdbc::H2
8
+ embedded_driver(config)
9
+ end
10
+ alias_method :jdbch2_connection, :h2_connection
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ require 'arjdbc/jdbc'
2
+ jdbc_require_driver 'jdbc/hsqldb'
3
+ require 'arjdbc/hsqldb/connection_methods'
4
+ require 'arjdbc/hsqldb/adapter'
@@ -0,0 +1,184 @@
1
+ module ::ArJdbc
2
+ module HSQLDB
3
+ def self.column_selector
4
+ [/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::ArJdbc::HSQLDB::Column)}]
5
+ end
6
+
7
+ module Column
8
+ private
9
+ def simplified_type(field_type)
10
+ case field_type
11
+ when /longvarchar/i then :text
12
+ when /tinyint/i then :boolean
13
+ when /real/i then :float
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ # Override of ActiveRecord::ConnectionAdapters::Column
20
+ def extract_limit(sql_type)
21
+ # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns, which
22
+ # for AR purposes should be interpreted as "no limit"
23
+ return nil if sql_type =~ /\(0\)/
24
+ super
25
+ end
26
+
27
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
28
+ def default_value(value)
29
+ # H2 auto-generated key default value
30
+ return nil if value =~ /^\(NEXT VALUE FOR/i
31
+
32
+ # jdbc returns column default strings with actual single quotes around the value.
33
+ return $1 if value =~ /^'(.*)'$/
34
+
35
+ value
36
+ end
37
+ end
38
+
39
+ def adapter_name #:nodoc:
40
+ 'Hsqldb'
41
+ end
42
+
43
+ def self.arel2_visitors(config)
44
+ require 'arel/visitors/hsqldb'
45
+ {}.tap {|v| %w(hsqldb jdbchsqldb).each {|a| v[a] = ::Arel::Visitors::HSQLDB } }
46
+ end
47
+
48
+ def modify_types(tp)
49
+ tp[:primary_key] = "INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
50
+ tp[:integer][:limit] = nil
51
+ tp[:boolean][:limit] = nil
52
+ # set text and float limits so we don't see odd scales tacked on
53
+ # in migrations
54
+ tp[:boolean] = { :name => "tinyint" }
55
+ tp[:text][:limit] = nil
56
+ tp[:float][:limit] = 17 if defined?(::Jdbc::H2)
57
+ tp[:string][:limit] = 255
58
+ tp[:datetime] = { :name => "DATETIME" }
59
+ tp[:timestamp] = { :name => "DATETIME" }
60
+ tp[:time] = { :name => "TIME" }
61
+ tp[:date] = { :name => "DATE" }
62
+ tp
63
+ end
64
+
65
+ def quote(value, column = nil) # :nodoc:
66
+ return value.quoted_id if value.respond_to?(:quoted_id)
67
+
68
+ case value
69
+ when String
70
+ if respond_to?(:h2_adapter) && value.empty?
71
+ "''"
72
+ elsif column && column.type == :binary
73
+ "'#{value.unpack("H*")[0]}'"
74
+ elsif column && (column.type == :integer ||
75
+ column.respond_to?(:primary) && column.primary && column.klass != String)
76
+ value.to_i.to_s
77
+ else
78
+ "'#{quote_string(value)}'"
79
+ end
80
+ else
81
+ super
82
+ end
83
+ end
84
+
85
+ def quote_column_name(name) #:nodoc:
86
+ name = name.to_s
87
+ if name =~ /[-]/
88
+ %Q{"#{name.upcase}"}
89
+ else
90
+ name
91
+ end
92
+ end
93
+
94
+ def quote_string(str)
95
+ str.gsub(/'/, "''")
96
+ end
97
+
98
+ def quoted_true
99
+ '1'
100
+ end
101
+
102
+ def quoted_false
103
+ '0'
104
+ end
105
+
106
+ def add_column(table_name, column_name, type, options = {})
107
+ 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])}"
108
+ add_column_options!(add_column_sql, options)
109
+ execute(add_column_sql)
110
+ end
111
+
112
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
113
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
114
+ end
115
+
116
+ def change_column_default(table_name, column_name, default) #:nodoc:
117
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
118
+ end
119
+
120
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
121
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
122
+ end
123
+
124
+ # Maps logical Rails types to MySQL-specific data types.
125
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
126
+ return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
127
+
128
+ type
129
+ end
130
+
131
+ def rename_table(name, new_name)
132
+ execute "ALTER TABLE #{name} RENAME TO #{new_name}"
133
+ end
134
+
135
+ def last_insert_id
136
+ Integer(select_value("CALL IDENTITY()"))
137
+ end
138
+
139
+ def _execute(sql, name = nil)
140
+ result = super
141
+ ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id : result
142
+ end
143
+
144
+ def add_limit_offset!(sql, options) #:nodoc:
145
+ if sql =~ /^select/i
146
+ offset = options[:offset] || 0
147
+ bef = sql[7..-1]
148
+ if limit = options[:limit]
149
+ sql.replace "SELECT LIMIT #{offset} #{limit} #{bef}"
150
+ elsif offset > 0
151
+ sql.replace "SELECT LIMIT #{offset} 0 #{bef}"
152
+ end
153
+ end
154
+ end
155
+
156
+ # override to filter out system tables that otherwise end
157
+ # up in db/schema.rb during migrations. JdbcConnection#tables
158
+ # now takes an optional block filter so we can screen out
159
+ # rows corresponding to system tables. HSQLDB names its
160
+ # system tables SYSTEM.*, but H2 seems to name them without
161
+ # any kind of convention
162
+ def tables
163
+ @connection.tables.select {|row| row.to_s !~ /^system_/i }
164
+ end
165
+
166
+ def remove_index(table_name, options = {})
167
+ execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
168
+ end
169
+
170
+ def recreate_database(name)
171
+ drop_database(name)
172
+ end
173
+
174
+ # do nothing since database gets created upon connection. However
175
+ # this method gets called by rails db rake tasks so now we're
176
+ # avoiding method_missing error
177
+ def create_database(name)
178
+ end
179
+
180
+ def drop_database(name)
181
+ execute("DROP ALL OBJECTS")
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,15 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ def hsqldb_connection(config)
5
+ require "arjdbc/hsqldb"
6
+ config[:url] ||= "jdbc:hsqldb:#{config[:database]}"
7
+ config[:driver] ||= "org.hsqldb.jdbcDriver"
8
+ config[:adapter_spec] = ::ArJdbc::HSQLDB
9
+ embedded_driver(config)
10
+ end
11
+
12
+ alias_method :jdbchsqldb_connection, :hsqldb_connection
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ require 'arjdbc/jdbc'
2
+ require 'arjdbc/informix/connection_methods'
3
+ require 'arjdbc/informix/adapter'
@@ -0,0 +1,142 @@
1
+ module ::ActiveRecord
2
+ class Base
3
+ after_save :write_lobs
4
+
5
+ private
6
+ def write_lobs
7
+ if connection.is_a?(ArJdbc::Informix)
8
+ self.class.columns.each do |c|
9
+ if [:text, :binary].include? c.type
10
+ value = self[c.name]
11
+ if respond_to?(:unserializable_attribute?)
12
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
13
+ else
14
+ value = value.to_yaml if value.is_a?(Hash)
15
+ end
16
+
17
+ unless value.nil? || (value == '')
18
+ connection.write_large_object(c.type == :binary,
19
+ c.name,
20
+ self.class.table_name,
21
+ self.class.primary_key,
22
+ quote_value(id),
23
+ value)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ module ::ArJdbc
33
+ module Informix
34
+ def self.extended(base)
35
+ @@db_major_version = base.select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
36
+ end
37
+
38
+ def self.column_selector
39
+ [ /informix/i,
40
+ lambda { |cfg, column| column.extend(::ArJdbc::Informix::Column) } ]
41
+ end
42
+
43
+ def self.jdbc_connection_class
44
+ ::ActiveRecord::ConnectionAdapters::InformixJdbcConnection
45
+ end
46
+
47
+ module Column
48
+ private
49
+ # TODO: Test all Informix column types.
50
+ def simplified_type(field_type)
51
+ if field_type =~ /serial/i
52
+ :primary_key
53
+ else
54
+ super
55
+ end
56
+ end
57
+ end
58
+
59
+ def modify_types(tp)
60
+ tp[:primary_key] = "SERIAL PRIMARY KEY"
61
+ tp[:string] = { :name => "VARCHAR", :limit => 255 }
62
+ tp[:integer] = { :name => "INTEGER" }
63
+ tp[:float] = { :name => "FLOAT" }
64
+ tp[:decimal] = { :name => "DECIMAL" }
65
+ tp[:datetime] = { :name => "DATETIME YEAR TO FRACTION(5)" }
66
+ tp[:timestamp] = { :name => "DATETIME YEAR TO FRACTION(5)" }
67
+ tp[:time] = { :name => "DATETIME HOUR TO FRACTION(5)" }
68
+ tp[:date] = { :name => "DATE" }
69
+ tp[:binary] = { :name => "BYTE" }
70
+ tp[:boolean] = { :name => "BOOLEAN" }
71
+ tp
72
+ end
73
+
74
+ def prefetch_primary_key?(table_name = nil)
75
+ true
76
+ end
77
+
78
+ def supports_migrations?
79
+ true
80
+ end
81
+
82
+ def default_sequence_name(table, column)
83
+ "#{table}_seq"
84
+ end
85
+
86
+ def add_limit_offset!(sql, options)
87
+ if options[:limit]
88
+ limit = "FIRST #{options[:limit]}"
89
+ # SKIP available only in IDS >= 10
90
+ offset = (@@db_major_version >= 10 && options[:offset]?
91
+ "SKIP #{options[:offset]}" : "")
92
+ sql.sub!(/^select /i, "SELECT #{offset} #{limit} ")
93
+ end
94
+ sql
95
+ end
96
+
97
+ def next_sequence_value(sequence_name)
98
+ select_one("SELECT #{sequence_name}.nextval id FROM systables WHERE tabid=1")['id']
99
+ end
100
+
101
+ # TODO: Add some smart quoting for newlines in string and text fields.
102
+ def quote_string(string)
103
+ string.gsub(/\'/, "''")
104
+ end
105
+
106
+ def quote(value, column = nil)
107
+ if column && [:binary, :text].include?(column.type)
108
+ # LOBs are updated separately by an after_save trigger.
109
+ "NULL"
110
+ elsif column && column.type == :date
111
+ "'#{value.mon}/#{value.day}/#{value.year}'"
112
+ else
113
+ super
114
+ end
115
+ end
116
+
117
+ def create_table(name, options = {})
118
+ super(name, options)
119
+ execute("CREATE SEQUENCE #{name}_seq")
120
+ end
121
+
122
+ def rename_table(name, new_name)
123
+ execute("RENAME TABLE #{name} TO #{new_name}")
124
+ execute("RENAME SEQUENCE #{name}_seq TO #{new_name}_seq")
125
+ end
126
+
127
+ def drop_table(name)
128
+ super(name)
129
+ execute("DROP SEQUENCE #{name}_seq")
130
+ end
131
+
132
+ def remove_index(table_name, options = {})
133
+ @connection.execute_update("DROP INDEX #{index_name(table_name, options)}")
134
+ end
135
+
136
+ private
137
+ def select(sql, *rest)
138
+ # Informix does not like "= NULL", "!= NULL", or "<> NULL".
139
+ execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), *rest)
140
+ end
141
+ end # module Informix
142
+ end # module ::ArJdbc