aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2014-09-13 20:02:57 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2014-09-13 20:02:57 +0000
commit2e8ed2591678a6bec8dd6152d521f9d121af000a (patch)
tree0cac37addbc62fe6e29614649f13e5f82ac4cdd3 /src
parent84089cb1372dc7f12ddacdfd165b0c1e8633f8ed (diff)
downloadjackcess-2e8ed2591678a6bec8dd6152d521f9d121af000a.tar.gz
jackcess-2e8ed2591678a6bec8dd6152d521f9d121af000a.zip
Add the ability to create tables with calculated fields
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@873 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src')
-rw-r--r--src/changes/changes.xml3
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/ColumnBuilder.java47
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/TableBuilder.java2
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java21
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java33
5 files changed, 100 insertions, 6 deletions
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 8ef8f7e..6b41e9c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -18,6 +18,9 @@
Add the ability to set properties in DatabaseBuilder, TableBuilder,
and ColumnBuilder.
</action>
+ <action dev="jahlborn" type="add">
+ Add the ability to create tables with calculated fields.
+ </action>
</release>
<release version="2.0.4" date="2014-04-05">
<action dev="jahlborn" type="add">
diff --git a/src/main/java/com/healthmarketscience/jackcess/ColumnBuilder.java b/src/main/java/com/healthmarketscience/jackcess/ColumnBuilder.java
index 57c5bb5..628df86 100644
--- a/src/main/java/com/healthmarketscience/jackcess/ColumnBuilder.java
+++ b/src/main/java/com/healthmarketscience/jackcess/ColumnBuilder.java
@@ -63,6 +63,8 @@ public class ColumnBuilder {
private boolean _autoNumber;
/** whether or not the column allows compressed unicode */
private boolean _compressedUnicode;
+ /** whether or not the column is calculated */
+ private boolean _calculated;
/** whether or not the column is a hyperlink (memo only) */
private boolean _hyperlink;
/** 0-based column number */
@@ -192,6 +194,28 @@ public class ColumnBuilder {
}
/**
+ * Sets whether of not the new column is a calculated column.
+ */
+ public ColumnBuilder setCalculated(boolean calculated) {
+ _calculated = calculated;
+ return this;
+ }
+
+ public boolean isCalculated() {
+ return _calculated;
+ }
+
+ /**
+ * Convenience method to set the various info for a calculated type (flag,
+ * result type property and expression)
+ */
+ public ColumnBuilder setCalculatedInfo(String expression) {
+ setCalculated(true);
+ putProperty(PropertyMap.EXPRESSION_PROP, expression);
+ return putProperty(PropertyMap.RESULT_TYPE_PROP, getType().getValue());
+ }
+
+ /**
* Sets whether of not the new column allows unicode compression.
*/
public ColumnBuilder setHyperlink(boolean hyperlink) {
@@ -227,6 +251,10 @@ public class ColumnBuilder {
public Map<String,PropertyMap.Property> getProperties() {
return _props;
}
+
+ private PropertyMap.Property getProperty(String name) {
+ return ((_props != null) ? _props.get(name) : null);
+ }
/**
* Sets all attributes except name from the given Column template.
@@ -370,6 +398,25 @@ public class ColumnBuilder {
"Only memo columns can be hyperlinks");
}
}
+
+ if(isCalculated()) {
+ if(!format.isSupportedCalculatedDataType(getType())) {
+ throw new IllegalArgumentException(
+ "Database format " + format + " does not support calculated type " +
+ getType());
+ }
+
+ // must have an expression
+ if(getProperty(PropertyMap.EXPRESSION_PROP) == null) {
+ throw new IllegalArgumentException(
+ "No expression provided for calculated type " + getType());
+ }
+
+ // must have result type (just fill in if missing)
+ if(getProperty(PropertyMap.RESULT_TYPE_PROP) == null) {
+ putProperty(PropertyMap.RESULT_TYPE_PROP, getType().getValue());
+ }
+ }
}
/**
diff --git a/src/main/java/com/healthmarketscience/jackcess/TableBuilder.java b/src/main/java/com/healthmarketscience/jackcess/TableBuilder.java
index b28d35b..c1d95f2 100644
--- a/src/main/java/com/healthmarketscience/jackcess/TableBuilder.java
+++ b/src/main/java/com/healthmarketscience/jackcess/TableBuilder.java
@@ -212,7 +212,7 @@ public class TableBuilder {
_props.put(name, PropertyMapImpl.createProperty(name, type, value));
return this;
}
-
+
/**
* Creates a new Table in the given Database with the currently configured
* attributes.
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
index 4dc1afd..40c8c6c 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
@@ -1571,6 +1571,7 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
buffer.put(col.getType().getValue());
buffer.putInt(TableImpl.MAGIC_TABLE_NUMBER); //constant magic number
buffer.putShort(col.getColumnNumber()); //Column Number
+
if (col.getType().isVariableLength()) {
if(!col.getType().isLongValue()) {
buffer.putShort(variableOffset++);
@@ -1580,13 +1581,16 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
} else {
buffer.putShort((short) 0);
}
+
buffer.putShort(col.getColumnNumber()); //Column Number again
+
if(col.getType().isTextual()) {
// this will write 4 bytes (note we don't support writing dbs which
// use the text code page)
writeSortOrder(buffer, col.getTextSortOrder(), creator.getFormat());
} else {
- if(col.getType().getHasScalePrecision()) {
+ // note scale/precision not stored for calculated numeric fields
+ if(col.getType().getHasScalePrecision() && !col.isCalculated()) {
buffer.put(col.getPrecision()); // numeric precision
buffer.put(col.getScale()); // numeric scale
} else {
@@ -1595,13 +1599,20 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
}
buffer.putShort((short) 0); //Unknown
}
+
buffer.put(getColumnBitFlags(col)); // misc col flags
- if (col.isCompressedUnicode()) { //Compressed
- buffer.put((byte) 1);
+
+ // note access doesn't seem to allow unicode compression for calced fields
+ if(col.isCalculated()) {
+ buffer.put(CALCULATED_EXT_FLAG_MASK);
+ } else if (col.isCompressedUnicode()) { //Compressed
+ buffer.put(COMPRESSED_UNICODE_EXT_FLAG_MASK);
} else {
- buffer.put((byte) 0);
+ buffer.put((byte)0);
}
+
buffer.putInt(0); //Unknown, but always 0.
+
//Offset for fixed length columns
if (col.getType().isVariableLength()) {
buffer.putShort((short) 0);
@@ -1609,11 +1620,13 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
buffer.putShort(fixedOffset);
fixedOffset += col.getType().getFixedSize(col.getLength());
}
+
if(!col.getType().isLongValue()) {
buffer.putShort(col.getLength()); //Column length
} else {
buffer.putShort((short)0x0000); // unused
}
+
}
for (ColumnBuilder col : columns) {
TableImpl.writeName(buffer, col.getName(), creator.getCharset());
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java b/src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java
index ebc9081..fcb39bd 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/JetFormat.java
@@ -32,11 +32,13 @@ import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
-import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DataType;
+import com.healthmarketscience.jackcess.Database;
/**
* Encapsulates constants describing a specific version of the Access Jet format
@@ -139,6 +141,13 @@ public abstract class JetFormat {
}
}
+ /** calculated types supported in version 14 */
+ private static final Set<DataType> V14_CALC_TYPES =
+ EnumSet.of(DataType.BOOLEAN, DataType.BYTE, DataType.INT, DataType.LONG,
+ DataType.FLOAT, DataType.DOUBLE, DataType.GUID,
+ DataType.SHORT_DATE_TIME, DataType.MONEY, DataType.NUMERIC,
+ DataType.TEXT, DataType.MEMO);
+
/** the JetFormat constants for the Jet database version "3" */
public static final JetFormat VERSION_3 = new Jet3Format();
/** the JetFormat constants for the Jet database version "4" */
@@ -507,6 +516,8 @@ public abstract class JetFormat {
public abstract boolean isSupportedDataType(DataType type);
+ public abstract boolean isSupportedCalculatedDataType(DataType type);
+
@Override
public String toString() {
return _name;
@@ -733,6 +744,11 @@ public abstract class JetFormat {
public boolean isSupportedDataType(DataType type) {
return (type != DataType.COMPLEX_TYPE);
}
+
+ @Override
+ public boolean isSupportedCalculatedDataType(DataType type) {
+ return false;
+ }
}
private static class Jet4Format extends JetFormat {
@@ -958,6 +974,11 @@ public abstract class JetFormat {
public boolean isSupportedDataType(DataType type) {
return (type != DataType.COMPLEX_TYPE);
}
+
+ @Override
+ public boolean isSupportedCalculatedDataType(DataType type) {
+ return false;
+ }
}
private static final class MSISAMFormat extends Jet4Format {
@@ -1010,6 +1031,11 @@ public abstract class JetFormat {
public boolean isSupportedDataType(DataType type) {
return true;
}
+
+ @Override
+ public boolean isSupportedCalculatedDataType(DataType type) {
+ return false;
+ }
}
private static final class Jet14Format extends Jet12Format {
@@ -1031,6 +1057,11 @@ public abstract class JetFormat {
protected Map<String,Database.FileFormat> getPossibleFileFormats() {
return PossibleFileFormats.POSSIBLE_VERSION_14;
}
+
+ @Override
+ public boolean isSupportedCalculatedDataType(DataType type) {
+ return V14_CALC_TYPES.contains(type);
+ }
}
}