cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From torehal...@apache.org
Subject svn commit: r764243 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/merge/ test/java/org/apache/cayenne/merge/
Date Sat, 11 Apr 2009 20:00:22 GMT
Author: torehalset
Date: Sat Apr 11 20:00:21 2009
New Revision: 764243

URL: http://svn.apache.org/viewvc?rev=764243&view=rev
Log:
CAY-1206: merge: a way to set value for null for madatory columns
Now possible to add a ValueForNullProvider that will be used
to set value for null on mandatory columns. This is not (yet?)
available from the modeler.

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DefaultValueForNullProvider.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DummyReverseToken.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/EmptyValueForNullProvider.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetValueForNullToDb.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/ValueForNullProvider.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/ValueForNullTest.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergerFactoryTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java?rev=764243&r1=764242&r2=764243&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DbMerger.java
Sat Apr 11 20:00:21 2009
@@ -45,13 +45,23 @@
 
 /**
  * Traverse a {@link DataNode} and a {@link DataMap} and create a group of
- * {@link MergerToken}s to alter the {@link DataNode} datastore to match the
+ * {@link MergerToken}s to alter the {@link DataNode} data store to match the
  * {@link DataMap}.
  * 
  */
 public class DbMerger {
 
     private MergerFactory factory;
+    
+    private ValueForNullProvider valueForNull = new EmptyValueForNullProvider();
+
+    /**
+     * Set a {@link ValueForNullProvider} that will be used to set value for null on not
+     * null columns
+     */
+    public void setValueForNullProvider(ValueForNullProvider valueProvider) {
+        valueForNull = valueProvider;
+    }
 
     /**
      * A method that return true if the given table name should be included. The default
@@ -185,7 +195,12 @@
             if (detected == null) {
                 tokens.add(factory.createAddColumnToDb(dbEntity, attr));
                 if (attr.isMandatory()) {
-                    // TODO: default value
+                    if (valueForNull.hasValueFor(dbEntity, attr)) {
+                        tokens.add(factory.createSetValueForNullToDb(
+                                dbEntity,
+                                attr,
+                                valueForNull));
+                    }
                     tokens.add(factory.createSetNotNullToDb(dbEntity, attr));
                 }
                 continue;
@@ -194,6 +209,12 @@
             // check for not null
             if (attr.isMandatory() != detected.isMandatory()) {
                 if (attr.isMandatory()) {
+                    if (valueForNull.hasValueFor(dbEntity, attr)) {
+                        tokens.add(factory.createSetValueForNullToDb(
+                                dbEntity,
+                                attr,
+                                valueForNull));
+                    }
                     tokens.add(factory.createSetNotNullToDb(dbEntity, attr));
                 }
                 else {

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DefaultValueForNullProvider.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DefaultValueForNullProvider.java?rev=764243&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DefaultValueForNullProvider.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DefaultValueForNullProvider.java
Sat Apr 11 20:00:21 2009
@@ -0,0 +1,71 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ ****************************************************************/
+package org.apache.cayenne.merge;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cayenne.access.jdbc.ParameterBinding;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+
+public class DefaultValueForNullProvider implements ValueForNullProvider {
+
+    private Map<String, ParameterBinding> values = new HashMap<String, ParameterBinding>();
+
+    public void set(DbEntity entity, DbAttribute column, Object value, int type) {
+        values.put(createKey(entity, column), new ParameterBinding(value, type, column
+                .getAttributePrecision()));
+    }
+
+    protected ParameterBinding get(DbEntity entity, DbAttribute column) {
+        return values.get(createKey(entity, column));
+    }
+
+    public List<String> createSql(DbEntity entity, DbAttribute column) {
+        ParameterBinding value = get(entity, column);
+        if (value == null) {
+            return Collections.emptyList();
+        }
+
+        // TODO: change things so it is possible to use prepared statements here
+        StringBuilder sql = new StringBuilder();
+        sql.append("UPDATE ");
+        sql.append(entity.getFullyQualifiedName());
+        sql.append(" SET ");
+        sql.append(column.getName());
+        sql.append("='");
+        sql.append(value.getValue());
+        sql.append("' WHERE ");
+        sql.append(column.getName());
+        sql.append(" IS NULL");
+        return Collections.singletonList(sql.toString());
+    }
+
+    public boolean hasValueFor(DbEntity entity, DbAttribute column) {
+        return values.containsKey(createKey(entity, column));
+    }
+
+    private String createKey(DbEntity entity, DbAttribute attribute) {
+        return (entity.getFullyQualifiedName() + "." + attribute.getName()).toUpperCase();
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DummyReverseToken.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DummyReverseToken.java?rev=764243&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DummyReverseToken.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/DummyReverseToken.java
Sat Apr 11 20:00:21 2009
@@ -0,0 +1,58 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ ****************************************************************/
+package org.apache.cayenne.merge;
+
+/**
+ * The reverse of a {@link MergerToken} that can not be reversed.. This will not execute
+ * any thing, but {@link #createReverse(MergerFactory)} will get back the reverse that
+ * this was made from.
+ */
+class DummyReverseToken implements MergerToken {
+
+    private MergerToken reverse;
+
+    public DummyReverseToken(MergerToken reverse) {
+        this.reverse = reverse;
+    }
+
+    public MergerToken createReverse(MergerFactory factory) {
+        return reverse;
+    }
+
+    public void execute(MergerContext mergerContext) {
+        // can not execute
+    }
+
+    public MergeDirection getDirection() {
+        return reverse.getDirection().reverseDirection();
+    }
+
+    public String getTokenName() {
+        return "Can not execute the reverse of " + reverse.getTokenName();
+    }
+
+    public String getTokenValue() {
+        return reverse.getTokenValue();
+    }
+
+    public boolean isReversible() {
+        return true;
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/EmptyValueForNullProvider.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/EmptyValueForNullProvider.java?rev=764243&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/EmptyValueForNullProvider.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/EmptyValueForNullProvider.java
Sat Apr 11 20:00:21 2009
@@ -0,0 +1,40 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ ****************************************************************/
+package org.apache.cayenne.merge;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+
+/**
+ * A dummy {@link ValueForNullProvider} that are not able to provide any values
+ */
+class EmptyValueForNullProvider implements ValueForNullProvider {
+
+    public List<String> createSql(DbEntity entity, DbAttribute column) {
+        return Collections.emptyList();
+    }
+
+    public boolean hasValueFor(DbEntity entity, DbAttribute column) {
+        return false;
+    }
+
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java?rev=764243&r1=764242&r2=764243&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/MergerFactory.java
Sat Apr 11 20:00:21 2009
@@ -79,6 +79,10 @@
     public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute column) {
         return new SetAllowNullToDb(entity, column);
     }
+    
+    public MergerToken createSetValueForNullToDb(DbEntity entity, DbAttribute column, ValueForNullProvider
valueForNullProvider){
+        return new SetValueForNullToDb(entity, column, valueForNullProvider);
+    }
 
     public MergerToken createSetColumnTypeToModel(
             DbEntity entity,
@@ -109,4 +113,5 @@
     public MergerToken createDropRelationshipToModel(DbEntity entity, DbRelationship rel)
{
         return new DropRelationshipToModel(entity, rel);
     }
+    
 }

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetValueForNullToDb.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetValueForNullToDb.java?rev=764243&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetValueForNullToDb.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/SetValueForNullToDb.java
Sat Apr 11 20:00:21 2009
@@ -0,0 +1,50 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ ****************************************************************/
+package org.apache.cayenne.merge;
+
+import java.util.List;
+
+import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+
+
+public class SetValueForNullToDb extends AbstractToDbToken.EntityAndColumn {
+    
+    private ValueForNullProvider valueForNullProvider;
+
+    public SetValueForNullToDb(DbEntity entity, DbAttribute column, ValueForNullProvider
valueForNullProvider) {
+        super(entity, column);
+        this.valueForNullProvider = valueForNullProvider;
+    }
+    
+    @Override
+    public List<String> createSql(DbAdapter adapter) {
+        return valueForNullProvider.createSql(getEntity(), getColumn());
+    }
+
+    public MergerToken createReverse(MergerFactory factory) {
+        return new DummyReverseToken(this);
+    }
+    
+    public String getTokenName() {
+        return "Set value for null";
+    }
+    
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/ValueForNullProvider.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/ValueForNullProvider.java?rev=764243&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/ValueForNullProvider.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/merge/ValueForNullProvider.java
Sat Apr 11 20:00:21 2009
@@ -0,0 +1,38 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ ****************************************************************/
+package org.apache.cayenne.merge;
+
+import java.util.List;
+
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+
+public interface ValueForNullProvider {
+    
+    /**
+     * @return true if there exist a value that should be inserted for null values
+     */
+    public boolean hasValueFor(DbEntity entity, DbAttribute column);
+
+    /**
+     * @return a {@link List} of sql to set value for null
+     */
+    public List<String> createSql(DbEntity entity, DbAttribute column);
+
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java?rev=764243&r1=764242&r2=764243&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergeCase.java
Sat Apr 11 20:00:21 2009
@@ -29,6 +29,8 @@
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.access.QueryLogger;
 import org.apache.cayenne.dba.DbAdapter;
@@ -44,6 +46,7 @@
 
 public class MergeCase extends CayenneCase {
 
+    protected DataDomain dom;
     protected DataNode node;
     protected DataMap map;
 
@@ -69,7 +72,15 @@
         return createMerger().createMergeTokens(node, map);
     }
 
-    protected DataMap createDataMap() {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        deleteTestData();
+        createTestData("testArtists");
+        DataNode orgNode = getDomain().getDataNodes().iterator().next();
+        
+        
         // clone DataMap by saving and loading from XML as to avoid modifying shared test
         // DataMap
         DataMap originalMap = getDomain().getMap("testmap");
@@ -78,22 +89,19 @@
         originalMap.encodeAsXML(outWriter);
         outWriter.flush();
         StringReader in = new StringReader(out.toString());
-        DataMap map = new MapLoader().loadDataMap(new InputSource(in));
-
+        map = new MapLoader().loadDataMap(new InputSource(in));
+        
         // map must operate in an EntityResolve namespace...
         EntityResolver testResolver = new EntityResolver();
         testResolver.addDataMap(map);
-        return map;
-    }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        deleteTestData();
-        createTestData("testArtists");
-        node = getDomain().getDataNodes().iterator().next();
-        map = createDataMap();
+        node = new DataNode("mergenode");
+        node.setAdapter(orgNode.getAdapter());
+        node.setDataSource(orgNode.getDataSource());
+        node.addDataMap(map);
+        
+        dom = new DataDomain("mergetestdomain");
+        dom.addNode(node);
 
         filterDataMap(node, map);
 
@@ -252,6 +260,11 @@
         catch (Exception e) {
         }
     }
+    
+    @Override
+    protected DataContext createDataContext() {
+        return dom.createDataContext();
+    }
 
     @Override
     protected void tearDown() throws Exception {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergerFactoryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergerFactoryTest.java?rev=764243&r1=764242&r2=764243&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergerFactoryTest.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/MergerFactoryTest.java
Sat Apr 11 20:00:21 2009
@@ -150,7 +150,7 @@
 
         // try to insert some rows to check that pk stuff is working
         DataContext ctxt = createDataContext();
-        DataMap sourceMap = ctxt.getEntityResolver().getDataMap("testmap");
+        DataMap sourceMap = map;//ctxt.getEntityResolver().getDataMap("testmap");
 
         try {
             sourceMap.addDbEntity(dbEntity);

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/ValueForNullTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/ValueForNullTest.java?rev=764243&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/ValueForNullTest.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/merge/ValueForNullTest.java
Sat Apr 11 20:00:21 2009
@@ -0,0 +1,126 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ ****************************************************************/
+package org.apache.cayenne.merge;
+
+import java.sql.Types;
+import java.util.List;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.cayenne.DataObject;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.access.jdbc.ParameterBinding;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.query.SelectQuery;
+
+public class ValueForNullTest extends MergeCase {
+
+    private static final String DEFAULT_VALUE_STRING = "DEFSTRING";
+
+    public void test() throws Exception {
+        DbEntity dbEntity = map.getDbEntity("PAINTING");
+        assertNotNull(dbEntity);
+        ObjEntity objEntity = map.getObjEntity("Painting");
+        assertNotNull(objEntity);
+
+        DataContext ctxt = createDataContext();
+
+        // insert some rows before adding "not null" column
+        final int nrows = 10;
+        for (int i = 0; i < nrows; i++) {
+            DataObject o = (DataObject) ctxt.newObject("Painting");
+            o.writeProperty("paintingTitle", "ptitle" + i);
+        }
+        ctxt.commitChanges();
+
+        // create and add new column to model and db
+        DbAttribute column = new DbAttribute("NEWCOL2", Types.VARCHAR, dbEntity);
+
+        column.setMandatory(false);
+        column.setMaxLength(10);
+        dbEntity.addAttribute(column);
+        assertTrue(dbEntity.getAttributes().contains(column));
+        assertEquals(column, dbEntity.getAttribute(column.getName()));
+        assertTokensAndExecute(node, map, 1, 0);
+
+        // need obj attr to be able to query
+        ObjAttribute objAttr = new ObjAttribute("newcol2");
+        objAttr.setDbAttributePath(column.getName());
+        objEntity.addAttribute(objAttr);
+
+        // check that is was merged
+        assertTokensAndExecute(node, map, 0, 0);
+
+        // set not null
+        column.setMandatory(true);
+
+        // merge to db
+        assertTokensAndExecute(node, map, 2, 0);
+
+        // check that is was merged
+        assertTokensAndExecute(node, map, 0, 0);
+
+        // check values for null
+        Expression qual = ExpressionFactory.matchExp(
+                objAttr.getName(),
+                DEFAULT_VALUE_STRING);
+        SelectQuery query = new SelectQuery("Painting", qual);
+        List<Persistent> rows = ctxt.performQuery(query);
+        assertEquals(nrows, rows.size());
+
+        // clean up
+        dbEntity.removeAttribute(column.getName());
+        assertTokensAndExecute(node, map, 1, 0);
+        assertTokensAndExecute(node, map, 0, 0);
+    }
+
+    @Override
+    protected DbMerger createMerger() {
+        DbMerger merger = super.createMerger();
+
+        merger.setValueForNullProvider(new DefaultValueForNullProvider() {
+
+            @Override
+            protected ParameterBinding get(DbEntity entity, DbAttribute column) {
+                int type = column.getType();
+                switch (type) {
+                    case Types.VARCHAR:
+                        return new ParameterBinding(DEFAULT_VALUE_STRING, type, -1);
+                    default:
+                        throw new AssertionFailedError("should not get here");
+                }
+            }
+
+            @Override
+            public boolean hasValueFor(DbEntity entity, DbAttribute column) {
+                return true;
+            }
+
+        });
+
+        return merger;
+    }
+
+}



Mime
View raw message