activerecord-jdbc-adapter 0.9.7-java → 1.0.0.beta1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/History.txt +11 -0
  2. data/Manifest.txt +71 -38
  3. data/lib/active_record/connection_adapters/cachedb_adapter.rb +1 -1
  4. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -13
  5. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -13
  6. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -13
  7. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -1
  8. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -661
  9. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -1
  10. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -13
  11. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -13
  12. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -1
  13. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -13
  14. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -13
  15. data/lib/activerecord-jdbc-adapter.rb +2 -2
  16. data/lib/arjdbc.rb +29 -0
  17. data/lib/arjdbc/cachedb.rb +3 -0
  18. data/lib/arjdbc/cachedb/adapter.rb +20 -0
  19. data/lib/arjdbc/cachedb/connection_methods.rb +10 -0
  20. data/lib/arjdbc/db2.rb +2 -0
  21. data/lib/{jdbc_adapter/jdbc_db2.rb → arjdbc/db2/adapter.rb} +1 -17
  22. data/lib/arjdbc/derby.rb +7 -0
  23. data/lib/{jdbc_adapter/jdbc_derby.rb → arjdbc/derby/adapter.rb} +8 -26
  24. data/lib/arjdbc/derby/connection_methods.rb +18 -0
  25. data/lib/arjdbc/discover.rb +99 -0
  26. data/lib/arjdbc/firebird.rb +2 -0
  27. data/lib/{jdbc_adapter/jdbc_firebird.rb → arjdbc/firebird/adapter.rb} +12 -16
  28. data/lib/arjdbc/h2.rb +4 -0
  29. data/lib/arjdbc/h2/adapter.rb +15 -0
  30. data/lib/arjdbc/h2/connection_methods.rb +12 -0
  31. data/lib/arjdbc/hsqldb.rb +4 -0
  32. data/lib/{jdbc_adapter/jdbc_hsqldb.rb → arjdbc/hsqldb/adapter.rb} +6 -58
  33. data/lib/arjdbc/hsqldb/connection_methods.rb +14 -0
  34. data/lib/arjdbc/informix.rb +3 -0
  35. data/lib/{jdbc_adapter/jdbc_informix.rb → arjdbc/informix/adapter.rb} +6 -19
  36. data/lib/arjdbc/informix/connection_methods.rb +10 -0
  37. data/lib/arjdbc/jdbc.rb +2 -0
  38. data/lib/arjdbc/jdbc/adapter.rb +235 -0
  39. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  40. data/lib/arjdbc/jdbc/callbacks.rb +44 -0
  41. data/lib/arjdbc/jdbc/column.rb +38 -0
  42. data/lib/arjdbc/jdbc/compatibility.rb +51 -0
  43. data/lib/arjdbc/jdbc/connection.rb +97 -0
  44. data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
  45. data/lib/arjdbc/jdbc/core_ext.rb +24 -0
  46. data/lib/arjdbc/jdbc/discover.rb +18 -0
  47. data/lib/arjdbc/jdbc/driver.rb +44 -0
  48. data/lib/arjdbc/jdbc/extension.rb +47 -0
  49. data/lib/arjdbc/jdbc/java.rb +14 -0
  50. data/lib/{jdbc_adapter → arjdbc/jdbc}/jdbc.rake +0 -0
  51. data/lib/{jdbc_adapter → arjdbc/jdbc}/missing_functionality_helper.rb +5 -5
  52. data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
  53. data/lib/{jdbc_adapter → arjdbc/jdbc}/railtie.rb +1 -1
  54. data/lib/{jdbc_adapter → arjdbc/jdbc}/rake_tasks.rb +0 -0
  55. data/lib/arjdbc/jdbc/require_driver.rb +16 -0
  56. data/lib/arjdbc/jdbc/type_converter.rb +119 -0
  57. data/lib/arjdbc/mimer.rb +2 -0
  58. data/lib/{jdbc_adapter/jdbc_mimer.rb → arjdbc/mimer/adapter.rb} +16 -19
  59. data/lib/arjdbc/mssql.rb +4 -0
  60. data/lib/{jdbc_adapter/jdbc_mssql.rb → arjdbc/mssql/adapter.rb} +19 -31
  61. data/lib/arjdbc/mssql/connection_methods.rb +13 -0
  62. data/lib/{jdbc_adapter → arjdbc/mssql}/tsql_helper.rb +1 -1
  63. data/lib/arjdbc/mysql.rb +4 -0
  64. data/lib/arjdbc/mysql/adapter.rb +388 -0
  65. data/lib/arjdbc/mysql/connection_methods.rb +26 -0
  66. data/lib/arjdbc/oracle.rb +3 -0
  67. data/lib/{jdbc_adapter/jdbc_oracle.rb → arjdbc/oracle/adapter.rb} +9 -17
  68. data/lib/arjdbc/oracle/connection_methods.rb +11 -0
  69. data/lib/arjdbc/postgresql.rb +4 -0
  70. data/lib/{jdbc_adapter/jdbc_postgre.rb → arjdbc/postgresql/adapter.rb} +7 -36
  71. data/lib/arjdbc/postgresql/connection_methods.rb +21 -0
  72. data/lib/arjdbc/sqlite3.rb +4 -0
  73. data/lib/{jdbc_adapter/jdbc_sqlite3.rb → arjdbc/sqlite3/adapter.rb} +106 -104
  74. data/lib/arjdbc/sqlite3/connection_methods.rb +33 -0
  75. data/lib/arjdbc/sybase.rb +2 -0
  76. data/lib/arjdbc/sybase/adapter.rb +46 -0
  77. data/lib/arjdbc/version.rb +8 -0
  78. data/lib/jdbc_adapter.rb +2 -27
  79. data/lib/jdbc_adapter/version.rb +3 -5
  80. data/rails_generators/templates/config/initializers/jdbc.rb +1 -1
  81. data/rakelib/compile.rake +3 -2
  82. data/rakelib/package.rake +3 -3
  83. data/src/java/{jdbc_adapter/JdbcDerbySpec.java → arjdbc/derby/DerbyModule.java} +32 -32
  84. data/src/java/{jdbc_adapter/JdbcAdapterInternalService.java → arjdbc/jdbc/AdapterJavaService.java} +13 -7
  85. data/src/java/{jdbc_adapter → arjdbc/jdbc}/JdbcConnectionFactory.java +6 -6
  86. data/src/java/{jdbc_adapter → arjdbc/jdbc}/RubyJdbcConnection.java +91 -16
  87. data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
  88. data/src/java/{jdbc_adapter → arjdbc/mssql}/MssqlRubyJdbcConnection.java +5 -2
  89. data/src/java/{jdbc_adapter/JdbcMySQLSpec.java → arjdbc/mysql/MySQLModule.java} +12 -12
  90. data/src/java/{jdbc_adapter/PostgresRubyJdbcConnection.java → arjdbc/postgresql/PostgresqlRubyJdbcConnection.java} +11 -9
  91. data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +64 -0
  92. data/test/abstract_db_create.rb +4 -1
  93. data/test/activerecord/connection_adapters/type_conversion_test.rb +1 -1
  94. data/test/db/cachedb.rb +0 -0
  95. data/test/db/derby.rb +12 -14
  96. data/test/db/hsqldb.rb +3 -2
  97. data/test/db/jndi_config.rb +4 -4
  98. data/test/db/sqlite3.rb +2 -6
  99. data/test/db2_simple_test.rb +23 -0
  100. data/test/derby_migration_test.rb +50 -3
  101. data/test/jdbc_common.rb +1 -1
  102. data/test/jndi_callbacks_test.rb +1 -0
  103. data/test/postgres_nonseq_pkey_test.rb +0 -2
  104. data/test/postgres_schema_search_path_test.rb +0 -2
  105. data/test/simple.rb +3 -3
  106. data/test/sybase_jtds_simple_test.rb +22 -0
  107. metadata +82 -46
  108. data/lib/active_record/connection_adapters/jdbc_adapter_spec.rb +0 -26
  109. data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
  110. data/lib/jdbc_adapter/jdbc_cachedb.rb +0 -33
  111. data/lib/jdbc_adapter/jdbc_mysql.rb +0 -260
  112. data/lib/jdbc_adapter/jdbc_sybase.rb +0 -50
  113. data/src/java/jdbc_adapter/SQLBlock.java +0 -27
  114. data/src/java/jdbc_adapter/Sqlite3RubyJdbcConnection.java +0 -41
  115. data/test/jdbc_adapter/jdbc_db2_test.rb +0 -26
  116. data/test/jdbc_adapter/jdbc_sybase_test.rb +0 -33
  117. data/test/minirunit.rb +0 -109
  118. data/test/minirunit/testConnect.rb +0 -14
  119. data/test/minirunit/testH2.rb +0 -73
  120. data/test/minirunit/testHsqldb.rb +0 -73
  121. data/test/minirunit/testLoadActiveRecord.rb +0 -3
  122. data/test/minirunit/testMysql.rb +0 -83
  123. data/test/minirunit/testRawSelect.rb +0 -24
