Browse Source

Expose the ddl attribute on properties. Set the attribute appropriately for known builtin properties. fixes issue #145

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

+ 6
- 0
src/changes/changes.xml View File

@@ -4,6 +4,12 @@
<author email="javajedi@users.sf.net">Tim McCune</author>
</properties>
<body>
<release version="2.1.11" date="TBD">
<action dev="jahlborn" type="fix" system="SourceForge2" issue="145">
Expose the "ddl" attribute on properties. Set the attribute
appropriately for known builtin properties.
</action>
</release>
<release version="2.1.10" date="2018-01-18">
<action dev="jahlborn" type="update" system="SourceForge2Features"
issue="37">

+ 18
- 0
src/main/java/com/healthmarketscience/jackcess/PropertyMap.java View File

@@ -96,6 +96,16 @@ public interface PropertyMap extends Iterable<PropertyMap.Property>
*/
public Property put(String name, DataType type, Object value);

/**
* Creates a new (or updates an existing) property in the map.
* <p/>
* Note, this change will not be persisted until the {@link #save} method
* has been called.
*
* @return the newly created (or updated) property
*/
public Property put(String name, DataType type, Object value, boolean isDdl);

/**
* Puts all the given properties into this map.
*
@@ -125,6 +135,14 @@ public interface PropertyMap extends Iterable<PropertyMap.Property>

public DataType getType();

/**
* Whether or not this property is a DDL object. If {@code true}, users
* can't change or delete the property in access without the dbSecWriteDef
* permission. Additionally, certain properties must be flagged correctly
* or the access engine may not recognize them correctly.
*/
public boolean isDdl();

public Object getValue();

/**

+ 56
- 42
src/main/java/com/healthmarketscience/jackcess/impl/PropertyMapImpl.java View File

@@ -33,28 +33,28 @@ import com.healthmarketscience.jackcess.PropertyMap;
*/
public class PropertyMapImpl implements PropertyMap
{
private static final Map<String,DataType> DEFAULT_TYPES =
new HashMap<String,DataType>();
private static final Map<String,PropDef> DEFAULT_TYPES =
new HashMap<String,PropDef>();

static {
DEFAULT_TYPES.put(ACCESS_VERSION_PROP, DataType.TEXT);
DEFAULT_TYPES.put(TITLE_PROP, DataType.TEXT);
DEFAULT_TYPES.put(AUTHOR_PROP, DataType.TEXT);
DEFAULT_TYPES.put(COMPANY_PROP, DataType.TEXT);
DEFAULT_TYPES.put(DEFAULT_VALUE_PROP, DataType.MEMO);
DEFAULT_TYPES.put(REQUIRED_PROP, DataType.BOOLEAN);
DEFAULT_TYPES.put(ALLOW_ZERO_LEN_PROP, DataType.BOOLEAN);
DEFAULT_TYPES.put(DECIMAL_PLACES_PROP, DataType.BYTE);
DEFAULT_TYPES.put(FORMAT_PROP, DataType.TEXT);
DEFAULT_TYPES.put(INPUT_MASK_PROP, DataType.TEXT);
DEFAULT_TYPES.put(CAPTION_PROP, DataType.MEMO);
DEFAULT_TYPES.put(VALIDATION_RULE_PROP, DataType.TEXT);
DEFAULT_TYPES.put(VALIDATION_TEXT_PROP, DataType.TEXT);
DEFAULT_TYPES.put(GUID_PROP, DataType.BINARY);
DEFAULT_TYPES.put(DESCRIPTION_PROP, DataType.MEMO);
DEFAULT_TYPES.put(RESULT_TYPE_PROP, DataType.BYTE);
DEFAULT_TYPES.put(EXPRESSION_PROP, DataType.MEMO);
DEFAULT_TYPES.put(ACCESS_VERSION_PROP, new PropDef(DataType.TEXT, false));
DEFAULT_TYPES.put(TITLE_PROP, new PropDef(DataType.TEXT, false));
DEFAULT_TYPES.put(AUTHOR_PROP, new PropDef(DataType.TEXT, false));
DEFAULT_TYPES.put(COMPANY_PROP, new PropDef(DataType.TEXT, false));
DEFAULT_TYPES.put(DEFAULT_VALUE_PROP, new PropDef(DataType.MEMO, true));
DEFAULT_TYPES.put(REQUIRED_PROP, new PropDef(DataType.BOOLEAN, true));
DEFAULT_TYPES.put(ALLOW_ZERO_LEN_PROP, new PropDef(DataType.BOOLEAN, true));
DEFAULT_TYPES.put(DECIMAL_PLACES_PROP, new PropDef(DataType.BYTE, true));
DEFAULT_TYPES.put(FORMAT_PROP, new PropDef(DataType.TEXT, true));
DEFAULT_TYPES.put(INPUT_MASK_PROP, new PropDef(DataType.TEXT, true));
DEFAULT_TYPES.put(CAPTION_PROP, new PropDef(DataType.MEMO, false));
DEFAULT_TYPES.put(VALIDATION_RULE_PROP, new PropDef(DataType.TEXT, true));
DEFAULT_TYPES.put(VALIDATION_TEXT_PROP, new PropDef(DataType.TEXT, true));
DEFAULT_TYPES.put(GUID_PROP, new PropDef(DataType.BINARY, true));
DEFAULT_TYPES.put(DESCRIPTION_PROP, new PropDef(DataType.MEMO, false));
DEFAULT_TYPES.put(RESULT_TYPE_PROP, new PropDef(DataType.BYTE, true));
DEFAULT_TYPES.put(EXPRESSION_PROP, new PropDef(DataType.MEMO, true));
}

private final String _mapName;
@@ -107,11 +107,11 @@ public class PropertyMapImpl implements PropertyMap
}

