The attached patch adds the ability to have the DAS manage collision
columns. Currently this is implemented with a "managed" attribute on
column -- there may be some room for improvement here, as having
"managed" and "collision" on Column doesn't seem all that intuitive.
Also, the first cut only supports Integer columns. We should identify
which types need to be supported. Are there any beyond numeric types
and date/timestamp?
Index: src/test/java/org/apache/tuscany/das/rdb/test/OCCTests.java
===================================================================
--- src/test/java/org/apache/tuscany/das/rdb/test/OCCTests.java (revision 
418312)
+++ src/test/java/org/apache/tuscany/das/rdb/test/OCCTests.java (working copy)
@@ -55,4 +55,48 @@
                                throw ex;
                }
        }
+       
+       public void testManagedOCC() throws Exception {
+               DAS das = 
DAS.FACTORY.createDAS(getConfig("ManagedBooksConfig.xml"), getConnection());
+               Command select = das.getCommand("select book 1");
+               DataObject root = select.executeQuery();
+               DataObject book = root.getDataObject("BOOK[1]");
+               //Change a field to mark the instance 'dirty'
+               book.setInt("QUANTITY", 2);
+               int occValue = book.getInt("OCC");
+               das.applyChanges(root);
+               
+               root = select.executeQuery();
+               book = root.getDataObject("BOOK[1]");
+               assertEquals(occValue + 1, book.getInt("OCC"));         
+       }
+       
+       public void testManagedOCCFailure() throws Exception {
+               DAS das = 
DAS.FACTORY.createDAS(getConfig("ManagedBooksConfig.xml"), getConnection());
+               //Read a book instance
+        Command select = das.getCommand("select book 1");
+               DataObject root = select.executeQuery();
+               DataObject book = root.getDataObject("BOOK[1]");
+               //Change a field to mark the instance 'dirty'
+               book.setInt("QUANTITY", 2);
+
+               
+               DAS das2 = 
DAS.FACTORY.createDAS(getConfig("ManagedBooksConfig.xml"), getConnection());
+               //Read a book instance
+        Command select2= das2.getCommand("select book 1");
+               DataObject root2 = select2.executeQuery();
+               DataObject book2 = root2.getDataObject("BOOK[1]");
+               //Change a field to mark the instance 'dirty'
+               book2.setInt("QUANTITY", 5);
+               das2.applyChanges(root2);
+
+        //Try to apply changes an catch the OCC Exception
+               try {           
+                       das.applyChanges(root);
+                       fail("An OCCException should be thrown");
+               } catch (RuntimeException ex) {
+                       if ( !ex.getMessage().equals("OCC Exception") )
+                               throw ex;
+               }
+       }
 }
Index: src/test/resources/ManagedBooksConfig.xml
===================================================================
--- /dev/null   (revision 0)
+++ src/test/resources/ManagedBooksConfig.xml   (revision 0)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="ASCII"?>
+<!--
+  Copyright (c) 2005 The Apache Software Foundation or its licensors, as 
applicable.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ -->
+<Config 
xsi:noNamespaceSchemaLocation="http:///org.apache.tuscany.das.rdb/config.xsd"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";> 
+
+    <Command name="select book 1" SQL="select * from BOOK where BOOK_ID = 1" 
kind="Select"/>
+    <Command name="update book 1" SQL="update BOOK set OCC = ? where BOOK_ID = 
1" kind="Update"/>
+
+       <Table tableName="BOOK">
+        <Column columnName="BOOK_ID" primaryKey="true"/>
+           <Column columnName="OCC" collision="true" managed="true"/>
+    </Table>
+    
+</Config>
Index: src/main/java/org/apache/tuscany/das/rdb/impl/ParameterImpl.java
===================================================================
--- src/main/java/org/apache/tuscany/das/rdb/impl/ParameterImpl.java    
(revision 417540)
+++ src/main/java/org/apache/tuscany/das/rdb/impl/ParameterImpl.java    
(working copy)
@@ -42,7 +42,7 @@
        private int index;
        private Type type;
        private String name;
