activerecord-jdbc-adapter 1.3.18 → 1.3.19

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86270ab993887f84a2f2bb4dbbb8826b95c23ca8
4
- data.tar.gz: 7af7d89826ae8b430395bedbf64af8aeab0a3cfc
3
+ metadata.gz: 19e56fe06c05f03b099bb62c6d6cad31e533d206
4
+ data.tar.gz: b48a142b0ed768d61928d393f66f5f23ef104237
5
5
  SHA512:
6
- metadata.gz: e2c2d95d0620b913bea2f02c5448bb709ed5e6e7033434ca367c011f0d6b6dc55d4b4862f6011fa0371fa9ae88d2396af143fe8b202da2f8ea10fe833c4dcc61
7
- data.tar.gz: 87d7ffe54e5fe6e44871e85f16af7db741c1fec6cbd37b82dfb235d59cb0ad7f24af9f6074f7368bb613320f4fdfbcb017fa17f23337ba761b11f95dcfe5d112
6
+ metadata.gz: f3f2e725dcbaf68da28f4a4dbec5815d350132d8383980adc608a2b269f6a55e2efc90e42169178c432b98d22063abcdd602159b46cf17bb663f3adeb186ad04
7
+ data.tar.gz: b1c911e93edfcc4f25c9ac0e091541fa0834f1e6b731c0bbcc57e5df6b06014a3b83fb87c11b241a36f9697b6f02a22fa0c709c57eba5d3b350525447325dc4c
data/Appraisals CHANGED
@@ -12,6 +12,7 @@ appraise "rails31" do
12
12
  end
13
13
 
14
14
  appraise "rails32" do
15
+ gem 'i18n', '< 0.7'
15
16
  gem "activerecord", "~> 3.2.19", :require => false
16
17
  end
17
18
 
data/Gemfile CHANGED
@@ -52,7 +52,7 @@ if sqlite_version = ENV['JDBC_SQLITE_VERSION'] # for testing against different v
52
52
  gem 'jdbc-sqlite3', sqlite_version, :require => nil, :platform => :jruby, :group => :test
53
53
  end
54
54
 
55
- gem 'mysql2', :require => nil, :platform => :mri, :group => :test
55
+ gem 'mysql2', '< 0.4', :require => nil, :platform => :mri, :group => :test
56
56
  gem 'pg', :require => nil, :platform => :mri, :group => :test
57
57
  gem 'sqlite3', :require => nil, :platform => :mri, :group => :test
58
58
  group :mssql do
