Explorar el Código

improve date handling, handle more binary/character input types

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@420 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-1.1.21
James Ahlborn hace 14 años
padre
commit
1302a37c91
Se han modificado 2 ficheros con 102 adiciones y 11 borrados
  1. 9
    0
      src/changes/changes.xml
  2. 93
    11
      src/java/com/healthmarketscience/jackcess/Column.java

+ 9
- 0
src/changes/changes.xml Ver fichero

@@ -4,6 +4,15 @@
<author email="javajedi@users.sf.net">Tim McCune</author>
</properties>
<body>
<release version="1.1.21" date="TBD">
<action dev="jahlborn" type="fix" issue="2899605">
Further improvements to date handling.
</action>
<action dev="jahlborn" type="update">
Handler more binary/character input types (Blob, Clob, InputStream,
Reader), based on user submitted patch.
</action>
</release>
<release version="1.1.20" date="2009-11-18">
<action dev="jahlborn" type="fix" issue="2884599">
Add support for updating GUID indexes and for auto-number GUID

+ 93
- 11
src/java/com/healthmarketscience/jackcess/Column.java Ver fichero

@@ -27,14 +27,20 @@ King of Prussia, PA 19406

package com.healthmarketscience.jackcess;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Reader;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
@@ -719,13 +725,21 @@ public class Column implements Comparable<Column> {
// seems access stores dates in the local timezone. guess you just hope
// you read it in the same timezone in which it was written!
long dateBits = buffer.getLong();
long time = (long)(Double.longBitsToDouble(dateBits)
* MILLISECONDS_PER_DAY);
time -= MILLIS_BETWEEN_EPOCH_AND_1900;
time -= getTimeZoneOffset(time);
long time = fromDateDouble(Double.longBitsToDouble(dateBits));
return new DateExt(time, dateBits);
}
/**
* Returns a java long time value converted from an access date double.
*/
private static long fromDateDouble(double value)
{
long time = Math.round(value * MILLISECONDS_PER_DAY);
time -= MILLIS_BETWEEN_EPOCH_AND_1900;
time -= getTimeZoneOffset(time);
return time;
}

/**
* Writes a date value.
*/
@@ -741,16 +755,26 @@ public class Column implements Comparable<Column> {
} else {
buffer.putDouble(toDateDouble(value));
}
}

/**
* Returns an access date double converted from a java Date/Calendar/Number
* time value.
*/
private static double toDateDouble(Object value)
{
// seems access stores dates in the local timezone. guess you just
// hope you read it in the same timezone in which it was written!
long time = ((value instanceof Date) ?
((Date)value).getTime() :
((Number)value).longValue());
((value instanceof Calendar) ?
((Calendar)value).getTimeInMillis() :
((Number)value).longValue()));
time += getTimeZoneOffset(time);
time += MILLIS_BETWEEN_EPOCH_AND_1900;
double dTime = time / MILLISECONDS_PER_DAY;
buffer.putDouble(dTime);
}
return time / MILLISECONDS_PER_DAY;
}

/**
@@ -1069,7 +1093,7 @@ public class Column implements Comparable<Column> {
getType());
}

ByteBuffer buffer = ByteBuffer.wrap((byte[])obj);
ByteBuffer buffer = ByteBuffer.wrap(toByteArray(obj));
buffer.order(order);
return buffer;
}
@@ -1089,7 +1113,7 @@ public class Column implements Comparable<Column> {
}

// create long value buffer
return writeLongValue((byte[]) obj, remainingRowLength);
return writeLongValue(toByteArray(obj), remainingRowLength);
}

/**
@@ -1153,7 +1177,7 @@ public class Column implements Comparable<Column> {
case BINARY:
case UNKNOWN_0D:
case UNKNOWN_11:
byte[] bytes = (byte[])obj;
byte[] bytes = toByteArray(obj);
if(bytes.length != getLength()) {
throw new IOException("Invalid fixed size binary data, size "
+ getLength() + ", got " + bytes.length);
@@ -1439,15 +1463,73 @@ public class Column implements Comparable<Column> {
* @return an appropriate CharSequence representation of the given object.
*/
public static CharSequence toCharSequence(Object value)
throws IOException
{
if(value == null) {
return null;
} else if(value instanceof CharSequence) {
return (CharSequence)value;
} else if(value instanceof Clob) {
try {
Clob c = (Clob)value;
// note, start pos is 1-based
return c.getSubString(1L, (int)c.length());
} catch(SQLException e) {
throw (IOException)(new IOException(e.getMessage())).initCause(e);
}
} else if(value instanceof Reader) {
char[] buf = new char[8 * 1024];
StringBuilder sout = new StringBuilder();
Reader in = (Reader)value;
int read = 0;
while((read = in.read(buf)) != -1) {
sout.append(buf, 0, read);
}
return sout;
}

return value.toString();
}

/**
* @return an appropriate byte[] representation of the given object.
*/
public static byte[] toByteArray(Object value)
throws IOException
{
if(value == null) {
return null;
} else if(value instanceof byte[]) {
return (byte[])value;
} else if(value instanceof Blob) {
try {
Blob b = (Blob)value;
// note, start pos is 1-based
return b.getBytes(1L, (int)b.length());
} catch(SQLException e) {
throw (IOException)(new IOException(e.getMessage())).initCause(e);
}
}

ByteArrayOutputStream bout = new ByteArrayOutputStream();

if(value instanceof InputStream) {
byte[] buf = new byte[8 * 1024];
InputStream in = (InputStream)value;
int read = 0;
while((read = in.read(buf)) != -1) {
bout.write(buf, 0, read);
}
} else {
// if all else fails, serialize it
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(value);
oos.close();
}

return bout.toByteArray();
}

/**
* Interpret a boolean value (null == false)
*/

Cargando…
Cancelar
Guardar