-       private Object value;
+       protected Object value = null;
        private int direction = IN;
        private Converter converter;
        
@@ -121,4 +121,6 @@
                buffer.append("\nValue: " + getValue());
                return buffer.toString();
        }
+       
+       
 }
Index: src/main/java/org/apache/tuscany/das/rdb/impl/ManagedParameterImpl.java
===================================================================
--- /dev/null   (revision 0)
+++ src/main/java/org/apache/tuscany/das/rdb/impl/ManagedParameterImpl.java     
(revision 0)
@@ -0,0 +1,17 @@
+package org.apache.tuscany.das.rdb.impl;
+
+public class ManagedParameterImpl extends ParameterImpl {
+       
+       public void setValue(Object oldValue) {
+               this.value = updateValue(oldValue);
+       }
+       
+       private Object updateValue(Object oldValue) {
+               if ( oldValue instanceof Integer) 
+                       return new Integer( ((Integer)oldValue).intValue() + 1);
+               else 
+                       throw new RuntimeException("Unsupported type for 
managed column: " + oldValue.getClass().getName());            
+       }
+       
+
+}
Index: src/main/java/org/apache/tuscany/das/rdb/config/wrapper/TableWrapper.java
===================================================================
--- src/main/java/org/apache/tuscany/das/rdb/config/wrapper/TableWrapper.java   
(revision 417540)
+++ src/main/java/org/apache/tuscany/das/rdb/config/wrapper/TableWrapper.java   
(working copy)
@@ -121,4 +121,15 @@
                else
                        return c.getColumnName();
        }
+
+       public String getManagedColumnPropertyName() {
+               Iterator i = table.getColumn().iterator();
+               while (i.hasNext()) {
+                       Column c = (Column) i.next();
+                       if (c.isManaged())
+                               return c.getPropertyName() == null ? 
c.getColumnName() : c.getPropertyName();
+               }
+               return null;
+               
+       }
 }
Index: 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/BaseGenerator.java
===================================================================
--- src/main/java/org/apache/tuscany/das/rdb/generator/impl/BaseGenerator.java  
(revision 417540)
+++ src/main/java/org/apache/tuscany/das/rdb/generator/impl/BaseGenerator.java  
(working copy)
@@ -1,14 +1,10 @@
 package org.apache.tuscany.das.rdb.generator.impl;
 
 import org.apache.tuscany.das.rdb.Converter;
