activerecord-jdbc-adapter 50.8-java → 51.1-java
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 +5 -5
- data/.gitignore +1 -2
- data/.travis.yml +26 -51
- data/Gemfile +3 -1
- data/README.md +9 -11
- data/Rakefile +15 -78
- data/activerecord-jdbc-adapter.gemspec +2 -2
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/arjdbc/abstract/core.rb +4 -12
- data/lib/arjdbc/abstract/database_statements.rb +4 -10
- data/lib/arjdbc/abstract/statement_cache.rb +4 -4
- data/lib/arjdbc/abstract/transaction_support.rb +2 -9
- data/lib/arjdbc/jdbc.rb +4 -0
- data/lib/arjdbc/jdbc/column.rb +11 -5
- data/lib/arjdbc/jdbc/connection_methods.rb +9 -2
- data/lib/arjdbc/jdbc/error.rb +1 -1
- data/lib/arjdbc/jdbc/jdbc.rake +4 -0
- data/lib/arjdbc/mssql.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +804 -0
- data/lib/arjdbc/mssql/column.rb +200 -0
- data/lib/arjdbc/mssql/connection_methods.rb +79 -0
- data/lib/arjdbc/mssql/explain_support.rb +99 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/types.rb +343 -0
- data/lib/arjdbc/mssql/utils.rb +82 -0
- data/lib/arjdbc/mysql/adapter.rb +14 -11
- data/lib/arjdbc/mysql/connection_methods.rb +9 -18
- data/lib/arjdbc/postgresql/adapter.rb +108 -59
- data/lib/arjdbc/postgresql/column.rb +3 -6
- data/lib/arjdbc/postgresql/connection_methods.rb +3 -12
- data/lib/arjdbc/postgresql/oid_types.rb +14 -93
- data/lib/arjdbc/sqlite3/adapter.rb +171 -140
- data/lib/arjdbc/sqlite3/connection_methods.rb +1 -2
- data/lib/arjdbc/tasks/database_tasks.rb +36 -16
- data/lib/arjdbc/tasks/databases.rake +75 -32
- data/lib/arjdbc/tasks/databases3.rake +215 -0
- data/lib/arjdbc/tasks/databases4.rake +39 -0
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/01-tomcat.rake +2 -2
- data/rakelib/02-test.rake +3 -0
- data/rakelib/compile.rake +70 -0
- data/rakelib/db.rake +7 -21
- data/rakelib/rails.rake +4 -5
- data/src/java/arjdbc/ArJdbcModule.java +15 -5
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +2 -2
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +87 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +1 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +41 -120
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +14 -310
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +2 -2
- data/src/java/arjdbc/postgresql/ByteaUtils.java +1 -0
- data/src/java/arjdbc/postgresql/PgResultSetMetaDataWrapper.java +23 -0
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +13 -21
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +46 -41
- data/src/java/arjdbc/util/DateTimeUtils.java +5 -141
- data/src/java/arjdbc/util/QuotingUtils.java +7 -6
- data/src/java/arjdbc/util/StringHelper.java +20 -6
- metadata +25 -16
- data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +0 -61
- data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +0 -52
@@ -27,6 +27,7 @@ package arjdbc.postgresql;
|
|
27
27
|
|
28
28
|
import arjdbc.jdbc.Callable;
|
29
29
|
import arjdbc.jdbc.DriverWrapper;
|
30
|
+
import arjdbc.postgresql.PostgreSQLResult;
|
30
31
|
import arjdbc.util.DateTimeUtils;
|
31
32
|
import arjdbc.util.StringHelper;
|
32
33
|
|
@@ -54,7 +55,6 @@ import org.joda.time.DateTimeZone;
|
|
54
55
|
import org.jruby.*;
|
55
56
|
import org.jruby.anno.JRubyMethod;
|
56
57
|
import org.jruby.exceptions.RaiseException;
|
57
|
-
import org.jruby.ext.bigdecimal.RubyBigDecimal;
|
58
58
|
import org.jruby.javasupport.JavaUtil;
|
59
59
|
import org.jruby.runtime.ObjectAllocator;
|
60
60
|
import org.jruby.runtime.ThreadContext;
|
@@ -100,7 +100,6 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
100
100
|
POSTGRES_JDBC_TYPE_FOR.put("line", Types.OTHER);
|
101
101
|
POSTGRES_JDBC_TYPE_FOR.put("lseg", Types.OTHER);
|
102
102
|
POSTGRES_JDBC_TYPE_FOR.put("ltree", Types.OTHER);
|
103
|
-
POSTGRES_JDBC_TYPE_FOR.put("money", Types.OTHER);
|
104
103
|
POSTGRES_JDBC_TYPE_FOR.put("numrange", Types.OTHER);
|
105
104
|
POSTGRES_JDBC_TYPE_FOR.put("path", Types.OTHER);
|
106
105
|
POSTGRES_JDBC_TYPE_FOR.put("point", Types.OTHER);
|
@@ -281,30 +280,6 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
281
280
|
return mapExecuteResult(context, connection, resultSet).toARResult(context);
|
282
281
|
}
|
283
282
|
|
284
|
-
@Override
|
285
|
-
protected void setArrayParameter(final ThreadContext context,
|
286
|
-
final Connection connection, final PreparedStatement statement,
|
287
|
-
final int index, final IRubyObject value,
|
288
|
-
final IRubyObject attribute, final int type) throws SQLException {
|
289
|
-
|
290
|
-
final String typeName = resolveArrayBaseTypeName(context, attribute);
|
291
|
-
final RubyArray valueForDB = (RubyArray) value.callMethod(context, "values");
|
292
|
-
|
293
|
-
Object[] values;
|
294
|
-
switch (typeName) {
|
295
|
-
case "datetime":
|
296
|
-
case "timestamp": {
|
297
|
-
values = PgDateTimeUtils.timestampStringArray(context, valueForDB);
|
298
|
-
break;
|
299
|
-
}
|
300
|
-
default:
|
301
|
-
values = valueForDB.toArray();
|
302
|
-
break;
|
303
|
-
}
|
304
|
-
|
305
|
-
statement.setArray(index, connection.createArrayOf(typeName, values));
|
306
|
-
}
|
307
|
-
|
308
283
|
@Override
|
309
284
|
protected void setBlobParameter(final ThreadContext context,
|
310
285
|
final Connection connection, final PreparedStatement statement,
|
@@ -328,9 +303,47 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
328
303
|
final Connection connection, final PreparedStatement statement,
|
329
304
|
final int index, IRubyObject value,
|
330
305
|
final IRubyObject attribute, final int type) throws SQLException {
|
331
|
-
|
332
|
-
|
333
|
-
|
306
|
+
|
307
|
+
if ( value instanceof RubyFloat ) {
|
308
|
+
final double doubleValue = ( (RubyFloat) value ).getValue();
|
309
|
+
if ( Double.isInfinite(doubleValue) ) {
|
310
|
+
setTimestampInfinity(statement, index, doubleValue);
|
311
|
+
return;
|
312
|
+
}
|
313
|
+
}
|
314
|
+
|
315
|
+
RubyTime timeValue = toTime(context, value);
|
316
|
+
|
317
|
+
final Timestamp timestamp;
|
318
|
+
|
319
|
+
if (timeValue.getDateTime().getYear() > 0) {
|
320
|
+
timeValue = timeInDefaultTimeZone(context, timeValue);
|
321
|
+
DateTime dateTime = timeValue.getDateTime();
|
322
|
+
timestamp = new Timestamp(dateTime.getMillis());
|
323
|
+
|
324
|
+
if (timeValue.getNSec() > 0) timestamp.setNanos((int) (timestamp.getNanos() + timeValue.getNSec()));
|
325
|
+
|
326
|
+
statement.setTimestamp(index, timestamp, getCalendar(dateTime.getZone()));
|
327
|
+
}
|
328
|
+
else {
|
329
|
+
setTimestampBC(statement, index, timeValue);
|
330
|
+
}
|
331
|
+
}
|
332
|
+
|
333
|
+
private static void setTimestampBC(final PreparedStatement statement,
|
334
|
+
final int index, final RubyTime timeValue) throws SQLException {
|
335
|
+
DateTime dateTime = timeValue.getDateTime();
|
336
|
+
@SuppressWarnings("deprecated")
|
337
|
+
Timestamp timestamp = new Timestamp(dateTime.getYear() - 1900,
|
338
|
+
dateTime.getMonthOfYear() - 1,
|
339
|
+
dateTime.getDayOfMonth(),
|
340
|
+
dateTime.getHourOfDay(),
|
341
|
+
dateTime.getMinuteOfHour(),
|
342
|
+
dateTime.getSecondOfMinute(),
|
343
|
+
dateTime.getMillisOfSecond() * 1_000_000 + (int) timeValue.getNSec()
|
344
|
+
);
|
345
|
+
|
346
|
+
statement.setObject(index, timestamp);
|
334
347
|
}
|
335
348
|
|
336
349
|
private static void setTimestampInfinity(final PreparedStatement statement,
|
@@ -352,8 +365,7 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
352
365
|
final int index, IRubyObject value,
|
353
366
|
final IRubyObject attribute, final int type) throws SQLException {
|
354
367
|
// to handle more fractional second precision than (default) 59.123 only
|
355
|
-
|
356
|
-
statement.setObject(index, timeStr, Types.OTHER);
|
368
|
+
super.setTimestampParameter(context, connection, statement, index, value, attribute, type);
|
357
369
|
}
|
358
370
|
|
359
371
|
@Override
|
@@ -407,7 +419,8 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
407
419
|
break;
|
408
420
|
|
409
421
|
case "enum":
|
410
|
-
|
422
|
+
// FIXME: This doesn't work but it gives a better error message than letting it be treated as a PGobject
|
423
|
+
statement.setObject(index, value.toString());
|
411
424
|
break;
|
412
425
|
|
413
426
|
case "interval":
|
@@ -428,14 +441,6 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
428
441
|
}
|
429
442
|
break;
|
430
443
|
|
431
|
-
case "money":
|
432
|
-
if (value instanceof RubyBigDecimal) {
|
433
|
-
statement.setBigDecimal(index, ((RubyBigDecimal) value).getValue());
|
434
|
-
} else {
|
435
|
-
setPGobjectParameter(statement, index, value, columnType);
|
436
|
-
}
|
437
|
-
break;
|
438
|
-
|
439
444
|
case "lseg":
|
440
445
|
pointValues = parseDoubles(value);
|
441
446
|
statement.setObject(index, new PGlseg(pointValues[0], pointValues[1], pointValues[2], pointValues[3]));
|
@@ -480,7 +485,7 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
|
|
480
485
|
return points;
|
481
486
|
}
|
482
487
|
|
483
|
-
private
|
488
|
+
private Double[] parseDoubles(IRubyObject value) {
|
484
489
|
Matcher matches = doubleValuePattern.matcher(value.toString());
|
485
490
|
ArrayList<Double> doubles = new ArrayList<Double>(4); // Paths and polygons may be larger but this covers points/circles/boxes/line segments
|
486
491
|
|
@@ -28,10 +28,8 @@ import java.sql.Time;
|
|
28
28
|
import java.sql.Timestamp;
|
29
29
|
import java.util.TimeZone;
|
30
30
|
|
31
|
-
import org.joda.time.Chronology;
|
32
31
|
import org.joda.time.DateTime;
|
33
32
|
import org.joda.time.DateTimeZone;
|
34
|
-
import org.joda.time.chrono.GJChronology;
|
35
33
|
import org.joda.time.chrono.ISOChronology;
|
36
34
|
import org.jruby.Ruby;
|
37
35
|
import org.jruby.RubyFloat;
|
@@ -42,7 +40,6 @@ import org.jruby.runtime.Block;
|
|
42
40
|
import org.jruby.runtime.ThreadContext;
|
43
41
|
import org.jruby.runtime.builtin.IRubyObject;
|
44
42
|
import org.jruby.util.ByteList;
|
45
|
-
import org.jruby.util.TypeConverter;
|
46
43
|
|
47
44
|
import static arjdbc.util.StringHelper.decByte;
|
48
45
|
|
@@ -52,20 +49,6 @@ import static arjdbc.util.StringHelper.decByte;
|
|
52
49
|
*/
|
53
50
|
public abstract class DateTimeUtils {
|
54
51
|
|
55
|
-
private static final GJChronology CHRONO_ITALY_UTC = GJChronology.getInstance(DateTimeZone.UTC);
|
56
|
-
|
57
|
-
public static RubyTime toTime(final ThreadContext context, final IRubyObject value) {
|
58
|
-
if (!(value instanceof RubyTime)) { // unlikely
|
59
|
-
return (RubyTime) TypeConverter.convertToTypeWithCheck(value, context.runtime.getTime(), "to_time");
|
60
|
-
}
|
61
|
-
return (RubyTime) value;
|
62
|
-
}
|
63
|
-
|
64
|
-
public static DateTime dateTimeInZone(final DateTime dateTime, final DateTimeZone zone) {
|
65
|
-
if (zone == dateTime.getZone()) return dateTime;
|
66
|
-
return dateTime.withZone(zone);
|
67
|
-
}
|
68
|
-
|
69
52
|
@SuppressWarnings("deprecation")
|
70
53
|
public static ByteList timeToString(final Time time) {
|
71
54
|
final ByteList str = new ByteList(8); // hh:mm:ss
|
@@ -221,11 +204,9 @@ public abstract class DateTimeUtils {
|
|
221
204
|
final int hours = time.getHours();
|
222
205
|
final int minutes = time.getMinutes();
|
223
206
|
final int seconds = time.getSeconds();
|
224
|
-
int nanos = time.getNanos(); // max 999-999-999
|
225
|
-
final int millis = nanos / 1000000;
|
226
|
-
nanos = nanos % 1000000;
|
207
|
+
final int nanos = time.getNanos(); // max 999-999-999
|
227
208
|
|
228
|
-
DateTime dateTime = new DateTime(2000, 1, 1, hours, minutes, seconds,
|
209
|
+
DateTime dateTime = new DateTime(2000, 1, 1, hours, minutes, seconds, defaultZone);
|
229
210
|
return RubyTime.newTime(context.runtime, dateTime, nanos);
|
230
211
|
}
|
231
212
|
|
@@ -238,11 +219,9 @@ public abstract class DateTimeUtils {
|
|
238
219
|
final int hours = timestamp.getHours();
|
239
220
|
final int minutes = timestamp.getMinutes();
|
240
221
|
final int seconds = timestamp.getSeconds();
|
241
|
-
int nanos = timestamp.getNanos(); // max 999-999-999
|
242
|
-
final int millis = nanos / 1000000;
|
243
|
-
nanos = nanos % 1000000;
|
222
|
+
final int nanos = timestamp.getNanos(); // max 999-999-999
|
244
223
|
|
245
|
-
DateTime dateTime = new DateTime(year, month, day, hours, minutes, seconds,
|
224
|
+
DateTime dateTime = new DateTime(year, month, day, hours, minutes, seconds, 0, defaultZone);
|
246
225
|
return RubyTime.newTime(context.runtime, dateTime, nanos);
|
247
226
|
}
|
248
227
|
|
@@ -267,15 +246,6 @@ public abstract class DateTimeUtils {
|
|
267
246
|
return newDate(context, year, month, day, ISOChronology.getInstance(zone));
|
268
247
|
}
|
269
248
|
|
270
|
-
@SuppressWarnings("deprecation")
|
271
|
-
public static IRubyObject newDate(final ThreadContext context, final Date date) {
|
272
|
-
final int year = date.getYear() + 1900;
|
273
|
-
final int month = date.getMonth() + 1;
|
274
|
-
final int day = date.getDate();
|
275
|
-
|
276
|
-
return newDate(context, year, month, day, CHRONO_ITALY_UTC);
|
277
|
-
}
|
278
|
-
|
279
249
|
// @Deprecated
|
280
250
|
public static Timestamp convertToTimestamp(final RubyFloat value) {
|
281
251
|
final Timestamp timestamp = new Timestamp(value.getLongValue() * 1000); // millis
|
@@ -570,7 +540,7 @@ public abstract class DateTimeUtils {
|
|
570
540
|
}
|
571
541
|
|
572
542
|
private static IRubyObject newDate(final ThreadContext context, final int year, final int month, final int day,
|
573
|
-
final
|
543
|
+
final ISOChronology chronology) {
|
574
544
|
// NOTE: JRuby really needs a native date.rb until than its a bit costly going from ...
|
575
545
|
// java.sql.Date -> allocating a DateTime proxy, help a bit by shooting at the internals
|
576
546
|
//
|
@@ -607,110 +577,4 @@ public abstract class DateTimeUtils {
|
|
607
577
|
return n;
|
608
578
|
}
|
609
579
|
|
610
|
-
|
611
|
-
private static final char[] ZEROS = {'0', '0', '0', '0', '0', '0'};
|
612
|
-
private static final char[][] NUMBERS;
|
613
|
-
|
614
|
-
static {
|
615
|
-
// maximum value is 60 (seconds)
|
616
|
-
NUMBERS = new char[60][];
|
617
|
-
for (int i = 0; i < NUMBERS.length; i++) {
|
618
|
-
NUMBERS[i] = ((i < 10 ? "0" : "") + Integer.toString(i)).toCharArray();
|
619
|
-
}
|
620
|
-
}
|
621
|
-
|
622
|
-
/**
|
623
|
-
* Converts a ruby timestamp to a java string, optionally with timezone and timezone adjustment
|
624
|
-
* @param context
|
625
|
-
* @param value the ruby value, typically a Time
|
626
|
-
* @param zone DateTimeZone to adjust to, optional
|
627
|
-
* @param withZone include timezone in the string?
|
628
|
-
* @return timestamp as string
|
629
|
-
*/
|
630
|
-
public static String timestampTimeToString(final ThreadContext context,
|
631
|
-
final IRubyObject value, DateTimeZone zone, boolean withZone) {
|
632
|
-
RubyTime timeValue = toTime(context, value);
|
633
|
-
DateTime dt = timeValue.getDateTime();
|
634
|
-
|
635
|
-
StringBuilder sb = new StringBuilder(36);
|
636
|
-
|
637
|
-
int year = dt.getYear();
|
638
|
-
if (year <= 0) {
|
639
|
-
year--;
|
640
|
-
} else if (zone != null) {
|
641
|
-
dt = dateTimeInZone(dt, zone);
|
642
|
-
year = dt.getYear();
|
643
|
-
}
|
644
|
-
|
645
|
-
Chronology chrono = dt.getChronology();
|
646
|
-
long millis = dt.getMillis();
|
647
|
-
|
648
|
-
// always use 4 digits for year to avoid short dates being misinterpreted
|
649
|
-
sb.append(Math.abs(year));
|
650
|
-
int lead = 4 - sb.length();
|
651
|
-
if (lead > 0) sb.insert(0, ZEROS, 0, lead);
|
652
|
-
sb.append('-');
|
653
|
-
sb.append(NUMBERS[chrono.monthOfYear().get(millis)]);
|
654
|
-
sb.append('-');
|
655
|
-
sb.append(NUMBERS[chrono.dayOfMonth().get(millis)]);
|
656
|
-
if (year < 0) sb.append(" BC");
|
657
|
-
sb.append(' ');
|
658
|
-
|
659
|
-
appendTime(sb, chrono, millis, (int) timeValue.getUSec(), withZone);
|
660
|
-
|
661
|
-
return sb.toString();
|
662
|
-
}
|
663
|
-
|
664
|
-
/**
|
665
|
-
* Converts a ruby time to a java string, optionally with timezone and timezone adjustment
|
666
|
-
* @param context
|
667
|
-
* @param value the ruby value, typically a Time
|
668
|
-
* @param zone DateTimeZone to adjust to, optional
|
669
|
-
* @param withZone include timezone in the string?
|
670
|
-
* @return time as string
|
671
|
-
*/
|
672
|
-
public static String timeString(final ThreadContext context,
|
673
|
-
final IRubyObject value, DateTimeZone zone, boolean withZone) {
|
674
|
-
StringBuilder sb = new StringBuilder(21);
|
675
|
-
RubyTime timeValue = toTime(context, value);
|
676
|
-
DateTime dt = timeValue.getDateTime();
|
677
|
-
if (zone != null) dt = dateTimeInZone(dt, zone);
|
678
|
-
|
679
|
-
appendTime(sb, dt.getChronology(), dt.getMillis(), (int) timeValue.getUSec(), withZone);
|
680
|
-
return sb.toString();
|
681
|
-
}
|
682
|
-
|
683
|
-
private static void appendTime(StringBuilder sb, Chronology chrono,
|
684
|
-
long millis, int usec, boolean withZone) {
|
685
|
-
sb.append(NUMBERS[chrono.hourOfDay().get(millis)]);
|
686
|
-
sb.append(':');
|
687
|
-
sb.append(NUMBERS[chrono.minuteOfHour().get(millis)]);
|
688
|
-
sb.append(':');
|
689
|
-
sb.append(NUMBERS[chrono.secondOfMinute().get(millis)]);
|
690
|
-
|
691
|
-
// PG has microsecond resolution. Change when nanos are required
|
692
|
-
int micros = chrono.millisOfSecond().get(millis) * 1000 + usec;
|
693
|
-
if (micros > 0) {
|
694
|
-
sb.append('.');
|
695
|
-
|
696
|
-
int len = sb.length();
|
697
|
-
sb.append(micros);
|
698
|
-
int lead = 6 - (sb.length() - len);
|
699
|
-
if (lead > 0) sb.insert(len, ZEROS, 0, lead);
|
700
|
-
|
701
|
-
for (int end = sb.length() - 1; sb.charAt(end) == '0'; end--) {
|
702
|
-
sb.setLength(end);
|
703
|
-
}
|
704
|
-
}
|
705
|
-
|
706
|
-
if (withZone) {
|
707
|
-
int offset = chrono.getZone().getOffset(millis) / 1000;
|
708
|
-
int absoff = Math.abs(offset);
|
709
|
-
int hours = absoff / 3600;
|
710
|
-
int mins = (absoff - hours * 3600) / 60;
|
711
|
-
|
712
|
-
sb.append(offset < 0 ? '-' : '+');
|
713
|
-
sb.append(NUMBERS[hours]).append(':').append(NUMBERS[mins]);
|
714
|
-
}
|
715
|
-
}
|
716
580
|
}
|
@@ -52,6 +52,7 @@ public abstract class QuotingUtils {
|
|
52
52
|
return quoteCharWith(context, string, value, quote, 0, 8);
|
53
53
|
}
|
54
54
|
|
55
|
+
@SuppressWarnings("deprecation")
|
55
56
|
public static RubyString quoteCharWith(
|
56
57
|
final ThreadContext context,
|
57
58
|
final RubyString string,
|
@@ -71,8 +72,8 @@ public abstract class QuotingUtils {
|
|
71
72
|
new byte[realSize + newOffset + newSizeDiff],
|
72
73
|
stringBytes.getEncoding(), false
|
73
74
|
);
|
74
|
-
quotedBytes.
|
75
|
-
quotedBytes.
|
75
|
+
quotedBytes.begin = newOffset;
|
76
|
+
quotedBytes.realSize = 0;
|
76
77
|
}
|
77
78
|
quotedBytes.append(bytes, appendFrom, i - appendFrom);
|
78
79
|
quotedBytes.append(quote).append(value); // e.g. "'" => "''"
|
@@ -87,6 +88,7 @@ public abstract class QuotingUtils {
|
|
87
88
|
return context.runtime.newString(quotedBytes);
|
88
89
|
}
|
89
90
|
|
91
|
+
@SuppressWarnings("deprecation")
|
90
92
|
public static RubyString quoteCharAndDecorateWith(
|
91
93
|
final ThreadContext context, final RubyString string,
|
92
94
|
final char value, final char quote,
|
@@ -100,7 +102,7 @@ public abstract class QuotingUtils {
|
|
100
102
|
final ByteList quoted = new ByteList(
|
101
103
|
new byte[realSize + 2], string.getEncoding(), false
|
102
104
|
);
|
103
|
-
quoted.
|
105
|
+
quoted.begin = 0; quoted.realSize = 0;
|
104
106
|
quoted.append(prefix);
|
105
107
|
quoted.append(str.unsafeBytes(), str.getBegin(), realSize);
|
106
108
|
quoted.append(suffix);
|
@@ -108,9 +110,8 @@ public abstract class QuotingUtils {
|
|
108
110
|
}
|
109
111
|
// we got a new string with a reserve of 1 byte front and back :
|
110
112
|
final ByteList quoted = quotedString.getByteList();
|
111
|
-
quoted.
|
112
|
-
quoted.
|
113
|
-
quoted.setRealSize(quoted.getRealSize() + 1);
|
113
|
+
quoted.begin = 0; // setBegin invalidates
|
114
|
+
quoted.bytes[0] = prefix; quoted.realSize++;
|
114
115
|
quoted.append(suffix);
|
115
116
|
return quotedString;
|
116
117
|
}
|
@@ -25,9 +25,12 @@ package arjdbc.util;
|
|
25
25
|
|
26
26
|
import java.io.IOException;
|
27
27
|
import java.io.InputStream;
|
28
|
+
import java.nio.charset.Charset;
|
28
29
|
|
29
30
|
import org.jcodings.Encoding;
|
31
|
+
import org.jcodings.specific.UTF8Encoding;
|
30
32
|
import org.jruby.Ruby;
|
33
|
+
import org.jruby.RubyEncoding;
|
31
34
|
import org.jruby.RubyString;
|
32
35
|
import org.jruby.util.ByteList;
|
33
36
|
|
@@ -58,6 +61,18 @@ public abstract class StringHelper {
|
|
58
61
|
return RubyString.newString(runtime, new ByteList(bytes, false));
|
59
62
|
}
|
60
63
|
|
64
|
+
private static final Charset ASCII_CHARSET = Charset.forName("ISO-8859-1");
|
65
|
+
|
66
|
+
public static RubyString newASCIIString(final Ruby runtime, final String str) {
|
67
|
+
final ByteList byteList = new ByteList(str.getBytes(ASCII_CHARSET), false);
|
68
|
+
return RubyString.newString(runtime, byteList);
|
69
|
+
}
|
70
|
+
|
71
|
+
public static RubyString newUTF8String(final Ruby runtime, final byte[] bytes) {
|
72
|
+
final ByteList byteList = new ByteList(bytes, false);
|
73
|
+
return RubyString.newString(runtime, byteList, UTF8Encoding.INSTANCE);
|
74
|
+
}
|
75
|
+
|
61
76
|
public static RubyString newDefaultInternalString(final Ruby runtime, final byte[] bytes) {
|
62
77
|
final ByteList byteList = new ByteList(bytes, false);
|
63
78
|
Encoding enc = runtime.getDefaultInternalEncoding();
|
@@ -68,19 +83,18 @@ public abstract class StringHelper {
|
|
68
83
|
public static RubyString newDefaultInternalString(final Ruby runtime, final CharSequence str) {
|
69
84
|
Encoding enc = runtime.getDefaultInternalEncoding();
|
70
85
|
if (enc == null) enc = runtime.getEncodingService().getJavaDefault();
|
71
|
-
return
|
86
|
+
return RubyString.newString(runtime, new ByteList(RubyEncoding.encode(str, enc.getCharset()), enc));
|
72
87
|
}
|
73
88
|
|
74
|
-
// NOTE: a 'better' RubyString.newInternalFromJavaExternal - to be back-ported in JRuby 9.2
|
75
89
|
public static RubyString newDefaultInternalString(final Ruby runtime, final String str) {
|
76
|
-
|
77
|
-
if (enc == null) enc = runtime.getEncodingService().getJavaDefault();
|
78
|
-
return RubyString.newString(runtime, str, enc);
|
90
|
+
return RubyString.newInternalFromJavaExternal(runtime, str);
|
79
91
|
}
|
80
92
|
|
81
93
|
public static int readBytes(final ByteList output, final InputStream input)
|
82
94
|
throws IOException {
|
83
|
-
|
95
|
+
@SuppressWarnings("deprecation") // capacity :
|
96
|
+
final int buffSize = output.bytes.length - output.begin;
|
97
|
+
return readBytes(output, input, buffSize);
|
84
98
|
}
|
85
99
|
|
86
100
|
public static int readBytes(final ByteList output, final InputStream input, int buffSize)
|