activerecord-jdbc-adapter 1.2.8 → 1.2.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +5 -6
- data/History.txt +11 -0
- data/gemfiles/rails23.gemfile +2 -1
- data/gemfiles/rails23.gemfile.lock +5 -2
- data/gemfiles/rails30.gemfile +2 -1
- data/gemfiles/rails30.gemfile.lock +5 -2
- data/gemfiles/rails31.gemfile +2 -1
- data/gemfiles/rails31.gemfile.lock +5 -2
- data/gemfiles/rails32.gemfile +2 -1
- data/gemfiles/rails32.gemfile.lock +5 -2
- data/lib/arel/engines/sql/compilers/mssql_compiler.rb +1 -1
- data/lib/arel/visitors/sql_server.rb +4 -4
- data/lib/arjdbc/db2/adapter.rb +14 -3
- data/lib/arjdbc/discover.rb +1 -1
- data/lib/arjdbc/jdbc/adapter.rb +1 -0
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/connection.rb +73 -63
- data/lib/arjdbc/jdbc/extension.rb +1 -1
- data/lib/arjdbc/mssql.rb +3 -0
- data/lib/arjdbc/mssql/adapter.rb +132 -115
- data/lib/arjdbc/mssql/connection_methods.rb +1 -1
- data/lib/arjdbc/mssql/limit_helpers.rb +62 -66
- data/lib/arjdbc/mssql/lock_helpers.rb +2 -2
- data/lib/arjdbc/mssql/tsql_methods.rb +58 -0
- data/lib/arjdbc/mssql/utils.rb +53 -0
- data/lib/arjdbc/oracle/adapter.rb +61 -39
- data/lib/arjdbc/sqlite3/adapter.rb +3 -6
- data/lib/arjdbc/version.rb +1 -1
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +4 -2
- data/src/java/arjdbc/mssql/MSSQLModule.java +70 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +128 -0
- data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +25 -112
- data/test/db/mssql.rb +8 -8
- data/test/db2_simple_test.rb +7 -0
- data/test/models/entry.rb +2 -1
- data/test/mssql_binary_test.rb +6 -0
- data/test/mssql_db_create_test.rb +5 -2
- data/test/mssql_identity_insert_test.rb +1 -2
- data/test/mssql_ignore_system_views_test.rb +5 -5
- data/test/mssql_limit_offset_test.rb +51 -55
- data/test/mssql_multibyte_test.rb +1 -2
- data/test/mssql_row_locking_test.rb +1 -1
- data/test/mssql_simple_test.rb +6 -10
- data/test/{mssql_row_locking_sql_test.rb → mssql_test.rb} +110 -18
- data/test/mysql_db_create_test.rb +13 -7
- data/test/oracle_simple_test.rb +18 -0
- data/test/postgres_db_create_test.rb +26 -13
- data/test/simple.rb +45 -15
- data/test/sqlite3_schema_dump_test.rb +6 -0
- data/test/sqlite3_type_conversion_test.rb +20 -17
- data/test/test_helper.rb +44 -2
- metadata +9 -4
- data/lib/arjdbc/mssql/tsql_helper.rb +0 -53
@@ -1,127 +1,40 @@
|
|
1
1
|
/*
|
2
|
-
|
3
|
-
* Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
|
4
|
-
* Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
|
5
|
-
* Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
|
2
|
+
* The MIT License
|
6
3
|
*
|
7
|
-
*
|
8
|
-
* a copy of this software and associated documentation files (the
|
9
|
-
* "Software"), to deal in the Software without restriction, including
|
10
|
-
* without limitation the rights to use, copy, modify, merge, publish,
|
11
|
-
* distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
-
* permit persons to whom the Software is furnished to do so, subject to
|
13
|
-
* the following conditions:
|
4
|
+
* Copyright 2013 Karol Bucek.
|
14
5
|
*
|
15
|
-
*
|
16
|
-
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
11
|
+
* furnished to do so, subject to the following conditions:
|
17
12
|
*
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
21
|
-
*
|
22
|
-
*
|
23
|
-
*
|
24
|
-
*
|
25
|
-
|
13
|
+
* The above copyright notice and this permission notice shall be included in
|
14
|
+
* all copies or substantial portions of the Software.
|
15
|
+
*
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
* THE SOFTWARE.
|
23
|
+
*/
|
26
24
|
package arjdbc.mssql;
|
27
25
|
|
28
|
-
import java.sql.ResultSet;
|
29
|
-
import java.sql.SQLException;
|
30
|
-
import java.sql.Types;
|
31
|
-
import java.util.List;
|
32
|
-
|
33
|
-
import arjdbc.jdbc.RubyJdbcConnection;
|
34
|
-
import static arjdbc.jdbc.RubyJdbcConnection.ColumnData;
|
35
|
-
|
36
26
|
import org.jruby.Ruby;
|
37
27
|
import org.jruby.RubyClass;
|
38
|
-
import org.jruby.RubyString;
|
39
|
-
import org.jruby.runtime.ObjectAllocator;
|
40
|
-
import org.jruby.runtime.ThreadContext;
|
41
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
42
28
|
|
43
29
|
/**
|
44
|
-
*
|
45
|
-
* @
|
30
|
+
* @see MSSQLRubyJdbcConnection
|
31
|
+
* @deprecated only for Java API backwards-compatibility
|
46
32
|
*/
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
33
|
+
@Deprecated
|
34
|
+
public class MssqlRubyJdbcConnection extends MSSQLRubyJdbcConnection {
|
35
|
+
|
51
36
|
protected MssqlRubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
|
52
37
|
super(runtime, metaClass);
|
53
|
-
_row_num = runtime.newString("_row_num");
|
54
|
-
}
|
55
|
-
|
56
|
-
public static RubyClass createMssqlJdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
|
57
|
-
RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("MssqlJdbcConnection",
|
58
|
-
jdbcConnection, MSSQL_JDBCCONNECTION_ALLOCATOR);
|
59
|
-
clazz.defineAnnotatedMethods(MssqlRubyJdbcConnection.class);
|
60
|
-
|
61
|
-
return clazz;
|
62
|
-
}
|
63
|
-
|
64
|
-
private static ObjectAllocator MSSQL_JDBCCONNECTION_ALLOCATOR = new ObjectAllocator() {
|
65
|
-
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
66
|
-
return new MssqlRubyJdbcConnection(runtime, klass);
|
67
|
-
}
|
68
|
-
};
|
69
|
-
|
70
|
-
protected static IRubyObject booleanToRuby(Ruby runtime, ResultSet resultSet, boolean booleanValue)
|
71
|
-
throws SQLException {
|
72
|
-
if (booleanValue == false && resultSet.wasNull()) return runtime.getNil();
|
73
|
-
return runtime.newBoolean(booleanValue);
|
74
|
-
}
|
75
|
-
|
76
|
-
/**
|
77
|
-
* Treat LONGVARCHAR as CLOB on Mssql for purposes of converting a JDBC value to Ruby.
|
78
|
-
* Treat BOOLEAN/BIT as Boolean, rather than the default behaviour of conversion to string
|
79
|
-
*/
|
80
|
-
@Override
|
81
|
-
protected IRubyObject jdbcToRuby(Ruby runtime, int column, int type, ResultSet resultSet)
|
82
|
-
throws SQLException {
|
83
|
-
if ( Types.BOOLEAN == type || Types.BIT == type ) {
|
84
|
-
return booleanToRuby(runtime, resultSet, resultSet.getBoolean(column));
|
85
|
-
}
|
86
|
-
if (type == Types.LONGVARCHAR) {
|
87
|
-
type = Types.CLOB;
|
88
|
-
}
|
89
|
-
return super.jdbcToRuby(runtime, column, type, resultSet);
|
90
|
-
}
|
91
|
-
|
92
|
-
/**
|
93
|
-
* Microsoft SQL 2000+ support schemas
|
94
|
-
*/
|
95
|
-
@Override
|
96
|
-
protected boolean databaseSupportsSchemas() {
|
97
|
-
return true;
|
98
|
-
}
|
99
|
-
|
100
|
-
@Override
|
101
|
-
protected void populateFromResultSet(ThreadContext context, Ruby runtime, List results,
|
102
|
-
ResultSet resultSet, ColumnData[] columns) throws SQLException {
|
103
|
-
super.populateFromResultSet(context, runtime, results, resultSet, filterRowNumFromColumns(columns));
|
104
|
-
}
|
105
|
-
|
106
|
-
/**
|
107
|
-
* Filter out the <tt>_row_num</tt> column from results.
|
108
|
-
*/
|
109
|
-
private ColumnData[] filterRowNumFromColumns(ColumnData[] columns) {
|
110
|
-
for (int i = 0; i < columns.length; i++) {
|
111
|
-
if (columns[i].name.equals(_row_num)) {
|
112
|
-
ColumnData[] filtered = new ColumnData[columns.length - 1];
|
113
|
-
if (i > 0) {
|
114
|
-
System.arraycopy(columns, 0, filtered, 0, i);
|
115
|
-
}
|
116
|
-
|
117
|
-
if (i + 1 < columns.length) {
|
118
|
-
System.arraycopy(columns, i + 1, filtered, i, columns.length - (i + 1));
|
119
|
-
}
|
120
|
-
|
121
|
-
return filtered;
|
122
|
-
}
|
123
|
-
}
|
124
|
-
|
125
|
-
return columns;
|
126
38
|
}
|
39
|
+
|
127
40
|
}
|
data/test/db/mssql.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'jdbc_common'
|
2
2
|
|
3
|
-
MSSQL_CONFIG = {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
:database => 'weblog_development'
|
8
|
-
}
|
9
|
-
MSSQL_CONFIG[:host] = ENV['SQLHOST'] if ENV['SQLHOST']
|
3
|
+
MSSQL_CONFIG = { :adapter => 'mssql' }
|
4
|
+
MSSQL_CONFIG[:database] = ENV['SQLDATABASE'] || 'weblog_development'
|
5
|
+
MSSQL_CONFIG[:username] = ENV['SQLUSER'] || 'blog'
|
6
|
+
MSSQL_CONFIG[:password] = ENV['SQLPASS'] || ''
|
10
7
|
|
11
|
-
|
8
|
+
MSSQL_CONFIG[:host] = ENV['SQLHOST'] || 'localhost'
|
9
|
+
MSSQL_CONFIG[:port] = ENV['SQLPORT'] if ENV['SQLPORT']
|
10
|
+
|
11
|
+
ActiveRecord::Base.establish_connection(MSSQL_CONFIG)
|
data/test/db2_simple_test.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
require 'jdbc_common'
|
2
2
|
require 'db/db2'
|
3
3
|
|
4
|
+
DbTypeMigration.big_decimal_precision = 31
|
5
|
+
|
4
6
|
class DB2SimpleTest < Test::Unit::TestCase
|
5
7
|
include SimpleTestMethods
|
8
|
+
include ActiveRecord3TestMethods
|
9
|
+
include DirtyAttributeTests
|
10
|
+
include XmlColumnTests
|
11
|
+
|
12
|
+
def xml_sql_type; 'XML'; end
|
6
13
|
|
7
14
|
# For backwards compatibility with how the DB2 code in
|
8
15
|
# jdbc_adapter 0.9.x handled booleans.
|
data/test/models/entry.rb
CHANGED
@@ -2,10 +2,10 @@ class CreateEntries < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
3
3
|
create_table "entries", :force => true do |t|
|
4
4
|
t.column :title, :string, :limit => 100
|
5
|
-
t.column :updated_on, :datetime
|
6
5
|
t.column :content, :text
|
7
6
|
t.column :rating, :decimal, :precision => 10, :scale => 2
|
8
7
|
t.column :user_id, :integer
|
8
|
+
t.column :updated_on, :datetime # treated as date "_on" convention
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -26,6 +26,7 @@ class CreateUsers < ActiveRecord::Migration
|
|
26
26
|
def self.up
|
27
27
|
create_table "users", :force => true do |t|
|
28
28
|
t.column :login, :string, :limit => 100, :null => false
|
29
|
+
t.timestamps # created_at / updated_at
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
@@ -18,8 +18,11 @@ class MysqlDbCreateTest < Test::Unit::TestCase
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
ActiveRecord::Base.establish_connection(db_config.merge(:database => "master"))
|
21
|
-
|
22
|
-
|
21
|
+
if ActiveRecord::Base.connection.send(:sqlserver_2000?)
|
22
|
+
select = "SELECT name FROM master..sysdatabases ORDER BY name"
|
23
|
+
else
|
24
|
+
select = "SELECT name FROM sys.sysdatabases"
|
25
|
+
end
|
23
26
|
databases = ActiveRecord::Base.connection.select_rows(select).flatten
|
24
27
|
assert databases.include?(@db_name)
|
25
28
|
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'jdbc_common'
|
2
2
|
require 'db/mssql'
|
3
3
|
|
4
|
-
class
|
5
|
-
|
4
|
+
class MSSQLIgnoreSystemViewsTest < Test::Unit::TestCase
|
6
5
|
include MigrationSetup
|
7
6
|
|
8
7
|
def test_system_views_ignored
|
@@ -23,8 +22,9 @@ class IgnoreSystemViewsTest < Test::Unit::TestCase
|
|
23
22
|
|
24
23
|
private
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
def table_exists?(*args)
|
26
|
+
ActiveRecord::Base.connection.table_exists?(*args)
|
27
|
+
end
|
28
|
+
|
29
29
|
end
|
30
30
|
|
@@ -1,88 +1,84 @@
|
|
1
1
|
require 'jdbc_common'
|
2
2
|
require 'db/mssql'
|
3
3
|
|
4
|
-
|
4
|
+
class MSSQLLimitOffsetTest < Test::Unit::TestCase
|
5
5
|
|
6
|
-
class CreateLegacyShips < ActiveRecord::Migration
|
6
|
+
class CreateLegacyShips < ActiveRecord::Migration
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def self.up
|
9
|
+
create_table "legacy_ships",{:primary_key => :ShipKey} do |t|
|
10
|
+
t.string "name", :limit => 50, :null => false
|
11
|
+
t.integer "width", :default => 123
|
12
|
+
t.integer "length", :default => 456
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
drop_table "legacy_ships"
|
13
18
|
end
|
14
|
-
end
|
15
19
|
|
16
|
-
def self.down
|
17
|
-
drop_table "legacy_ships"
|
18
20
|
end
|
19
21
|
|
20
|
-
|
22
|
+
class LegacyShip < ActiveRecord::Base
|
23
|
+
self.primary_key = "ShipKey"
|
24
|
+
end
|
21
25
|
|
22
|
-
class
|
23
|
-
self.primary_key = "ShipKey"
|
24
|
-
end
|
26
|
+
class CreateLongShips < ActiveRecord::Migration
|
25
27
|
|
26
|
-
|
28
|
+
def self.up
|
29
|
+
create_table "long_ships", :force => true do |t|
|
30
|
+
t.string "name", :limit => 50, :null => false
|
31
|
+
t.integer "width", :default => 123
|
32
|
+
t.integer "length", :default => 456
|
33
|
+
end
|
34
|
+
end
|
27
35
|
|
28
|
-
|
29
|
-
|
30
|
-
t.string "name", :limit => 50, :null => false
|
31
|
-
t.integer "width", :default => 123
|
32
|
-
t.integer "length", :default => 456
|
36
|
+
def self.down
|
37
|
+
drop_table "long_ships"
|
33
38
|
end
|
34
|
-
end
|
35
39
|
|
36
|
-
def self.down
|
37
|
-
drop_table "long_ships"
|
38
40
|
end
|
39
41
|
|
40
|
-
|
42
|
+
class LongShip < ActiveRecord::Base
|
43
|
+
has_many :vikings
|
44
|
+
end
|
41
45
|
|
42
|
-
class
|
43
|
-
has_many :vikings
|
44
|
-
end
|
46
|
+
class CreateVikings < ActiveRecord::Migration
|
45
47
|
|
46
|
-
|
48
|
+
def self.up
|
49
|
+
create_table "vikings", :force => true do |t|
|
50
|
+
t.integer "long_ship_id", :null => false
|
51
|
+
t.string "name", :limit => 50, :default => "Sven"
|
52
|
+
end
|
53
|
+
end
|
47
54
|
|
48
|
-
|
49
|
-
|
50
|
-
t.integer "long_ship_id", :null => false
|
51
|
-
t.string "name", :limit => 50, :default => "Sven"
|
55
|
+
def self.down
|
56
|
+
drop_table "vikings"
|
52
57
|
end
|
53
|
-
end
|
54
58
|
|
55
|
-
def self.down
|
56
|
-
drop_table "vikings"
|
57
59
|
end
|
58
60
|
|
59
|
-
|
61
|
+
class Viking < ActiveRecord::Base
|
62
|
+
belongs_to :long_ship
|
63
|
+
end
|
60
64
|
|
61
|
-
class Viking < ActiveRecord::Base
|
62
|
-
belongs_to :long_ship
|
63
|
-
end
|
64
65
|
|
66
|
+
class CreateNoIdVikings < ActiveRecord::Migration
|
67
|
+
def self.up
|
68
|
+
create_table "no_id_vikings", :force => true do |t|
|
69
|
+
t.string "name", :limit => 50, :default => "Sven"
|
70
|
+
end
|
71
|
+
remove_column "no_id_vikings", "id"
|
72
|
+
end
|
65
73
|
|
66
|
-
|
67
|
-
|
68
|
-
create_table "no_id_vikings", :force => true do |t|
|
69
|
-
t.string "name", :limit => 50, :default => "Sven"
|
74
|
+
def self.down
|
75
|
+
drop_table "no_id_vikings"
|
70
76
|
end
|
71
|
-
remove_column "no_id_vikings", "id"
|
72
77
|
end
|
73
78
|
|
74
|
-
|
75
|
-
drop_table "no_id_vikings"
|
79
|
+
class NoIdViking < ActiveRecord::Base
|
76
80
|
end
|
77
|
-
|
78
|
-
|
79
|
-
class NoIdViking < ActiveRecord::Base
|
80
|
-
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
class MsSQLLimitOffsetTest < Test::Unit::TestCase
|
85
|
-
|
81
|
+
|
86
82
|
def setup
|
87
83
|
CreateLegacyShips.up
|
88
84
|
CreateLongShips.up
|
data/test/mssql_simple_test.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'jdbc_common'
|
2
2
|
require 'db/mssql'
|
3
3
|
|
4
|
-
class
|
5
|
-
|
4
|
+
class MSSQLSimpleTest < Test::Unit::TestCase
|
6
5
|
include SimpleTestMethods
|
6
|
+
include ActiveRecord3TestMethods
|
7
|
+
include DirtyAttributeTests
|
7
8
|
|
8
|
-
# MS SQL 2005 doesn't have a DATE class, only TIMESTAMP
|
9
|
-
undef_method :test_save_date
|
9
|
+
# MS SQL 2005 doesn't have a DATE class, only TIMESTAMP
|
10
10
|
|
11
11
|
# String comparisons are insensitive by default
|
12
12
|
undef_method :test_validates_uniqueness_of_strings_case_sensitive
|
@@ -21,7 +21,6 @@ class MsSQLSimpleTest < Test::Unit::TestCase
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_change_column_default
|
24
|
-
|
25
24
|
Entry.connection.change_column "entries", "title", :string, :default => "new default"
|
26
25
|
Entry.reset_column_information
|
27
26
|
assert_equal("new default", Entry.new.title)
|
@@ -29,11 +28,9 @@ class MsSQLSimpleTest < Test::Unit::TestCase
|
|
29
28
|
Entry.connection.change_column "entries", "title", :string, :default => nil
|
30
29
|
Entry.reset_column_information
|
31
30
|
assert_equal(nil, Entry.new.title)
|
32
|
-
|
33
31
|
end
|
34
32
|
|
35
33
|
def test_change_column_nullability
|
36
|
-
|
37
34
|
Entry.connection.change_column "entries", "title", :string, :null => true
|
38
35
|
Entry.reset_column_information
|
39
36
|
title_column = Entry.columns.find { |c| c.name == "title" }
|
@@ -43,13 +40,12 @@ class MsSQLSimpleTest < Test::Unit::TestCase
|
|
43
40
|
Entry.reset_column_information
|
44
41
|
title_column = Entry.columns.find { |c| c.name == "title" }
|
45
42
|
assert(!title_column.null)
|
46
|
-
|
47
43
|
end
|
48
44
|
|
49
45
|
# ACTIVERECORD_JDBC-124
|
50
46
|
def test_model_does_not_have_row_num_column
|
51
47
|
entry = Entry.first
|
52
|
-
|
53
|
-
|
48
|
+
assert_false entry.attributes.keys.include?("_row_num")
|
49
|
+
assert_false entry.respond_to?(:_row_num)
|
54
50
|
end
|
55
51
|
end
|