-import org.apache.tuscany.das.rdb.config.Table;
-import org.apache.tuscany.das.rdb.config.wrapper.TableWrapper;
 
 public class BaseGenerator {
 
-       protected Converter getConverter(Table t, String name) {
-               TableWrapper tw = new TableWrapper(t);
-               String converter = tw.getConverter(name);
+       protected Converter getConverter(String converter) {                    
                if ( converter != null ) {
                        try {
                                return (Converter) 
Thread.currentThread().getContextClassLoader().loadClass(converter).newInstance();
Index: 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/DeleteGenerator.java
===================================================================
--- 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/DeleteGenerator.java    
    (revision 417540)
+++ 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/DeleteGenerator.java    
    (working copy)
@@ -64,15 +64,16 @@
        }
 
        public DeleteCommandImpl getDeleteCommand(Table t) {
+               TableWrapper tw = new TableWrapper(t);
                DeleteCommandImpl deleteCommand = new 
DeleteCommandImpl(getDeleteStatement(t));
                
-               Iterator i = getDeleteParameters(t).iterator();
+               Iterator i = tw.getPrimaryKeyProperties().iterator();
                for(int idx=1; i.hasNext(); idx++) {
                        String property = (String) i.next();
                        ParameterImpl p = new ParameterImpl();
                        p.setName(property);
                        p.setType(SDODataTypes.OBJECT);
-                       p.setConverter(getConverter(t, property));
+                       p.setConverter(getConverter(tw.getConverter(property)));
                        p.setIndex(idx);
                        deleteCommand.addParameter(p);
                }
Index: 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/UpdateGenerator.java
===================================================================
--- 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/UpdateGenerator.java    
    (revision 417540)
+++ 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/UpdateGenerator.java    
    (working copy)
@@ -26,6 +26,7 @@
 import org.apache.tuscany.das.rdb.config.wrapper.MappingWrapper;
 import org.apache.tuscany.das.rdb.config.wrapper.RelationshipWrapper;
 import org.apache.tuscany.das.rdb.config.wrapper.TableWrapper;
+import org.apache.tuscany.das.rdb.impl.ManagedParameterImpl;
 import org.apache.tuscany.das.rdb.impl.OptimisticWriteCommandImpl;
 import org.apache.tuscany.das.rdb.impl.ParameterImpl;
 import org.apache.tuscany.das.rdb.impl.UpdateCommandImpl;
@@ -47,7 +48,9 @@
        }
 
        public UpdateCommandImpl getUpdateCommand(MappingWrapper mapping, 
DataObject changedObject, Table table) {
-               ArrayList parameters = new ArrayList();
+               ArrayList updatedProperties = new ArrayList();
+               ArrayList managedProperties = new ArrayList();
+               ArrayList whereClauseProperties = new ArrayList();
                Type type = changedObject.getType();
                TableWrapper t = new TableWrapper(table);
                StringBuffer statement = new StringBuffer("update ");
@@ -59,8 +62,8 @@
                Iterator i = getChangedFields(mapping, summary, 
changedObject).iterator();
 
                while (i.hasNext()) {
-                       Property attr = (Property) i.next();
-                       Column c = t.getColumnByPropertyName(attr.getName());
+                       Property property = (Property) i.next();
+                       Column c = 
t.getColumnByPropertyName(property.getName());
                        if ((c != null) && (c.isCollision() || 
c.isPrimaryKey())) {
                                // get rid of comma if OCC or PK is last field
                                if (!i.hasNext()) {
@@ -68,33 +71,39 @@
                                                        
.delete(statement.length() - 2, statement.length());
                                }
                        } else {
-                               parameters.add(attr);
-                               statement.append(c == null ? attr.getName() : 
c.getColumnName());
+                               updatedProperties.add(property);
+                               statement.append(c == null ? property.getName() 
: c.getColumnName());
                                statement.append(" = ?");
                                if (i.hasNext())
                                        statement.append(", ");
                        }
                }
 
+               if ( t.getManagedColumnPropertyName() != null ) {
+                       statement.append(", ");
+                       statement.append(t.getManagedColumnPropertyName());
+                       statement.append(" = ?");
+                       
managedProperties.add(changedObject.getProperty(t.getManagedColumnPropertyName()));
+               }
                statement.append(" where ");
 
                Iterator names = t.getPrimaryKeyNames().iterator();
-               Iterator properties = t.getPrimaryKeyProperties().iterator();
-               while (names.hasNext() && properties.hasNext()) {
+               Iterator pkProperties = t.getPrimaryKeyProperties().iterator();
+               while (names.hasNext() && pkProperties.hasNext()) {
                        String name = (String) names.next();
-                       String property = (String) properties.next();
+                       String property = (String) pkProperties.next();
                        statement.append(name);
                        statement.append(" = ?");
-                       if (names.hasNext() && properties.hasNext())
+                       if (names.hasNext() && pkProperties.hasNext())
                                statement.append(" and ");
-                       parameters.add(type.getProperty(property));
+                       whereClauseProperties.add(type.getProperty(property));
                }
 
                if (t.getCollisionColumn() != null) {
                        statement.append(" and ");
                        
statement.append(t.getCollisionColumn().getColumnName());
                        statement.append(" = ?");
-                       
parameters.add(type.getProperty(t.getCollisionColumnPropertyName()));
+                       
whereClauseProperties.add(type.getProperty(t.getCollisionColumnPropertyName()));
                }
 
                
@@ -104,21 +113,31 @@
                else
                        updateCommand = new 
UpdateCommandImpl(statement.toString());
                
-               Iterator params = parameters.iterator();
-               for (int idx = 1; params.hasNext(); idx++ ) {
-                       Property p = (Property)params.next();
-                       ParameterImpl param = new ParameterImpl();
-                       param.setName(p.getName());
-                       param.setType(p.getType());
-                       param.setConverter(getConverter(table, p.getName()));
-                       param.setIndex(idx);
-                       updateCommand.addParameter(param);
+               
+               int idx = 1;
+               Iterator params = updatedProperties.iterator();         
+               while ( params.hasNext()) {
+                       Property p = (Property)params.next();                   
+                       updateCommand.addParameter(createParameter(t, p, 
idx++));
                }
+               
+               params = managedProperties.iterator();
+               while ( params.hasNext()) {
+                       Property p = (Property)params.next();                   
+                       updateCommand.addParameter(createManagedParameter(t, p, 
idx++));
+               }
+               
+               params = whereClauseProperties.iterator();              
+               while ( params.hasNext()) {
+                       Property p = (Property)params.next();                   
+                       updateCommand.addParameter(createParameter(t, p, 
idx++));
+               }
+               
                DebugUtil.debugln(getClass(), debug, statement.toString());
                return updateCommand;
        }
 
-       private List getAttributeProperties(DataObject obj) {
+       private List getDataTypeProperties(DataObject obj) {
                ArrayList fields = new ArrayList();
                Iterator i = obj.getType().getProperties().iterator();
                while ( i.hasNext() ) {
@@ -163,30 +182,48 @@
                ArrayList parameters = new ArrayList();
                ArrayList pkParams = new ArrayList();
                
-               Iterator i = getAttributeProperties(changedObject).iterator();
+               Iterator i = getDataTypeProperties(changedObject).iterator();
                while (i.hasNext()) {
-                       Property attr = (Property) i.next();
-                       String field = attr.getName();
+                       Property property = (Property) i.next();
+                       String propertyName = property.getName();
 
-                       ParameterImpl p = getParameter(table, 
type.getProperty(field));
-                       if (pkNames.contains(field)) {
+                       ParameterImpl p = createParameter(wrapper, 
type.getProperty(propertyName));
+                       if (pkNames.contains(propertyName)) {
                                pkParams.add(p);
                        } else {
                                parameters.add(p);
                        }
                }
-               parameters.addAll(pkParams);
+               parameters.addAll(pkParams);            
+               
                return parameters;
                
        }
 
-       private ParameterImpl getParameter(Table table, Property property) {
+       private ParameterImpl createManagedParameter(TableWrapper table, 
Property property, int idx) {
+               ParameterImpl param = new ManagedParameterImpl();
+               param.setName(property.getName());
+               param.setType(property.getType());
+               
param.setConverter(getConverter(table.getConverter(property.getName())));
+               if ( idx != -1)
+                       param.setIndex(idx);
+               
+               return param;
+       }
+       private ParameterImpl createParameter(TableWrapper table, Property 
property) {
+               return createParameter(table, property, -1);
+       }
+       private ParameterImpl createParameter(TableWrapper table, Property 
property, int idx) {         
                ParameterImpl param = new ParameterImpl();
                param.setName(property.getName());
                param.setType(property.getType());
-               param.setConverter(getConverter(table, property.getName()));
+               
param.setConverter(getConverter(table.getConverter(property.getName())));
+               if ( idx != -1)
+                       param.setIndex(idx);
                
                return param;
        }
+
+
 }
 
Index: 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/InsertGenerator.java
===================================================================
--- 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/InsertGenerator.java    
    (revision 417540)
+++ 
src/main/java/org/apache/tuscany/das/rdb/generator/impl/InsertGenerator.java    
    (working copy)
@@ -91,7 +91,7 @@
                        ParameterImpl p = new ParameterImpl();
                        p.setName(property.getName());
                        p.setType(property.getType());
-                       p.setConverter(getConverter(t, property.getName()));
+                       
p.setConverter(getConverter(table.getConverter(property.getName())));
                        p.setIndex(idx);
                        cmd.addParameter(p);
 
Index: 
src/main/java/org/apache/tuscany/das/rdb/graphbuilder/schema/ESchemaMaker.java
===================================================================
--- 
src/main/java/org/apache/tuscany/das/rdb/graphbuilder/schema/ESchemaMaker.java  
    (revision 417540)
+++ 
src/main/java/org/apache/tuscany/das/rdb/graphbuilder/schema/ESchemaMaker.java  
    (working copy)
@@ -76,6 +76,7 @@
 
                        ResultMetadata resultMetadata = (ResultMetadata) 
iter.next();
 
+                       // Create a Type for each Table represented in the 
ResultSet
                        Iterator names = 
resultMetadata.getAllTablePropertyNames()
                                        .iterator();
                        while (names.hasNext()) {
@@ -90,7 +91,7 @@
                        // TODO tablePropertyMap is temporary until Tuscany-203 
is fixed
                        HashMap tablePropertyMap = new HashMap();
                        
-                       for (int i = 1; i <= 
resultMetadata.getColumnNames().size(); i++) {
+                       for (int i = 1; i <= resultMetadata.getResultSetSize(); 
i++) {
 
                                Property ref = 
rootType.getProperty(resultMetadata.getTablePropertyName(i));
                                
@@ -167,10 +168,7 @@
                                Property childProp = 
SDOUtil.createProperty(child, r.getName() + "_opposite", parent);
                                SDOUtil.setOpposite(parentProp, childProp);
                                SDOUtil.setOpposite(childProp, parentProp);
-                               SDOUtil.setMany(parentProp, r.isMany());
-                               
-                                                               
-
+                               SDOUtil.setMany(parentProp, r.isMany());        
                                                                        
                        }
 
                }
Index: 
src/main/java/org/apache/tuscany/das/rdb/graphbuilder/impl/ResultMetadata.java
===================================================================
--- 
src/main/java/org/apache/tuscany/das/rdb/graphbuilder/impl/ResultMetadata.java  
    (revision 417540)
+++ 
src/main/java/org/apache/tuscany/das/rdb/graphbuilder/impl/ResultMetadata.java  
    (working copy)
@@ -39,9 +39,9 @@
 
     private HashMap tableToColumnMap = new HashMap();
 
-    private ArrayList tablePropertyNames = new ArrayList();
+    private ArrayList typeNames = new ArrayList();
 
-    private ArrayList columnPropertyNames = new ArrayList();
+    private ArrayList propertyNames = new ArrayList();
 
     private final ResultSet resultSet;
 
@@ -69,52 +69,26 @@
         for (int i = 1; i <= resultSetShape.getColumnCount(); i++) {
             String tableName = resultSetShape.getTableName(i);
 
-            String tableProperty = mappingWrapper
+            String typeName = mappingWrapper
                     .getTableTypeName(tableName);
-            String columnProperty = mappingWrapper.getColumnPropertyName(
+            String propertyName = mappingWrapper.getColumnPropertyName(
                     tableName, resultSetShape.getColumnName(i));
-            String converter = mappingWrapper.getConverter(tableName,
+            String converterName = mappingWrapper.getConverter(tableName,
                     resultSetShape.getColumnName(i));
-            if (converter != null) {
-                
-                try {
-                    
-                    Class converterClazz=  Class.forName(converter, true, 
Thread.currentThread().getContextClassLoader());
-                    if(null != converterClazz)
-                        converters[i - 1]=  (Converter) 
converterClazz.newInstance();
-                     
-                }catch( Exception e){
-                  //try loading below....
-                    converters[i - 1]= null; //safety
-                }
-                    
-                    
-                 if(null == converters[i - 1] )   
-                 try{   
-                    
-                    
-                    Converter convInstance = (Converter) Class.forName(
-                            converter).newInstance();
-                    converters[i - 1] = convInstance;
-                } catch (Exception ex) {
-                    throw new RuntimeException(ex);
-                }
-
-            } else {
-                // TODO make static
-                converters[i - 1] = new DefaultConverter();
-            }
+            
+            converters[i-1] = loadConverter(converterName);
+            
             DebugUtil.debugln(getClass(), debug, "Adding table/column: "
-                    + tableProperty + "/" + columnProperty);
-            tablePropertyNames.add(tableProperty);
-            columnPropertyNames.add(columnProperty);
+                    + typeName + "/" + propertyName);
+            typeNames.add(typeName);
+            propertyNames.add(propertyName);
 
             Collection columns = (Collection) tableToColumnMap
-                    .get(tableProperty);
+                    .get(typeName);
             if (columns == null)
                 columns = new ArrayList();
-            columns.add(columnProperty);
-            tableToColumnMap.put(tableProperty, columns);
+            columns.add(propertyName);
+            tableToColumnMap.put(typeName, columns);
         }
 
         // Add any tables defined in the model but not included in the 
ResultSet
@@ -138,17 +112,36 @@
 
     }
 
+       private Converter loadConverter(String converterName) {
+               if (converterName != null) {
+                   
+                   try {
+                       
+                       Class converterClazz=  Class.forName(converterName, 
true, Thread.currentThread().getContextClassLoader());
+                       if(null != converterClazz)
+                           return (Converter) converterClazz.newInstance();    
                 
+                   } catch( Exception ex){
+                       throw new RuntimeException(ex);
+                   }           
+                   
+               try{                                                            
+                       Class converterClazz = Class.forName(converterName);
+                       if ( converterClazz != null)
+                               return (Converter)converterClazz.newInstance(); 
              
+                   } catch (Exception ex) {
+                       throw new RuntimeException(ex);
+                   }
+               }
+               return new DefaultConverter();
+       }
+
     private void debug(Object string) {
         if (debug)
             DebugUtil.debugln(getClass(), debug, string);
-    }
+    }   
 
-    public Collection getColumnNames() {
-        return columnPropertyNames;
-    }
-
     public String getColumnPropertyName(int i) {
-        return (String) columnPropertyNames.get(i - 1);
+        return (String) propertyNames.get(i - 1);
     }
 
     public String getDatabaseColumnName(int i) {
@@ -156,7 +149,7 @@
     }
 
     public String getTableName(String columnName) {
-        return (String) tablePropertyNames.get(columnPropertyNames
+        return (String) typeNames.get(propertyNames
                 .indexOf(columnName));
     }
 
@@ -165,12 +158,12 @@
     }
 
     public Type getDataType(String columnName) {
-        return resultSetShape.getColumnType(columnPropertyNames
+        return resultSetShape.getColumnType(propertyNames
                 .indexOf(columnName));
     }
 
     public String getTablePropertyName(int i) {
-        return (String) tablePropertyNames.get(i - 1);
+        return (String) typeNames.get(i - 1);
     }
 
     public Collection getAllTablePropertyNames() {
@@ -181,7 +174,7 @@
 
         StringBuffer result = new StringBuffer(super.toString());
         result.append(" (Table Names: ");
-        Iterator i = tablePropertyNames.iterator();
+        Iterator i = typeNames.iterator();
         while (i.hasNext()) {
             String tableName = (String) i.next();
             result.append(' ');
@@ -191,7 +184,7 @@
 
         result.append(" columnNames: ");
 
-        i = columnPropertyNames.iterator();
+        i = propertyNames.iterator();
         while (i.hasNext()) {
             String columnName = (String) i.next();
             result.append(' ');
Index: src/main/resources/config.xsd
===================================================================
--- src/main/resources/config.xsd       (revision 417540)
+++ src/main/resources/config.xsd       (working copy)
@@ -68,7 +68,8 @@
       <xsd:attribute name="converterClassName" type="xsd:string"/>     
       <xsd:attribute name="primaryKey" type="xsd:boolean"/>
       <xsd:attribute name="generated" type="xsd:boolean"/>
-      <xsd:attribute name="collision" type="xsd:boolean"/>    
+      <xsd:attribute name="collision" type="xsd:boolean"/>
+      <xsd:attribute name="managed" type="xsd:boolean"/>    
    </xsd:complexType>
    <xsd:complexType name="ResultDescriptor">
       <xsd:attribute name="columnName" type="xsd:string"/>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to