@@ -1,3 +1,14 @@
1
+ == 1.0.0
2
+
3
+ - (1.0.0.beta1)
4
+ - Make database-specific extensions only load when necessary
5
+ - Allow for discovery of database extensions outside of ar-jdbc
6
+ proper. This should allow for custom database development to be
7
+ developed and released without relying on AR-JDBC core.
8
+ - Get AR's own tests running as close to 100% as possible. MySQL is
9
+ currently 100%, SQLite3 is close.
10
+ - JRUBY-4876: Bump up Derby's max index name length (Uwe Kubosch)
11
+
1
12
  == 0.9.7
2
13
 
3
14
  - JRUBY-4781: Fix multiple database connection collision issue w/
@@ -4,6 +4,7 @@ README.txt
4
4
  Rakefile
5
5
  LICENSE.txt
6
6
  lib/activerecord-jdbc-adapter.rb
7
+ lib/arjdbc.rb
7
8
  lib/jdbc_adapter.rb
8
9
  lib/pg.rb
9
10
  lib/active_record/connection_adapters/cachedb_adapter.rb
@@ -12,7 +13,6 @@ lib/active_record/connection_adapters/h2_adapter.rb
12
13
  lib/active_record/connection_adapters/hsqldb_adapter.rb
13
14
  lib/active_record/connection_adapters/informix_adapter.rb
14
15
  lib/active_record/connection_adapters/jdbc_adapter.rb
15
- lib/active_record/connection_adapters/jdbc_adapter_spec.rb
16
16
  lib/active_record/connection_adapters/jndi_adapter.rb
17
17
  lib/active_record/connection_adapters/mssql_adapter.rb
18
18
  lib/active_record/connection_adapters/mysql_adapter.rb
@@ -24,26 +24,68 @@ lib/arel/engines/sql/compilers/derby_compiler.rb
24
24
  lib/arel/engines/sql/compilers/h2_compiler.rb
25
25
  lib/arel/engines/sql/compilers/hsqldb_compiler.rb
26
26
  lib/arel/engines/sql/compilers/jdbc_compiler.rb
