diff --git a/formatter.xml b/formatter.xml new file mode 100644 index 0000000..d792987 --- /dev/null +++ b/formatter.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index a9da086..d4d5b6d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ org.objectquery objectquery - 1.0.2-SNAPSHOT + 1.5.0-SNAPSHOT jar objectquery diff --git a/site/.gitignore b/site/.gitignore new file mode 100644 index 0000000..d47428b --- /dev/null +++ b/site/.gitignore @@ -0,0 +1,2 @@ +javadoc +tutorials diff --git a/site/changelog_1_0_0.html b/site/changelog_1_0_0.html new file mode 100644 index 0000000..0ab175a --- /dev/null +++ b/site/changelog_1_0_0.html @@ -0,0 +1,23 @@ + + + + +
1.0.0
+
+
+ * Main Implementation of Object Query Engine
+ * Support of projections
+	- Simple
+	- Grouping Min Max Avg Sum Count
+ * Support of Conditions
+	- Simple
+	- Grouping And Or
+ * Support of Orders
+ * Support of Having
+ * Implemented JPA Object Query
+ * Implemented JDO Object Query
+ * Implemented OrientDB Object Query
+
+
+ + diff --git a/site/changelog_1_0_1.html b/site/changelog_1_0_1.html new file mode 100644 index 0000000..4fee036 --- /dev/null +++ b/site/changelog_1_0_1.html @@ -0,0 +1,13 @@ + + + + +
1.0.1
+
+
+ * Implemented BETWEEN operator
+ * Fix paramenter name generation with a path longer than 2 item
+
+
+ + diff --git a/site/changelog_1_5_0.html b/site/changelog_1_5_0.html new file mode 100644 index 0000000..4c01286 --- /dev/null +++ b/site/changelog_1_5_0.html @@ -0,0 +1,15 @@ + + + + +
1.5.0
+
+
+ * Renamed wrong named condition functions and deprecated the old
+ * Add support of subquery with relative capable implementations
+ * Add support of join with relative capable implementions
+ * Implemented Hibernate Object Query
+
+
+ + diff --git a/site/doc.html b/site/doc.html new file mode 100644 index 0000000..eed512c --- /dev/null +++ b/site/doc.html @@ -0,0 +1,154 @@ +
+

Documentation

+
+
+

Tutorials

+
+ Simple Tutorial
+ Video Tutorials
+ Javadocs: 1.0.0 , 1.0.1 , 1.5.0 +
+
+
+

Install By Maven

+
+

+ Insert the specify maven dependency for each implementation:

+ JPA: +

+<dependency>
+	<groupId>org.objectquery</groupId>
+	<artifactId>jpaobjectquery</artifactId>
+	<version>1.5.0</version>
+</dependency>
+
+ JDO: +
+<dependency>
+	<groupId>org.objectquery</groupId>
+	<artifactId>jdoobjectquery</artifactId>
+	<version>1.5.0</version>
+</dependency>
+
+ OrientDB: +
+<dependency>
+	<groupId>org.objectquery</groupId>
+	<artifactId>orientdbobjectquery</artifactId>
+	<version>1.5.0</version>
+</dependency>
+
+ Hibernate: +
+<dependency>
+	<groupId>org.objectquery</groupId>
+	<artifactId>hibernateobjectquery</artifactId>
+	<version>1.5.0</version>
+</dependency>
+
+

+
+
+ +
+

Query Engine Support

+
+ JPA +

+ Direct execute: +

+javax.persistence.EntityManager entityManager= ....
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+List<Person> res = (List<Person>)JPAObjectQuery.execute(query, entityManager);
+...
+
+ JPA query generation: +
+javax.persistence.EntityManager entityManager= ....
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+javax.persistence.Query jpaQuery = JPAObjectQuery.buildQuery(query, entityManager);
+...
+
+ JPQL string and parameters generation: +
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+JPQLQueryGenerator jpqlGenerator = JPAObjectQuery.jpqlGenerator(query);
+String jpql = jpqlGenerator.getQuery();
+Map<String,Object> paramenters = jpqlGenerator.getParameters();
+...
+
+

+ JDO +

+ Direct execute: +

+javax.jdo.PersistenceManager peristenceManager= ....
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+List<Person> res = (List<Person>)JDOObjectQuery.execute(query, peristenceManager);
+...
+
+ JDOQL string and parameters generation: +
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+JDOQLQueryGenerator jdoqlGenerator = JDOObjectQuery.jdoqlGenerator(query);
+String jpql = jdoqlGenerator.getQuery();
+Map<String,Object> paramenters = jdoqlGenerator.getParameters();
+...
+
+

+ OrientDB +

+ Direct execute: +

+com.orientechnologies.orient.object.db.OObjectDatabaseTx db= ....
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+List<Person> res = (List<Person>)OrientDBObjectQuery.execute(query, db);
+...
+
+ OrientDB Query string and parameters generation: +
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+OrientDBQueryGenerator oriendbGenerator = OrientDBObjectQuery.oriendbGenerator(query);
+String orientdbql = oriendbGenerator.getQuery();
+Map<String,Object> paramenters = oriendbGenerator.getParameters();
+...
+
+

+
+ Hibernate +

+ Direct execute: +

+org.hibernate.Session session= ....
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+List<Person> res = (List<Person>)HibernateObjectQuery.execute(query, session);
+...
+
+ Hibernate query generation: +
+org.hibernate.Session session= ....
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+org.hibernate.Query jpaQuery = HibernateObjectQuery.buildQuery(query, session);
+...
+
+ HQL string and parameters generation: +
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+...
+HQLQueryGenerator hqlGenerator = HibernateObjectQuery.hqlGenerator(query);
+String hql = hqlGenerator.getQuery();
+Map<String,Object> paramenters = hqlGenerator.getParameters();
+...
+
+

+
+
diff --git a/site/img/logo2.png b/site/img/logo2.png new file mode 100644 index 0000000..6e8dc68 Binary files /dev/null and b/site/img/logo2.png differ diff --git a/site/img/logo2.xcf b/site/img/logo2.xcf new file mode 100644 index 0000000..69e69d4 Binary files /dev/null and b/site/img/logo2.xcf differ diff --git a/site/img/texture2.png b/site/img/texture2.png new file mode 100644 index 0000000..6c19be6 Binary files /dev/null and b/site/img/texture2.png differ diff --git a/site/img/texture2.xcf b/site/img/texture2.xcf new file mode 100644 index 0000000..329a0ba Binary files /dev/null and b/site/img/texture2.xcf differ diff --git a/site/index.php b/site/index.php index fc2e148..c6ab880 100644 --- a/site/index.php +++ b/site/index.php @@ -1,10 +1,12 @@ - +"roadmap","doc"=>"doc","support"=>"support","tutorial-simple"=>"tutorial-simple","vtutorial"=>"vtutorial"); +?> - + Object Query @@ -63,393 +65,24 @@ function handleClick(event) } - +
- +
-
> -
-

Overview

-
-
-
-

What Is

-
-

- Object Query is a simple query builder thought for java, that allow to write typesafe and refactor resistant query, without bound to persistence engine. -

-
-
-
-

License

-
-

- The Apache Software License, Version 2.0 -

-
-
-
-

Support

-
-

- issue tracker:https://github.com/organizations/objectquery/dashboard/issues -

-

- mailing list:https://groups.google.com/group/objectquery -

-

- source:https://github.com/organizations/objectquery -

-

-
-

Roadmap

-

1.0.0

- - - - - - - -
base select statement DONE
projections with grouping functions DONE
conditions and nested conditions DONE
order by with grouping functions DONE
having clause JPA Only
ignore case like condition type DONE
-

1.5.0

- - - -
Nested Query TODO
Join TODO
-

2.0.0

- - - - -
support for update operation TODO
support for delete operation TODO
support for insert operation TODO
-
-
-
> -
-

Install

-
-
-
-

Maven

-
-

- Insert the specify maven dependency for each implementation:

- JPA: -

-<dependency>
-	<groupId>org.objectquery</groupId>
-	<artifactId>jpaobjectquery</artifactId>
-	<version>1.0.0</version>
-</dependency>
-
- JDO: -
-<dependency>
-	<groupId>org.objectquery</groupId>
-	<artifactId>jdoobjectquery</artifactId>
-	<version>1.0.0</version>
-</dependency>
-
- OrientDB: -
-<dependency>
-	<groupId>org.objectquery</groupId>
-	<artifactId>orientdbobjectquery</artifactId>
-	<version>1.0.0</version>
-</dependency>
-
-

-
-
-
> -
-

Build A query

-
- -
-
-

Requirements

-
-

- The requirements for build a query with query builder is an java Object Oriented "Domain" that is an group of persisted objects. -

-
-
-
-

Domain

-
-

-

-public class Dog {
-	private String name;
-	private Person owner;
-	private Home home;
-	...gets sets...
-};
-
-
-public class Person {
-	private String name;
-	private List<Person> friends;
-	private Person mum;
-	private Person dud;
-	private Home home;
-	private Dog dog;
-	...gets sets...
-}
-
-
-public class Home {
-	public enum HomeType {KENNEL,HOUSE};
-	private String address;
-	private HomeType type;
-	private int weight;
-	private double price;
-	...gets sets...
-}
-
-

-
-
-
-

Simple Query Building

-
-

- Search All person that live in "rue d'anton" with a mum with name "elisabeth" and order by name. -

-
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-Person toSearch = query.target();
-query.eq(toSearch.getHome().getAddress(),"rue d'anton");
-query.eq(toSearch.getMum().getName(),"elisabeth");
-query.order(toSearch.getName());
-
-
-
-
-

Projection

-
-

- Select name and address of person. -

-
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-Person toSearch = query.target();
-query.prj(toSearch.getName());
-query.prj(toSearch.getHome().getAddress());
-
-
-
-
-

Grouping Functions

-

-

- Count all person that live in "rue d'anton" -

-
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-Person toSearch = query.target();
-query.prj(toSearch,ProjectionType.COUNT);
-query.eq(toSearch.getHome().getAddress(),"rue d'anton");
-
-
-
-
-

Condition group -

-

- Search all person with name elisabeth or jhon. -

-
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-Person toSearch = query.target();
-QueryCondition or = oq.or();
-or.eq(toSearch.getName(),"elisabeth");
-or.eq(toSearch.getName(),"jhon");
-
-
-
-
-

Primitive Type

-
-

Primitive type need a different management, for some technical reasons is not possible use primitive type directly
for use it we need to box it

-
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-Person toSearch = query.target();
-query.eq(query.box(toSearch.getWeight()),2);
-query.eq(query.box(toSearch.getPrice()),4000.0);
-
-
-
-
-

Condition Operator

-
- - - - - - - - - - - - - - - - - -
OperatorImplementation
JPAJDOOrientDb
eqokokok
notEqokokok
likeokokok
notLikeokokok
minokokok
minEqokokok
maxokokok
maxEqokokok
inokokok
notInokokok
containsokokok
notContainsokokok
orokokok
andokokok
-
-
-
-

Projection

-
- - - - - - - -
OperatorImplementation
JPAJDOOrientDb
MAXokokok
MINokokok
AVGokokok
COUNTokokok
-
-
-
-

Order Operator

-
- - - - - -
OperatorImplementation
JPAJDOOrientDb
ASCokokok
DESCokokok
-
-
-
-

Having Operator

-
- Projection - - - - - - - -
OperatorImplementation
JPAJDOOrientDb
MAXokkoko
MINokkoko
AVGokkoko
COUNTokkoko
- Condition Operator - - - - - - - - - - - - - - - - - -
OperatorImplementation
JPAJDOOrientDb
eqokkoko
notEqokkoko
likeokkoko
notLikeokkoko
minokkoko
minEqokkoko
maxokkoko
maxEqokkoko
inokkoko
notInokkoko
containsokkoko
notContainsokkoko
orokkoko
andokkoko
-
-
-
> -
-

Query Engine Support

-
-
-

JPA

-

- Direct execute: -

-javax.persistence.EntityManager entityManager= ....
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-...
-List<Person> res = (List<Person>)JPAObjectQuery.execute(query, entityManager);
-...
-
- JPA query generation: -
-javax.persistence.EntityManager entityManager= ....
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-...
-javax.persistence.Query jpaQuery = JPAObjectQuery.buildQuery(query, entityManager);
-...
-
- JPQL string and parameters generation: -
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-...
-JPQLQueryGenerator jpqlGenerator = JPAObjectQuery.jpqlGenerator(query);
-String jpql = jpqlGenerator.getQuery();
-Map<String,Object> paramenters = jpqlGenerator.getParameters();
-...
-
-

