Package org.mongodb.morphia

Source Code of org.mongodb.morphia.TestUpdateOps$EntityLogs

/**
* Copyright (C) 2010 Olafur Gauti Gudmundsson
*
* 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.
*/


package org.mongodb.morphia;


import com.mongodb.DBObject;
import com.mongodb.WriteConcern;
import org.bson.types.ObjectId;
import org.junit.Assert;
import org.junit.Test;
import org.mongodb.morphia.TestQuery.ContainsPic;
import org.mongodb.morphia.TestQuery.Pic;
import org.mongodb.morphia.annotations.Embedded;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.annotations.Indexed;
import org.mongodb.morphia.annotations.PreLoad;
import org.mongodb.morphia.annotations.PrePersist;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.mongodb.morphia.query.UpdateResults;
import org.mongodb.morphia.query.ValidationException;
import org.mongodb.morphia.testmodel.Circle;
import org.mongodb.morphia.testmodel.Rectangle;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;


/**
* @author Scott Hernandez
*/
public class TestUpdateOps extends TestBase {

    private static class ContainsIntArray {
        @Id
        private ObjectId id;
        private final Integer[] values = {1, 2, 3};
    }

    private static class ContainsInt {
        @Id
        private ObjectId id;
        private int val;
    }

    @Entity
    private static class ContainsPicKey {
        @Id
        private ObjectId id;
        private String name = "test";
        private Key<Pic> pic;
    }

    @Entity(noClassnameStored = true)
    public static class EntityLogs {
        @Id
        private ObjectId id;
        @Indexed
        private String uuid;
        @Embedded
        private List<EntityLog> logs = new ArrayList<EntityLog>();
        private DBObject raw;

        @PreLoad
        public void preload(final DBObject raw) {
            this.raw = raw;
        }
    }

    @Embedded
    public static class EntityLog {
        private Date receivedTs;
        private String value;
        private DBObject raw;

        public EntityLog() {
        }

        public EntityLog(final String value) {
            this.value = value;
        }

        @PreLoad
        public void preload(final DBObject raw) {
            this.raw = raw;
        }

        @PrePersist
        public void pickReceivedTs() {
            receivedTs = new Date();
        }
    }