27
+ lib/arjdbc/cachedb.rb
28
+ lib/arjdbc/db2.rb
29
+ lib/arjdbc/derby.rb
30
+ lib/arjdbc/discover.rb
31
+ lib/arjdbc/firebird.rb
32
+ lib/arjdbc/h2.rb
33
+ lib/arjdbc/hsqldb.rb
34
+ lib/arjdbc/informix.rb
35
+ lib/arjdbc/jdbc.rb
36
+ lib/arjdbc/mimer.rb
37
+ lib/arjdbc/mssql.rb
38
+ lib/arjdbc/mysql.rb
39
+ lib/arjdbc/oracle.rb
40
+ lib/arjdbc/postgresql.rb
41
+ lib/arjdbc/sqlite3.rb
42
+ lib/arjdbc/sybase.rb
43
+ lib/arjdbc/version.rb
44
+ lib/arjdbc/cachedb/adapter.rb
45
+ lib/arjdbc/cachedb/connection_methods.rb
46
+ lib/arjdbc/db2/adapter.rb
47
+ lib/arjdbc/derby/adapter.rb
48
+ lib/arjdbc/derby/connection_methods.rb
49
+ lib/arjdbc/firebird/adapter.rb
50
+ lib/arjdbc/h2/adapter.rb
51
+ lib/arjdbc/h2/connection_methods.rb
52
+ lib/arjdbc/hsqldb/adapter.rb
53
+ lib/arjdbc/hsqldb/connection_methods.rb
54
+ lib/arjdbc/informix/adapter.rb
55
+ lib/arjdbc/informix/connection_methods.rb
56
+ lib/arjdbc/jdbc/adapter.rb
57
+ lib/arjdbc/jdbc/callbacks.rb
58
+ lib/arjdbc/jdbc/column.rb
59
+ lib/arjdbc/jdbc/compatibility.rb
60
+ lib/arjdbc/jdbc/connection.rb
61
+ lib/arjdbc/jdbc/connection_methods.rb
62
+ lib/arjdbc/jdbc/core_ext.rb
63
+ lib/arjdbc/jdbc/discover.rb
64
+ lib/arjdbc/jdbc/driver.rb
65
+ lib/arjdbc/jdbc/extension.rb
66
+ lib/arjdbc/jdbc/java.rb
67
+ lib/arjdbc/jdbc/missing_functionality_helper.rb
68
+ lib/arjdbc/jdbc/quoted_primary_key.rb
69
+ lib/arjdbc/jdbc/railtie.rb
70
+ lib/arjdbc/jdbc/rake_tasks.rb
71
+ lib/arjdbc/jdbc/require_driver.rb
72
+ lib/arjdbc/jdbc/type_converter.rb
73
+ lib/arjdbc/mimer/adapter.rb
74
+ lib/arjdbc/mssql/adapter.rb
75
+ lib/arjdbc/mssql/connection_methods.rb
76
+ lib/arjdbc/mssql/tsql_helper.rb
77
+ lib/arjdbc/mysql/adapter.rb
78
+ lib/arjdbc/mysql/connection_methods.rb
79
+ lib/arjdbc/oracle/adapter.rb
80
+ lib/arjdbc/oracle/connection_methods.rb
81
+ lib/arjdbc/postgresql/adapter.rb
82
+ lib/arjdbc/postgresql/connection_methods.rb
83
+ lib/arjdbc/sqlite3/adapter.rb
84
+ lib/arjdbc/sqlite3/connection_methods.rb
85
+ lib/arjdbc/sybase/adapter.rb
27
86
  lib/generators/jdbc/jdbc_generator.rb
28
- lib/jdbc_adapter/jdbc_cachedb.rb
29
- lib/jdbc_adapter/jdbc_db2.rb
30
- lib/jdbc_adapter/jdbc_derby.rb
31
- lib/jdbc_adapter/jdbc_firebird.rb
32
- lib/jdbc_adapter/jdbc_hsqldb.rb
33
- lib/jdbc_adapter/jdbc_informix.rb
34
- lib/jdbc_adapter/jdbc_mimer.rb
35
- lib/jdbc_adapter/jdbc_mssql.rb
36
- lib/jdbc_adapter/jdbc_mysql.rb
37
- lib/jdbc_adapter/jdbc_oracle.rb
38
- lib/jdbc_adapter/jdbc_postgre.rb
39
- lib/jdbc_adapter/jdbc_sqlite3.rb
40
- lib/jdbc_adapter/jdbc_sybase.rb
41
- lib/jdbc_adapter/missing_functionality_helper.rb
42
- lib/jdbc_adapter/railtie.rb
43
- lib/jdbc_adapter/rake_tasks.rb
44
- lib/jdbc_adapter/tsql_helper.rb
45
87
  lib/jdbc_adapter/version.rb
46
- lib/jdbc_adapter/jdbc_adapter_internal.jar
88
+ lib/arjdbc/jdbc/adapter_java.jar
47
89
  test/abstract_db_create.rb
48
90
  test/cachedb_simple_test.rb
49
91
  test/db2_simple_test.rb
@@ -60,7 +102,6 @@ test/jdbc_common.rb
60
102
  test/jndi_callbacks_test.rb
61
103
  test/jndi_test.rb
62
104
  test/manualTestDatabase.rb
63
- test/minirunit.rb
64
105
  test/mssql_db_create_test.rb
65
106
  test/mssql_identity_insert_test.rb
66
107
  test/mssql_legacy_types_test.rb
@@ -99,14 +140,6 @@ test/db/mysql.rb
99
140
  test/db/oracle.rb
100
141
  test/db/postgres.rb
101
142
  test/db/sqlite3.rb