-
-
-

JDO

-

- Direct execute: -

-javax.jdo.PersistenceManager peristenceManager= ....
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-...
-List<Person> res = (List<Person>)JDOObjectQuery.execute(query, peristenceManager);
-...
-
- JDOQL string and parameters generation: -
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-...
-JDOQLQueryGenerator jdoqlGenerator = JDOObjectQuery.jdoqlGenerator(query);
-String jpql = jdoqlGenerator.getQuery();
-Map<String,Object> paramenters = jdoqlGenerator.getParameters();
-...
-
-

-
-
-

OrientDB

-

- Direct execute: -

-com.orientechnologies.orient.object.db.OObjectDatabaseTx db= ....
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-...
-List<Person> res = (List<Person>)OrientDBObjectQuery.execute(query, db);
-...
-
- OrientDB Query string and parameters generation: -
-ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
-...
-OrientDBQueryGenerator oriendbGenerator = OrientDBObjectQuery.oriendbGenerator(query);
-String orientdbql = oriendbGenerator.getQuery();
-Map<String,Object> paramenters = oriendbGenerator.getParameters();
-...
-
-

-
-
-
+ diff --git a/site/overview.html b/site/overview.html new file mode 100644 index 0000000..9310a48 --- /dev/null +++ b/site/overview.html @@ -0,0 +1,30 @@ +
+
+

Overview

+
+
+
+

What Is

+
+

+ Object Query is a simple query builder thought for java, that allow to write typesafe and refactor resistant query, without bound to persistence engine. +

+
+
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+Person toSearch = query.target();
+query.prj(toSearch.getName());
+query.eq(toSearch.getMum().getName(),"elisabeth");
+query.gt(toSearch.getAge(),20);
+query.order(toSearch.getName());
+
+
+
+
+

License

+
+

+ The Apache Software License, Version 2.0 +

+
+
diff --git a/site/roadmap.html b/site/roadmap.html new file mode 100644 index 0000000..e3ebe3c --- /dev/null +++ b/site/roadmap.html @@ -0,0 +1,99 @@ +
+

Roadmap

+
+

Engine Status

+

1.0.0 => changelog

+ + + + + + + +
base select statement DONE
projections with grouping functions DONE
conditions and nested conditions DONE
order by with grouping functions DONE
having clause PARTIAL DONE
ignore case like condition type DONE
+

1.0.1 => changelog

+

1.5.0 => changelog

+ + + +
Nested Query DONE
Join DONE
+

2.0.0

+ + + + +
support for update operation TODO
support for delete operation TODO
support for insert operation TODO
+
+
+