    @Test
    public void testIncDec() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(1, 10), new Rectangle(1, 10), new Rectangle(10, 10),
                                   new Rectangle(10, 10)};

        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        final Query<Rectangle> q1 = getDs().find(Rectangle.class, "height", 1D);
        final Query<Rectangle> q2 = getDs().find(Rectangle.class, "height", 2D);

        assertEquals(3, getDs().getCount(q1));
        assertEquals(0, getDs().getCount(q2));

        final UpdateResults results = getDs().update(q1, getDs().createUpdateOperations(Rectangle.class).inc("height"));
        assertUpdated(results, 3);

        assertEquals(0, getDs().getCount(q1));
        assertEquals(3, getDs().getCount(q2));

        getDs().update(q2, getDs().createUpdateOperations(Rectangle.class).dec("height"));
        assertEquals(3, getDs().getCount(q1));
        assertEquals(0, getDs().getCount(q2));

        getDs().update(getDs().find(Rectangle.class, "width", 1D),
                       getDs().createUpdateOperations(Rectangle.class).set("height", 1D).set("width", 1D),
                       true);
        assertNotNull(getDs().find(Rectangle.class, "width", 1D).get());
        assertNull(getDs().find(Rectangle.class, "width", 2D).get());
        getDs().update(getDs().find(Rectangle.class, "width", 1D),
                       getDs().createUpdateOperations(Rectangle.class).set("height", 2D).set("width", 2D),
                       true);
        assertNull(getDs().find(Rectangle.class, "width", 1D).get());
        assertNotNull(getDs().find(Rectangle.class, "width", 2D).get());
    }

    @Test
    public void testInsertUpdate() throws Exception {
        final UpdateResults res = getDs().update(getDs().createQuery(Circle.class).field("radius").equal(0),
                                                 getDs().createUpdateOperations(Circle.class).inc("radius", 1D), true);
        assertInserted(res);
    }

    @Test
    public void testSetUnset() throws Exception {
        final Key<Circle> key = getDs().save(new Circle(1));

        UpdateResults res = getDs().updateFirst(getDs().find(Circle.class, "radius", 1D),
                                                getDs().createUpdateOperations(Circle.class).set("radius", 2D));

        assertUpdated(res, 1);

        final Circle c = getDs().getByKey(Circle.class, key);
        assertEquals(2D, c.getRadius(), 0);


        res = getDs().updateFirst(getDs().find(Circle.class, "radius", 2D), getDs().createUpdateOperations(Circle.class).unset("radius"));
        assertUpdated(res, 1);

        final Circle c2 = getDs().getByKey(Circle.class, key);
        assertEquals(0D, c2.getRadius(), 0);
    }

    @Test
    public void testSetOnInsertWhenInserting() throws Exception {
        checkMinServerVersion(2.4);
        ObjectId id = new ObjectId();
        UpdateResults res = getDs().updateFirst(getDs().createQuery(Circle.class).field("id").equal(id),
                                                getDs().createUpdateOperations(Circle.class).setOnInsert("radius", 2D), true);

        assertInserted(res);

        final Circle c = getDs().get(Circle.class, id);

        assertNotNull(c);
        assertEquals(2D, c.getRadius(), 0);
    }

    @Test
    public void testSetOnInsertWhenUpdating() throws Exception {
        checkMinServerVersion(2.4);
        ObjectId id = new ObjectId();
        UpdateResults res = getDs().updateFirst(getDs().createQuery(Circle.class).field("id").equal(id),
                                                getDs().createUpdateOperations(Circle.class).setOnInsert("radius", 1D), true);

        assertInserted(res);

        res = getDs().updateFirst(getDs().createQuery(Circle.class).field("id").equal(id),
                                  getDs().createUpdateOperations(Circle.class).setOnInsert("radius", 2D), true);

        assertUpdated(res, 1);

        final Circle c = getDs().get(Circle.class, id);

        assertNotNull(c);
        assertEquals(1D, c.getRadius(), 0);
    }


    @Test(expected = ValidationException.class)
    public void testValidationBadFieldName() throws Exception {
        getDs().update(getDs().createQuery(Circle.class).field("radius").equal(0),
                       getDs().createUpdateOperations(Circle.class).inc("r", 1D),
                       true, WriteConcern.SAFE);
        Assert.assertTrue(false); //should not get here.
    }

    @Test
    public void testInsertUpdatesUnsafe() throws Exception {
        getDs().getDB().requestStart();
        try {
            getDs().update(getDs().createQuery(Circle.class).field("radius").equal(0),
                           getDs().createUpdateOperations(Circle.class).inc("radius", 1D), true, WriteConcern.UNACKNOWLEDGED);
            assertEquals(1, getDs().getCount(Circle.class));
        } finally {
            getDs().getDB().requestDone();
        }
    }

    @Test
    public void testUpdateWithDifferentType() throws Exception {
        final ContainsInt cInt = new ContainsInt();
        cInt.val = 21;
        getDs().save(cInt);

        final UpdateResults res = getDs().updateFirst(getDs().createQuery(ContainsInt.class),
                                                      getDs().createUpdateOperations(ContainsInt.class).inc("val", 1.1D));
        assertUpdated(res, 1);

        final ContainsInt ciLoaded = getDs().find(ContainsInt.class).limit(1).get();
        assertEquals(22, ciLoaded.val);
    }

    @Test
    public void testRemoveFirst() throws Exception {
        final ContainsIntArray cIntArray = new ContainsIntArray();
        getDs().save(cIntArray);
        ContainsIntArray cIALoaded = getDs().get(cIntArray);
        assertEquals(3, cIALoaded.values.length);
        assertArrayEquals((new ContainsIntArray()).values, cIALoaded.values);

        //remove 1
        UpdateResults res = getDs().updateFirst(getDs().createQuery(ContainsIntArray.class),
                                                getDs().createUpdateOperations(ContainsIntArray.class).removeFirst("values"));
        assertUpdated(res, 1);
        cIALoaded = getDs().get(cIntArray);
        assertArrayEquals(new Integer[]{2, 3}, cIALoaded.values);

        //remove 3
        res = getDs().updateFirst(getDs().createQuery(ContainsIntArray.class),
                                  getDs().createUpdateOperations(ContainsIntArray.class).removeLast("values"));
        assertUpdated(res, 1);
        cIALoaded = getDs().get(cIntArray);
        assertArrayEquals(new Integer[]{2}, cIALoaded.values);
    }

    private void assertUpdated(final UpdateResults res, final int count) {
        assertEquals(0, res.getInsertedCount());
        assertEquals(count, res.getUpdatedCount());
        assertEquals(true, res.getUpdatedExisting());
    }

    private void assertInserted(final UpdateResults res) {
        assertEquals(1, res.getInsertedCount());
        assertEquals(0, res.getUpdatedCount());
        assertEquals(false, res.getUpdatedExisting());
    }

    @Test
    public void testAdd() throws Exception {
        ContainsIntArray cIntArray = new ContainsIntArray();
        getDs().save(cIntArray);
        ContainsIntArray cIALoaded = getDs().get(cIntArray);
        assertEquals(3, cIALoaded.values.length);
        assertArrayEquals((new ContainsIntArray()).values, cIALoaded.values);

        //add 4 to array
        UpdateResults res = getDs().updateFirst(getDs().createQuery(ContainsIntArray.class),
                                                getDs().createUpdateOperations(ContainsIntArray.class).add("values", 4, false));
        assertUpdated(res, 1);

        cIALoaded = getDs().get(cIntArray);
        assertArrayEquals(new Integer[]{1, 2, 3, 4}, cIALoaded.values);

        //add unique (4) -- noop
        res = getDs().updateFirst(getDs().createQuery(ContainsIntArray.class),
                                  getDs().createUpdateOperations(ContainsIntArray.class).add("values", 4, false));
        assertUpdated(res, 1);

        cIALoaded = getDs().get(cIntArray);
        assertArrayEquals(new Integer[]{1, 2, 3, 4}, cIALoaded.values);

        //add dup 4
        res = getDs().updateFirst(getDs().createQuery(ContainsIntArray.class),
                                  getDs().createUpdateOperations(ContainsIntArray.class).add("values", 4, true));
        assertUpdated(res, 1);

        cIALoaded = getDs().get(cIntArray);
        assertArrayEquals(new Integer[]{1, 2, 3, 4, 4}, cIALoaded.values);

        //cleanup for next tests
        getDs().delete(getDs().find(ContainsIntArray.class));
        cIntArray = getDs().getByKey(ContainsIntArray.class, getDs().save(new ContainsIntArray()));

        //add [4,5]
        final List<Integer> newValues = new ArrayList<Integer>();
        newValues.add(4);
        newValues.add(5);
        res = getDs().updateFirst(getDs().createQuery(ContainsIntArray.class),
                                  getDs().createUpdateOperations(ContainsIntArray.class).addAll("values", newValues, false));
        assertUpdated(res, 1);

        cIALoaded = getDs().get(cIntArray);
        assertArrayEquals(new Integer[]{1, 2, 3, 4, 5}, cIALoaded.values);

        //add them again... noop
        res = getDs().updateFirst(getDs().createQuery(ContainsIntArray.class),
                                  getDs().createUpdateOperations(ContainsIntArray.class).addAll("values", newValues, false));
        assertUpdated(res, 1);

        cIALoaded = getDs().get(cIntArray);
        assertArrayEquals(new Integer[]{1, 2, 3, 4, 5}, cIALoaded.values);

        //add dups [4,5]
        res = getDs().updateFirst(getDs().createQuery(ContainsIntArray.class),
                                  getDs().createUpdateOperations(ContainsIntArray.class).addAll("values", newValues, true));
        assertUpdated(res, 1);

        cIALoaded = getDs().get(cIntArray);
        assertArrayEquals(new Integer[]{1, 2, 3, 4, 5, 4, 5}, cIALoaded.values);

    }

    @Test
    public void testExistingUpdates() throws Exception {
        Circle c = new Circle(100D);
        getDs().save(c);
        c = new Circle(12D);
        getDs().save(c);
        UpdateResults res = getDs().updateFirst(getDs().createQuery(Circle.class),
                                                getDs().createUpdateOperations(Circle.class).inc("radius", 1D));
        assertUpdated(res, 1);

        res = getDs().update(getDs().createQuery(Circle.class), getDs().createUpdateOperations(Circle.class).inc("radius"));
        assertUpdated(res, 2);

        //test possible data type change.
        final Circle cLoaded = getDs().find(Circle.class, "radius", 13).get();
        assertNotNull(cLoaded);
        assertEquals(13D, cLoaded.getRadius(), 0D);
    }

    @Test
    public void testInsertWithRef() throws Exception {
        final Pic pic = new Pic();
        pic.setName("fist");
        final Key<Pic> picKey = getDs().save(pic);

        //test with Key<Pic>
        UpdateResults res = getDs().updateFirst(getDs().find(ContainsPic.class, "name", "first").filter("pic", picKey),
                                                getDs().createUpdateOperations(ContainsPic.class).set("name", "A"), true);

        assertInserted(res);
        assertEquals(1, getDs().find(ContainsPic.class).countAll());

        getDs().delete(getDs().find(ContainsPic.class));

        //test with pic object
        res = getDs().updateFirst(getDs().find(ContainsPic.class, "name", "first").filter("pic", pic),
                                  getDs().createUpdateOperations(ContainsPic.class).set("name", "second"), true);

        assertInserted(res);
        assertEquals(1, getDs().find(ContainsPic.class).countAll());

        //test reading the object.
        final ContainsPic cp = getDs().find(ContainsPic.class).get();
        assertNotNull(cp);
        assertEquals("second", cp.getName());
        assertNotNull(cp.getPic());
        assertNotNull(cp.getPic().getName());
        assertEquals("fist", cp.getPic().getName());

    }

    @Test
    public void testUpdateRef() throws Exception {
        final ContainsPic cp = new ContainsPic();
        cp.setName("cp one");

        getDs().save(cp);

        final Pic pic = new Pic();
        pic.setName("fist");
        final Key<Pic> picKey = getDs().save(pic);


        //test with Key<Pic>
        final UpdateResults res = getDs().updateFirst(getDs().find(ContainsPic.class, "name", cp.getName()),
                                                      getDs().createUpdateOperations(ContainsPic.class).set("pic", pic));

        assertEquals(1, res.getUpdatedCount());

        //test reading the object.
        final ContainsPic cp2 = getDs().find(ContainsPic.class).get();
        assertNotNull(cp2);
        assertEquals(cp2.getName(), cp.getName());
        assertNotNull(cp2.getPic());
        assertNotNull(cp2.getPic().getName());
        assertEquals(cp2.getPic().getName(), pic.getName());

        getDs().updateFirst(getDs().find(ContainsPic.class, "name", cp.getName()),
                            getDs().createUpdateOperations(ContainsPic.class).set("pic", picKey));

        //test reading the object.
        final ContainsPic cp3 = getDs().find(ContainsPic.class).get();
        assertNotNull(cp3);
        assertEquals(cp3.getName(), cp.getName());
        assertNotNull(cp3.getPic());
        assertNotNull(cp3.getPic().getName());
        assertEquals(cp3.getPic().getName(), pic.getName());
    }

    @Test
    public void testUpdateKeyRef() throws Exception {
        final ContainsPicKey cpk = new ContainsPicKey();
        cpk.name = "cpk one";

        getDs().save(cpk);

        final Pic pic = new Pic();
        pic.setName("fist again");
        final Key<Pic> picKey = getDs().save(pic);
        // picKey = getDs().getKey(pic);


        //test with Key<Pic>
        final UpdateResults res = getDs().updateFirst(getDs().find(ContainsPicKey.class, "name", cpk.name),
                                                      getDs().createUpdateOperations(ContainsPicKey.class).set("pic", pic));

        assertEquals(1, res.getUpdatedCount());

        //test reading the object.
        final ContainsPicKey cpk2 = getDs().find(ContainsPicKey.class).get();
        assertNotNull(cpk2);
        assertEquals(cpk2.name, cpk.name);
        assertNotNull(cpk2.pic);
        assertEquals(cpk2.pic, picKey);

        getDs().updateFirst(getDs().find(ContainsPicKey.class, "name", cpk.name),
                            getDs().createUpdateOperations(ContainsPicKey.class).set("pic", picKey));

        //test reading the object.
        final ContainsPicKey cpk3 = getDs().find(ContainsPicKey.class).get();
        assertNotNull(cpk3);
        assertEquals(cpk3.name, cpk.name);
        assertNotNull(cpk3.pic);
        assertEquals(cpk3.pic, picKey);
    }

    @Test
    public void testUpdateAll() {
        getMorphia().map(EntityLogs.class, EntityLog.class);
        String uuid = "4ec6ada9-081a-424f-bee0-934c0bc4fab7";

        EntityLogs logs = new EntityLogs();
        logs.uuid = uuid;
        getDs().save(logs);

        Query<EntityLogs> finder = getDs().find(EntityLogs.class).field("uuid").equal(uuid);

        // both of these entries will have a className attribute
        List<EntityLog> latestLogs = Arrays.asList(new EntityLog("whatever1"), new EntityLog("whatever2"));
        UpdateOperations<EntityLogs> updateOperationsAll = getDs().createUpdateOperations(EntityLogs.class)
                                                                  .addAll("logs", latestLogs, false);
        getDs().update(finder, updateOperationsAll, true);
        validateNoClassName(finder.get());

        // this entry will NOT have a className attribute
        UpdateOperations<EntityLogs> updateOperations3 = getDs().createUpdateOperations(EntityLogs.class)
                                                                .add("logs", new EntityLog("whatever3"), false);
        getDs().update(finder, updateOperations3, true);
        validateNoClassName(finder.get());

        // this entry will NOT have a className attribute
        UpdateOperations<EntityLogs> updateOperations4 = getDs().createUpdateOperations(EntityLogs.class)
                                                                .add("logs", new EntityLog("whatever4"), false);
        getDs().update(finder, updateOperations4, true);
        validateNoClassName(finder.get());
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    private void validateNoClassName(final EntityLogs loaded) {
        List<DBObject> logs = (List<DBObject>) loaded.raw.get("logs");
        for (DBObject o : logs) {
            Assert.assertNull(o.get("className"));
        }
    }
}
TOP

Related Classes of org.mongodb.morphia.TestUpdateOps$EntityLogs

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.