From 4ecff29629eb503ac843f575b52e43e2e807e4df Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Fri, 11 Oct 2013 03:38:18 +0000 Subject: [PATCH] add public api for modifying properties git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@817 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../jackcess/PropertyMap.java | 34 +++++++++++++++++-- .../jackcess/impl/DatabaseImpl.java | 15 +++++--- .../jackcess/impl/PropertyMapImpl.java | 25 +++++++++++--- .../jackcess/impl/PropertyMaps.java | 34 +++++++++++++++++-- .../jackcess/impl/TableImpl.java | 16 +++++++++ 5 files changed, 110 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/healthmarketscience/jackcess/PropertyMap.java b/src/main/java/com/healthmarketscience/jackcess/PropertyMap.java index 6e2634c..a651811 100644 --- a/src/main/java/com/healthmarketscience/jackcess/PropertyMap.java +++ b/src/main/java/com/healthmarketscience/jackcess/PropertyMap.java @@ -19,6 +19,8 @@ USA package com.healthmarketscience.jackcess; +import java.io.IOException; + /** * Map of properties for a database object. * @@ -67,17 +69,45 @@ public interface PropertyMap extends Iterable */ public Object getValue(String name, Object defaultValue); + /** + * Creates a new (or updates an existing) property in the map. + *

+ * 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); + + /** + * Removes the property with the given name + * + * @return the removed property, or {@code null} if none found + */ + public Property remove(String name); + + /** + * Saves the current state of this map. + */ + public void save() throws IOException; + /** * Info about a property defined in a PropertyMap. */ public interface Property { - public String getName(); public DataType getType(); public Object getValue(); - + + /** + * Sets the new value for this property. + *

+ * Note, this change will not be persisted until the {@link + * PropertyMap#save} method has been called. + */ + public void setValue(Object newValue); } } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java index 99b938a..810868c 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java @@ -176,7 +176,7 @@ public class DatabaseImpl implements Database /** System catalog column name of the flags column */ private static final String CAT_COL_FLAGS = "Flags"; /** System catalog column name of the properties column */ - private static final String CAT_COL_PROPS = "LvProp"; + static final String CAT_COL_PROPS = "LvProp"; /** System catalog column name of the remote database */ private static final String CAT_COL_DATABASE = "Database"; /** System catalog column name of the remote table name */ @@ -771,10 +771,11 @@ public class DatabaseImpl implements Database * returns non-{@code null} result). * @usage _intermediate_method_ */ - public PropertyMaps readProperties(byte[] propsBytes, int objectId) + public PropertyMaps readProperties(byte[] propsBytes, int objectId, + RowIdImpl rowId) throws IOException { - return getPropsHandler().read(propsBytes, objectId); + return getPropsHandler().read(propsBytes, objectId, rowId); } /** @@ -1146,10 +1147,12 @@ public class DatabaseImpl implements Database Row objectRow = _tableFinder.getObjectRow( objectId, SYSTEM_CATALOG_PROPS_COLUMNS); byte[] propsBytes = null; + RowIdImpl rowId = null; if(objectRow != null) { propsBytes = (byte[])objectRow.get(CAT_COL_PROPS); + rowId = (RowIdImpl)objectRow.getId(); } - return readProperties(propsBytes, objectId); + return readProperties(propsBytes, objectId, rowId); } /** @@ -1171,11 +1174,13 @@ public class DatabaseImpl implements Database _dbParentId, dbName, SYSTEM_CATALOG_PROPS_COLUMNS); byte[] propsBytes = null; int objectId = -1; + RowIdImpl rowId = null; if(objectRow != null) { propsBytes = (byte[])objectRow.get(CAT_COL_PROPS); objectId = (Integer)objectRow.get(CAT_COL_ID); + rowId = (RowIdImpl)objectRow.getId(); } - return readProperties(propsBytes, objectId); + return readProperties(propsBytes, objectId, rowId); } public String getDatabasePassword() throws IOException diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/PropertyMapImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/PropertyMapImpl.java index c084583..11bdf21 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/PropertyMapImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/PropertyMapImpl.java @@ -19,6 +19,7 @@ USA package com.healthmarketscience.jackcess.impl; +import java.io.IOException; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; @@ -82,18 +83,30 @@ public class PropertyMapImpl implements PropertyMap return value; } + public PropertyImpl put(String name, DataType type, Object value) { + return put(name, type, (byte)0, value); + } + /** * Puts a property into this map with the given information. */ - public void put(String name, DataType type, byte flag, Object value) { - _props.put(DatabaseImpl.toLookupName(name), - new PropertyImpl(name, type, flag, value)); + public PropertyImpl put(String name, DataType type, byte flag, Object value) { + PropertyImpl prop = new PropertyImpl(name, type, flag, value); + _props.put(DatabaseImpl.toLookupName(name), prop); + return prop; + } + + public PropertyImpl remove(String name) { + return (PropertyImpl)_props.remove(DatabaseImpl.toLookupName(name)); } public Iterator iterator() { return _props.values().iterator(); } + public void save() throws IOException { + getOwner().save(); + } @Override public String toString() { @@ -119,7 +132,7 @@ public class PropertyMapImpl implements PropertyMap private final String _name; private final DataType _type; private final byte _flag; - private final Object _value; + private Object _value; private PropertyImpl(String name, DataType type, byte flag, Object value) { _name = name; @@ -140,6 +153,10 @@ public class PropertyMapImpl implements PropertyMap return _value; } + public void setValue(Object newValue) { + _value = newValue; + } + public byte getFlag() { return _flag; } diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/PropertyMaps.java b/src/main/java/com/healthmarketscience/jackcess/impl/PropertyMaps.java index b3e345b..50712bc 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/PropertyMaps.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/PropertyMaps.java @@ -52,10 +52,12 @@ public class PropertyMaps implements Iterable private final Map _maps = new LinkedHashMap(); private final int _objectId; + private final RowIdImpl _rowId; private final Handler _handler; - public PropertyMaps(int objectId, Handler handler) { + public PropertyMaps(int objectId, RowIdImpl rowId, Handler handler) { _objectId = objectId; + _rowId = rowId; _handler = handler; } @@ -109,6 +111,10 @@ public class PropertyMaps implements Iterable return _handler.write(this); } + public void save() throws IOException { + _handler.save(this); + } + @Override public String toString() { return CustomToStringStyle.builder(this) @@ -123,22 +129,27 @@ public class PropertyMaps implements Iterable { /** the current database */ private final DatabaseImpl _database; + /** the system table "property" column */ + private final ColumnImpl _propCol; /** cache of PropColumns used to read/write property values */ private final Map _columns = new HashMap(); Handler(DatabaseImpl database) { _database = database; + _propCol = _database.getSystemCatalog().getColumn( + DatabaseImpl.CAT_COL_PROPS); } /** * @return a PropertyMaps instance decoded from the given bytes (always * returns non-{@code null} result). */ - public PropertyMaps read(byte[] propBytes, int objectId) + public PropertyMaps read(byte[] propBytes, int objectId, + RowIdImpl rowId) throws IOException { - PropertyMaps maps = new PropertyMaps(objectId, this); + PropertyMaps maps = new PropertyMaps(objectId, rowId, this); if((propBytes == null) || (propBytes.length == 0)) { return maps; } @@ -216,6 +227,23 @@ public class PropertyMaps implements Iterable return bab.toArray(); } + /** + * Saves PropertyMaps instance to the db. + */ + public void save(PropertyMaps maps) throws IOException + { + RowIdImpl rowId = maps._rowId; + if(rowId == null) { + throw new IllegalStateException( + "PropertyMaps cannot be saved without a row id"); + } + + byte[] mapsBytes = write(maps); + + // for now assume all properties come from system catalog table + _propCol.getTable().updateValue(_propCol, rowId, mapsBytes); + } + private void writeBlock( PropertyMapImpl propMap, Set propNames, short blockType, ByteArrayBuilder bab) diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java index 1d7e2e0..7939b90 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java @@ -1598,6 +1598,22 @@ public class TableImpl implements Table getDefaultCursor().getRowState(), (RowIdImpl)rowId, row); } + /** + * Update the given column's value for the given row id. Provided RowId + * must have previously been returned from this Table. + * @throws IllegalStateException if the given row is not valid, or deleted. + * @usage _intermediate_method_ + */ + public void updateValue(Column column, RowId rowId, Object value) + throws IOException + { + Object[] row = new Object[_columns.size()]; + Arrays.fill(row, Column.KEEP_VALUE); + column.setRowValue(row, value); + + updateRow(rowId, row); + } + public > M updateRowFromMap( RowState rowState, RowIdImpl rowId, M row) throws IOException -- 2.39.5