Implementations Status Grid

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureEngineJPAJDOHibernateOrientDB
Projectionsimplequery.prj(target.getName())okokokokok
maxquery.prj(target.getName(),ProjectionType.MAX)
minquery.prj(target.getName(),ProjectionType.MIN)
countquery.prj(target.getName(),ProjectionType.COUNT)
avgquery.prj(target.getName(),ProjectionType.AVG)
sumquery.prj(target.getName(),ProjectionType.SUM)
ConditionSimpleeqquery.eq(target.getName(),"name")okokokokok
notEqquery.notEq(target.getName(),"name")
gtquery.gt(target.getAge(),20)
gtEqquery.gtEq(target.getAge(),20)
ltquery.lt(target.getAge(),20)
ltEqquery.ltEq(target.getAge(),20)
inquery.in(target.getAge(),collection)
notInquery.notIn(target.getAge(),collection)
containsquery.contains(target.getAge(),collection)
notContainsquery.notContains(target.getAge(),collection)
likequery.like(target.getAge(),likeStrin)
notLikequery.notLike(target.getAge(),likeString)
likeNoCasequery.likeNc(target.getAge(),likeString)
notLikeNoCasequery.notLikeNc(target.getAge(),likeString)
groupANDquery.and()okokokokok
ORquery.or()
OrderASCquery.order(target.getName())okokokokok
DESCquery.order(target.getName(),OrderType.DESC)
ASC/DESC ProjectionTypequery.order(target.getName(),ProjectionType.COUNT,OrderType.ASC)
FeatureEngineJPAJDOHibernateOrientDB
HavingGroup Operationmaxquery.having(target.getAge(),ProjectionType.MAX)okokkookko
minquery.having(target.getAge(),ProjectionType.MIN)
countquery.having(target.getAge(),ProjectionType.COUNT)
avgquery.having(target.getAge(),ProjectionType.AVG)
sumquery.having(target.getAge(),ProjectionType.SUM)
Conditioneqquery.having(target.getAge(),ProjectionType.MAX).eq(10)ok partialokpartialok partial
notEqquery.having(target.getAge(),ProjectionType.MAX).notEq(10)
gtquery.having(target.getAge(),ProjectionType.MAX).gt(20)
gtEqquery.having(target.getAge(),ProjectionType.MAX).gtEq(20)
ltquery.having(target.getAge(),ProjectionType.MAX).lt(20)
ltEqquery.having(target.getAge(),ProjectionType.MAX).ltEq(20)
inkokoko
notIn
contains
notContains
like
notLike
likeNoCase
notLikeNoCase
AND
OR
Joininnerquery.join(Person.class)okkokokoko
leftquery.join(Person.class,JoinType.LEFT)
rightquery.join(Person.class,JoinType.RIGHT)
outerquery.join(Person.class,JoinType.OUTER)
inner pathquery.join(target.getMom(),Person.class)okok
left pathquery.join(target.getMom(),Person.class,JoinType.LEFT)
right pathquery.join(target.getMom(),Person.class,JoinType.RIGHT)
outer pathquery.join(target.getMom(),Person.class,JoinType.OUTER)
SubqueryCan Add Subquery Inprojectionquery.prj(subquery)okkokookko
fromkokoko
conditionquery.eq(target.getMom(),subquery)okokok
havingquery.having(subquery,ProjectType.MAX)okkoko
orderquery.order(subquery,OrderType.ASC)okkoko
Can Add to A Subqueryprojectionquery.prj(subquery)kokoko
fromkokoko
conditionquery.eq(target.getMom())okokok
havingquery.having(target.getAge(),ProjectType.MAX)okokok
orderquery.order(target.getName(),OrderType.ASC)okokok
+
+
+ diff --git a/site/style.css b/site/style.css index 5926ef3..4242b54 100644 --- a/site/style.css +++ b/site/style.css @@ -6,11 +6,11 @@ html ,body{ } body { color:#35420D; - background-image:url('img/texture.png'); + background-image:url('img/texture2.png'); } body >header >img { - width:10%; + width:10em; } nav { padding-top:2em; @@ -21,7 +21,7 @@ nav { } nav ul a{ text-decoration:none; - color:#35420D; + color:#2b2b2a; } nav ul { width:100%; @@ -44,6 +44,9 @@ nav li:hover { font-weight:900; } +section >header { + text-align:center; +} section >header, section > p, article { padding: 1em; } @@ -69,7 +72,7 @@ footer { bottom:0; z-index:-1; background:white; - margin:0.5em 0; +2 margin:0.5em 0; } footer >div { width: 25em; @@ -81,24 +84,32 @@ footer >div { top:0; height:1em; } +.v_tutorial { + float:left; + margin:1em; + dislpay:block; + +} .roadmap{ min-width:30em; padding:0; } -.roadmap,.roadmap td { +.roadmap,.roadmap td ,.roadmap th { border:solid 1px #35420D; } -.roadmap td { +.roadmap td,.roadmap th { padding:0.2em; } .road_done,.road_todo { width:5em; } -.road_done, .supported{ +.road_done, .supported, .sup{ background-color:#5BB75B; + text-align:center; } -.road_todo, .unsupported{ +.road_todo, .unsupported, .unsup{ background-color:#DA4F49; + text-align:center; } .condition_table { width:50%; @@ -108,3 +119,18 @@ footer >div { font-weight:bold; text-align:center; } + + +@media only screen +and (max-device-width : 480px) { + + body >header >img { + width:4em; + position:absolute; + top:0; + } + nav { + float:clear; + } + +} diff --git a/site/support.html b/site/support.html new file mode 100644 index 0000000..fa724f5 --- /dev/null +++ b/site/support.html @@ -0,0 +1,17 @@ +
+

Support

+
+

+ Issue Tracker:https://github.com/organizations/objectquery/dashboard/issues +

+

+ Mailing List: list@objectquery.org register +

+

+ Source:https://github.com/organizations/objectquery +

+

+ IRC:#objectquery +

+

+
diff --git a/site/tutorial-simple.html b/site/tutorial-simple.html new file mode 100644 index 0000000..453279a --- /dev/null +++ b/site/tutorial-simple.html @@ -0,0 +1,150 @@ +
+
+

Simple Tutorial

+
+ +
+
+

Requirements

+
+

+ The requirements for build a query with query builder is an java Object Oriented "Domain" that is an group of persisted objects. +

+
+
+
+

Domain

+
+

+

+public class Dog {
+	private String name;
+	private Person owner;
+	private Home home;
+	...gets sets...
+};
+
+
+public class Person {
+	private String name;
+	private List<Person> friends;
+	private Person mum;
+	private Person dud;
+	private Home home;
+	private Dog dog;
+	...gets sets...
+}
+
+
+public class Home {
+	public enum HomeType {KENNEL,HOUSE};
+	private String address;
+	private HomeType type;
+	private int weight;
+	private double price;
+	...gets sets...
+}
+
+

+
+
+
+

Simple Query Building

+
+

+ Search All person that live in "rue d'anton" with a mum with name "elisabeth" and order by name. +

+
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+Person toSearch = query.target();
+query.eq(toSearch.getHome().getAddress(),"rue d'anton");
+query.eq(toSearch.getMum().getName(),"elisabeth");
+query.order(toSearch.getName());
+
+

+ Correspondent Pseudo QL +

+
+select from Person where home.address="rue d'anton" and mum.name="elisabeth" order by name
+
+
+
+
+

Projection

+
+

+ Select name and address of person. +

+
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+Person toSearch = query.target();
+query.prj(toSearch.getName());
+query.prj(toSearch.getHome().getAddress());
+
+

+ Correspondent Pseudo QL +

+
+select name, home.address from Person 
+
+
+
+
+

Grouping Functions

+

+

+ Count all person that live in "rue d'anton" +

+
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+Person toSearch = query.target();
+query.prj(toSearch,ProjectionType.COUNT);
+query.eq(toSearch.getHome().getAddress(),"rue d'anton");
+
+

+ Correspondent Pseudo QL +

+
+select count(*) from Person where home.address="rue d'anton" 
+
+
+
+
+

Condition group +

+

+ Search all person with name elisabeth or jhon. +

+
+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+Person toSearch = query.target();
+QueryCondition or = oq.or();
+or.eq(toSearch.getName(),"elisabeth");
+or.eq(toSearch.getName(),"jhon");
+
+

+ Correspondent Pseudo QL +

+
+select from Person where name="elisabeth" or name="jhon"
+
+
+
+
+

Primitive Type

+
+

Primitive type need a different management, for some technical reasons is not possible use primitive type directly
for use it we need to box it

+
+ObjectQuery<Home> query = new GenericObjectQuery<Home>(Home.class);
+Home toSearch = query.target();
+query.eq(query.box(toSearch.getWeight()),2);
+query.eq(query.box(toSearch.getPrice()),4000.0);
+
+

+ Correspondent Pseudo QL +

+
+select from Home where weight=2 and price=4000.0
+
+
+
diff --git a/site/tutorial.html b/site/tutorial.html new file mode 100644 index 0000000..5ccd160 --- /dev/null +++ b/site/tutorial.html @@ -0,0 +1,17 @@ +
+

Tutorials

+
+
+

JPA Start tutorial

+
+

Video tutorial

+

All tutorial files

+
+
+
+

OrientDB Start tutorial

+
+

Video tutorial

+

All tutorial files

+
+
diff --git a/site/vtutorial.html b/site/vtutorial.html new file mode 100644 index 0000000..c08b93f --- /dev/null +++ b/site/vtutorial.html @@ -0,0 +1,16 @@ +
+

Video Tutorials

+
+
+

JPA Start Video tutorial:

+ +

Download the sample code

+
+
+

OrientDB Start Video tutorial:

+ +

Download the sample code

+
+
+
+
diff --git a/src/main/java/org/objectquery/ObjectQuery.java b/src/main/java/org/objectquery/ObjectQuery.java index 31514a2..f016cee 100644 --- a/src/main/java/org/objectquery/ObjectQuery.java +++ b/src/main/java/org/objectquery/ObjectQuery.java @@ -1,5 +1,6 @@ package org.objectquery; +import org.objectquery.generic.JoinType; import org.objectquery.generic.OrderType; import org.objectquery.generic.ProjectionType; @@ -16,17 +17,14 @@ *

*
Example Of Usage
* - *
- * 
- * ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
- * Person toSearch = query.target();
- * query.prj(toSearch.getName());
- * query.eq(toSearch.getMum().getName(),"elisabeth");
- * query.gt(toSearch.getAge(),20);
- * query.order(toSearch.getName());
- * 
- * 
- * + *

+ObjectQuery<Person> query = new GenericObjectQuery<Person>(Person.class);
+Person toSearch = query.target();
+query.prj(toSearch.getName());
+query.eq(toSearch.getMum().getName(),"elisabeth");
+query.gt(toSearch.getAge(),20);
+query.order(toSearch.getName());
+
*

* The main implementation is GenericObjecQuery but is not garantee that will be * the same in future, we suggest to box the creation of ObjectQuery instances @@ -177,4 +175,53 @@ public interface ObjectQuery extends QueryCondition { * @return the having condition manager. */ HavingCondition having(Object projection, ProjectionType type); + + /** + * Create a new Sub Query of current query. + * + * @param target + * class target of sub query. + * @return the ObjectQuery instance of sub query. + */ + ObjectQuery subQuery(Class target); + + /** + * Create a join object with the specified type + * + * @param joinClass + * the type of the join object. + * @return the new join object. + */ + J join(Class joinClass); + + /** + * Create a join object with the specified type + * + * @param joinClass + * the type of the join object. + * @return the new join object. + */ + J join(Class joinClass, JoinType type); + + /** + * Create a join object with the specified type, on the specified base path + * + * @param joinPath + * the path to reach the base object. + * @param joinClass + * the type of the join object. + * @return the new join object. + */ + J join(J joinPath, Class joinClass); + + /** + * Create a join object with the specified type, on the specified base path + * + * @param joinPath + * the path to reach the base object. + * @param joinClass + * the type of the join object. + * @return the new join object. + */ + J join(J joinPath, Class joinClass, JoinType type); } diff --git a/src/main/java/org/objectquery/QueryCondition.java b/src/main/java/org/objectquery/QueryCondition.java index e7fceda..52c7036 100644 --- a/src/main/java/org/objectquery/QueryCondition.java +++ b/src/main/java/org/objectquery/QueryCondition.java @@ -15,7 +15,17 @@ public interface QueryCondition { void eq(C target, T value); /** - * Add an not equal condition between two values. + * Add an equal condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void eq(C target, ObjectQuery value); + + /** + * Add a not equal condition between two values. * * @param target * the base operation target. @@ -25,47 +35,186 @@ public interface QueryCondition { void notEq(C target, T value); /** - * Add an max condition between two values. + * Add a not equal condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void notEq(C target, ObjectQuery value); + + /** + * Add a "grater than" condition between two values. + * + * @param target + * the base operation target. + * @param value + * the operation expected value. + */ + void gt(C target, T value); + + /** + * Add a "grater than" condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void gt(C target, ObjectQuery value); + + /** + * Add a "grater than or equals" condition between two values. + * + * @param target + * the base operation target. + * @param value + * the operation expected value. + */ + void gtEq(C target, T value); + + /** + * Add an "grater than or equals" condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void gtEq(C target, ObjectQuery value); + + /** + * Add a max condition between two values. * * @param target * the base operation target. * @param value * the operation expected value. */ + @Deprecated void max(C target, T value); /** - * Add an max or equals condition between two values. + * Add a max condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + @Deprecated + void max(C target, ObjectQuery value); + + /** + * Add a max or equals condition between two values. * * @param target * the base operation target. * @param value * the operation expected value. */ + @Deprecated void maxEq(C target, T value); + + /** + * Add an max or equals condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + @Deprecated + void maxEq(C target, ObjectQuery value); /** - * Add an min condition between two values. + * Add a "lesser than" condition between two values. * * @param target * the base operation target. * @param value * the operation expected value. */ + void lt(C target, T value); + + /** + * Add a "lesser than" condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void lt(C target, ObjectQuery value); + + /** + * Add a "lesser than" or equals condition between two values. + * + * @param target + * the base operation target. + * @param value + * the operation expected value. + */ + void ltEq(C target, T value); + + /** + * Add a min or equals condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void ltEq(C target,ObjectQuery value); + + + /** + * Add a min condition between two values. + * + * @param target + * the base operation target. + * @param value + * the operation expected value. + */ + @Deprecated void min(C target, T value); + + /** + * Add a min condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + @Deprecated + void min(C target, ObjectQuery value); /** - * Add an min or equals condition between two values. + * Add a min or equals condition between two values. * * @param target * the base operation target. * @param value * the operation expected value. */ + @Deprecated void minEq(C target, T value); /** - * Add an like condition between two values. + * Add a min or equals condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + @Deprecated + void minEq(C target,ObjectQuery value); + + /** + * Add a like condition between two values. * * @param target * the base operation target. @@ -75,7 +224,7 @@ public interface QueryCondition { void like(C target, T value); /** - * Add an not like condition between two values. + * Add a not like condition between two values. * * @param target * the base operation target. @@ -95,7 +244,17 @@ public interface QueryCondition { > void in(C target, T value); /** - * Add an not in condition between two values. + * Add an in condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void in(C target, ObjectQuery value); + + /** + * Add a not in condition between two values. * * @param target * the base operation target. @@ -105,7 +264,17 @@ public interface QueryCondition { > void notIn(C target, T value); /** - * Add an contains condition between two values. + * Add a not in condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void notIn(C target, ObjectQuery value); + + /** + * Add a contains condition between two values. * * @param target * the base operation target. @@ -113,9 +282,19 @@ public interface QueryCondition { * the operation expected value. */ void contains(Collection target, T value); + + /** + * Add a contains condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void contains(Collection target, ObjectQuery value); /** - * Add an contains condition between two values. + * Add a not contains condition between two values. * * @param target * the base operation target. @@ -125,7 +304,17 @@ public interface QueryCondition { void notContains(Collection target, T value); /** - * Add an like condition between two values without case match. + * Add a not contains condition between expression and a query. + * + * @param target + * the base operation target. + * @param value + * the query source of expected value. + */ + void notContains(Collection target, ObjectQuery value); + + /** + * Add a like condition between two values without case match. * * @param target * the base operation target. @@ -135,7 +324,7 @@ public interface QueryCondition { void likeNc(C target, T value); /** - * Add an not like condition between two values without case match. + * Add a not like condition between two values without case match. * * @param target * the base operation target. diff --git a/src/main/java/org/objectquery/generic/ConditionItem.java b/src/main/java/org/objectquery/generic/ConditionItem.java index 51a4efd..943d778 100644 --- a/src/main/java/org/objectquery/generic/ConditionItem.java +++ b/src/main/java/org/objectquery/generic/ConditionItem.java @@ -35,6 +35,8 @@ public void clear() { item = null; if (value instanceof PathItem) ((PathItem) value).clear(); + else if (value instanceof GenericObjectQuery) + ((GenericObjectQuery) value).clear(); value = null; } } diff --git a/src/main/java/org/objectquery/generic/ConditionType.java b/src/main/java/org/objectquery/generic/ConditionType.java index 8dcaabd..8619e85 100644 --- a/src/main/java/org/objectquery/generic/ConditionType.java +++ b/src/main/java/org/objectquery/generic/ConditionType.java @@ -5,5 +5,5 @@ * */ public enum ConditionType { - EQUALS, NOT_EQUALS, MIN, MIN_EQUALS, MAX, MAX_EQUALS, IN, CONTAINS, LIKE, NOT_IN, NOT_CONTAINS, NOT_LIKE, LIKE_NOCASE, NOT_LIKE_NOCASE, BETWEEN + EQUALS, NOT_EQUALS, LESS, LESS_EQUALS, GREATER, GREATER_EQUALS, IN, CONTAINS, LIKE, NOT_IN, NOT_CONTAINS, NOT_LIKE, LIKE_NOCASE, NOT_LIKE_NOCASE,BETWEEN } diff --git a/src/main/java/org/objectquery/generic/GenericHavingCondition.java b/src/main/java/org/objectquery/generic/GenericHavingCondition.java index b85dc09..eec81c7 100644 --- a/src/main/java/org/objectquery/generic/GenericHavingCondition.java +++ b/src/main/java/org/objectquery/generic/GenericHavingCondition.java @@ -1,40 +1,60 @@ package org.objectquery.generic; import org.objectquery.HavingCondition; +import org.objectquery.ObjectQuery; public class GenericHavingCondition implements HavingCondition { private InternalQueryBuilder builder; - private PathItem item; + private GenericObjectQuery objectQuery; + private Object item; private ProjectionType type; - public GenericHavingCondition(InternalQueryBuilder builder, PathItem item, ProjectionType type) { + public GenericHavingCondition(InternalQueryBuilder builder, GenericObjectQuery objectQuery, PathItem item, ProjectionType type) { this.builder = builder; this.item = item; this.type = type; + this.objectQuery = objectQuery; + } + + public GenericHavingCondition(InternalQueryBuilder builder, GenericObjectQuery objectQuery, ObjectQuery item, ProjectionType type) { + this.builder = builder; + this.item = item; + this.type = type; + this.objectQuery = objectQuery; + } + + private void having(ConditionType conditionType, Object value) { + Object curValue; + if ((curValue = objectQuery.unproxable.get(value)) == null) + curValue = value; + if (item instanceof PathItem) + builder.having((PathItem) item, type, conditionType, curValue); + else + builder.having((ObjectQuery) item, type, conditionType, curValue); } public void eq(Double value) { - builder.having(item, type, ConditionType.EQUALS, value); + having(ConditionType.EQUALS, value); } public void notEq(Double value) { - builder.having(item, type, ConditionType.NOT_EQUALS, value); + having(ConditionType.NOT_EQUALS, value); } public void max(Double value) { - builder.having(item, type, ConditionType.MAX, value); + having(ConditionType.GREATER, value); } public void maxEq(Double value) { - builder.having(item, type, ConditionType.MAX_EQUALS, value); + having(ConditionType.GREATER_EQUALS, value); } public void min(Double value) { - builder.having(item, type, ConditionType.MIN, value); + having(ConditionType.LESS, value); } public void minEq(Double value) { - builder.having(item, type, ConditionType.MIN_EQUALS, value); + having(ConditionType.LESS_EQUALS, value); } } diff --git a/src/main/java/org/objectquery/generic/GenericInternalQueryBuilder.java b/src/main/java/org/objectquery/generic/GenericInternalQueryBuilder.java index e715f58..a0927a5 100644 --- a/src/main/java/org/objectquery/generic/GenericInternalQueryBuilder.java +++ b/src/main/java/org/objectquery/generic/GenericInternalQueryBuilder.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import org.objectquery.ObjectQuery; + public class GenericInternalQueryBuilder extends ConditionGroup implements InternalQueryBuilder { private List orders = new ArrayList(); @@ -25,6 +27,10 @@ public static void buildPath(PathItem item, StringBuilder builder, String separa builder.append(item.getName()); } + public void order(ObjectQuery order, ProjectionType projectionType, OrderType type) { + orders.add(new Order(order, projectionType, type)); + } + public void order(PathItem item, ProjectionType projectionType, OrderType type) { orders.add(new Order(item, projectionType, type)); } @@ -33,10 +39,18 @@ public void projection(PathItem item, ProjectionType type) { projections.add(new Projection(item, type)); } + public void projection(ObjectQuery projection, ProjectionType type) { + projections.add(new Projection(projection, type)); + } + public void having(PathItem item, ProjectionType projectionType, ConditionType conditionType, Object value) { havings.add(new Having(item, projectionType, conditionType, value)); } + public void having(ObjectQuery item, ProjectionType projectionType, ConditionType conditionType, Object value) { + havings.add(new Having(item, projectionType, conditionType, value)); + } + public List getOrders() { return orders; } diff --git a/src/main/java/org/objectquery/generic/GenericObjectQuery.java b/src/main/java/org/objectquery/generic/GenericObjectQuery.java index 77c914d..47de813 100644 --- a/src/main/java/org/objectquery/generic/GenericObjectQuery.java +++ b/src/main/java/org/objectquery/generic/GenericObjectQuery.java @@ -1,6 +1,8 @@ package org.objectquery.generic; +import java.util.ArrayList; import java.util.IdentityHashMap; +import java.util.List; import java.util.Map; import java.util.WeakHashMap; @@ -13,23 +15,27 @@ public class GenericObjectQuery extends QueryConditionImpl implements ObjectQuery { - // Pool of classes is weak but probably never will be cleared to check. + // Pool of classes is weak but probably never will be cleared, to check!. private static final Map, Class> pool = new WeakHashMap, Class>(); private T target; private Class targetClass; InternalQueryBuilder builder; - Map unproxable = new IdentityHashMap(); + Map unproxable; private Class primitiveToBoxType; private Object primitiveToBoxValue; private PathItem primitiveToBoxPath; + private final boolean subQuery; + private int subCount = 0; + private List joins = new ArrayList(); public Object proxy(Class clazz, PathItem parent, String name) { if (clazz.isPrimitive()) { Object result = PrimitiveFactory.newNumberInstance(clazz, (byte) 0); primitiveToBoxType = clazz; primitiveToBoxValue = result; - unproxable.put(result, new PathItem(clazz, parent, name)); - primitiveToBoxPath = new PathItem(clazz, parent, name); + PathItem item = new PathItem(clazz, parent, name); + unproxable.put(result, item); + primitiveToBoxPath = item; return result; } if (String.class.isAssignableFrom(clazz)) { @@ -64,16 +70,22 @@ public Object proxy(Class clazz, PathItem parent, String name) { } - public GenericObjectQuery(Class clazz) { - this(new GenericInternalQueryBuilder(GroupType.AND), clazz); - } - @SuppressWarnings("unchecked") - public GenericObjectQuery(InternalQueryBuilder builder, Class clazz) { + private GenericObjectQuery(InternalQueryBuilder builder, Class clazz, Map unproxable, boolean subQuery) { super(builder); this.builder = builder; this.target = (T) proxy(clazz, null, ""); this.targetClass = clazz; + this.unproxable = unproxable; + this.subQuery = subQuery; + } + + public GenericObjectQuery(Class targetClass) { + this(new GenericInternalQueryBuilder(GroupType.AND), targetClass); + } + + public GenericObjectQuery(InternalQueryBuilder builder, Class targetClass) { + this(builder, targetClass, new IdentityHashMap(), false); } public T target() { @@ -85,24 +97,33 @@ public void prj(Object projection) { } public void prj(Object projection, ProjectionType type) { - builder.projection(extractItem(projection), type); + if (isSubQuery()) { + throw new ObjectQueryException("Add projection to a subquery is actually not supported"); + } + if (projection instanceof GenericObjectQuery) { + if (!((GenericObjectQuery) projection).isSubQuery()) + throw new ObjectQueryException( + "The given sub query is not a sub query instance, use the method ObjectQuery.subQuery to obtain a sub query instance"); + builder.projection((ObjectQuery) projection, type); + } else + builder.projection(extractItem(projection), type); } private PathItem extractItem(Object object) { if (object == null) - throw new ObjectQueryException("The given object is null", null); + throw new ObjectQueryException("The given object is null"); PathItem item; if (!(object instanceof ProxyObject)) { if ((item = unproxable.get(object)) == null) { if (isPrimitive(object.getClass())) - throw new ObjectQueryException("The given object is an primitive type autoboxed use box() function to box primitive values", null); + throw new ObjectQueryException("The given object is an primitive type autoboxed use box() function to box primitive values"); else - throw new ObjectQueryException("The given object as order isn't a proxy, use target() method for start to take object for query", null); + throw new ObjectQueryException("The given object as order isn't a proxy, use target() method for start to take object for query"); } } else { if (!(((ProxyObject) object).getHandler() instanceof ObjectQueryHandler)) throw new ObjectQueryException( - "The given object as condition isn't a objectquery proxy, use target() method for start to take object for query", null); + "The given object as condition isn't a objectquery proxy, use target() method for start to take object for query"); item = ((ObjectQueryHandler) ((ProxyObject) object).getHandler()).getPath(); } return item; @@ -117,7 +138,13 @@ public void order(Object order, OrderType type) { } public void order(Object order, ProjectionType projectionType, OrderType type) { - builder.order(extractItem(order), projectionType, type); + if (order instanceof GenericObjectQuery) { + if (!((GenericObjectQuery) order).isSubQuery()) + throw new ObjectQueryException( + "The given sub query is not a sub query instance, use the method ObjectQuery.subQuery to obtain a sub query instance"); + builder.order((ObjectQuery) order, projectionType, type); + } else + builder.order(extractItem(order), projectionType, type); } private boolean isPrimitive(Class clazz) { @@ -128,9 +155,9 @@ private boolean isPrimitive(Class clazz) { @SuppressWarnings("unchecked") private Z box(Class clazz, Object value) { if (primitiveToBoxType == null || primitiveToBoxValue == null || primitiveToBoxPath == null) - throw new ObjectQueryException("not present a primitive call to box.", null); + throw new ObjectQueryException("not present a primitive call to box."); if (!clazz.equals(primitiveToBoxType)) - throw new ObjectQueryException("present a wrong primitive type that not match with call to box.", null); + throw new ObjectQueryException("present a wrong primitive type that not match with call to box."); unproxable.put(primitiveToBoxValue, primitiveToBoxPath); return (Z) primitiveToBoxValue; @@ -177,11 +204,59 @@ public Class getTargetClass() { } public HavingCondition having(Object projection, ProjectionType type) { - return new GenericHavingCondition(builder, extractItem(projection), type); + if (projection instanceof GenericObjectQuery) { + if (!((GenericObjectQuery) projection).isSubQuery()) + throw new ObjectQueryException( + "The given sub query is not a sub query instance, use the method ObjectQuery.subQuery to obtain a sub query instance"); + return new GenericHavingCondition(builder, this, (ObjectQuery) projection, type); + } else + return new GenericHavingCondition(builder, this, extractItem(projection), type); + } + + public PathItem getRootPathItem() { + return ((ObjectQueryHandler) ((ProxyObject) target).getHandler()).getPath(); } public void clear() { unproxable.clear(); builder.clear(); } + + public boolean isSubQuery() { + return subQuery; + } + + public ObjectQuery subQuery(Class targetClass) { + if (!subQuery) + getRootPathItem().setName("A"); + GenericObjectQuery subQ = new GenericObjectQuery(new GenericInternalQueryBuilder(GroupType.AND), targetClass, unproxable, true); + subQ.getRootPathItem().setName(getRootPathItem().getName() + "A" + (subCount++)); + return subQ; + } + + public J join(Class joinClass) { + return join(null, joinClass); + } + + public J join(Class joinClass, JoinType type) { + return join(null, joinClass, type); + } + + public J join(J joinPath, Class joinClass) { + return join(joinPath, joinClass, JoinType.INNER); + } + + @SuppressWarnings("unchecked") + public J join(J joinPath, Class joinClass, JoinType type) { + if (!subQuery) + getRootPathItem().setName("A"); + J res = (J) proxy(joinClass, null, getRootPathItem().getName() + "B" + (joins.size())); + joins.add(new Join(((ObjectQueryHandler) ((ProxyObject) res).getHandler()).getPath(), joinPath != null ? extractItem(joinPath) : null, type, joinClass)); + return res; + } + + public List getJoins() { + return joins; + } + } diff --git a/src/main/java/org/objectquery/generic/Having.java b/src/main/java/org/objectquery/generic/Having.java index 566a1b8..12024fd 100644 --- a/src/main/java/org/objectquery/generic/Having.java +++ b/src/main/java/org/objectquery/generic/Having.java @@ -1,20 +1,28 @@ package org.objectquery.generic; +import org.objectquery.ObjectQuery; + public class Having { - private PathItem item; + private Object item; private ProjectionType projectionType; private ConditionType conditionType; private Object value; public Having(PathItem item, ProjectionType projectionType, ConditionType conditionType, Object value) { - super(); this.item = item; this.projectionType = projectionType; this.conditionType = conditionType; this.value = value; } - public PathItem getItem() { + public Having(ObjectQuery item, ProjectionType projectionType, ConditionType conditionType, Object value) { + this.item = item; + this.projectionType = projectionType; + this.conditionType = conditionType; + this.value = value; + } + + public Object getItem() { return item; } @@ -31,7 +39,10 @@ public Object getValue() { } public void clear() { - item.clear(); + if (item instanceof PathItem) + ((PathItem) item).clear(); + else if (item instanceof GenericObjectQuery) + ((GenericObjectQuery) item).clear(); item = null; if (value instanceof PathItem) ((PathItem) value).clear(); diff --git a/src/main/java/org/objectquery/generic/InternalQueryBuilder.java b/src/main/java/org/objectquery/generic/InternalQueryBuilder.java index 63dbc17..34fb518 100644 --- a/src/main/java/org/objectquery/generic/InternalQueryBuilder.java +++ b/src/main/java/org/objectquery/generic/InternalQueryBuilder.java @@ -1,5 +1,7 @@ package org.objectquery.generic; +import org.objectquery.ObjectQuery; + /** * Interface to implement a custom query builder from the specified tecnology. * @@ -16,6 +18,28 @@ public interface InternalQueryBuilder extends InternalConditionBuilder { */ void projection(PathItem item, ProjectionType type); + /** + * Add a sub Query projection to query with an operator. + * + * @param item + * the sub Query projection object to add. + * @param type + * the type of projection to add. + */ + void projection(ObjectQuery projection, ProjectionType type); + + /** + * Add an sub query order to query. + * + * @param item + * the order to add. + * @param projectionType + * the gruping function in the order. + * @param type + * the type of order. + */ + void order(ObjectQuery order, ProjectionType projectionType, OrderType type); + /** * Add an order to query. * @@ -42,6 +66,20 @@ public interface InternalQueryBuilder extends InternalConditionBuilder { */ void having(PathItem item, ProjectionType projectionType, ConditionType conditionType, Object value); + /** + * Create Add a new having item + * + * @param item + * having operation target + * @param projectionType + * the type of having projection. + * @param conditionType + * the type of having condition. + * @param value + * the condition value. + */ + void having(ObjectQuery item, ProjectionType projectionType, ConditionType conditionType, Object value); + /** * Clear all object used for build query and the object can be reused for * build another query. diff --git a/src/main/java/org/objectquery/generic/Join.java b/src/main/java/org/objectquery/generic/Join.java new file mode 100644 index 0000000..716e440 --- /dev/null +++ b/src/main/java/org/objectquery/generic/Join.java @@ -0,0 +1,33 @@ +package org.objectquery.generic; + +public class Join { + + private PathItem root; + private PathItem joinPath; + private JoinType type; + private Class javaType; + + public Join(PathItem root, PathItem joinPath, JoinType type, Class javaType) { + this.root = root; + this.joinPath = joinPath; + this.type = type; + this.javaType = javaType; + } + + public PathItem getRoot() { + return root; + } + + public PathItem getJoinPath() { + return joinPath; + } + + public JoinType getType() { + return type; + } + + public Class getJavaType() { + return javaType; + } + +} diff --git a/src/main/java/org/objectquery/generic/JoinType.java b/src/main/java/org/objectquery/generic/JoinType.java new file mode 100644 index 0000000..a372bf3 --- /dev/null +++ b/src/main/java/org/objectquery/generic/JoinType.java @@ -0,0 +1,5 @@ +package org.objectquery.generic; + +public enum JoinType { + INNER, LEFT, RIGHT, OUTER +} diff --git a/src/main/java/org/objectquery/generic/ObjectQueryException.java b/src/main/java/org/objectquery/generic/ObjectQueryException.java index e55d8fa..014a838 100644 --- a/src/main/java/org/objectquery/generic/ObjectQueryException.java +++ b/src/main/java/org/objectquery/generic/ObjectQueryException.java @@ -7,4 +7,9 @@ public class ObjectQueryException extends RuntimeException { public ObjectQueryException(String message, Throwable cause) { super(message, cause); } + + public ObjectQueryException(String message) { + super(message); + } + } diff --git a/src/main/java/org/objectquery/generic/ObjectQueryHandler.java b/src/main/java/org/objectquery/generic/ObjectQueryHandler.java index 1c3fe67..195f14e 100644 --- a/src/main/java/org/objectquery/generic/ObjectQueryHandler.java +++ b/src/main/java/org/objectquery/generic/ObjectQueryHandler.java @@ -22,7 +22,7 @@ public Object invoke(Object self, Method thisMethod, Method proceed, Object[] ar } else if (name.startsWith("is") && Character.isUpperCase(name.charAt(2))) { returnValue = abstractObjectQuery.proxy(thisMethod.getReturnType(), path, Character.toLowerCase(name.charAt(2)) + name.substring(3)); } else { - throw new ObjectQueryException("Unsupported opertation this is an Object for Query", null); + throw new ObjectQueryException("Unsupported opertation this is an Object for Query"); } return returnValue; } @@ -30,4 +30,5 @@ public Object invoke(Object self, Method thisMethod, Method proceed, Object[] ar public PathItem getPath() { return path; } + } diff --git a/src/main/java/org/objectquery/generic/Order.java b/src/main/java/org/objectquery/generic/Order.java index 6415dcc..ad40af2 100644 --- a/src/main/java/org/objectquery/generic/Order.java +++ b/src/main/java/org/objectquery/generic/Order.java @@ -1,18 +1,26 @@ package org.objectquery.generic; +import org.objectquery.ObjectQuery; + public class Order { - private PathItem item; + private Object item; private ProjectionType projectionType; private OrderType type; + public Order(ObjectQuery item, ProjectionType projectionType, OrderType type) { + this.item = item; + this.projectionType = projectionType; + this.type = type; + } + public Order(PathItem item, ProjectionType projectionType, OrderType type) { this.item = item; this.projectionType = projectionType; this.type = type; } - public PathItem getItem() { + public Object getItem() { return item; } @@ -25,7 +33,10 @@ public ProjectionType getProjectionType() { } public void clear() { - item.clear(); - item=null; + if (item instanceof GenericObjectQuery) + ((GenericObjectQuery) item).clear(); + else + ((PathItem) item).clear(); + item = null; } } diff --git a/src/main/java/org/objectquery/generic/PathItem.java b/src/main/java/org/objectquery/generic/PathItem.java index 79f11fc..39740f5 100644 --- a/src/main/java/org/objectquery/generic/PathItem.java +++ b/src/main/java/org/objectquery/generic/PathItem.java @@ -20,6 +20,10 @@ public String getName() { return name; } + public void setName(String name) { + this.name = name; + } + public PathItem getParent() { return parent; } diff --git a/src/main/java/org/objectquery/generic/Projection.java b/src/main/java/org/objectquery/generic/Projection.java index bb1e993..0662c73 100644 --- a/src/main/java/org/objectquery/generic/Projection.java +++ b/src/main/java/org/objectquery/generic/Projection.java @@ -1,16 +1,23 @@ package org.objectquery.generic; +import org.objectquery.ObjectQuery; + public class Projection { - private PathItem item; + private Object item; private ProjectionType type; + public Projection(ObjectQuery item, ProjectionType type) { + this.item = item; + this.type = type; + } + public Projection(PathItem item, ProjectionType type) { this.item = item; this.type = type; } - public PathItem getItem() { + public Object getItem() { return item; } @@ -19,7 +26,10 @@ public ProjectionType getType() { } public void clear() { - item.clear(); + if (item instanceof GenericObjectQuery) + ((GenericObjectQuery) item).clear(); + else + ((PathItem) item).clear(); item = null; } diff --git a/src/main/java/org/objectquery/generic/QueryConditionImpl.java b/src/main/java/org/objectquery/generic/QueryConditionImpl.java index 76b42c6..b03f61f 100644 --- a/src/main/java/org/objectquery/generic/QueryConditionImpl.java +++ b/src/main/java/org/objectquery/generic/QueryConditionImpl.java @@ -2,10 +2,11 @@ import java.util.Collection; -import org.objectquery.QueryCondition; - import javassist.util.proxy.ProxyObject; +import org.objectquery.ObjectQuery; +import org.objectquery.QueryCondition; + public class QueryConditionImpl implements QueryCondition { private GenericObjectQuery objectQuery; @@ -23,34 +24,47 @@ public QueryConditionImpl(GenericObjectQuery objectQuery, ConditionGroup grou public void condition(Object base, ConditionType type, Object value, Object value1) { if (base == null) - throw new ObjectQueryException("The given object as condition is null", null); + throw new ObjectQueryException("The given object as condition is null"); PathItem item = null; Class baseType = base.getClass(); if (!(base instanceof ProxyObject)) { if ((item = objectQuery.unproxable.get(base)) == null) - throw new ObjectQueryException("The given object as condition isn't a proxy, use box() method for wrap primitive types for the query", null); + throw new ObjectQueryException( + "The given object as condition isn't a proxy, use target() method for start to take object for query or box() for manage primitive types"); } else { if (!(((ProxyObject) base).getHandler() instanceof ObjectQueryHandler)) throw new ObjectQueryException( - "The given object as condition isn't a objectquery proxy, use target() method for start to take object for query", null); + "The given object as condition isn't a objectquery proxy, use target() method for start to take object for query"); item = ((ObjectQueryHandler) ((ProxyObject) base).getHandler()).getPath(); baseType = base.getClass().getSuperclass(); } if (type == null) - throw new ObjectQueryException("The given type of condition is null", null); + throw new ObjectQueryException("The given type of condition is null"); Object curValue = null; if (value != null) { - if (ConditionType.IN.equals(type) || ConditionType.NOT_IN.equals(type)) { - if (!(value.getClass().isArray() || value instanceof Collection)) - throw new ObjectQueryException("The given object value is not an array or collection required for in value", null); - } else if (ConditionType.CONTAINS.equals(type) || ConditionType.NOT_CONTAINS.equals(type)) { - if (!(base.getClass().isArray() || base instanceof Collection)) - throw new ObjectQueryException("The given object value is not an array or collection required for in value", null); - } else if (!baseType.isAssignableFrom(value.getClass())) - throw new ObjectQueryException("The given object value is not assignabled to gived condition", null); - + if (value instanceof GenericObjectQuery) { + // TODO: Be careful because in the future can be possible + // another implementation. + GenericObjectQuery val = (GenericObjectQuery) value; + if (!val.isSubQuery()) + throw new ObjectQueryException( + "The given sub query is not a sub query instance, use the method ObjectQuery.subQuery to obtain a sub query instance"); + if (!baseType.isAssignableFrom(val.getTargetClass())) + throw new ObjectQueryException("The given object value is not assignabled to gived condition"); + if (!((GenericInternalQueryBuilder) val.getBuilder()).getProjections().isEmpty()) + throw new ObjectQueryException("The query given as value are using projection that is not allowed"); + } else { + if (ConditionType.IN.equals(type) || ConditionType.NOT_IN.equals(type)) { + if (!(value.getClass().isArray() || value instanceof Collection)) + throw new ObjectQueryException("The given object value is not an array or collection required for in value"); + } else if (ConditionType.CONTAINS.equals(type) || ConditionType.NOT_CONTAINS.equals(type)) { + if (!(base.getClass().isArray() || base instanceof Collection)) + throw new ObjectQueryException("The given object value is not an array or collection required for in value"); + } else if (!baseType.isAssignableFrom(value.getClass())) + throw new ObjectQueryException("The given object value is not assignabled to gived condition"); + } if (value instanceof ProxyObject && ((ProxyObject) value).getHandler() instanceof ObjectQueryHandler) curValue = ((ObjectQueryHandler) ((ProxyObject) value).getHandler()).getPath(); else if ((curValue = objectQuery.unproxable.get(value)) == null) @@ -85,25 +99,89 @@ public void eq(C target, T value) { condition(target, ConditionType.EQUALS, value, null); } + public void eq(C target, ObjectQuery value) { + condition(target, ConditionType.EQUALS, value, null); + } + public void notEq(C target, T value) { condition(target, ConditionType.NOT_EQUALS, value, null); } + public void notEq(C target, ObjectQuery value) { + condition(target, ConditionType.NOT_EQUALS, value, null); + } + + public void gt(C target, T value) { + condition(target, ConditionType.GREATER, value, null); + } + + public void gt(C target, ObjectQuery value) { + condition(target, ConditionType.GREATER, value, null); + } + + public void gtEq(C target, T value) { + condition(target, ConditionType.GREATER_EQUALS, value, null); + } + + public void gtEq(C target, ObjectQuery value) { + condition(target, ConditionType.GREATER_EQUALS, value, null); + } + + @Deprecated public void max(C target, T value) { - condition(target, ConditionType.MAX, value, null); + condition(target, ConditionType.GREATER, value, null); } + @Deprecated + public void max(C target, ObjectQuery value) { + condition(target, ConditionType.GREATER, value, null); + } + + @Deprecated public void maxEq(C target, T value) { - condition(target, ConditionType.MAX_EQUALS, value, null); + condition(target, ConditionType.GREATER_EQUALS, value, null); + } + + @Deprecated + public void maxEq(C target, ObjectQuery value) { + condition(target, ConditionType.GREATER_EQUALS, value, null); + } + + public void lt(C target, T value) { + condition(target, ConditionType.LESS, value, null); + } + + public void lt(C target, ObjectQuery value) { + condition(target, ConditionType.LESS, value, null); + } + public void ltEq(C target, T value) { + condition(target, ConditionType.LESS_EQUALS, value, null); + } + + public void ltEq(C target, ObjectQuery value) { + condition(target, ConditionType.LESS_EQUALS, value, null); + } + + @Deprecated public void min(C target, T value) { - condition(target, ConditionType.MIN, value, null); + condition(target, ConditionType.LESS, value, null); + } + + @Deprecated + public void min(C target, ObjectQuery value) { + condition(target, ConditionType.LESS, value, null); } + @Deprecated public void minEq(C target, T value) { - condition(target, ConditionType.MIN_EQUALS, value, null); + condition(target, ConditionType.LESS_EQUALS, value, null); + } + @Deprecated + public void minEq(C target, ObjectQuery value) { + condition(target, ConditionType.LESS_EQUALS, value, null); } public void like(C target, T value) { @@ -116,25 +194,38 @@ public void notLike(C target, T value) { public > void in(C target, T value) { condition(target, ConditionType.IN, value, null); + } + public void in(C target, ObjectQuery value) { + condition(target, ConditionType.IN, value, null); } public > void notIn(C target, T value) { condition(target, ConditionType.NOT_IN, value, null); } + public void notIn(C target, ObjectQuery value) { + condition(target, ConditionType.NOT_IN, value, null); + } + public void contains(Collection target, T value) { condition(target, ConditionType.CONTAINS, value, null); + } + public void contains(Collection target, ObjectQuery value) { + condition(target, ConditionType.CONTAINS, value, null); } public void notContains(Collection target, T value) { condition(target, ConditionType.NOT_CONTAINS, value, null); } + public void notContains(Collection target, ObjectQuery value) { + condition(target, ConditionType.NOT_CONTAINS, value, null); + } + public void likeNc(C target, T value) { condition(target, ConditionType.LIKE_NOCASE, value, null); - } public void notLikeNc(C target, T value) { diff --git a/src/test/java/org/objectquery/generic/MockQueryBuilder.java b/src/test/java/org/objectquery/generic/MockQueryBuilder.java index 4194014..872d372 100644 --- a/src/test/java/org/objectquery/generic/MockQueryBuilder.java +++ b/src/test/java/org/objectquery/generic/MockQueryBuilder.java @@ -34,12 +34,65 @@ private void stringfyGroup(ConditionGroup group, StringBuilder builder) { } } + private void stringfyQuery(GenericObjectQuery goq, StringBuilder builder) { + GenericInternalQueryBuilder iqb = (GenericInternalQueryBuilder) goq.getBuilder(); + List conditionsString = new ArrayList(); + List ordersString = new ArrayList(); + List projectionsString = new ArrayList(); + List havingString = new ArrayList(); + build(iqb.getConditions(), iqb.getOrders(), iqb.getProjections(), iqb.getHavings(), conditionsString, ordersString, projectionsString, havingString); + builder.append("select "); + Iterator iter = null; + if (!projectionsString.isEmpty()) { + iter = projectionsString.iterator(); + while (iter.hasNext()) { + builder.append(iter.next()); + if (iter.hasNext()) + builder.append(","); + } + } + builder.append(" from ").append(goq.getTargetClass().getSimpleName()).append(" ").append(goq.getRootPathItem().getName()); + if (!conditionsString.isEmpty()) { + builder.append(" where "); + iter = conditionsString.iterator(); + while (iter.hasNext()) { + builder.append(iter.next()); + if (iter.hasNext()) + builder.append(" ").append(iqb.getType().toString()).append(" "); + } + } + + if (!havingString.isEmpty()) { + builder.append(" having "); + while (iter.hasNext()) { + builder.append(iter.next()); + if (iter.hasNext()) { + // TODO:Fix when refactored for support of different + // grouping operator in having condition. + builder.append(" AND "); + } + } + } + + if (!ordersString.isEmpty()) { + builder.append(" order by "); + while (iter.hasNext()) { + builder.append(iter.next()); + if (iter.hasNext()) + builder.append(","); + } + } + + } + private void stringfyCondition(ConditionItem cond, StringBuilder sb) { buildPath(cond.getItem(), sb); sb.append(" ").append(cond.getType()).append(" "); if (cond.getValue() instanceof PathItem) buildPath((PathItem) cond.getValue(), sb); - else + else if (cond.getValue() instanceof GenericObjectQuery) { + stringfyQuery((GenericObjectQuery) cond.getValue(), sb); + } else sb.append(cond.getValue()); if (ConditionType.BETWEEN.equals(cond.getType())) { sb.append(" AND "); @@ -51,7 +104,13 @@ private void stringfyCondition(ConditionItem cond, StringBuilder sb) { } public void build() { - for (ConditionElement cond : getConditions()) { + build(getConditions(), getOrders(), getProjections(), getHavings(), conditionsString, ordersString, projectionsString, havingString); + } + + private void build(List conditions, List orders, List projections, List havings, + List conditionsString, List ordersString, List projectionsString, List havingString) { + + for (ConditionElement cond : conditions) { if (cond instanceof ConditionItem) { StringBuilder sb = new StringBuilder(); stringfyCondition((ConditionItem) cond, sb); @@ -62,25 +121,32 @@ public void build() { conditionsString.add(sb.toString()); } } - for (Order ord : getOrders()) { + for (Order ord : orders) { StringBuilder sb = new StringBuilder(); - buildPath(ord.getItem(), sb); + if (ord.getItem() instanceof PathItem) + buildPath((PathItem) ord.getItem(), sb); + else + stringfyQuery((GenericObjectQuery) ord.getItem(), sb); if (ord.getProjectionType() != null) sb.append(" ").append(ord.getProjectionType()); if (ord.getType() != null) sb.append(" ").append(ord.getType()); ordersString.add(sb.toString()); } - for (Projection proj : getProjections()) { + for (Projection proj : projections) { StringBuilder sb = new StringBuilder(); - buildPath(proj.getItem(), sb); + if (proj.getItem() instanceof PathItem) + buildPath((PathItem) proj.getItem(), sb); + else + stringfyQuery((GenericObjectQuery) proj.getItem(), sb); if (proj.getType() != null) sb.append(" ").append(proj.getType()); projectionsString.add(sb.toString()); } - for (Having having : getHavings()) { + for (Having having : havings) { StringBuilder sb = new StringBuilder(); - buildPath(having.getItem(), sb); + if (having.getItem() instanceof PathItem) + buildPath((PathItem) having.getItem(), sb); sb.append(" ").append(having.getProjectionType()); sb.append(" ").append(having.getConditionType()); sb.append(" ").append(having.getValue()); diff --git a/src/test/java/org/objectquery/generic/TestGenericObjectQuery.java b/src/test/java/org/objectquery/generic/TestGenericObjectQuery.java index 9811722..4534897 100644 --- a/src/test/java/org/objectquery/generic/TestGenericObjectQuery.java +++ b/src/test/java/org/objectquery/generic/TestGenericObjectQuery.java @@ -8,6 +8,7 @@ import org.junit.Assert; import org.junit.Test; import org.objectquery.ObjectQuery; +import org.objectquery.generic.domain.Dog; import org.objectquery.generic.domain.Person; public class TestGenericObjectQuery { @@ -23,7 +24,7 @@ public void testInvalidCall() { ObjectQuery query = new GenericObjectQuery(null, Person.class); query.target().setDog(null); } - + @Test(expected = ObjectQueryException.class) public void testWrongObjectProjection() { ObjectQuery query = new GenericObjectQuery(null, Person.class); @@ -112,7 +113,7 @@ public Object invoke(Object self, Method thisMethod, Method proceed, Object[] ar return null; } }); - query.eq(o, null); + query.eq(o, (Object) null); } @Test(expected = ObjectQueryException.class) @@ -128,6 +129,21 @@ public Object invoke(Object self, Method thisMethod, Method proceed, Object[] ar query.prj(o); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test(expected = ObjectQueryException.class) + public void testWrongNestedQueryType() throws Exception { + GenericObjectQuery query = new GenericObjectQuery(null, Person.class); + query.eq(query.target().getDog(), (ObjectQuery) new GenericObjectQuery(Person.class)); + } + + @Test(expected = ObjectQueryException.class) + public void testWrongNestedQueryProjection() throws Exception { + GenericObjectQuery query = new GenericObjectQuery(null, Person.class); + ObjectQuery dogq = new GenericObjectQuery(Dog.class); + dogq.prj(dogq.target().getOwner()); + query.eq(query.target().getDog(), dogq); + } + @Test(expected = ObjectQueryException.class) public void testWrongBoxValue() throws Exception { GenericObjectQuery query = new GenericObjectQuery(null, Person.class); @@ -154,7 +170,7 @@ public void testSimpleQueryBuild() { ObjectQuery query = new GenericObjectQuery(builder, Person.class); Person toSearch = query.target(); query.eq(toSearch.getHome().getAddress(), "rue d'anton"); - query.eq(toSearch.getMum().getName(), "elisabeth"); + query.eq(toSearch.getMom().getName(), "elisabeth"); query.order(toSearch.getName()); builder.build(); @@ -162,21 +178,48 @@ public void testSimpleQueryBuild() { Assert.assertEquals("There is more orders than expected", builder.getOrdersString().size(), 1); Assert.assertTrue("Not present expected condition", builder.getConditionsString().contains("home.address EQUALS rue d'anton")); - Assert.assertTrue("Not present expected condition", builder.getConditionsString().contains("mum.name EQUALS elisabeth")); + Assert.assertTrue("Not present expected condition", builder.getConditionsString().contains("mom.name EQUALS elisabeth")); Assert.assertTrue("Not present expected order", builder.getOrdersString().contains("name")); } + @Test(expected = ObjectQueryException.class) + public void testInvalidSubQueryCondition() { + GenericObjectQuery query = new GenericObjectQuery(Person.class); + query.eq(query.target(), new GenericObjectQuery(Person.class)); + } + + @Test(expected = ObjectQueryException.class) + public void testInvalidSubQueryProjection() { + GenericObjectQuery query = new GenericObjectQuery(Person.class); + query.prj(new GenericObjectQuery(Person.class)); + } + + @Test(expected = ObjectQueryException.class) + public void testInvalidSubQueryOrder() { + GenericObjectQuery query = new GenericObjectQuery(Person.class); + query.order(new GenericObjectQuery(Person.class)); + } + + @Test(expected = ObjectQueryException.class) + public void testInvalidSubQueryProjectionAdd() { + GenericObjectQuery query = new GenericObjectQuery(Person.class); + query.subQuery(Person.class).prj(query.target().getName()); + } + @Test public void testClean() { MockQueryBuilder builder = new MockQueryBuilder(); GenericObjectQuery query = new GenericObjectQuery(builder, Person.class); Person toSearch = query.target(); query.prj(toSearch.getHome().getAddress()); + query.prj(query.subQuery(Person.class)); query.eq(toSearch.getHome().getAddress(), "rue d'anton"); - query.eq(toSearch.getMum().getName(), "elisabeth"); - query.eq(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.having(toSearch.getMum().getName(), ProjectionType.COUNT).eq(query.box(toSearch.getHome().getPrice())); + query.eq(toSearch.getMom().getName(), "elisabeth"); + query.eq(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.eq(toSearch.getMom(), query.subQuery(Person.class)); + query.having(toSearch.getMom().getName(), ProjectionType.COUNT).eq(query.box(toSearch.getHome().getPrice())); query.order(toSearch.getName()); + query.order(query.subQuery(Person.class)); builder.build(); query.clear(); diff --git a/src/test/java/org/objectquery/generic/TestGroupCondition.java b/src/test/java/org/objectquery/generic/TestGroupCondition.java index 33da73b..a296151 100644 --- a/src/test/java/org/objectquery/generic/TestGroupCondition.java +++ b/src/test/java/org/objectquery/generic/TestGroupCondition.java @@ -4,7 +4,6 @@ import org.junit.Test; import org.objectquery.ObjectQuery; import org.objectquery.QueryCondition; -import org.objectquery.generic.GenericObjectQuery; import org.objectquery.generic.domain.Person; public class TestGroupCondition { diff --git a/src/test/java/org/objectquery/generic/TestJoin.java b/src/test/java/org/objectquery/generic/TestJoin.java new file mode 100644 index 0000000..5949639 --- /dev/null +++ b/src/test/java/org/objectquery/generic/TestJoin.java @@ -0,0 +1,47 @@ +package org.objectquery.generic; + +import org.junit.Assert; +import org.junit.Test; +import org.objectquery.generic.domain.Person; + +public class TestJoin { + + @Test + public void testSimpleCreateJoin() { + MockQueryBuilder qb = new MockQueryBuilder(); + GenericObjectQuery objectQuery = new GenericObjectQuery(qb, Person.class); + Person join = objectQuery.join(Person.class); + objectQuery.eq(objectQuery.target().getName(), join.getName()); + qb.build(); + + Assert.assertEquals(1, qb.getConditionsString().size()); + + Assert.assertEquals("A.name EQUALS AB0.name", qb.getConditionsString().get(0)); + Assert.assertEquals(1, objectQuery.getJoins().size()); + Assert.assertEquals(Person.class, objectQuery.getJoins().get(0).getRoot().getClazz()); + Assert.assertEquals("AB0", objectQuery.getJoins().get(0).getRoot().getName()); + Assert.assertEquals(JoinType.INNER, objectQuery.getJoins().get(0).getType()); + Assert.assertNull(objectQuery.getJoins().get(0).getJoinPath()); + + } + + @Test + public void testLinkedCreateJoin() { + MockQueryBuilder qb = new MockQueryBuilder(); + GenericObjectQuery objectQuery = new GenericObjectQuery(qb, Person.class); + Person join = objectQuery.join(objectQuery.target().getMom(), Person.class, JoinType.OUTER); + objectQuery.eq(objectQuery.target().getName(), join.getName()); + qb.build(); + + Assert.assertEquals(1, qb.getConditionsString().size()); + + Assert.assertEquals("A.name EQUALS AB0.name", qb.getConditionsString().get(0)); + Assert.assertEquals(1, objectQuery.getJoins().size()); + Assert.assertEquals(Person.class, objectQuery.getJoins().get(0).getRoot().getClazz()); + Assert.assertEquals("AB0", objectQuery.getJoins().get(0).getRoot().getName()); + Assert.assertEquals("mom", objectQuery.getJoins().get(0).getJoinPath().getName()); + Assert.assertEquals("A", objectQuery.getJoins().get(0).getJoinPath().getParent().getName()); + Assert.assertEquals(JoinType.OUTER, objectQuery.getJoins().get(0).getType()); + + } +} diff --git a/src/test/java/org/objectquery/generic/TestPrimitiveBoxedType.java b/src/test/java/org/objectquery/generic/TestPrimitiveBoxedType.java index c6ec34c..f7136e0 100644 --- a/src/test/java/org/objectquery/generic/TestPrimitiveBoxedType.java +++ b/src/test/java/org/objectquery/generic/TestPrimitiveBoxedType.java @@ -10,7 +10,6 @@ import org.junit.Assert; import org.junit.Test; import org.objectquery.ObjectQuery; -import org.objectquery.generic.GenericObjectQuery; import org.objectquery.generic.domain.BoxedPrimitiveDomain; public class TestPrimitiveBoxedType { diff --git a/src/test/java/org/objectquery/generic/TestPrimitiveType.java b/src/test/java/org/objectquery/generic/TestPrimitiveType.java index f5c14e3..a140244 100644 --- a/src/test/java/org/objectquery/generic/TestPrimitiveType.java +++ b/src/test/java/org/objectquery/generic/TestPrimitiveType.java @@ -3,7 +3,6 @@ import org.junit.Assert; import org.junit.Test; import org.objectquery.ObjectQuery; -import org.objectquery.generic.GenericObjectQuery; import org.objectquery.generic.domain.PrimitiveDomain; public class TestPrimitiveType { diff --git a/src/test/java/org/objectquery/generic/TestQueryCondition.java b/src/test/java/org/objectquery/generic/TestQueryCondition.java index e7e281c..eb055d6 100644 --- a/src/test/java/org/objectquery/generic/TestQueryCondition.java +++ b/src/test/java/org/objectquery/generic/TestQueryCondition.java @@ -3,7 +3,6 @@ import org.junit.Assert; import org.junit.Test; import org.objectquery.ObjectQuery; -import org.objectquery.generic.GenericObjectQuery; import org.objectquery.generic.domain.Person; public class TestQueryCondition { @@ -11,20 +10,19 @@ public class TestQueryCondition { @Test public void testPathValueQueryBuild() { MockQueryBuilder builder = new MockQueryBuilder(); - ObjectQuery query = new GenericObjectQuery(builder, Person.class); + GenericObjectQuery query = new GenericObjectQuery(builder, Person.class); Person toSearch = query.target(); query.eq(toSearch.getHome().getAddress(), toSearch.getDog().getHome().getAddress()); - query.eq(toSearch.getDud().getHome(), toSearch.getDog().getHome()); - query.eq(toSearch.getMum().getName(), toSearch.getDog().getOwner().getName()); + query.eq(toSearch.getDad().getHome(), toSearch.getDog().getHome()); + query.eq(toSearch.getMom().getName(), toSearch.getDog().getOwner().getName()); query.order(toSearch.getName()); - builder.build(); Assert.assertEquals("There is more conditions than expected", builder.getConditionsString().size(), 3); Assert.assertEquals("There is more orders than expected", builder.getOrdersString().size(), 1); Assert.assertEquals("Not present expected condition", "home.address EQUALS dog.home.address", builder.getConditionsString().get(0)); - Assert.assertEquals("Not present expected condition", "dud.home EQUALS dog.home", builder.getConditionsString().get(1)); - Assert.assertEquals("Not present expected condition", "mum.name EQUALS dog.owner.name", builder.getConditionsString().get(2)); + Assert.assertEquals("Not present expected condition", "dad.home EQUALS dog.home", builder.getConditionsString().get(1)); + Assert.assertEquals("Not present expected condition", "mom.name EQUALS dog.owner.name", builder.getConditionsString().get(2)); Assert.assertEquals("Not present expected order", builder.getOrdersString().get(0), "name"); } @@ -33,40 +31,85 @@ public void testConditionsTypes() { MockQueryBuilder builder = new MockQueryBuilder(); ObjectQuery query = new GenericObjectQuery(builder, Person.class); Person toSearch = query.target(); - query.eq(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.contains(toSearch.getFriends(), toSearch.getDud()); - query.in(toSearch.getMum(), toSearch.getDud().getFriends()); - query.like(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.max(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.maxEq(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.min(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.minEq(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.notEq(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.notIn(toSearch.getMum(), toSearch.getDud().getFriends()); - query.notContains(toSearch.getMum().getFriends(), toSearch.getDud()); - query.notLike(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.likeNc(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.notLikeNc(toSearch.getMum().getName(), toSearch.getDud().getName()); - query.between(query.box(toSearch.getHome().getPrice()), query.box(toSearch.getMum().getHome().getPrice()), - query.box(toSearch.getDud().getHome().getPrice())); + query.eq(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.contains(toSearch.getFriends(), toSearch.getDad()); + query.in(toSearch.getMom(), toSearch.getDad().getFriends()); + query.like(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.gt(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.gtEq(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.lt(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.ltEq(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.notEq(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.notIn(toSearch.getMom(), toSearch.getDad().getFriends()); + query.notContains(toSearch.getMom().getFriends(), toSearch.getDad()); + query.notLike(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.likeNc(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.notLikeNc(toSearch.getMom().getName(), toSearch.getDad().getName()); + query.between(query.box(toSearch.getHome().getPrice()), query.box(toSearch.getMom().getHome().getPrice()), + query.box(toSearch.getDad().getHome().getPrice())); builder.build(); Assert.assertEquals(15, builder.getConditionsString().size()); - Assert.assertEquals("mum.name EQUALS dud.name", builder.getConditionsString().get(0)); - Assert.assertEquals("friends CONTAINS dud", builder.getConditionsString().get(1)); - Assert.assertEquals("mum IN dud.friends", builder.getConditionsString().get(2)); - Assert.assertEquals("mum.name LIKE dud.name", builder.getConditionsString().get(3)); - Assert.assertEquals("mum.name MAX dud.name", builder.getConditionsString().get(4)); - Assert.assertEquals("mum.name MAX_EQUALS dud.name", builder.getConditionsString().get(5)); - Assert.assertEquals("mum.name MIN dud.name", builder.getConditionsString().get(6)); - Assert.assertEquals("mum.name MIN_EQUALS dud.name", builder.getConditionsString().get(7)); - Assert.assertEquals("mum.name NOT_EQUALS dud.name", builder.getConditionsString().get(8)); - Assert.assertEquals("mum NOT_IN dud.friends", builder.getConditionsString().get(9)); - Assert.assertEquals("mum.friends NOT_CONTAINS dud", builder.getConditionsString().get(10)); - Assert.assertEquals("mum.name NOT_LIKE dud.name", builder.getConditionsString().get(11)); - Assert.assertEquals("mum.name LIKE_NOCASE dud.name", builder.getConditionsString().get(12)); - Assert.assertEquals("mum.name NOT_LIKE_NOCASE dud.name", builder.getConditionsString().get(13)); - Assert.assertEquals("home.price BETWEEN mum.home.price AND dud.home.price", builder.getConditionsString().get(14)); + Assert.assertEquals("mom.name EQUALS dad.name", builder.getConditionsString().get(0)); + Assert.assertEquals("friends CONTAINS dad", builder.getConditionsString().get(1)); + Assert.assertEquals("mom IN dad.friends", builder.getConditionsString().get(2)); + Assert.assertEquals("mom.name LIKE dad.name", builder.getConditionsString().get(3)); + Assert.assertEquals("mom.name GREATER dad.name", builder.getConditionsString().get(4)); + Assert.assertEquals("mom.name GREATER_EQUALS dad.name", builder.getConditionsString().get(5)); + Assert.assertEquals("mom.name LESS dad.name", builder.getConditionsString().get(6)); + Assert.assertEquals("mom.name LESS_EQUALS dad.name", builder.getConditionsString().get(7)); + Assert.assertEquals("mom.name NOT_EQUALS dad.name", builder.getConditionsString().get(8)); + Assert.assertEquals("mom NOT_IN dad.friends", builder.getConditionsString().get(9)); + Assert.assertEquals("mom.friends NOT_CONTAINS dad", builder.getConditionsString().get(10)); + Assert.assertEquals("mom.name NOT_LIKE dad.name", builder.getConditionsString().get(11)); + Assert.assertEquals("mom.name LIKE_NOCASE dad.name", builder.getConditionsString().get(12)); + Assert.assertEquals("mom.name NOT_LIKE_NOCASE dad.name", builder.getConditionsString().get(13)); + Assert.assertEquals("home.price BETWEEN mom.home.price AND dad.home.price", builder.getConditionsString().get(14)); + + } + + @Test + public void testConditionsSubquery() { + MockQueryBuilder builder = new MockQueryBuilder(); + ObjectQuery query = new GenericObjectQuery(builder, Person.class); + Person toSearch = query.target(); + ObjectQuery subQuery = query.subQuery(Person.class); + query.eq(toSearch.getMom(), subQuery); + query.contains(toSearch.getFriends(), subQuery); + query.in(toSearch.getMom(), subQuery); + // query.like(toSearch.getMum(), new + // GenericObjectQuery(Person.class)); + query.gt(toSearch.getMom(), subQuery); + query.gtEq(toSearch.getMom(), subQuery); + query.lt(toSearch.getMom(), subQuery); + query.ltEq(toSearch.getMom(), subQuery); + query.notEq(toSearch.getMom(), subQuery); + query.notIn(toSearch.getMom(), subQuery); + query.notContains(toSearch.getMom().getFriends(), subQuery); + // query.notLike(toSearch.getMum().getName(), + // toSearch.getDud().getName()); + // query.likeNc(toSearch.getMum().getName(), + // toSearch.getDud().getName()); + // query.notLikeNc(toSearch.getMum().getName(), + // toSearch.getDud().getName()); + builder.build(); + Assert.assertEquals("A.mom EQUALS select from Person AA0", builder.getConditionsString().get(0)); + Assert.assertEquals("A.friends CONTAINS select from Person AA0", builder.getConditionsString().get(1)); + Assert.assertEquals("A.mom IN select from Person AA0", builder.getConditionsString().get(2)); + // Assert.assertEquals("mum.name LIKE dud.name", + // builder.getConditionsString().get(3)); + Assert.assertEquals("A.mom GREATER select from Person AA0", builder.getConditionsString().get(3)); + Assert.assertEquals("A.mom GREATER_EQUALS select from Person AA0", builder.getConditionsString().get(4)); + Assert.assertEquals("A.mom LESS select from Person AA0", builder.getConditionsString().get(5)); + Assert.assertEquals("A.mom LESS_EQUALS select from Person AA0", builder.getConditionsString().get(6)); + Assert.assertEquals("A.mom NOT_EQUALS select from Person AA0", builder.getConditionsString().get(7)); + Assert.assertEquals("A.mom NOT_IN select from Person AA0", builder.getConditionsString().get(8)); + Assert.assertEquals("A.mom.friends NOT_CONTAINS select from Person AA0", builder.getConditionsString().get(9)); + // Assert.assertEquals("mum.name NOT_LIKE dud.name", + // builder.getConditionsString().get(11)); + // Assert.assertEquals("mum.name LIKE_NOCASE dud.name", + // builder.getConditionsString().get(12)); + // Assert.assertEquals("mum.name NOT_LIKE_NOCASE dud.name", } } diff --git a/src/test/java/org/objectquery/generic/TestQueryHaving.java b/src/test/java/org/objectquery/generic/TestQueryHaving.java index dd46744..031ff0f 100644 --- a/src/test/java/org/objectquery/generic/TestQueryHaving.java +++ b/src/test/java/org/objectquery/generic/TestQueryHaving.java @@ -10,21 +10,21 @@ public class TestQueryHaving { @Test public void testSimpleHanving() { MockQueryBuilder builder = new MockQueryBuilder(); - ObjectQuery query = new GenericObjectQuery(builder,Person.class); - + ObjectQuery query = new GenericObjectQuery(builder, Person.class); + Person target = query.target(); query.having(target.getName(), ProjectionType.COUNT).eq(2D); builder.build(); - Assert.assertEquals(1,builder.getHavingString().size()); - Assert.assertEquals("name COUNT EQUALS 2.0",builder.getHavingString().get(0)); - + Assert.assertEquals(1, builder.getHavingString().size()); + Assert.assertEquals("name COUNT EQUALS 2.0", builder.getHavingString().get(0)); + } @Test public void testAllType() { MockQueryBuilder builder = new MockQueryBuilder(); - ObjectQuery query = new GenericObjectQuery(builder,Person.class); - + ObjectQuery query = new GenericObjectQuery(builder, Person.class); + Person target = query.target(); query.having(target.getName(), ProjectionType.COUNT).eq(2D); query.having(target.getName(), ProjectionType.MIN).eq(2D); @@ -32,20 +32,20 @@ public void testAllType() { query.having(target.getName(), ProjectionType.AVG).eq(2D); query.having(target.getName(), ProjectionType.SUM).eq(2D); builder.build(); - Assert.assertEquals(5,builder.getHavingString().size()); - Assert.assertEquals("name COUNT EQUALS 2.0",builder.getHavingString().get(0)); - Assert.assertEquals("name MIN EQUALS 2.0",builder.getHavingString().get(1)); - Assert.assertEquals("name MAX EQUALS 2.0",builder.getHavingString().get(2)); - Assert.assertEquals("name AVG EQUALS 2.0",builder.getHavingString().get(3)); - Assert.assertEquals("name SUM EQUALS 2.0",builder.getHavingString().get(4)); + Assert.assertEquals(5, builder.getHavingString().size()); + Assert.assertEquals("name COUNT EQUALS 2.0", builder.getHavingString().get(0)); + Assert.assertEquals("name MIN EQUALS 2.0", builder.getHavingString().get(1)); + Assert.assertEquals("name MAX EQUALS 2.0", builder.getHavingString().get(2)); + Assert.assertEquals("name AVG EQUALS 2.0", builder.getHavingString().get(3)); + Assert.assertEquals("name SUM EQUALS 2.0", builder.getHavingString().get(4)); } @Test public void testAllCondition() { MockQueryBuilder builder = new MockQueryBuilder(); - ObjectQuery query = new GenericObjectQuery(builder,Person.class); - + ObjectQuery query = new GenericObjectQuery(builder, Person.class); + Person target = query.target(); query.having(target.getName(), ProjectionType.COUNT).eq(2D); query.having(target.getName(), ProjectionType.COUNT).notEq(2D); @@ -54,14 +54,13 @@ public void testAllCondition() { query.having(target.getName(), ProjectionType.COUNT).min(2D); query.having(target.getName(), ProjectionType.COUNT).minEq(2D); builder.build(); - Assert.assertEquals(6,builder.getHavingString().size()); - Assert.assertEquals("name COUNT EQUALS 2.0",builder.getHavingString().get(0)); - Assert.assertEquals("name COUNT NOT_EQUALS 2.0",builder.getHavingString().get(1)); - Assert.assertEquals("name COUNT MAX 2.0",builder.getHavingString().get(2)); - Assert.assertEquals("name COUNT MAX_EQUALS 2.0",builder.getHavingString().get(3)); - Assert.assertEquals("name COUNT MIN 2.0",builder.getHavingString().get(4)); - Assert.assertEquals("name COUNT MIN_EQUALS 2.0",builder.getHavingString().get(5)); + Assert.assertEquals(6, builder.getHavingString().size()); + Assert.assertEquals("name COUNT EQUALS 2.0", builder.getHavingString().get(0)); + Assert.assertEquals("name COUNT NOT_EQUALS 2.0", builder.getHavingString().get(1)); + Assert.assertEquals("name COUNT GREATER 2.0", builder.getHavingString().get(2)); + Assert.assertEquals("name COUNT GREATER_EQUALS 2.0", builder.getHavingString().get(3)); + Assert.assertEquals("name COUNT LESS 2.0", builder.getHavingString().get(4)); + Assert.assertEquals("name COUNT LESS_EQUALS 2.0", builder.getHavingString().get(5)); } } - diff --git a/src/test/java/org/objectquery/generic/TestQueryOrder.java b/src/test/java/org/objectquery/generic/TestQueryOrder.java index d1c9858..eeefd53 100644 --- a/src/test/java/org/objectquery/generic/TestQueryOrder.java +++ b/src/test/java/org/objectquery/generic/TestQueryOrder.java @@ -4,9 +4,6 @@ import org.junit.Test; import org.objectquery.ObjectQuery; -import org.objectquery.generic.GenericObjectQuery; -import org.objectquery.generic.OrderType; -import org.objectquery.generic.ProjectionType; import org.objectquery.generic.domain.Person; public class TestQueryOrder { @@ -42,7 +39,20 @@ public void testOrdersProjection() { Assert.assertEquals(2, builder.getOrdersString().size()); Assert.assertEquals("dog.name COUNT ASC", builder.getOrdersString().get(0)); Assert.assertEquals("dog.name MAX DESC", builder.getOrdersString().get(1)); + } + + @Test + public void testOrdersSubquery() { + MockQueryBuilder builder = new MockQueryBuilder(); + ObjectQuery query = new GenericObjectQuery(builder, Person.class); + + query.order(query.subQuery(Person.class), ProjectionType.COUNT, OrderType.ASC); + query.order(query.subQuery(Person.class), ProjectionType.MAX, OrderType.DESC); + builder.build(); + Assert.assertEquals(2, builder.getOrdersString().size()); + Assert.assertEquals("select from Person AA0 COUNT ASC", builder.getOrdersString().get(0)); + Assert.assertEquals("select from Person AA1 MAX DESC", builder.getOrdersString().get(1)); } } diff --git a/src/test/java/org/objectquery/generic/TestQueryProjection.java b/src/test/java/org/objectquery/generic/TestQueryProjection.java index d4e3ed1..284302e 100644 --- a/src/test/java/org/objectquery/generic/TestQueryProjection.java +++ b/src/test/java/org/objectquery/generic/TestQueryProjection.java @@ -3,8 +3,6 @@ import org.junit.Assert; import org.junit.Test; import org.objectquery.ObjectQuery; -import org.objectquery.generic.GenericObjectQuery; -import org.objectquery.generic.ProjectionType; import org.objectquery.generic.domain.Person; public class TestQueryProjection { @@ -14,20 +12,34 @@ public void addProjectionTest() { MockQueryBuilder builder = new MockQueryBuilder(); ObjectQuery query = new GenericObjectQuery(builder, Person.class); Person toSearch = query.target(); - query.prj(toSearch.getMum().getName()); - query.prj(toSearch.getMum().getName(), ProjectionType.COUNT); - query.prj(toSearch.getMum().getName(), ProjectionType.AVG); - query.prj(toSearch.getMum().getName(), ProjectionType.MAX); - query.prj(toSearch.getMum().getName(), ProjectionType.MIN); - query.prj(toSearch.getMum().getName(), ProjectionType.SUM); + query.prj(toSearch.getMom().getName()); + query.prj(toSearch.getMom().getName(), ProjectionType.COUNT); + query.prj(toSearch.getMom().getName(), ProjectionType.AVG); + query.prj(toSearch.getMom().getName(), ProjectionType.MAX); + query.prj(toSearch.getMom().getName(), ProjectionType.MIN); + query.prj(toSearch.getMom().getName(), ProjectionType.SUM); builder.build(); Assert.assertEquals(6, builder.getProjectionsString().size()); - Assert.assertEquals("mum.name", builder.getProjectionsString().get(0)); - Assert.assertEquals("mum.name COUNT", builder.getProjectionsString().get(1)); - Assert.assertEquals("mum.name AVG", builder.getProjectionsString().get(2)); - Assert.assertEquals("mum.name MAX", builder.getProjectionsString().get(3)); - Assert.assertEquals("mum.name MIN", builder.getProjectionsString().get(4)); - Assert.assertEquals("mum.name SUM", builder.getProjectionsString().get(5)); + Assert.assertEquals("mom.name", builder.getProjectionsString().get(0)); + Assert.assertEquals("mom.name COUNT", builder.getProjectionsString().get(1)); + Assert.assertEquals("mom.name AVG", builder.getProjectionsString().get(2)); + Assert.assertEquals("mom.name MAX", builder.getProjectionsString().get(3)); + Assert.assertEquals("mom.name MIN", builder.getProjectionsString().get(4)); + Assert.assertEquals("mom.name SUM", builder.getProjectionsString().get(5)); } + + @Test + public void addSubqueryProjectionTest() { + MockQueryBuilder builder = new MockQueryBuilder(); + ObjectQuery query = new GenericObjectQuery(builder, Person.class); + query.prj(query.subQuery(Person.class)); + query.prj(query.subQuery(Person.class), ProjectionType.SUM); + builder.build(); + + Assert.assertEquals(2, builder.getProjectionsString().size()); + Assert.assertEquals("select from Person AA0", builder.getProjectionsString().get(0)); + Assert.assertEquals("select from Person AA1 SUM", builder.getProjectionsString().get(1)); + } + } diff --git a/src/test/java/org/objectquery/generic/TestRequiredSpeed.java b/src/test/java/org/objectquery/generic/TestRequiredSpeed.java index 7fe3e07..0a3f584 100644 --- a/src/test/java/org/objectquery/generic/TestRequiredSpeed.java +++ b/src/test/java/org/objectquery/generic/TestRequiredSpeed.java @@ -31,8 +31,8 @@ public void buildQuery() { Person toSearch = query.target(); query.eq(toSearch.getHome().getAddress(), toSearch.getDog().getHome().getAddress()); - query.eq(toSearch.getDud().getHome(), toSearch.getDog().getHome()); - query.eq(toSearch.getMum().getName(), toSearch.getDog().getOwner().getName()); + query.eq(toSearch.getDad().getHome(), toSearch.getDog().getHome()); + query.eq(toSearch.getMom().getName(), toSearch.getDog().getOwner().getName()); query.order(toSearch.getName()); builder.build(); Assert.assertEquals("size of result conditions", 3, builder.getConditionsString().size()); diff --git a/src/test/java/org/objectquery/generic/TestSubQuery.java b/src/test/java/org/objectquery/generic/TestSubQuery.java new file mode 100644 index 0000000..207e060 --- /dev/null +++ b/src/test/java/org/objectquery/generic/TestSubQuery.java @@ -0,0 +1,79 @@ +package org.objectquery.generic; + +import org.junit.Assert; +import org.junit.Test; +import org.objectquery.ObjectQuery; +import org.objectquery.generic.domain.Person; + +public class TestSubQuery { + + @Test + public void testSubquerySimple() { + MockQueryBuilder builder = new MockQueryBuilder(); + ObjectQuery query = new GenericObjectQuery(builder, Person.class); + + ObjectQuery subQuery = query.subQuery(Person.class); + subQuery.eq(subQuery.target().getName(), "test"); + query.eq(query.target().getDad(), subQuery); + + builder.build(); + + Assert.assertEquals("A.dad EQUALS select from Person AA0 where AA0.name EQUALS test", builder.getConditionsString().get(0)); + + } + + @Test + public void testBackReferenceSubquery() { + MockQueryBuilder builder = new MockQueryBuilder(); + GenericObjectQuery query = new GenericObjectQuery(builder, Person.class); + Person target = query.target(); + ObjectQuery subQuery = query.subQuery(Person.class); + subQuery.eq(subQuery.target().getName(), target.getDog().getName()); + query.eq(query.target().getDad(), subQuery); + + builder.build(); + + Assert.assertEquals(1, builder.getConditions().size()); + Assert.assertEquals("A.dad EQUALS select from Person AA0 where AA0.name EQUALS A.dog.name", builder.getConditionsString().get(0)); + } + + @Test + public void testDoubleSubQuery() { + + MockQueryBuilder builder = new MockQueryBuilder(); + GenericObjectQuery query = new GenericObjectQuery(builder, Person.class); + Person target = query.target(); + ObjectQuery subQuery = query.subQuery(Person.class); + query.eq(target.getDad(), subQuery); + subQuery.eq(subQuery.target().getName(), target.getDog().getName()); + ObjectQuery doubSubQuery = subQuery.subQuery(Person.class); + subQuery.eq(subQuery.target().getMom(), doubSubQuery); + + doubSubQuery.eq(doubSubQuery.target().getMom().getName(), subQuery.target().getMom().getName()); + doubSubQuery.eq(doubSubQuery.target().getMom().getName(), query.target().getMom().getName()); + + builder.build(); + Assert.assertEquals(1, builder.getConditions().size()); + Assert.assertEquals( + "A.dad EQUALS select from Person AA0 where AA0.name EQUALS A.dog.name AND AA0.mom EQUALS select from Person AA0A0 where AA0A0.mom.name EQUALS AA0.mom.name AND AA0A0.mom.name EQUALS A.mom.name", + builder.getConditionsString().get(0)); + + } + + @Test + public void testMultipleReferenceSubquery() { + MockQueryBuilder builder = new MockQueryBuilder(); + GenericObjectQuery query = new GenericObjectQuery(builder, Person.class); + Person target = query.target(); + ObjectQuery subQuery = query.subQuery(Person.class); + ObjectQuery subQuery1 = query.subQuery(Person.class); + query.eq(target.getDad(), subQuery); + query.eq(target.getMom(), subQuery1); + builder.build(); + + Assert.assertEquals(2, builder.getConditions().size()); + Assert.assertEquals("A.dad EQUALS select from Person AA0", builder.getConditionsString().get(0)); + Assert.assertEquals("A.mom EQUALS select from Person AA1", builder.getConditionsString().get(1)); + } + +} diff --git a/src/test/java/org/objectquery/generic/domain/Person.java b/src/test/java/org/objectquery/generic/domain/Person.java index 6e343d4..3fe1438 100644 --- a/src/test/java/org/objectquery/generic/domain/Person.java +++ b/src/test/java/org/objectquery/generic/domain/Person.java @@ -5,8 +5,8 @@ public class Person { private String name; private List friends; - private Person mum; - private Person dud; + private Person mom; + private Person dad; private Home home; private Dog dog; @@ -26,20 +26,20 @@ public void setFriends(List friends) { this.friends = friends; } - public Person getMum() { - return mum; + public Person getMom() { + return mom; } public void setMum(Person mum) { - this.mum = mum; + this.mom = mum; } - public Person getDud() { - return dud; + public Person getDad() { + return dad; } public void setDud(Person dud) { - this.dud = dud; + this.dad = dud; } public Home getHome() {