102
- test/jdbc_adapter/jdbc_db2_test.rb
103
- test/jdbc_adapter/jdbc_sybase_test.rb
104
- test/minirunit/testConnect.rb
105
- test/minirunit/testH2.rb
106
- test/minirunit/testHsqldb.rb
107
- test/minirunit/testLoadActiveRecord.rb
108
- test/minirunit/testMysql.rb
109
- test/minirunit/testRawSelect.rb
110
143
  test/models/add_not_null_column_to_table.rb
111
144
  test/models/auto_id.rb
112
145
  test/models/data_types.rb
@@ -115,16 +148,16 @@ test/models/mixed_case.rb
115
148
  test/models/reserved_word.rb
116
149
  test/models/string_id.rb
117
150
  test/models/validates_uniqueness_of_string.rb
118
- lib/jdbc_adapter/jdbc.rake
119
- src/java/jdbc_adapter/JdbcAdapterInternalService.java
120
- src/java/jdbc_adapter/JdbcConnectionFactory.java
121
- src/java/jdbc_adapter/JdbcDerbySpec.java
122
- src/java/jdbc_adapter/JdbcMySQLSpec.java
123
- src/java/jdbc_adapter/MssqlRubyJdbcConnection.java
124
- src/java/jdbc_adapter/PostgresRubyJdbcConnection.java
125
- src/java/jdbc_adapter/RubyJdbcConnection.java
126
- src/java/jdbc_adapter/SQLBlock.java
127
- src/java/jdbc_adapter/Sqlite3RubyJdbcConnection.java
151
+ lib/arjdbc/jdbc/jdbc.rake
152
+ src/java/arjdbc/derby/DerbyModule.java
153
+ src/java/arjdbc/jdbc/AdapterJavaService.java
154
+ src/java/arjdbc/jdbc/JdbcConnectionFactory.java
155
+ src/java/arjdbc/jdbc/RubyJdbcConnection.java
156
+ src/java/arjdbc/jdbc/SQLBlock.java
157
+ src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java
158
+ src/java/arjdbc/mysql/MySQLModule.java
159
+ src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java
160
+ src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java
128
161
  rakelib/compile.rake
129
162
  rakelib/package.rake
130
163
  rakelib/rails.rake
