]> source.dussan.org Git - jackcess.git/commitdiff
add public api for modifying properties
authorJames Ahlborn <jtahlborn@yahoo.com>
Fri, 11 Oct 2013 03:38:18 +0000 (03:38 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Fri, 11 Oct 2013 03:38:18 +0000 (03:38 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@817 f203690c-595d-4dc9-a70b-905162fa7fd2

src/main/java/com/healthmarketscience/jackcess/PropertyMap.java
src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
src/main/java/com/healthmarketscience/jackcess/impl/PropertyMapImpl.java
src/main/java/com/healthmarketscience/jackcess/impl/PropertyMaps.java
src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java

index 6e2634c4b7c4fbc226e8ba4c331819ae2302a955..a651811148cf3368c71f65859e35753820c0fa8d 100644 (file)
@@ -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<PropertyMap.Property>
    */
   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);
   }
 }
index 99b938a38446538b48cee11196ccbfe0883893e3..810868cfb5692870bc13c0604eb2416957bafe31 100644 (file)
@@ -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
index c084583475852f8d4449686349c7586be9e64227..11bdf21a1daae4a9bbd613793d07cc5d06669cc1 100644 (file)
@@ -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<Property> 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;
     }
index b3e345b2e86a788342f8c8ff26268baf6075f390..50712bc0bbf708187eca214a03dc2abcbfdb662c 100644 (file)
@@ -52,10 +52,12 @@ public class PropertyMaps implements Iterable<PropertyMapImpl>
   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;
   }
 
@@ -109,6 +111,10 @@ public class PropertyMaps implements Iterable<PropertyMapImpl>
     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<PropertyMapImpl>
   {
     /** 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;
       }
@@ -216,6 +227,23 @@ public class PropertyMaps implements Iterable<PropertyMapImpl>
       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)
index 1d7e2e0f984e0098f9ad724ce8569bdb4b0c03be..7939b90be649e022f306ec6bb9916f46550d9535 100644 (file)
@@ -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 extends Map<String,Object>> M updateRowFromMap(
       RowState rowState, RowIdImpl rowId, M row) 
      throws IOException