public PropertyImpl put(String name, Object value) {
return put(name, null, (byte)0, value);
return put(name, null, value, false);
}

public PropertyImpl put(String name, DataType type, Object value) {
return put(name, type, (byte)0, value);
return put(name, type, value, false);
}

public void putAll(Iterable<? extends Property> props) {
@@ -125,18 +125,15 @@ public class PropertyMapImpl implements PropertyMap
}
public PropertyImpl put(Property prop) {
byte flag = 0;
if(prop instanceof PropertyImpl) {
flag = ((PropertyImpl)prop).getFlag();
}
return put(prop.getName(), prop.getType(), flag, prop.getValue());
return put(prop.getName(), prop.getType(), prop.getValue(), prop.isDdl());
}

/**
* Puts a property into this map with the given information.
*/
public PropertyImpl put(String name, DataType type, byte flag, Object value) {
PropertyImpl prop = (PropertyImpl)createProperty(name, type, flag, value);
public PropertyImpl put(String name, DataType type, Object value,
boolean isDdl) {
PropertyImpl prop = (PropertyImpl)createProperty(name, type, value, isDdl);
_props.put(DatabaseImpl.toLookupName(name), prop);
return prop;
}
@@ -174,17 +171,20 @@ public class PropertyMapImpl implements PropertyMap
}