@@ -1 +1 @@
1
- require 'active_record/connection_adapters/jdbc_adapter'
1
+ require 'arjdbc/cachedb'
@@ -1,13 +1 @@
1
- tried_gem = false
2
- begin
3
- require "jdbc/derby"
4
- rescue LoadError
5
- unless tried_gem
6
- require 'rubygems'
7
- gem "jdbc-derby"
8
- tried_gem = true
9
- retry
10
- end
11
- # trust that the derby jar is already present
12
- end
13
- require 'active_record/connection_adapters/jdbc_adapter'
1
+ require 'arjdbc/derby'
@@ -1,13 +1 @@
1
- tried_gem = false
2
- begin
3
- require "jdbc/h2"
4
- rescue LoadError
5
- unless tried_gem
6
- require 'rubygems'
7
- gem "jdbc-h2"
8
- tried_gem = true
9
- retry
10
- end
11
- # trust that the hsqldb jar is already present
12
- end
13
- require 'active_record/connection_adapters/jdbc_adapter'
1
+ require 'arjdbc/h2'
@@ -1,13 +1 @@
1
- tried_gem = false
2
- begin
3
- require "jdbc/hsqldb"
4
- rescue LoadError
5
- unless tried_gem
6
- require 'rubygems'
7
- gem "jdbc-hsqldb"
8
- tried_gem = true
9
- retry
10
- end
11
- # trust that the hsqldb jar is already present
12
- end
13
- require 'active_record/connection_adapters/jdbc_adapter'
1
+ require 'arjdbc/hsqldb'
@@ -1 +1 @@
1
- require 'active_record/connection_adapters/jdbc_adapter'
1
+ require 'arjdbc/informix'
@@ -1,661 +1 @@
1
- require 'active_record/version'
2
- require 'active_record/connection_adapters/abstract_adapter'
3
- require 'java'
4
- require 'active_record/connection_adapters/jdbc_adapter_spec'
5
- require 'jdbc_adapter/jdbc_adapter_internal'
6
- require 'bigdecimal'
7
-
8
- # AR's 2.2 version of this method is sufficient, but we need it for
9
- # older versions
10
- if ActiveRecord::VERSION::MAJOR <= 2 && ActiveRecord::VERSION::MINOR < 2
11
- module ActiveRecord
12
- module ConnectionAdapters # :nodoc:
13
- module SchemaStatements
14
- # Convert the speficied column type to a SQL string.
15
- def type_to_sql(type, limit = nil, precision = nil, scale = nil)
16
- if native = native_database_types[type]
17
- column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
18
-
19
- if type == :decimal # ignore limit, use precision and scale
20
- scale ||= native[:scale]
21
-
22
- if precision ||= native[:precision]
23
- if scale
24
- column_type_sql << "(#{precision},#{scale})"
25
- else
26
- column_type_sql << "(#{precision})"
27
- end
28
- elsif scale
29
- raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale if specified"
30
- end
31
-
32
- elsif limit ||= native.is_a?(Hash) && native[:limit]
33
- column_type_sql << "(#{limit})"
34
- end
35
-
36
- column_type_sql
37
- else
38
- type
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
45
-
46
- module JdbcSpec
47
- module ActiveRecordExtensions
48
- def jdbc_connection(config)
49
- ::ActiveRecord::ConnectionAdapters::JdbcAdapter.new(nil, logger, config)
50
- end
51
- alias jndi_connection jdbc_connection
52
-
53
- def embedded_driver(config)
54
- config[:username] ||= "sa"
55
- config[:password] ||= ""
56
- jdbc_connection(config)
57
- end
58
- end
59
-
60
- module QuotedPrimaryKeyExtension
61
- def self.extended(base)
62
- # Rails 3 method Rails 2 method
63
- meth = [:arel_attributes_values, :attributes_with_quotes].detect do |m|
64
- base.private_instance_methods.include?(m.to_s)
65
- end
66
- pk_hash_key = "self.class.primary_key"
67
- pk_hash_value = '"?"'
68
- if meth == :arel_attributes_values
69
- pk_hash_key = "self.class.arel_table[#{pk_hash_key}]"
70
- pk_hash_value = "Arel::SqlLiteral.new(#{pk_hash_value})"
71
- end
72
- if meth
73
- base.module_eval %{
74
- alias :#{meth}_pre_pk :#{meth}
75
- def #{meth}(include_primary_key = true, *args) #:nodoc:
76
- aq = #{meth}_pre_pk(include_primary_key, *args)
77
- if connection.is_a?(JdbcSpec::Oracle) || connection.is_a?(JdbcSpec::Mimer)
78
- aq[#{pk_hash_key}] = #{pk_hash_value} if include_primary_key && aq[#{pk_hash_key}].nil?
79
- end
80
- aq
81
- end
82
- }
83
- end
84
- end
85
- end
86
- end
87
-
88
- module ActiveRecord
89
- class Base
90
- extend JdbcSpec::ActiveRecordExtensions
91
- end
92
-
93
- module ConnectionAdapters
94
- module Java
95
- Class = java.lang.Class
96
- URL = java.net.URL
97
- URLClassLoader = java.net.URLClassLoader
98
- end
99
-
100
- module Jdbc
101
- Mutex = java.lang.Object.new
102
- DriverManager = java.sql.DriverManager
103
- Statement = java.sql.Statement
104
- Types = java.sql.Types
105
-
106
- # some symbolic constants for the benefit of the JDBC-based
107
- # JdbcConnection#indexes method
108
- module IndexMetaData
109
- INDEX_NAME = 6
110
- NON_UNIQUE = 4
111
- TABLE_NAME = 3
112
- COLUMN_NAME = 9
113
- end
114
-
115
- module TableMetaData
116
- TABLE_CAT = 1
117
- TABLE_SCHEM = 2
118
- TABLE_NAME = 3
119
- TABLE_TYPE = 4
120
- end
121
-
122
- module PrimaryKeyMetaData
123
- COLUMN_NAME = 4
124
- end
125
-
126
- end
127
-
128
- # I want to use JDBC's DatabaseMetaData#getTypeInfo to choose the best native types to
129
- # use for ActiveRecord's Adapter#native_database_types in a database-independent way,
130
- # but apparently a database driver can return multiple types for a given
131
- # java.sql.Types constant. So this type converter uses some heuristics to try to pick
132
- # the best (most common) type to use. It's not great, it would be better to just
133
- # delegate to each database's existin AR adapter's native_database_types method, but I
134
- # wanted to try to do this in a way that didn't pull in all the other adapters as
135
- # dependencies. Suggestions appreciated.
136
- class JdbcTypeConverter
137
- # The basic ActiveRecord types, mapped to an array of procs that are used to #select
138
- # the best type. The procs are used as selectors in order until there is only one
139
- # type left. If all the selectors are applied and there is still more than one
140
- # type, an exception will be raised.
141
- AR_TO_JDBC_TYPES = {
142
- :string => [ lambda {|r| Jdbc::Types::VARCHAR == r['data_type'].to_i},
143
- lambda {|r| r['type_name'] =~ /^varchar/i},
144
- lambda {|r| r['type_name'] =~ /^varchar$/i},
145
- lambda {|r| r['type_name'] =~ /varying/i}],
146
- :text => [ lambda {|r| [Jdbc::Types::LONGVARCHAR, Jdbc::Types::CLOB].include?(r['data_type'].to_i)},
147
- lambda {|r| r['type_name'] =~ /^text$/i}, # For Informix
148
- lambda {|r| r['type_name'] =~ /^(text|clob)$/i},
149
- lambda {|r| r['type_name'] =~ /^character large object$/i},
150
- lambda {|r| r['sql_data_type'] == 2005}],
151
- :integer => [ lambda {|r| Jdbc::Types::INTEGER == r['data_type'].to_i},
152
- lambda {|r| r['type_name'] =~ /^integer$/i},
153
- lambda {|r| r['type_name'] =~ /^int4$/i},
154
- lambda {|r| r['type_name'] =~ /^int$/i}],
155
- :decimal => [ lambda {|r| Jdbc::Types::DECIMAL == r['data_type'].to_i},
156
- lambda {|r| r['type_name'] =~ /^decimal$/i},
157
- lambda {|r| r['type_name'] =~ /^numeric$/i},
158
- lambda {|r| r['type_name'] =~ /^number$/i},
159
- lambda {|r| r['type_name'] =~ /^real$/i},
160
- lambda {|r| r['precision'] == '38'},
161
- lambda {|r| r['data_type'] == '2'}],
162
- :float => [ lambda {|r| [Jdbc::Types::FLOAT,Jdbc::Types::DOUBLE, Jdbc::Types::REAL].include?(r['data_type'].to_i)},
163
- lambda {|r| r['data_type'].to_i == Jdbc::Types::REAL}, #Prefer REAL to DOUBLE for Postgresql
164
- lambda {|r| r['type_name'] =~ /^float/i},
165
- lambda {|r| r['type_name'] =~ /^double$/i},
166
- lambda {|r| r['type_name'] =~ /^real$/i},
167
- lambda {|r| r['precision'] == '15'}],
168
- :datetime => [ lambda {|r| Jdbc::Types::TIMESTAMP == r['data_type'].to_i},
169
- lambda {|r| r['type_name'] =~ /^datetime$/i},
170
- lambda {|r| r['type_name'] =~ /^timestamp$/i},
171
- lambda {|r| r['type_name'] =~ /^date/i},
172
- lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
173
- :timestamp => [ lambda {|r| Jdbc::Types::TIMESTAMP == r['data_type'].to_i},
174
- lambda {|r| r['type_name'] =~ /^timestamp$/i},
175
- lambda {|r| r['type_name'] =~ /^datetime/i},
176
- lambda {|r| r['type_name'] =~ /^date/i},
177
- lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
178
- :time => [ lambda {|r| Jdbc::Types::TIME == r['data_type'].to_i},
179
- lambda {|r| r['type_name'] =~ /^time$/i},
180
- lambda {|r| r['type_name'] =~ /^datetime/i}, # For Informix
181
- lambda {|r| r['type_name'] =~ /^date/i},
182
- lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
183
- :date => [ lambda {|r| Jdbc::Types::DATE == r['data_type'].to_i},
184
- lambda {|r| r['type_name'] =~ /^date$/i},
185
- lambda {|r| r['type_name'] =~ /^date/i},
186
- lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver3
187
- :binary => [ lambda {|r| [Jdbc::Types::LONGVARBINARY,Jdbc::Types::BINARY,Jdbc::Types::BLOB].include?(r['data_type'].to_i)},
188
- lambda {|r| r['type_name'] =~ /^blob/i},
189
- lambda {|r| r['type_name'] =~ /sub_type 0$/i}, # For FireBird
190
- lambda {|r| r['type_name'] =~ /^varbinary$/i}, # We want this sucker for Mimer
191
- lambda {|r| r['type_name'] =~ /^binary$/i}, ],
192
- :boolean => [ lambda {|r| [Jdbc::Types::TINYINT].include?(r['data_type'].to_i)},
193
- lambda {|r| r['type_name'] =~ /^bool/i},
194
- lambda {|r| r['data_type'] == '-7'},
195
- lambda {|r| r['type_name'] =~ /^tinyint$/i},
196
- lambda {|r| r['type_name'] =~ /^decimal$/i},
197
- lambda {|r| r['type_name'] =~ /^integer$/i}]
198
- }
199
-
200
- def initialize(types)
201
- @types = types
202
- @types.each {|t| t['type_name'] ||= t['local_type_name']} # Sybase driver seems to want 'local_type_name'
203
- end
204
-
205
- def choose_best_types
206
- type_map = {}
207
- @types.each do |row|
208
- name = row['type_name'].downcase
209
- k = name.to_sym
210
- type_map[k] = { :name => name }
211
- type_map[k][:limit] = row['precision'].to_i if row['precision']
212
- end
213
-
214
- AR_TO_JDBC_TYPES.keys.each do |k|
215
- typerow = choose_type(k)
216
- type_map[k] = { :name => typerow['type_name'].downcase }
217
- case k
218
- when :integer, :string, :decimal
219
- type_map[k][:limit] = typerow['precision'] && typerow['precision'].to_i
220
- when :boolean
221
- type_map[k][:limit] = 1
222
- end
223
- end
224
- type_map
225
- end
226
-
227
- def choose_type(ar_type)
228
- procs = AR_TO_JDBC_TYPES[ar_type]
229
- types = @types
230
- procs.each do |p|
231
- new_types = types.reject {|r| r["data_type"].to_i == Jdbc::Types::OTHER}
232
- new_types = new_types.select(&p)
233
- new_types = new_types.inject([]) do |typs,t|
234
- typs << t unless typs.detect {|el| el['type_name'] == t['type_name']}
235
- typs
236
- end
237
- return new_types.first if new_types.length == 1
238
- types = new_types if new_types.length > 0
239
- end
240
- raise "unable to choose type for #{ar_type} from:\n#{types.collect{|t| t['type_name']}.inspect}"
241
- end
242
- end
243
-
244
- class JdbcDriver
245
- def initialize(name)
246
- @name = name
247
- end
248
-
249
- def driver_class
250
- @driver_class ||= begin
251
- driver_class_const = (@name[0...1].capitalize + @name[1..@name.length]).gsub(/\./, '_')
252
- Jdbc::Mutex.synchronized do
253
- unless Jdbc.const_defined?(driver_class_const)
254
- driver_class_name = @name
255
- Jdbc.module_eval do
256
- include_class(driver_class_name) { driver_class_const }
257
- end
258
- end
259
- end
260
- driver_class = Jdbc.const_get(driver_class_const)
261
- raise "You specify a driver for your JDBC connection" unless driver_class
262
- driver_class
263
- end
264
- end
265
-
266
- def load
267
- Jdbc::DriverManager.registerDriver(create)
268
- end
269
-
270
- def connection(url, user, pass)
271
- Jdbc::DriverManager.getConnection(url, user, pass)
272
- rescue
273
- # bypass DriverManager to get around problem with dynamically loaded jdbc drivers
274
- props = java.util.Properties.new
275
- props.setProperty("user", user)
276
- props.setProperty("password", pass)
277
- create.connect(url, props)
278
- end
279
-
280
- def create
281
- driver_class.new
282
- end
283
- end
284
-
285
- class JdbcColumn < Column
286
- attr_writer :limit, :precision
287
-
288
- COLUMN_TYPES = ::JdbcSpec.constants.map{|c|
289
- ::JdbcSpec.const_get c }.select{ |c|
290
- c.respond_to? :column_selector }.map{|c|
291
- c.column_selector }.inject({}) { |h,val|
292
- h[val[0]] = val[1]; h }
293
-
294
- def initialize(config, name, default, *args)
295
- dialect = config[:dialect] || config[:driver]
296
- for reg, func in COLUMN_TYPES
297
- if reg === dialect.to_s
298
- func.call(config,self)
299
- end
300
- end
301
- super(name,default_value(default),*args)
302
- init_column(name, default, *args)
303
- end
304
-
305
- def init_column(*args)
306
- end
307
-
308
- def default_value(val)
309
- val
310
- end
311
- end
312
-
313
- include_class "jdbc_adapter.JdbcConnectionFactory"
314
-
315
- class JdbcConnection
316
- attr_reader :adapter, :connection_factory
317
-
318
- # @native_database_types - setup properly by adapter= versus set_native_database_types.
319
- # This contains type information for the adapter. Individual adapters can make tweaks
320
- # by defined modify_types
321
- #
322
- # @native_types - This is the default type settings sans any modifications by the
323
- # individual adapter. My guess is that if we loaded two adapters of different types
324
- # then this is used as a base to be tweaked by each adapter to create @native_database_types
325
-
326
- def initialize(config)
327
- @config = config.symbolize_keys!
328
- @config[:retry_count] ||= 5
329
- @config[:connection_alive_sql] ||= "select 1"
330
- if @config[:jndi]
331
- begin
332
- configure_jndi
333
- rescue => e
334
- warn "JNDI data source unavailable: #{e.message}; trying straight JDBC"
335
- configure_jdbc
336
- end
337
- else
338
- configure_jdbc
339
- end
340
- connection # force the connection to load
341
- set_native_database_types
342
- @stmts = {}
343
- rescue Exception => e
344
- raise "The driver encountered an error: #{e}"
345
- end
346
-
347
- def adapter=(adapter)
348
- @adapter = adapter
349
- @native_database_types = dup_native_types
350
- @adapter.modify_types(@native_database_types)
351
- end
352
-
353
- # Duplicate all native types into new hash structure so it can be modified
354
- # without destroying original structure.
355
- def dup_native_types
356
- types = {}
357
- @native_types.each_pair do |k, v|
358
- types[k] = v.inject({}) do |memo, kv|
359
- memo[kv.first] = begin kv.last.dup rescue kv.last end
360
- memo
361
- end
362
- end
363
- types
364
- end
365
- private :dup_native_types
366
-
367
- def jndi_connection?
368
- @jndi_connection
369
- end
370
-
371
- private
372
- def configure_jndi
373
- jndi = @config[:jndi].to_s
374
- ctx = javax.naming.InitialContext.new
375
- ds = ctx.lookup(jndi)
376
- @connection_factory = JdbcConnectionFactory.impl do
377
- ds.connection
378
- end
379
- unless @config[:driver]
380
- @config[:driver] = connection.meta_data.connection.java_class.name
381
- end
382
- @jndi_connection = true
383
- end
384
-
385
- def configure_jdbc
386
- driver = @config[:driver].to_s
387
- user = @config[:username].to_s
388
- pass = @config[:password].to_s
389
- url = @config[:url].to_s
390
-
391
- unless driver && url
392
- raise ::ActiveRecord::ConnectionFailed, "jdbc adapter requires driver class and url"
393
- end
394
-
395
- jdbc_driver = JdbcDriver.new(driver)
396
- jdbc_driver.load
397
- @connection_factory = JdbcConnectionFactory.impl do
398
- jdbc_driver.connection(url, user, pass)
399
- end
400
- end
401
- end
402
-
403
- class JdbcAdapter < AbstractAdapter
404
- module ShadowCoreMethods
405
- def alias_chained_method(meth, feature, target)
406
- if instance_methods.include?("#{meth}_without_#{feature}")
407
- alias_method "#{meth}_without_#{feature}".to_sym, target
408
- else
409
- alias_method meth, target if meth != target
410
- end
411
- end
412
- end
413
-
414
- module CompatibilityMethods
415
- def self.needed?(base)
416
- !base.instance_methods.include?("quote_table_name")
417
- end
418
-
419
- def quote_table_name(name)
420
- quote_column_name(name)
421
- end
422
- end
423
-
424
- module ConnectionPoolCallbacks
425
- def self.included(base)
426
- if base.respond_to?(:set_callback) # Rails 3 callbacks
427
- base.set_callback :checkin, :after, :on_checkin
428
- base.set_callback :checkout, :before, :on_checkout
429
- else
430
- base.checkin :on_checkin
431
- base.checkout :on_checkout
432
- end
433
- end
434
-
435
- def self.needed?
436
- ActiveRecord::Base.respond_to?(:connection_pool)
437
- end
438
-
439
- def on_checkin
440
- # default implementation does nothing
441
- end
442
-
443
- def on_checkout
444
- # default implementation does nothing
445
- end
446
- end
447
-
448
- module JndiConnectionPoolCallbacks
449
- def self.prepare(adapter, conn)
450
- if ActiveRecord::Base.respond_to?(:connection_pool) && conn.jndi_connection?
451
- adapter.extend self
452
- conn.disconnect! # disconnect initial connection in JdbcConnection#initialize
453
- end
454
- end
455
-
456
- def on_checkin
457
- disconnect!
458
- end
459
-
460
- def on_checkout
461
- reconnect!
462
- end
463
- end
464
-
465
- extend ShadowCoreMethods
466
- include CompatibilityMethods if CompatibilityMethods.needed?(self)
467
- include ConnectionPoolCallbacks if ConnectionPoolCallbacks.needed?
468
-
469
- attr_reader :config
470
-
471
- def initialize(connection, logger, config)
472
- @config = config
473
- spec = adapter_spec config
474
- unless connection
475
- connection_class = jdbc_connection_class spec
476
- connection = connection_class.new config
477
- end
478
- super(connection, logger)
479
- extend spec if spec
480
- connection.adapter = self
481
- JndiConnectionPoolCallbacks.prepare(self, connection)
482
- end
483
-
484
- def jdbc_connection_class(spec)
485
- connection_class = spec.jdbc_connection_class if spec && spec.respond_to?(:jdbc_connection_class)
486
- connection_class = ::ActiveRecord::ConnectionAdapters::JdbcConnection unless connection_class
487
- connection_class
488
- end
489
-
490
- # Locate specialized adapter specification if one exists based on config data
491
- def adapter_spec(config)
492
- dialect = (config[:dialect] || config[:driver]).to_s
493
- ::JdbcSpec.constants.map { |name| ::JdbcSpec.const_get name }.each do |constant|
494
- if constant.respond_to? :adapter_matcher
495
- spec = constant.adapter_matcher(dialect, config)
496
- return spec if spec
497
- end
498
- end
499
- nil
500
- end
501
-
502
- def modify_types(tp)
503
- tp
504
- end
505
-
506
- def adapter_name #:nodoc:
507
- 'JDBC'
508
- end
509
-
510
- def supports_migrations?
511
- true
512
- end
513
-
514
- def native_database_types #:nodoc:
515
- @connection.native_database_types
516
- end
517
-
518
- def database_name #:nodoc:
519
- @connection.database_name
520
- end
521
-
522
- def native_sql_to_type(tp)
523
- if /^(.*?)\(([0-9]+)\)/ =~ tp
524
- tname = $1
525
- limit = $2.to_i
526
- ntype = native_database_types
527
- if ntype[:primary_key] == tp
528
- return :primary_key,nil
529
- else
530
- ntype.each do |name,val|
531
- if name == :primary_key
532
- next
533
- end
534
- if val[:name].downcase == tname.downcase && (val[:limit].nil? || val[:limit].to_i == limit)
535
- return name,limit
536
- end
537
- end
538
- end
539
- elsif /^(.*?)/ =~ tp
540
- tname = $1
541
- ntype = native_database_types
542
- if ntype[:primary_key] == tp
543
- return :primary_key,nil
544
- else
545
- ntype.each do |name,val|
546
- if val[:name].downcase == tname.downcase && val[:limit].nil?
547
- return name,nil
548
- end
549
- end
550
- end
551
- else
552
- return :string,255
553
- end
554
- return nil,nil
555
- end
556
-
557
- def reconnect!
558
- @connection.reconnect!
559
- @connection
560
- end
561
-
562
- def disconnect!
563
- @connection.disconnect!
564
- end
565
-
566
- def jdbc_select_all(sql, name = nil)
567
- select(sql, name)
568
- end
569
- alias_chained_method :select_all, :query_cache, :jdbc_select_all
570
-
571
- def select_rows(sql, name = nil)
572
- rows = []
573
- select(sql, name).each {|row| rows << row.values }
574
- rows
575
- end
576
-
577
- def select_one(sql, name = nil)
578
- select(sql, name).first
579
- end
580
-
581
- def execute(sql, name = nil)
582
- log(sql, name) do
583
- _execute(sql,name)
584
- end
585
- end
586
-
587
- # we need to do it this way, to allow Rails stupid tests to always work
588
- # even if we define a new execute method. Instead of mixing in a new
589
- # execute, an _execute should be mixed in.
590
- def _execute(sql, name = nil)
591
- if JdbcConnection::select?(sql)
592
- @connection.execute_query(sql)
593
- elsif JdbcConnection::insert?(sql)
594
- @connection.execute_insert(sql)
595
- else
596
- @connection.execute_update(sql)
597
- end
598
- end
599
-
600
- def jdbc_update(sql, name = nil) #:nodoc:
601
- execute(sql, name)
602
- end
603
- alias_chained_method :update, :query_dirty, :jdbc_update
604
-
605
- def jdbc_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
606
- id = execute(sql, name = nil)
607
- id_value || id
608
- end
609
- alias_chained_method :insert, :query_dirty, :jdbc_insert
610
-
611
- def jdbc_columns(table_name, name = nil)
612
- @connection.columns(table_name.to_s)
613
- end
614
- alias_chained_method :columns, :query_cache, :jdbc_columns
615
-
616
- def tables
617
- @connection.tables
618
- end
619
-
620
- def indexes(table_name, name = nil, schema_name = nil)
621
- @connection.indexes(table_name, name, schema_name)
622
- end
623
-
624
- def begin_db_transaction
625
- @connection.begin
626
- end
627
-
628
- def commit_db_transaction
629
- @connection.commit
630
- end
631
-
632
- def rollback_db_transaction
633
- @connection.rollback
634
- end
635
-
636
- def write_large_object(*args)
637
- @connection.write_large_object(*args)
638
- end
639
-
640
- def pk_and_sequence_for(table)
641
- key = primary_key(table)
642
- [key, nil] if key
643
- end
644
-
645
- def primary_key(table)
646
- primary_keys(table).first
647
- end
648
-
649
- def primary_keys(table)
650
- @connection.primary_keys(table)
651
- end
652
-
653
- private
654
- def select(sql, name=nil)
655
- log(sql, name) do
656
- @connection.execute_query(sql)
657
- end
658
- end
659
- end
660
- end
661
- end
1
+ require 'arjdbc/jdbc'