Skip to content

Commit 732c838

Browse files
authored
Merge pull request #1040 from dr-itz/50-dev
Various fixes
2 parents 72c6f64 + e1faef5 commit 732c838

File tree

10 files changed

+103
-19
lines changed

10 files changed

+103
-19
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.tgz
33
*~
44
*.log
5+
/log/
56
patches*
67
*#
78
TAGS
@@ -30,4 +31,4 @@ Gemfile.lock
3031
.idea
3132
.settings
3233
activerecord-jdbc.iml
33-
lib/arjdbc/jdbc/adapter_java.jar
34+
lib/arjdbc/jdbc/adapter_java.jar

lib/arjdbc/abstract/database_statements.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ def exec_insert(sql, name = nil, binds = NO_BINDS, pk = nil, sequence_name = nil
1313
binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
1414

1515
if without_prepared_statement?(binds)
16-
log(sql, name) { @connection.execute_insert(sql) }
16+
log(sql, name) { @connection.execute_insert_pk(sql, pk) }
1717
else
1818
log(sql, name, binds) do
19-
@connection.execute_insert(sql, binds)
19+
@connection.execute_insert_pk(sql, binds, pk)
2020
end
2121
end
2222
end

lib/arjdbc/mysql/connection_methods.rb

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22
ArJdbc::ConnectionMethods.module_eval do
33
def mysql_connection(config)
4+
config = config.deep_dup
45
# NOTE: this isn't "really" necessary but Rails (in tests) assumes being able to :
56
# ActiveRecord::Base.mysql2_connection ActiveRecord::Base.configurations['arunit'].merge(database: ...)
67
config = symbolize_keys_if_necessary(config)

lib/arjdbc/postgresql/connection_methods.rb

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22
ArJdbc::ConnectionMethods.module_eval do
33
def postgresql_connection(config)
4+
config = config.deep_dup
45
# NOTE: this isn't "really" necessary but Rails (in tests) assumes being able to :
56
# ActiveRecord::Base.postgresql_connection ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false)
67
# ... while using symbols by default but than configurations returning string keys ;(

lib/arjdbc/sqlite3/connection_methods.rb

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22
ArJdbc::ConnectionMethods.module_eval do
33
def sqlite3_connection(config)
4+
config = config.deep_dup
45
config[:adapter_spec] ||= ::ArJdbc::SQLite3
56
config[:adapter_class] = ActiveRecord::ConnectionAdapters::SQLite3Adapter unless config.key?(:adapter_class)
67

rakelib/rails.rake

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace :rails do
5151
ruby_opts_string += " -C \"#{ar_path}\""
5252
ruby_opts_string += " -rbundler/setup"
5353
ruby_opts_string += " -rminitest -rminitest/excludes" unless ENV['NO_EXCLUDES'].eql?('true')
54-
file_list = ENV["TEST"] ? FileList[ ENV["TEST"] ] : test_files_finder.call
54+
file_list = ENV["TEST"] ? FileList[ ENV["TEST"].split(',') ] : test_files_finder.call
5555
file_list_string = file_list.map { |fn| "\"#{fn}\"" }.join(' ')
5656
# test_loader_code = "-e \"ARGV.each{|f| require f}\"" # :direct
5757
option_list = ( ENV["TESTOPTS"] || ENV["TESTOPT"] || ENV["TEST_OPTS"] || '' )

src/java/arjdbc/jdbc/RubyJdbcConnection.java

+50-7
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,10 @@ public synchronized IRubyObject reconnect(final ThreadContext context) {
727727

728728
private void connectImpl(final boolean forceConnection) throws SQLException {
729729
setConnection( forceConnection ? newConnection() : null );
730-
if ( forceConnection ) configureConnection();
730+
if (forceConnection) {
731+
if (getConnectionImpl() == null) throw new SQLException("Didn't get a connection. Wrong URL?");
732+
configureConnection();
733+
}
731734
}
732735

733736
@JRubyMethod(name = "read_only?")
@@ -885,23 +888,45 @@ protected IRubyObject mapExecuteResult(final ThreadContext context,
885888
return mapQueryResult(context, connection, resultSet);
886889
}
887890

891+
private static String[] createStatementPk(IRubyObject pk) {
892+
String[] statementPk;
893+
if (pk instanceof RubyArray) {
894+
RubyArray ary = (RubyArray) pk;
895+
int size = ary.size();
896+
statementPk = new String[size];
897+
for (int i = 0; i < size; i++) {
898+
statementPk[i] = sqlString(ary.eltInternal(i));
899+
}
900+
} else {
901+
statementPk = new String[] { sqlString(pk) };
902+
}
903+
return statementPk;
904+
}
905+
888906
/**
889907
* Executes an INSERT SQL statement
890908
* @param context
891909
* @param sql
910+
* @param pk Rails PK
892911
* @return ActiveRecord::Result
893912
* @throws SQLException
894913
*/
895-
@JRubyMethod(name = "execute_insert", required = 1)
896-
public IRubyObject execute_insert(final ThreadContext context, final IRubyObject sql) {
914+
@JRubyMethod(name = "execute_insert_pk", required = 2)
915+
public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject pk) {
897916
return withConnection(context, new Callable<IRubyObject>() {
898917
public IRubyObject call(final Connection connection) throws SQLException {
899918
Statement statement = null;
900919
final String query = sqlString(sql);
901920
try {
902921

903922
statement = createStatement(context, connection);
904-
statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
923+
924+
if (pk == context.nil || pk == context.fals || !supportsGeneratedKeys(connection)) {
925+
statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
926+
} else {
927+
statement.executeUpdate(query, createStatementPk(pk));
928+
}
929+
905930
return mapGeneratedKeys(context, connection, statement);
906931

907932
} catch (final SQLException e) {
@@ -914,23 +939,35 @@ public IRubyObject call(final Connection connection) throws SQLException {
914939
});
915940
}
916941

942+
@Deprecated
943+
@JRubyMethod(name = "execute_insert", required = 1)
944+
public IRubyObject execute_insert(final ThreadContext context, final IRubyObject sql) {
945+
return execute_insert_pk(context, sql, context.nil);
946+
}
947+
917948
/**
918949
* Executes an INSERT SQL statement using a prepared statement
919950
* @param context
920951
* @param sql
921952
* @param binds RubyArray of values to be bound to the query
953+
* @param pk Rails PK
922954
* @return ActiveRecord::Result
923955
* @throws SQLException
924956
*/
925-
@JRubyMethod(name = "execute_insert", required = 2)
926-
public IRubyObject execute_insert(final ThreadContext context, final IRubyObject sql, final IRubyObject binds) {
957+
@JRubyMethod(name = "execute_insert_pk", required = 3)
958+
public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject binds,
959+
final IRubyObject pk) {
927960
return withConnection(context, new Callable<IRubyObject>() {
928961
public IRubyObject call(final Connection connection) throws SQLException {
929962
PreparedStatement statement = null;
930963
final String query = sqlString(sql);
931964
try {
965+
if (pk == context.nil || pk == context.fals || !supportsGeneratedKeys(connection)) {
966+
statement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
967+
} else {
968+
statement = connection.prepareStatement(query, createStatementPk(pk));
969+
}
932970

933-
statement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
934971
setStatementParameters(context, connection, statement, (RubyArray) binds);
935972
statement.executeUpdate();
936973
return mapGeneratedKeys(context, connection, statement);
@@ -945,6 +982,12 @@ public IRubyObject call(final Connection connection) throws SQLException {
945982
});
946983
}
947984

985+
@Deprecated
986+
@JRubyMethod(name = "execute_insert", required = 2)
987+
public IRubyObject execute_insert(final ThreadContext context, final IRubyObject binds, final IRubyObject sql) {
988+
return execute_insert_pk(context, sql, binds, context.nil);
989+
}
990+
948991
/**
949992
* Executes an UPDATE (DELETE) SQL statement
950993
* @param context

test/db/mysql/unit_test.rb

+7-7
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def initialize; end
9696
connection_handler = connection_handler_stub
9797

9898
config = { :jndi => 'jdbc/TestDS' }
99-
connection_handler.expects(:jndi_connection)
99+
connection_handler.expects(:jndi_connection).with() { |c| config = c }
100100
connection_handler.mysql_connection config
101101

102102
# we do not complete username/database etc :
@@ -126,7 +126,7 @@ def initialize; end
126126
connection_handler = connection_handler_stub
127127

128128
config = { database: 'MyDB' }
129-
connection_handler.expects(:jdbc_connection)
129+
connection_handler.expects(:jdbc_connection).with() { |c| config = c }
130130
::Jdbc::MySQL.expects(:driver_name).returns('com.mysql.CustomDriver')
131131
connection_handler.mysql_connection config
132132
assert_equal 'com.mysql.CustomDriver', config[:driver]
@@ -138,7 +138,7 @@ def initialize; end
138138
connection_handler = connection_handler_stub
139139

140140
config = { database: 'MyDB' }
141-
connection_handler.expects(:jdbc_connection)
141+
connection_handler.expects(:jdbc_connection).with() { |c| config = c }
142142
::Jdbc::MySQL.expects(:driver_name).returns('com.mysql.cj.jdbc.Driver')
143143
connection_handler.mysql_connection config
144144
assert_equal 'com.mysql.cj.jdbc.Driver', config[:driver]
@@ -174,7 +174,7 @@ def teardown
174174
connection_handler = connection_handler_stub
175175

176176
config = { host: '127.0.0.1', database: 'MyDB' }
177-
connection_handler.expects(:jdbc_connection)
177+
connection_handler.expects(:jdbc_connection).with() { |c| config = c }
178178
connection_handler.mysql_connection config
179179

180180
# we do not complete username/database etc :
@@ -201,7 +201,7 @@ def teardown
201201
connection_handler = connection_handler_stub
202202

203203
config = { database: 'MyDB', driver: false }
204-
connection_handler.expects(:jdbc_connection)
204+
connection_handler.expects(:jdbc_connection).with() { |c| config = c }
205205
connection_handler.expects(:require).never
206206
connection_handler.mysql_connection config
207207
assert_not config[:driver] # allow Java's service discovery mechanism (with connector/j 8.0)
@@ -211,7 +211,7 @@ def teardown
211211
connection_handler = connection_handler_stub
212212

213213
config = { database: 'MyDB', driver: 'org.mariadb.jdbc.Driver' }
214-
connection_handler.expects(:jdbc_connection)
214+
connection_handler.expects(:jdbc_connection).with() { |c| config = c }
215215
connection_handler.mysql_connection config
216216

217217
# we do not complete username/database etc :
@@ -224,4 +224,4 @@ def teardown
224224

225225
end
226226

227-
end if defined? JRUBY_VERSION
227+
end if defined? JRUBY_VERSION
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
require 'test_helper'
2+
require 'db/postgres'
3+
4+
class PrimaryKeyIsNotTheFirstColumnTest < Test::Unit::TestCase
5+
6+
class CreateEmployees < ActiveRecord::Migration[4.2]
7+
def self.up
8+
create_table 'employees', :id => false do |t|
9+
t.string :full_name, :null => false
10+
t.primary_key :id, :serial
11+
end
12+
end
13+
def self.down
14+
drop_table 'employees'
15+
end
16+
end
17+
18+
def setup
19+
CreateEmployees.up
20+
end
21+
22+
def teardown
23+
CreateEmployees.down
24+
end
25+
26+
class Employee < ActiveRecord::Base
27+
end
28+
29+
def test_returning_when_primary_key_is_not_the_first_column
30+
e = Employee.new
31+
e.full_name = 'Slartibartfast'
32+
e.save!
33+
e.reload
34+
assert_equal 1, e.id
35+
end
36+
37+
end

test/db/postgresql/unit_test.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class PostgresUnitTest < Test::Unit::TestCase
2222
connection_handler = connection_handler_stub
2323

2424
config = { :jndi => 'jdbc/TestDS' }
25-
connection_handler.expects(:jndi_connection)
25+
connection_handler.expects(:jndi_connection).with() { |c| config = c }
2626
connection_handler.postgresql_connection config
2727

2828
# we do not complete username/database etc :

0 commit comments

Comments
 (0)