Browse Source

implement sql type to DataType conversions specific to access 2016 format

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1132 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.1.10
James Ahlborn 6 years ago
parent
commit
d1dcbd5dfb

+ 13
- 2
src/main/java/com/healthmarketscience/jackcess/ColumnBuilder.java View File

* Sets the type for the new column based on the given SQL type. * Sets the type for the new column based on the given SQL type.
*/ */
public ColumnBuilder setSQLType(int type) throws SQLException { public ColumnBuilder setSQLType(int type) throws SQLException {
return setSQLType(type, 0);
return setSQLType(type, 0, null);
} }
/** /**
public ColumnBuilder setSQLType(int type, int lengthInUnits) public ColumnBuilder setSQLType(int type, int lengthInUnits)
throws SQLException throws SQLException
{ {
return setType(DataType.fromSQLType(type, lengthInUnits));
return setSQLType(type, lengthInUnits, null);
}

/**
* Sets the type for the new column based on the given SQL type, target
* data length (in type specific units), and target FileFormat.
*/
public ColumnBuilder setSQLType(int type, int lengthInUnits,
Database.FileFormat fileFormat)
throws SQLException
{
return setType(DataType.fromSQLType(type, lengthInUnits, fileFormat));
} }


/** /**

+ 43
- 20
src/main/java/com/healthmarketscience/jackcess/DataType.java View File

package com.healthmarketscience.jackcess; package com.healthmarketscience.jackcess;


import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Date;
import java.math.BigDecimal;
import java.math.BigInteger;


import com.healthmarketscience.jackcess.impl.DatabaseImpl;
import com.healthmarketscience.jackcess.impl.JetFormat; import com.healthmarketscience.jackcess.impl.JetFormat;


/** /**
* String and parsed as Double, or {@code null}. Equivalent to SQL * String and parsed as Double, or {@code null}. Equivalent to SQL
* {@link Types#BIGINT}. * {@link Types#BIGINT}.
*/ */
BIG_INT((byte) 0x13, null, 8),
BIG_INT((byte) 0x13, Types.BIGINT, 8),
/** /**
* Dummy type for a fixed length type which is not currently supported. * Dummy type for a fixed length type which is not currently supported.
* Handled like a fixed length {@link #BINARY}. * Handled like a fixed length {@link #BINARY}.
1); 1);


/** Map of SQL types to Access data types */ /** Map of SQL types to Access data types */
private static final Map<Integer, DataType> SQL_TYPES =
new HashMap<Integer, DataType>();
private static final Map<Integer, DataType[]> SQL_TYPES =
new HashMap<Integer, DataType[]>();
/** Alternate map of SQL types to Access data types */ /** Alternate map of SQL types to Access data types */
private static final Map<Integer, DataType> ALT_SQL_TYPES = private static final Map<Integer, DataType> ALT_SQL_TYPES =
new HashMap<Integer, DataType>(); new HashMap<Integer, DataType>();
static { static {
for (DataType type : DataType.values()) { for (DataType type : DataType.values()) {
if (type._sqlType != null) { if (type._sqlType != null) {
SQL_TYPES.put(type._sqlType, type);
SQL_TYPES.put(type._sqlType, new DataType[]{type});
} }
} }
SQL_TYPES.put(Types.BIT, BYTE);
SQL_TYPES.put(Types.BLOB, OLE);
SQL_TYPES.put(Types.CLOB, MEMO);
SQL_TYPES.put(Types.BIGINT, LONG);
SQL_TYPES.put(Types.CHAR, TEXT);
SQL_TYPES.put(Types.DATE, SHORT_DATE_TIME);
SQL_TYPES.put(Types.REAL, DOUBLE);
SQL_TYPES.put(Types.TIME, SHORT_DATE_TIME);
SQL_TYPES.put(Types.VARBINARY, BINARY);
SQL_TYPES.put(Types.BIT, new DataType[]{BYTE});
SQL_TYPES.put(Types.BLOB, new DataType[]{OLE});
SQL_TYPES.put(Types.CLOB, new DataType[]{MEMO});
SQL_TYPES.put(Types.BIGINT, new DataType[]{LONG, BIG_INT});
SQL_TYPES.put(Types.CHAR, new DataType[]{TEXT});
SQL_TYPES.put(Types.DATE, new DataType[]{SHORT_DATE_TIME});
SQL_TYPES.put(Types.REAL, new DataType[]{DOUBLE});
SQL_TYPES.put(Types.TIME, new DataType[]{SHORT_DATE_TIME});
SQL_TYPES.put(Types.VARBINARY, new DataType[]{BINARY});


// the "alternate" types allow for larger values // the "alternate" types allow for larger values
ALT_SQL_TYPES.put(Types.VARCHAR, MEMO); ALT_SQL_TYPES.put(Types.VARCHAR, MEMO);
public static DataType fromSQLType(int sqlType) public static DataType fromSQLType(int sqlType)
throws SQLException throws SQLException
{ {
return fromSQLType(sqlType, 0);
return fromSQLType(sqlType, 0, null);
} }
public static DataType fromSQLType(int sqlType, int lengthInUnits) public static DataType fromSQLType(int sqlType, int lengthInUnits)
throws SQLException throws SQLException
{ {
DataType rtn = SQL_TYPES.get(sqlType);
if(rtn == null) {
return fromSQLType(sqlType, lengthInUnits, null);
}

public static DataType fromSQLType(int sqlType, int lengthInUnits,
Database.FileFormat fileFormat)
throws SQLException
{
DataType[] rtnArr = SQL_TYPES.get(sqlType);
if(rtnArr == null) {
throw new SQLException("Unsupported SQL type: " + sqlType); throw new SQLException("Unsupported SQL type: " + sqlType);
} }
DataType rtn = rtnArr[0];
if((rtnArr.length > 1) && (fileFormat != null)) {
// there are multiple possibilities, ordered from lowest version to
// highest version supported. go in opposite order to find the best
// type for this format
JetFormat format = DatabaseImpl.getFileFormatDetails(fileFormat)
.getFormat();
for(int i = rtnArr.length - 1; i >= 0; --i) {
DataType tmp = rtnArr[i];
if(format.isSupportedDataType(tmp)) {
rtn = tmp;
break;
}
}
}


// make sure size is reasonable // make sure size is reasonable
int size = lengthInUnits * rtn.getUnitSize(); int size = lengthInUnits * rtn.getUnitSize();
try { try {
java.lang.reflect.Field sqlTypeField = Types.class.getField(typeName); java.lang.reflect.Field sqlTypeField = Types.class.getField(typeName);
Integer value = (Integer)sqlTypeField.get(null); Integer value = (Integer)sqlTypeField.get(null);
SQL_TYPES.put(value, type);
SQL_TYPES.put(value, new DataType[]{type});
if(altType != null) { if(altType != null) {
ALT_SQL_TYPES.put(value, altType); ALT_SQL_TYPES.put(value, altType);
} }

+ 26
- 0
src/test/java/com/healthmarketscience/jackcess/impl/JetFormatTest.java View File

import java.io.InputStream; import java.io.InputStream;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.NonWritableChannelException; import java.nio.channels.NonWritableChannelException;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;


import com.healthmarketscience.jackcess.DataType;
import com.healthmarketscience.jackcess.Database; import com.healthmarketscience.jackcess.Database;
import static com.healthmarketscience.jackcess.Database.*; import static com.healthmarketscience.jackcess.Database.*;
import com.healthmarketscience.jackcess.DatabaseBuilder; import com.healthmarketscience.jackcess.DatabaseBuilder;
} }
} }


public void testSqlTypes() throws Exception {
JetFormat v2000 = JetFormat.VERSION_4;
for(DataType dt : DataType.values()) {
if(v2000.isSupportedDataType(dt)) {
Integer sqlType = null;
try {
sqlType = dt.getSQLType();
} catch(SQLException ignored) {}

if(sqlType != null) {
assertEquals(dt, DataType.fromSQLType(sqlType));
}
}
}

assertEquals(DataType.LONG, DataType.fromSQLType(java.sql.Types.BIGINT));
assertEquals(DataType.BIG_INT, DataType.fromSQLType(
java.sql.Types.BIGINT, 0, Database.FileFormat.V2016));
assertEquals(java.sql.Types.BIGINT, DataType.BIG_INT.getSQLType());
assertEquals(DataType.MEMO, DataType.fromSQLType(
java.sql.Types.VARCHAR, 1000));
}

public static void transferDbFrom(FileChannel channel, InputStream in) public static void transferDbFrom(FileChannel channel, InputStream in)
throws IOException throws IOException
{ {

Loading…
Cancel
Save