public static Property createProperty(String name, DataType type, Object value) {
return createProperty(name, type, (byte)0, value);
return createProperty(name, type, value, false);
}
public static Property createProperty(String name, DataType type, byte flag,
Object value) {
public static Property createProperty(String name, DataType type,
Object value, boolean isDdl) {
if(type == null) {
// attempt to get the default type for this property
type = DEFAULT_TYPES.get(name);
PropDef pd = DEFAULT_TYPES.get(name);

if(type == null) {
if(pd != null) {
type = pd._type;
isDdl |= pd._isDdl;
} else {
// choose the type based on the value
if(value instanceof String) {
type = DataType.TEXT;
@@ -214,9 +214,9 @@ public class PropertyMapImpl implements PropertyMap
}
}
return new PropertyImpl(name, type, flag, value);
return new PropertyImpl(name, type, value, isDdl);
}
/**
* Info about a property defined in a PropertyMap.
*/
@@ -224,13 +224,14 @@ public class PropertyMapImpl implements PropertyMap
{
private final String _name;
private final DataType _type;
private final byte _flag;
private final boolean _ddl;
private Object _value;

private PropertyImpl(String name, DataType type, byte flag, Object value) {
private PropertyImpl(String name, DataType type, Object value,
boolean ddl) {
_name = name;
_type = type;
_flag = flag;
_ddl = ddl;
_value = value;
}

@@ -250,8 +251,8 @@ public class PropertyMapImpl implements PropertyMap
_value = newValue;
}

public byte getFlag() {
return _flag;
public boolean isDdl() {
return _ddl;
}

@Override
@@ -260,8 +261,21 @@ public class PropertyMapImpl implements PropertyMap
if(val instanceof byte[]) {
val = ByteUtil.toHexString((byte[])val);
}
return getName() + "[" + getType() + ":" + _flag + "]=" + val;
return getName() + "[" + getType() + (_ddl ? ":ddl" : "") + "]=" + val;
}
}

/**
* Helper for holding info about default properties
*/
private static final class PropDef
{
private final DataType _type;
private final boolean _isDdl;

private PropDef(DataType type, boolean isDdl) {
_type = type;
_isDdl = isDdl;
}
}
}

+ 4
- 3
src/main/java/com/healthmarketscience/jackcess/impl/PropertyMaps.java View File

@@ -313,7 +313,7 @@ public class PropertyMaps implements Iterable<PropertyMapImpl>

int valLen = bbBlock.getShort();
int endPos = bbBlock.position() + valLen - 2;
byte flag = bbBlock.get();
boolean isDdl = (bbBlock.get() != 0);
DataType dataType = DataType.fromByte(bbBlock.get());
int nameIdx = bbBlock.getShort();
int dataSize = bbBlock.getShort();
@@ -324,7 +324,7 @@ public class PropertyMaps implements Iterable<PropertyMapImpl>
byte[] data = ByteUtil.getBytes(bbBlock, dataSize);
Object value = col.read(data);

map.put(propName, dataType, flag, value);
map.put(propName, dataType, value, isDdl);

bbBlock.position(endPos);
}
@@ -359,7 +359,8 @@ public class PropertyMaps implements Iterable<PropertyMapImpl>
int valStartPos = bab.position();
bab.reserveShort();

bab.put(prop.getFlag());
byte ddlFlag = (byte)(prop.isDdl() ? 1 : 0);
bab.put(ddlFlag);
bab.put(prop.getType().getValue());
bab.putShort((short)nameIdx);


+ 7
- 3
src/main/java/com/healthmarketscience/jackcess/impl/complex/MultiValueColumnPropertyMap.java View File

@@ -79,16 +79,20 @@ public class MultiValueColumnPropertyMap implements PropertyMap
}

public Property put(String name, Object value) {
return put(name, null, value);
return put(name, null, value, false);
}

public Property put(String name, DataType type, Object value) {
return put(name, type, value, false);
}

public Property put(String name, DataType type, Object value, boolean isDdl) {
// the only property which seems to go in the "primary" is the "multi
// value" property
if(isPrimaryKey(name)) {
return _primary.put(name, DataType.BOOLEAN, value);
return _primary.put(name, DataType.BOOLEAN, value, true);
}
return _complex.put(name, value);
return _complex.put(name, type, value, isDdl);
}

public void putAll(Iterable<? extends Property> props) {

+ 5
- 3
src/test/java/com/healthmarketscience/jackcess/PropertiesTest.java View File

@@ -68,13 +68,15 @@ public class PropertiesTest extends TestCase
assertSame(colMap, maps.get("TESTCOL"));
assertEquals("testcol", colMap.getName());

defMap.put("foo", DataType.TEXT, (byte)0, "bar");
defMap.put("baz", DataType.LONG, (byte)1, 13);
defMap.put("foo", DataType.TEXT, "bar", false);
defMap.put("baz", DataType.LONG, 13, true);

assertFalse(defMap.isEmpty());
assertEquals(2, defMap.getSize());
assertFalse(defMap.get("foo").isDdl());
assertTrue(defMap.get("baz").isDdl());

colMap.put("buzz", DataType.BOOLEAN, (byte)0, Boolean.TRUE);
colMap.put("buzz", DataType.BOOLEAN, Boolean.TRUE, true);

assertFalse(colMap.isEmpty());
assertEquals(1, colMap.getSize());

Loading…
Cancel
Save