// Path: stardao-core/src/main/java/io/stardog/stardao/core/Results.java
// @AutoValue
// public abstract class Results<M,N> {
//     @ApiModelProperty(value = "list of results returned", required = true)
//     public abstract List<M> getData();
// 
//     @ApiModelProperty(value = "identifier to return the next item in the sequence")
//     public abstract Optional<N> getNext();
// 
//     public static <M,N> Results<M,N> of(Iterable<M> data) {
//         return new AutoValue_Results<M, N>(ImmutableList.copyOf(data), Optional.empty());
//     }
// 
//     public static <M,N> Results<M,N> of(Iterable<M> data, N next) {
//         return new AutoValue_Results<M, N>(ImmutableList.copyOf(data), Optional.ofNullable(next));
//     }
// }
// 
// Path: stardao-core/src/main/java/io/stardog/stardao/core/Update.java
// @AutoValue
// @JsonDeserialize(using = UpdateDeserializer.class)
// @JsonSerialize(using = UpdateSerializer.class)
// public abstract class Update<P> {
//     public abstract P getPartial();
//     public abstract Set<String> getSetFields();
//     public abstract Set<String> getRemoveFields();
// 
//     public static <T> Update<T> of(T setObject, Set<String> setFields) {
//         return new AutoValue_Update<>(setObject, setFields, ImmutableSet.of());
//     }
// 
//     public static <T> Update<T> of(T setObject, Set<String> setFields, Set<String> removeFields) {
//         return new AutoValue_Update<>(setObject, setFields, removeFields);
//     }
// 
//     public boolean isEmpty() {
//         return getSetFields().isEmpty() && getRemoveFields().isEmpty();
//     }
// 
//     public Set<String> getUpdateFields() {
//         return Sets.union(getSetFields(), getRemoveFields());
//     }
// 
//     public boolean isUpdateField(String field) {
//         return getSetFields().contains(field) || getRemoveFields().contains(field);
//     }
// }