data/History.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## 1.3.19 (11/02/15)
2
+
3
+ - [sqlite] add supports_partial_index? and remove duplicate support_index_sort_order?
4
+ - [sqlite] fix missing save-point removal in release_savepoint
5
+ - test and fix current savepoint_name compatibility with AR versions (mostly 4.2)
6
+ * adjust returned current savepoint name to better match with AR (< 4.2)
7
+ * make sure savepoint rollback behave AR compatibly
8
+ - [mysql] revert to extracting BIT into an int as tinyint(1) (#687)
9
+ - [mysql] do not validate connection_alive_sql as there's a special /* ping */ query
10
+ - support timeouts on connection validation with `config[:connection_alive_timeout]`
11
+
1
12
  ## 1.3.18 (09/14/15)
2
13
 
3
14
  - since arel visitor instances might get re-used we need to avoid the @instance
@@ -396,7 +396,7 @@ module ActiveRecord
396
396
  # @param name the save-point name
397
397
  # @since 1.3.0
398
398
  # @extension added optional name parameter
399
- def rollback_to_savepoint(name = current_savepoint_name)
399
+ def rollback_to_savepoint(name = current_savepoint_name(true))
400
400
  @connection.rollback_savepoint(name)
401
401
  end
402
402
 
@@ -406,7 +406,7 @@ module ActiveRecord
406
406
  # @param name the save-point name
407
407
  # @since 1.3.0
408
408
  # @extension added optional name parameter
409
- def release_savepoint(name = current_savepoint_name)
409
+ def release_savepoint(name = current_savepoint_name(false))
410
410
  @connection.release_savepoint(name)
411
411
  end
412
412
 
@@ -417,17 +417,20 @@ module ActiveRecord
417
417
  # @return [String] the current save-point name
418
418
  # @since 1.3.0
419
419
  # @override
420
- def current_savepoint_name(create = nil)
420
+ def current_savepoint_name(compat = true)
421
421
  open_tx = open_transactions
422
- return "active_record_#{open_tx}" if create
422
+ return "active_record_#{open_tx}" if compat # by default behave like AR
423
423
 
424
424
  sp_names = @connection.marked_savepoint_names
425
- unless sp_names.empty?
426
- sp_names[ -(sp_names.size - open_tx + 1) ]
427
- else
428
- "active_record_#{open_tx}"
429
- end
430
- end
425
+ sp_names.last || "active_record_#{open_tx}"
426
+ # should (open_tx- 1) here but we play by AR's rules as it might fail
427
+ end unless ArJdbc::AR42
428
+
429
+ # @note Same as AR 4.2 but we're allowing an unused parameter.
430
+ # @private
431
+ def current_savepoint_name(compat = nil)
432
+ current_transaction.savepoint_name # unlike AR 3.2-4.1 might be nil
433
+ end if ArJdbc::AR42
431
434
 
432
435
  # @override
433
436
  def supports_views?
@@ -717,7 +717,7 @@ module ArJdbc
717
717
  end
718
718
 
719
719
  # @override
720
- def release_savepoint(name = current_savepoint_name)
720
+ def release_savepoint(name = current_savepoint_name(false))
721
721
  if @connection.jtds_driver?
722
722
  @connection.release_savepoint(name)
723
723
  else # MS invented it's "own" way
@@ -286,7 +286,7 @@ module ArJdbc
286
286
  version[0] && version[0] >= 5 # MySQL 5+
287
287
  end
288
288
 
289
- # NOTE: handled by JdbcAdapter we override only to have save-point in logs :
289
+ # NOTE: handled by JdbcAdapter only to have statements in logs :
290
290
 
291
291
  # @override
292
292
  def supports_savepoints?
@@ -299,12 +299,12 @@ module ArJdbc
299
299
  end
300
300
 
301
301
  # @override
302
- def rollback_to_savepoint(name = current_savepoint_name)
302
+ def rollback_to_savepoint(name = current_savepoint_name(true))
303
303
  log("ROLLBACK TO SAVEPOINT #{name}", 'Savepoint') { super }
304
304
  end
305
305
 
306
306
  # @override
307
- def release_savepoint(name = current_savepoint_name)
307
+ def release_savepoint(name = current_savepoint_name(false))
308
308
  log("RELEASE SAVEPOINT #{name}", 'Savepoint') { super }
309
309
  end
310
310
 
@@ -44,7 +44,7 @@ module ArJdbc
44
44
  pp << separator
45
45
  pp << build_footer(result.rows.length, elapsed)
46
46
 
47
- pp.join("\n") + "\n"
47
+ pp.join(sep = "\n") << sep
48
48
  end
49
49
 
50
50
  private
@@ -59,8 +59,7 @@ module ArJdbc
59
59
  end
60
60
 
61
61
  def build_separator(widths)
62
- padding = 1
63
- '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
62
+ padding = 1; "+#{widths.map { |w| '-' * (w + (padding * 2 )) }.join('+')}+"
64
63
  end
65
64
 
66
65
  def build_cells(items, widths)
@@ -70,7 +69,7 @@ module ArJdbc
70
69
  justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
71
70
  cells << item.to_s.send(justifier, widths[i])
72
71
  end
73
- '| ' + cells.join(' | ') + ' |'
72
+ "|#{cells.join(' | ')}|"
74
73
  end
75
74
 
76
75
  def build_footer(nrows, elapsed)
@@ -397,12 +397,12 @@ module ArJdbc
397
397
  end
398
398
 
399
399
  # @override
400
- def rollback_to_savepoint(name = current_savepoint_name)
400
+ def rollback_to_savepoint(name = current_savepoint_name(true))
401
401
  log("ROLLBACK TO SAVEPOINT #{name}", 'Savepoint') { super }
402
402
  end
403
403
 
404
404
  # @override
405
- def release_savepoint(name = current_savepoint_name)
405
+ def release_savepoint(name = current_savepoint_name(false))
406
406
  log("RELEASE SAVEPOINT #{name}", 'Savepoint') { super }
407
407
  end
408
408
 
@@ -155,22 +155,22 @@ module ArJdbc
155
155
  end
156
156
 
157
157
  # @override
158
- def supports_add_column?
159
- true
158
+ def supports_partial_index?
159
+ sqlite_version >= '3.8.0'
160
160
  end
161
161
 
162
162
  # @override
163
- def supports_count_distinct?
163
+ def supports_add_column?
164
164
  true
165
165
  end
166
166
 
167
167
  # @override
168
- def supports_autoincrement?
168
+ def supports_count_distinct?
169
169
  true
170
170
  end
171
171
 
172
172
  # @override
173
- def supports_index_sort_order?
173
+ def supports_autoincrement?
174
174
  true
175
175
  end
176
176
 
@@ -285,12 +285,12 @@ module ArJdbc
285
285
  end
286
286
 
287
287
  # @override
288
- def rollback_to_savepoint(name = current_savepoint_name)
288
+ def rollback_to_savepoint(name = current_savepoint_name(true))
289
289
  log("ROLLBACK TO SAVEPOINT #{name}", 'Savepoint') { super }
290
290
  end
291
291
 
292
292
  # @override
293
- def release_savepoint(name = current_savepoint_name)
293
+ def release_savepoint(name = current_savepoint_name(false))
294
294
  log("RELEASE SAVEPOINT #{name}", 'Savepoint') { super }
295
295
  end
296
296
 
@@ -1,5 +1,5 @@
1
1
  module ArJdbc
2
- VERSION = "1.3.18"
2
+ VERSION = "1.3.19"
3
3
  # @deprecated
4
4
  module Version
5
5
  # @private 1.2.x compatibility
@@ -2959,18 +2959,22 @@ public class RubyJdbcConnection extends RubyObject {
2959
2959
 
2960
2960
  protected boolean isConnectionValid(final ThreadContext context, final Connection connection) {
2961
2961
  if ( connection == null ) return false;
2962
- final IRubyObject alive_sql = getConfigValue(context, "connection_alive_sql");
2963
2962
  Statement statement = null;
2964
2963
  try {
2965
- RubyString aliveSQL = alive_sql.isNil() ? null : alive_sql.convertToString();
2964
+ final RubyString aliveSQL = getAliveSQL(context);
2965
+ final RubyInteger aliveTimeout = getAliveTimeout(context);
2966
2966
  if ( aliveSQL != null && isSelect(aliveSQL) ) {
2967
2967
  // expect a SELECT/CALL SQL statement
2968
2968
  statement = createStatement(context, connection);
2969
+ if (aliveTimeout != null) {
2970
+ statement.setQueryTimeout((int) aliveTimeout.getLongValue()); // 0 - no timeout
2971
+ }
2969
2972
  statement.execute( aliveSQL.toString() );
2970
2973
  return true; // connection alive
2971
2974
  }
2972
2975
  else { // alive_sql nil (or not a statement we can execute)
2973
- return connection.isValid(0); // since JDBC 4.0
2976
+ return connection.isValid(aliveTimeout == null ? 0 : (int) aliveTimeout.getLongValue()); // since JDBC 4.0
2977
+ // ... isValid(0) (default) means no timeout applied
2974
2978
  }
2975
2979
  }
2976
2980
  catch (Exception e) {
@@ -2988,6 +2992,22 @@ public class RubyJdbcConnection extends RubyObject {
2988
2992
  finally { close(statement); }
2989
2993
  }
2990
2994
 
2995
+ /**
2996
+ * internal API do not depend on it
2997
+ */
2998
+ protected final RubyString getAliveSQL(final ThreadContext context) {
2999
+ final IRubyObject alive_sql = getConfigValue(context, "connection_alive_sql");
3000
+ return alive_sql.isNil() ? null : alive_sql.convertToString();
3001
+ }
3002
+
3003
+ /**
3004
+ * internal API do not depend on it
3005
+ */
3006
+ protected final RubyInteger getAliveTimeout(final ThreadContext context) {
3007
+ final IRubyObject timeout = getConfigValue(context, "connection_alive_timeout");
3008
+ return timeout.isNil() ? null : timeout.convertToInteger("to_i");
3009
+ }
3010
+
2991
3011
  private boolean tableExists(final Ruby runtime,
2992
3012
  final Connection connection, final TableName tableName) throws SQLException {
2993
3013
  final IRubyObject matchedTables =
@@ -47,6 +47,7 @@ import org.jruby.Ruby;
47
47
  import org.jruby.RubyArray;
48
48
  import org.jruby.RubyClass;
49
49
  import org.jruby.RubyFloat;
50
+ import org.jruby.RubyInteger;
50
51
  import org.jruby.RubyModule;
51
52
  import org.jruby.RubyString;
52
53
  import org.jruby.exceptions.RaiseException;
@@ -97,9 +98,9 @@ public class MySQLRubyJdbcConnection extends RubyJdbcConnection {
97
98
  final ThreadContext context, final Ruby runtime,
98
99
  final int column, final int type, final ResultSet resultSet)
99
100
  throws SQLException {
100
- if ( Types.BOOLEAN == type || Types.BIT == type ) {
101
- final boolean value = resultSet.getBoolean(column);
102
- return resultSet.wasNull() ? runtime.getNil() : runtime.newFixnum(value ? 1 : 0);
101
+ if ( type == Types.BIT ) {
102
+ final int value = resultSet.getInt(column);
103
+ return resultSet.wasNull() ? runtime.getNil() : runtime.newFixnum(value);
103
104
  }
104
105
  return super.jdbcToRuby(context, runtime, column, type, resultSet);
105
106
  }
@@ -154,6 +155,42 @@ public class MySQLRubyJdbcConnection extends RubyJdbcConnection {
154
155
  return time - ( offset / 1000.0 );
155
156
  }
156
157
 
158
+ @Override
159
+ protected final boolean isConnectionValid(final ThreadContext context, final Connection connection) {
160
+ if ( connection == null ) return false;
161
+ Statement statement = null;
162
+ try {
163
+ final RubyString aliveSQL = getAliveSQL(context);
164
+ final RubyInteger aliveTimeout = getAliveTimeout(context);
165
+ if ( aliveSQL != null ) {
166
+ // expect a SELECT/CALL SQL statement
167
+ statement = createStatement(context, connection);
168
+ if (aliveTimeout != null) {
169
+ statement.setQueryTimeout((int) aliveTimeout.getLongValue()); // 0 - no timeout
170
+ }
171
+ statement.execute( aliveSQL.toString() );
172
+ return true; // connection alive
173
+ }
174
+ else { // alive_sql nil (or not a statement we can execute)
175
+ return connection.isValid(aliveTimeout == null ? 0 : (int) aliveTimeout.getLongValue()); // since JDBC 4.0
176
+ // ... isValid(0) (default) means no timeout applied
177
+ }
178
+ }
179
+ catch (Exception e) {
180
+ debugMessage(context, "connection considered broken due: " + e.toString());
181
+ return false;
182
+ }
183
+ catch (AbstractMethodError e) { // non-JDBC 4.0 driver
184
+ warn( context,
185
+ "WARN: driver does not support checking if connection isValid()" +
186
+ " please make sure you're using a JDBC 4.0 compilant driver or" +
187
+ " set `connection_alive_sql: ...` in your database configuration" );
188
+ debugStackTrace(context, e);
189
+ throw e;
190
+ }
191
+ finally { close(statement); }
192
+ }
193
+
157
194
  @Override
158
195
  protected IRubyObject indexes(final ThreadContext context, final String tableName, final String name, final String schemaName) {
159
196
  return withConnection(context, new Callable<IRubyObject>() {
@@ -327,7 +327,7 @@ public class SQLite3RubyJdbcConnection extends RubyJdbcConnection {
327
327
  public IRubyObject release_savepoint(final ThreadContext context, final IRubyObject name) {
328
328
  final Connection connection = getConnection(true);
329
329
  try {
330
- if ( getSavepoints(context).get(name) == null ) {
330
+ if ( getSavepoints(context).remove(name) == null ) {
331
331
  throw context.getRuntime().newRuntimeError("could not release savepoint: '" + name + "' (not set)");
332
332
  }
333
333
  // NOTE: JDBC driver does not implement release(Savepoint) :
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-jdbc-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.18
4
+ version: 1.3.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sieger, Ola Bini, Karol Bucek and JRuby contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-14 00:00:00.000000000 Z
11
+ date: 2015-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord