package com.healthmarketscience.jackcess;
+import java.io.IOException;
+
/**
* Map of properties for a database object.
*
*/
public Object getValue(String name, Object defaultValue);
+ /**
+ * 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);
+
+ /**
+ * 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.
+ * <p/>
+ * Note, this change will not be persisted until the {@link
+ * PropertyMap#save} method has been called.
+ */
+ public void setValue(Object newValue);
}
}
/** 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 */
* 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);
}
/**
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);
}
/**
_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
package com.healthmarketscience.jackcess.impl;
+import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
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<Property> iterator() {
return _props.values().iterator();
}
+ public void save() throws IOException {
+ getOwner().save();
+ }
@Override
public String toString() {
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;
return _value;
}
+ public void setValue(Object newValue) {
+ _value = newValue;
+ }
+
public byte getFlag() {
return _flag;
}
private final Map<String,PropertyMapImpl> _maps =
new LinkedHashMap<String,PropertyMapImpl>();
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;
}
return _handler.write(this);
}
+ public void save() throws IOException {
+ _handler.save(this);
+ }
+
@Override
public String toString() {
return CustomToStringStyle.builder(this)
{
/** 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<DataType,PropColumn> _columns =
new HashMap<DataType,PropColumn>();
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;
}
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<String> propNames,
short blockType, ByteArrayBuilder bab)
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 extends Map<String,Object>> M updateRowFromMap(
RowState rowState, RowIdImpl rowId, M row)
throws IOException