import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.document.Index;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.KeyAttribute;
import com.amazonaws.services.dynamodbv2.document.PrimaryKey;
import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
import com.amazonaws.services.dynamodbv2.document.spec.ScanSpec;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.amazonaws.services.dynamodbv2.local.embedded.DynamoDBEmbedded;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import io.stardog.stardao.core.Results;
import io.stardog.stardao.core.Update;
import org.junit.Before;
import org.junit.Test;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
        assertTrue(dao.checkUniqueField("email", "email", "new@example.com", null));
        assertFalse(dao.checkUniqueField("email", "email", "bob@example.com", null));
        TestModel bob = dao.loadByIndex("email", "email", "bob@example.com");
        assertTrue(dao.checkUniqueField("email", "email", "bob@exmaple.com", bob.getId()));
    }

    @Test
    public void testToCreateItem() throws Exception {
        Instant now = Instant.now();
        UUID creatorId = UUID.randomUUID();
        Item item = dao.toCreateItem(TestModel.builder().name("Ian White").build(), now, creatorId);
        assertNotNull(item.get("id"));
        assertEquals(creatorId.toString(), item.get("createId"));
        assertEquals(new BigDecimal(now.toEpochMilli()), item.get("createAt"));
    }

    @Test
    public void testUpdate() throws Exception {
        TestModel model = dao.create(TestModel.builder().name("Ian").build());
        dao.update(model.getId(), dao.updateOf(TestModel.builder().name("Rename").build()));
        TestModel change = dao.load(model.getId());
        assertEquals("Rename", change.getName());
    }

    @Test
    public void testUpdateAndReturn() throws Exception {
        TestModel model = dao.create(TestModel.builder().name("Ian").build());
        TestModel prev = dao.updateAndReturn(model.getId(), dao.updateOf(TestModel.builder().name("Rename").build()));
        assertEquals(model, prev);
        TestModel change = dao.load(model.getId());
// Path: stardao-core/src/main/java/io/stardog/stardao/core/Results.java
// @AutoValue
// public abstract class Results<M,N> {
//     @ApiModelProperty(value = "list of results returned", required = true)
//     public abstract List<M> getData();
// 
//     @ApiModelProperty(value = "identifier to return the next item in the sequence")
//     public abstract Optional<N> getNext();
// 
//     public static <M,N> Results<M,N> of(Iterable<M> data) {
//         return new AutoValue_Results<M, N>(ImmutableList.copyOf(data), Optional.empty());
//     }
// 
//     public static <M,N> Results<M,N> of(Iterable<M> data, N next) {
//         return new AutoValue_Results<M, N>(ImmutableList.copyOf(data), Optional.ofNullable(next));
//     }
// }
// 
// Path: stardao-core/src/main/java/io/stardog/stardao/core/Update.java
// @AutoValue
// @JsonDeserialize(using = UpdateDeserializer.class)
// @JsonSerialize(using = UpdateSerializer.class)
// public abstract class Update<P> {
//     public abstract P getPartial();
//     public abstract Set<String> getSetFields();
//     public abstract Set<String> getRemoveFields();
// 
//     public static <T> Update<T> of(T setObject, Set<String> setFields) {
//         return new AutoValue_Update<>(setObject, setFields, ImmutableSet.of());
//     }
// 
//     public static <T> Update<T> of(T setObject, Set<String> setFields, Set<String> removeFields) {
//         return new AutoValue_Update<>(setObject, setFields, removeFields);
//     }
// 
//     public boolean isEmpty() {
//         return getSetFields().isEmpty() && getRemoveFields().isEmpty();
//     }
// 
//     public Set<String> getUpdateFields() {
//         return Sets.union(getSetFields(), getRemoveFields());
//     }
// 
//     public boolean isUpdateField(String field) {
//         return getSetFields().contains(field) || getRemoveFields().contains(field);
//     }
// }


// Path: stardao-dynamodb/src/test/java/io/stardog/stardao/dynamodb/AbstractDynamoDaoTest.java
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.document.Index;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.KeyAttribute;
import com.amazonaws.services.dynamodbv2.document.PrimaryKey;
import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
import com.amazonaws.services.dynamodbv2.document.spec.ScanSpec;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.amazonaws.services.dynamodbv2.local.embedded.DynamoDBEmbedded;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import io.stardog.stardao.core.Results;
import io.stardog.stardao.core.Update;
import org.junit.Before;
import org.junit.Test;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

        assertTrue(dao.checkUniqueField("email", "email", "new@example.com", null));
        assertFalse(dao.checkUniqueField("email", "email", "bob@example.com", null));
        TestModel bob = dao.loadByIndex("email", "email", "bob@example.com");
        assertTrue(dao.checkUniqueField("email", "email", "bob@exmaple.com", bob.getId()));
    }

    @Test
    public void testToCreateItem() throws Exception {
        Instant now = Instant.now();
        UUID creatorId = UUID.randomUUID();
        Item item = dao.toCreateItem(TestModel.builder().name("Ian White").build(), now, creatorId);
        assertNotNull(item.get("id"));
        assertEquals(creatorId.toString(), item.get("createId"));
        assertEquals(new BigDecimal(now.toEpochMilli()), item.get("createAt"));
    }

    @Test
    public void testUpdate() throws Exception {
        TestModel model = dao.create(TestModel.builder().name("Ian").build());
        dao.update(model.getId(), dao.updateOf(TestModel.builder().name("Rename").build()));
        TestModel change = dao.load(model.getId());
        assertEquals("Rename", change.getName());
    }

    @Test
    public void testUpdateAndReturn() throws Exception {
        TestModel model = dao.create(TestModel.builder().name("Ian").build());
        TestModel prev = dao.updateAndReturn(model.getId(), dao.updateOf(TestModel.builder().name("Rename").build()));
        assertEquals(model, prev);
        TestModel change = dao.load(model.getId());
        assertEquals("Rename", change.getName());