@@ -19,10 +19,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import com.dateofrock.simpledbmapper.SimpleDBEntity;
import com.dateofrock.simpledbmapper.SimpleDBDomain;
import com.dateofrock.simpledbmapper.SimpleDBMappingException;

/**
@@ -68,13 +66,13 @@ public void setSort(Sort sort) {
/**
* @param limit
* 戻り値の最大数。SimpleDBの制限より設定できる最大値は2500(
* {@link SimpleDBEntity#MAX_QUERY_LIMIT})になります。
* {@link SimpleDBDomain#MAX_QUERY_LIMIT})になります。
*/
public void setLimit(int limit) {
if (limit < 0) {
throw new IllegalArgumentException("limitは1以上である必要があります");
}
if (limit > SimpleDBEntity.MAX_QUERY_LIMIT) {
if (limit > SimpleDBDomain.MAX_QUERY_LIMIT) {
String message = String.format("SimpleDBでサポートされる最大Limit数は2500です。指定されたlimit(=%s)は多すぎます。", limit);
throw new IllegalArgumentException(message);
}
@@ -85,18 +83,18 @@ public int getLimit() {
return this.limit;
}

public String whereExpressionString() {
public String describe() {
List<String> attributeNames = new ArrayList<String>();

StringBuilder expression = new StringBuilder();
expression.append(this.defaultCondition.expression()).append(" ");
expression.append(this.defaultCondition.describe()).append(" ");
attributeNames.add(this.defaultCondition.getAttributeName());

for (Map<String, Condition> conditionMap : this.conditions) {
for (String key : conditionMap.keySet()) {
expression.append(key).append(" ");
Condition condition = conditionMap.get(key);
expression.append(condition.expression());
expression.append(condition.describe());
expression.append(" ");
attributeNames.add(condition.getAttributeName());
}
@@ -107,7 +105,7 @@ public String whereExpressionString() {
throw new SimpleDBMappingException(
"The sort attribute must be present in at least one of the predicates of the expression. sortする場合、conditionにソートするキーを含める必要があります。これはSimpleDBの仕様です。http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/SortingDataSelect.html");
}
expression.append(this.sort.stringExpression());
expression.append(this.sort.describe());
}
return expression.toString();
}
@@ -0,0 +1,98 @@
/*
* Copyright 2012 Takehito Tanabe (dateofrock at gmail dot com)
*
* 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 com.dateofrock.simpledbmapper.query;

import java.util.List;

import com.dateofrock.simpledbmapper.SimpleDBMapper;

/**
* @author Takehito Tanabe (dateofrock at gmail dot com)
*/
public class QueryExpressionBuilder<T> {

private Class<T> clazz;
private QueryExpression expression;
private SimpleDBMapper mapper;

public QueryExpressionBuilder(Class<T> clazz, SimpleDBMapper mapper) {
this.clazz = clazz;
this.mapper = mapper;
}

public QueryExpressionBuilder<T> where(String attributeName, ComparisonOperator comparisonOperator,
Object attributeValue) {
Condition condition = new Condition(attributeName, comparisonOperator, attributeValue);
this.expression = new QueryExpression(condition);
return this;
}

public QueryExpressionBuilder<T> and(String attributeName, ComparisonOperator operator, Object attributeValue) {
Condition cond = new Condition(attributeName, operator, attributeValue);
this.expression.addAndCondtion(cond);
return this;
}

public QueryExpressionBuilder<T> or(String attributeName, ComparisonOperator operator, Object attributeValue) {
Condition cond = new Condition(attributeName, operator, attributeValue);
this.expression.addOrCondition(cond);
return this;
}

public QueryExpressionBuilder<T> intersection(String attributeName, ComparisonOperator operator,
Object attributeValue) {
Condition cond = new Condition(attributeName, operator, attributeValue);
this.expression.addIntersectionCondition(cond);
return this;
}

public QueryExpressionBuilder<T> orderBy(String attributeName) {
Sort sort = new Sort(attributeName);
this.expression.setSort(sort);
return this;
}

public QueryExpressionBuilder<T> orderBy(String attributeName, Ordering ordering) {
Sort sort = new Sort(ordering, attributeName);
this.expression.setSort(sort);
return this;
}

public QueryExpressionBuilder<T> limit(int limit) {
this.expression.setLimit(limit);
return this;
}

public QueryExpressionBuilder<T> eagerBlobFetch(String... blobAttributeNames) {
for (String blobAttributeName : blobAttributeNames) {
this.mapper.addEagerBlobFetch(blobAttributeName);
}
return this;
}

// public QueryExpressionBuilder<T> offset(int offset) {
// return this;
// }

public List<T> fetch() {
return this.mapper.select(this.clazz, this.expression);
}

public int count() {
return this.mapper.count(this.clazz, this.expression);
}

}
@@ -41,7 +41,7 @@ public String getAttributeName() {
return this.attributeName;
}

String stringExpression() {
public String describe() {
StringBuilder expression = new StringBuilder("order by ");
if (this.attributeName.equalsIgnoreCase("itemName()")) {
expression.append(this.attributeName);
@@ -15,10 +15,9 @@
*/
package com.dateofrock.simpledbmapper;

import static com.dateofrock.simpledbmapper.query.ComparisonOperator.Equals;
import static com.dateofrock.simpledbmapper.query.ComparisonOperator.Like;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static com.dateofrock.simpledbmapper.query.ComparisonOperator.*;
import static com.dateofrock.simpledbmapper.query.Ordering.*;
import static org.junit.Assert.*;

import java.io.InputStream;
import java.text.ParseException;
@@ -121,32 +120,41 @@ public void test() throws Exception {
int count = this.mapper.count(Book.class, expression);
assertEquals(1, count);

count = this.mapper.from(Book.class).where("title", Equals, "ドン引きの美学").count();
assertEquals(1, count);

expression = new QueryExpression(new Condition("title", Like, "%美学"));
count = this.mapper.count(Book.class, expression);
assertEquals(1, count);

expression = new QueryExpression(new Condition("publishedAt", ComparisonOperator.GreaterThan,
toDate("2000-1-1 00:00:00")));
expression = new QueryExpression(new Condition("publishedAt", GreaterThan, toDate("2000-1-1 00:00:00")));
Sort sort = new Sort(Ordering.ASC, "publishedAt");
expression.setSort(sort);

this.mapper.addEagerBlobFetch("coverImage");
List<Book> books = this.mapper.select(Book.class, expression);
assertBook(book1, books.get(0), true);
assertBook(book2, books.get(1), true);

sort = new Sort(Ordering.DESC, "publishedAt");
books = this.mapper.from(Book.class).where("publishedAt", GreaterThan, toDate("2000-1-1 00:00:00"))
.orderBy("publishedAt").eagerBlobFetch("coverImage", "review").fetch();
assertBook(book1, books.get(0), true);
assertBook(book2, books.get(1), true);

sort = new Sort(DESC, "publishedAt");
expression.setSort(sort);

books = this.mapper.select(Book.class, expression);
assertBook(book1, books.get(1), true);
assertBook(book2, books.get(0), true);

expression = new QueryExpression(new Condition("publishedAt", ComparisonOperator.GreaterThan,
toDate("2000-1-1 00:00:00")));
expression
.addAndCondtion(new Condition("publishedAt", ComparisonOperator.LessThan, toDate("2100-1-1 00:00:00")));
sort = new Sort(Ordering.ASC, "publishedAt");
books = this.mapper.from(Book.class).where("publishedAt", GreaterThan, toDate("2000-1-1 00:00:00"))
.orderBy("publishedAt", DESC).limit(10).fetch();
assertBook(book1, books.get(1), true);
assertBook(book2, books.get(0), true);

expression = new QueryExpression(new Condition("publishedAt", GreaterThan, toDate("2000-1-1 00:00:00")));
expression.addAndCondtion(new Condition("publishedAt", LessThan, toDate("2100-1-1 00:00:00")));
sort = new Sort(ASC, "publishedAt");
expression.setSort(sort);
books = this.mapper.select(Book.class, expression);
assertBook(book1, books.get(0), true);
@@ -21,7 +21,7 @@
import com.dateofrock.simpledbmapper.SimpleDBAttribute;
import com.dateofrock.simpledbmapper.SimpleDBBlob;
import com.dateofrock.simpledbmapper.SimpleDBBlob.FetchType;
import com.dateofrock.simpledbmapper.SimpleDBEntity;
import com.dateofrock.simpledbmapper.SimpleDBDomain;
import com.dateofrock.simpledbmapper.SimpleDBItemName;
import com.dateofrock.simpledbmapper.SimpleDBVersionAttribute;

@@ -30,7 +30,7 @@
*
* @author Takehito Tanabe (dateofrock at gmail dot com)
*/
@SimpleDBEntity(domainName = "SimpleDBMapper-Book", s3BucketName = "dateofrock-testing", s3KeyPrefix = "simpledb-mapper/")
@SimpleDBDomain(domainName = "SimpleDBMapper-Book", s3BucketName = "dateofrock-testing", s3KeyPrefix = "simpledb-mapper/")
public class Book {

@SimpleDBItemName
@@ -17,14 +17,14 @@

import java.util.Set;

import com.dateofrock.simpledbmapper.SimpleDBEntity;
import com.dateofrock.simpledbmapper.SimpleDBDomain;

/**
* テスト用モデル
*
* @author Takehito Tanabe (dateofrock at gmail dot com)
*/
@SimpleDBEntity(domainName = "SimpleDBMapper-Book", s3BucketName = "dateofrock-testing", s3KeyPrefix = "simpledb-mapper/")
@SimpleDBDomain(domainName = "SimpleDBMapper-Book", s3BucketName = "dateofrock-testing", s3KeyPrefix = "simpledb-mapper/")
public class BookSubClass extends Book {

public Set<String> tags;