From 3789fcb1e3471d0a0f1dfa357aa4c76f79ce0633 Mon Sep 17 00:00:00 2001 From: Lassi Immonen Date: Tue, 14 Sep 2010 13:59:36 +0000 Subject: [PATCH] Added couple of new operators --- .../query/mongodb/MongodbSerializer.java | 210 ++++++++++-------- .../query/mongodb/MongodbSerializerTest.java | 51 ++++- 2 files changed, 162 insertions(+), 99 deletions(-) diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbSerializer.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbSerializer.java index d4fa9cf86..f19daed1b 100644 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbSerializer.java +++ b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbSerializer.java @@ -1,5 +1,12 @@ package com.mysema.query.mongodb; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.bson.BSONObject; + import com.mongodb.BasicDBObject; import com.mysema.query.types.Constant; import com.mysema.query.types.Custom; @@ -15,114 +22,123 @@ import com.mysema.query.types.Visitor; /** * Serializes the given QueryDSL query to a DBObject querty format MongoDB understands. + * * @author laimw - * + * */ public class MongodbSerializer implements Visitor { -// public MongodbSerializer() { -// //BasicDBObject o = new BasicDBObject(); -// //o.append("firstName", "Juuso"); -// -// //o.append("firstName", new BasicDBObject("$ne", "Juuso")); -// //o.append("age", 3); -// } + // public MongodbSerializer() { + // //BasicDBObject o = new BasicDBObject(); + // //o.append("firstName", "Juuso"); + // + // //o.append("firstName", new BasicDBObject("$ne", "Juuso")); + // //o.append("age", 3); + // } - - - public Object handle(Expr where) { - return where.accept(this, null); - } + public Object handle(Expr where) { + return where.accept(this, null); + } - @Override - public Object visit(Constant expr, Void context) { - return expr.getConstant(); - } + @Override + public Object visit(Constant expr, Void context) { + return expr.getConstant(); + } - @Override - public Object visit(Custom expr, Void context) { - // TODO Auto-generated method stub - return null; - } + @Override + public Object visit(Custom expr, Void context) { + // TODO Auto-generated method stub + return null; + } - @Override - public Object visit(FactoryExpression expr, Void context) { - // TODO Auto-generated method stub - return null; - } - - private String leftAsString(Operation expr) { - return (String)expr.getArg(0).accept(this, null); - } - - private Object rightAsObj(Operation expr) { - return expr.getArg(1).accept(this, null); - } + @Override + public Object visit(FactoryExpression expr, Void context) { + // TODO Auto-generated method stub + return null; + } - @Override - public Object visit(Operation expr, Void context) { - Operator op = expr.getOperator(); -// if (op == Ops.OR) { -// return toTwoHandSidedQuery(operation, Occur.SHOULD, metadata); -// } else if (op == Ops.AND) { -// return toTwoHandSidedQuery(operation, Occur.MUST, metadata); -// } else if (op == Ops.NOT) { -// BooleanQuery bq = new BooleanQuery(); -// bq.add(new BooleanClause(toQuery(operation.getArg(0), metadata), Occur.MUST_NOT)); -// return bq; -// } else if (op == Ops.LIKE) { -// return like(operation, metadata); - if (op == Ops.EQ_OBJECT || op == Ops.EQ_PRIMITIVE || op == Ops.EQ_IGNORE_CASE) { - return new BasicDBObject(leftAsString(expr), rightAsObj(expr)); - } - if (op == Ops.AND) { - BasicDBObject left = (BasicDBObject) handle(expr.getArg(0)); - BasicDBObject right = (BasicDBObject) handle(expr.getArg(1)); - left.putAll(right.toMap()); - return left; - } - if (op == Ops.NE_OBJECT || op == Ops.NE_PRIMITIVE) { - return new BasicDBObject(leftAsString(expr), new BasicDBObject("$ne", rightAsObj(expr))); - } -// } else if (op == Ops.STARTS_WITH || op == Ops.STARTS_WITH_IC) { -// return startsWith(metadata, operation); -// } else if (op == Ops.ENDS_WITH || op == Ops.ENDS_WITH_IC) { -// return endsWith(operation, metadata); -// } else if (op == Ops.STRING_CONTAINS || op == Ops.STRING_CONTAINS_IC) { -// return stringContains(operation, metadata); -// } else if (op == Ops.BETWEEN) { -// return between(operation, metadata); -// } else if (op == Ops.IN) { -// return in(operation, metadata); -// } else if (op == Ops.LT || op == Ops.BEFORE) { -// return lt(operation, metadata); -// } else if (op == Ops.GT || op == Ops.AFTER) { -// return gt(operation, metadata); -// } else if (op == Ops.LOE || op == Ops.BOE) { -// return le(operation, metadata); -// } else if (op == Ops.GOE || op == Ops.AOE) { -// return ge(operation, metadata); -// } else if (op == PathType.DELEGATE) { -// return toQuery(operation.getArg(0), metadata); -// } - throw new UnsupportedOperationException("Illegal operation " + expr); - } + private String asString(Operation expr, int index) { + return (String) expr.getArg(index).accept(this, null); + } - @Override - public Object visit(Path expr, Void context) { - return expr.getMetadata().getExpression().toString(); - } + private Object asObj(Operation expr, int index) { + return expr.getArg(index).accept(this, null); + } - @Override - public Object visit(SubQueryExpression expr, Void context) { - // TODO Auto-generated method stub - return null; - } + private BasicDBObject dbo(String key, Object value) { + return new BasicDBObject(key, value); + } - @Override - public Object visit(Param expr, Void context) { - // TODO Auto-generated method stub - return null; + @Override + public Object visit(Operation expr, Void context) { + Operator op = expr.getOperator(); + // if (op == Ops.OR) { + // return toTwoHandSidedQuery(operation, Occur.SHOULD, metadata); + // } else if (op == Ops.NOT) { + // BooleanQuery bq = new BooleanQuery(); + // bq.add(new BooleanClause(toQuery(operation.getArg(0), metadata), Occur.MUST_NOT)); + // return bq; + // } else if (op == Ops.LIKE) { + // return like(operation, metadata); + if (op == Ops.EQ_OBJECT || op == Ops.EQ_PRIMITIVE /* || op == Ops.EQ_IGNORE_CASE */) { + return dbo(asString(expr, 0), asObj(expr, 1)); } + if (op == Ops.AND) { + BasicDBObject left = (BasicDBObject) handle(expr.getArg(0)); + left.putAll((BSONObject) handle(expr.getArg(1))); + return left; + } + if (op == Ops.NE_OBJECT || op == Ops.NE_PRIMITIVE) { + return dbo(asString(expr, 0), dbo("$ne", asObj(expr, 1))); + } + // } else if (op == Ops.STARTS_WITH || op == Ops.STARTS_WITH_IC) { + // return startsWith(metadata, operation); + // } else if (op == Ops.ENDS_WITH || op == Ops.ENDS_WITH_IC) { + // return endsWith(operation, metadata); + // } else if (op == Ops.STRING_CONTAINS || op == Ops.STRING_CONTAINS_IC) { + // return stringContains(operation, metadata); + if (op == Ops.BETWEEN) { + BasicDBObject value = new BasicDBObject("$gt", asObj(expr, 1)); + value.append("$lt", asObj(expr, 2)); + return dbo(asString(expr, 0), value); + } + if (op == Ops.IN) { + Collection values = (Collection) ((Constant) expr.getArg(1)).getConstant(); + return dbo(asString(expr, 0), dbo("$in",values.toArray())); + } + if (op == Ops.LT || op == Ops.BEFORE) { + return dbo(asString(expr, 0), dbo("$lt", asObj(expr, 1))); + } + if (op == Ops.GT || op == Ops.AFTER) { + return dbo(asString(expr, 0), dbo("$gt", asObj(expr, 1))); + } + if (op == Ops.LOE || op == Ops.BOE) { + return dbo(asString(expr, 0), dbo("$lte", asObj(expr, 1))); + } + if (op == Ops.GOE || op == Ops.AOE) { + return dbo(asString(expr, 0), dbo("$gte", asObj(expr, 1))); + } + // } else if (op == PathType.DELEGATE) { + // return toQuery(operation.getArg(0), metadata); + // } + throw new UnsupportedOperationException("Illegal operation " + expr); + } - } \ No newline at end of file + @Override + public Object visit(Path expr, Void context) { + return expr.getMetadata().getExpression().toString(); + } + + @Override + public Object visit(SubQueryExpression expr, Void context) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object visit(Param expr, Void context) { + // TODO Auto-generated method stub + return null; + } + +} \ No newline at end of file diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbSerializerTest.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbSerializerTest.java index 3e7f64630..db3ff6b46 100644 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbSerializerTest.java +++ b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbSerializerTest.java @@ -2,11 +2,19 @@ package com.mysema.query.mongodb; import static junit.framework.Assert.assertEquals; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.bson.BSONObject; import org.junit.Before; import org.junit.Test; import com.mongodb.BasicDBObject; import com.mysema.query.types.Expr; +import com.mysema.query.types.path.PDate; +import com.mysema.query.types.path.PDateTime; import com.mysema.query.types.path.PNumber; import com.mysema.query.types.path.PString; import com.mysema.query.types.path.PathBuilder; @@ -23,6 +31,11 @@ public class MongodbSerializerTest { private PNumber byteField; private PNumber floatField; + private PDate date; + private Date dateVal = new Date(); + private PDateTime dateTime; + private Timestamp dateTimeVal = new Timestamp(System.currentTimeMillis()); + private MongodbSerializer serializer; @Before @@ -36,6 +49,8 @@ public class MongodbSerializerTest { shortField = entityPath.getNumber("shortField", Short.class); byteField = entityPath.getNumber("byteField", Byte.class); floatField = entityPath.getNumber("floatField", Float.class); + date = entityPath.getDate("date", Date.class); + dateTime = entityPath.getDateTime("dateTime", Timestamp.class); } @Test @@ -47,6 +62,9 @@ public class MongodbSerializerTest { assertQuery(shortField.eq((short)1), dbo("shortField", 1)); assertQuery(byteField.eq((byte)1), dbo("byteField", 1L)); assertQuery(floatField.eq(1.0F), dbo("floatField", 1.0F)); + + assertQuery(date.eq(dateVal), dbo("date", dateVal)); + assertQuery(dateTime.eq(dateTimeVal), dbo("dateTime", dateTimeVal)); } @Test @@ -67,14 +85,43 @@ public class MongodbSerializerTest { assertQuery(title.ne("A"), dbo("title", dbo("$ne", "A"))); } + @Test + public void testLessAndGreaterAndBetween() { + + assertQuery(title.lt("A"), dbo("title", dbo("$lt", "A"))); + assertQuery(year.gt(1), dbo("year", dbo("$gt", 1))); + + assertQuery(title.loe("A"), dbo("title", dbo("$lte", "A"))); + assertQuery(year.goe(1), dbo("year", dbo("$gte", 1))); + + assertQuery( + year.gt(1).and(year.lt(10)), + dbo("year", dbo("$gt", 1)). + append("year", dbo("$lt", 10)) + ); + + assertQuery( + year.between(1, 10), + dbo("year", dbo("$gt", 1).append("$lt", 10)) + ); + } + + @Test + public void testIn() { + assertQuery(year.in(1,2,3), dbo("year", dbo("$in", 1,2,3))); + } private void assertQuery(Expr e, BasicDBObject expected) { BasicDBObject result = (BasicDBObject) serializer.handle(e); - assertEquals(expected, result); + assertEquals(expected.toString(), result.toString()); } - private static BasicDBObject dbo(String key, Object value) { + private static BasicDBObject dbo(String key, Object... value) { + if (value.length == 1) { + return new BasicDBObject(key, value[0]); + } + return new BasicDBObject(key, value); }