001: /**
002: * Speedo: an implementation of JDO compliant personality on top of JORM generic
003: * I/O sub-system.
004: * Copyright (C) 2001-2006 France Telecom
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * Contact: speedo@objectweb.org
021: *
022: * Authors: S. Chassande-Barrioz. A. Lefebvre
023: *
024: */package org.objectweb.speedo.ejb.runtime.query.parser;
025:
026: import junit.framework.TestCase;
027:
028: import java.io.CharArrayReader;
029:
030: import org.objectweb.util.monolog.api.Logger;
031: import org.objectweb.util.monolog.api.BasicLevel;
032: import org.objectweb.util.monolog.Monolog;
033: import org.objectweb.speedo.query.ejb.parser.EJBQL;
034:
035: /**
036: * Speedo QL Test
037: * Test a list of valid filters.
038: */
039: public class EJBQLTest extends TestCase {
040: final static String filters[] = {
041: //tests from specification
042: "SELECT DISTINCT o FROM Order AS o JOIN o.lineItems AS l WHERE l.shipped = FALSE",
043: "SELECT DISTINCT o FROM Order o JOIN o.lineItems l JOIN l.product p "
044: + "WHERE p.productType = 'office_supplies'",
045: "SELECT DISTINCT o1 FROM Order o1, Order o2 "
046: + "WHERE o1.quantity > o2.quantity AND "
047: + "o2.customer.lastname = 'Smith' AND "
048: + "o2.customer.firstname= 'John'",
049: "SELECT DISTINCT l.product FROM Order AS o, IN(o.lineItems) l",
050: "select c from Customer c, Employee e where c.hatsize = e.shoesize",
051: "SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1",
052: "SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1",
053: "SELECT OBJECT(c) FROM Customer c, IN(c.orders) o WHERE c.status = 1",
054: "SELECT c FROM Customer c LEFT JOIN c.orders o WHERE c.status = 1",
055: "SELECT c FROM Customer c LEFT OUTER JOIN c.orders o WHERE c.status = 1",
056: "SELECT d FROM Department d LEFT JOIN FETCH d.employees WHERE d.deptno = 1",
057: "SELECT DISTINCT o FROM Order o JOIN o.lineItems l JOIN l.product p "
058: + "WHERE p.productType = 'office_supplies'",
059: "SELECT DISTINCT o FROM Order o, IN(o.lineItems) l "
060: + "WHERE l.product.productType = 'office_supplies'",
061: "SELECT o FROM Order AS o, IN(o.lineItems) l, Product p",
062: //TODO handled names parameters
063: "SELECT c FROM Customer c WHERE c.status = :stat",
064: "SELECT o FROM Order o WHERE o.x BETWEEN o.y AND o.z",
065: "SELECT o FROM Order o WHERE o.y <= o.x AND o.x <= o.z",
066: "SELECT p FROM Order p WHERE p.age BETWEEN 15 and 19",
067: "SELECT p FROM Order p WHERE p.age >= 15 AND p.age <= 19",
068: "SELECT p FROM Order p WHERE p.age NOT BETWEEN 15 and 19",
069: "SELECT p FROM Order p WHERE p.age < 15 OR p.age > 19",
070: "SELECT o FROM Order o WHERE o.country IN ('UK','US','France')",
071: "SELECT o FROM Order o WHERE (o.country='UK') OR (o.country='US') OR (o.country='France')",
072: "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ("
073: + "SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = emp.spouse)",
074: "SELECT c FROM Customer c WHERE (SELECT COUNT(o) FROM c.orders o) > 10",
075: "SELECT goodCustomer FROM Customer goodCustomer "
076: + "WHERE goodCustomer.balanceOwed < "
077: + "(SELECT avg(c.balanceOwed) FROM Customer c)",
078: "SELECT c.status, avg(c.filledOrderCount), count(c) FROM Customer c "
079: + "GROUP BY c.status HAVING c.status IN (1, 2)",
080: "SELECT c.country, COUNT(c) FROM Customer c GROUP BY c.country "
081: + "HAVING COUNT(c.country) > 3",
082: //TODO: handle any keyword as part of a path - replacing with ccount for now
083: // "SELECT c.id, c.status FROM Customer c JOIN c.orders o WHERE o.count > 100",
084: "SELECT c.id, c.status FROM Customer c JOIN c.orders o WHERE o.ccount > 100",
085: //TODO: handle any keyword as part of a path - replacing with ccount for now
086: //"SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count) "
087: // + "FROM Customer c JOIN c.orders o WHERE o.count > 100",
088: "SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.ccount) "
089: + "FROM Customer c JOIN c.orders o WHERE o.ccount > 100",
090: "SELECT AVG(o.quantity) FROM Order o",
091: "SELECT SUM(l.price) FROM Order o JOIN o.lineItems l JOIN o.customer c "
092: + "WHERE c.lastname = 'Smith' AND c.firstname = 'John'",
093: "SELECT COUNT(o) FROM Order o",
094: "SELECT COUNT(l.price) FROM Order o JOIN o.lineItems l JOIN o.customer c "
095: + "WHERE c.lastname = 'Smith' AND c.firstname = 'John'",
096: "SELECT COUNT(l) FROM Order o JOIN o.lineItems l JOIN o.customer c "
097: + "WHERE c.lastname = 'Smith' AND c.firstname = 'John' "
098: + "AND l.price IS NOT NULL",
099: "SELECT o FROM Customer c JOIN c.orders o JOIN c.address a "
100: + "WHERE a.state = 'CA' ORDER BY o.quantity, o.totalcost",
101: "SELECT o.quantity, a.zipcode FROM Customer c JOIN c.orders o JOIN c.address a "
102: + "WHERE a.state = 'CA' ORDER BY o.quantity, a.zipcode",
103: //the following one is identified as not legal in the spec because orderby
104: // is not reflected in the select clause
105: /*
106: "SELECT p.product_name FROM Order o JOIN o.lineItems l JOIN l.product p JOIN o.customer c "
107: + "WHERE c.lastname = 'Smith' AND c.firstname = 'John' "
108: + "ORDER BY p.price",
109: */
110: "DELETE FROM Customer c WHERE c.status = 'inactive'",
111: "DELETE FROM Customer c WHERE c.status = 'inactive' AND c.orders IS EMPTY",
112: "UPDATE customer c SET c.status = 'outstanding' "
113: + "WHERE c.balance < 10000 AND 1000 > "
114: + "(SELECT COUNT(o) FROM customer cust JOIN cust.order o)",
115: //tests from specification: Examples
116: "SELECT o FROM Order o",
117: "SELECT o FROM Order o WHERE o.shippingAddress.state = 'CA'",
118: "SELECT DISTINCT o.shippingAddress.state FROM Order o",
119: "SELECT o FROM Order o WHERE o.lineItems IS NOT EMPTY",
120: "SELECT o FROM Order o WHERE o.lineItems IS EMPTY",
121: "SELECT DISTINCT o FROM Order o JOIN o.lineItems l WHERE l.shipped = FALSE",
122: "SELECT o FROM Order o WHERE "
123: + "NOT (o.shippingAddress.state = o.billingAddress.state "
124: + "AND o.shippingAddress.city = o.billingAddress.city "
125: + "AND o.shippingAddress.street = o.billingAddress.street)",
126: "SELECT o FROM Order o WHERE o.shippingAddress <> o.billingAddress",
127: "SELECT DISTINCT o FROM Order o JOIN o.lineItems l "
128: + "WHERE l.product.type = 'book' AND "
129: + "l.product.name = 'Applying Enterprise JavaBeans: Component-Based Development for the J2EE Platform'",
130: "SELECT DISTINCT o FROM Order o, IN(o.lineItems) l WHERE l.product.name = ?1",
131: //additional tests
132: "SELECT o.shippingAddress.state FROM Order o",
133: "SELECT o FROM Order o WHERE o.shippingAddress.state IS NOT EMPTY",
134: "SELECT o FROM Order o WHERE o.shippingAddress.state = ?1",
135: "SELECT o FROM Order o WHERE o.shippingAddress.state = o.state",
136: "SELECT o FROM Order o WHERE 'CA' = o.shippingAddress.state",
137: "SELECT o FROM Order o WHERE 12 = o.shippingAddress.state",
138: "SELECT o FROM Order o WHERE o.shippingAddress.state = 12"
139:
140: };
141:
142: private final static String LOGGER_NAME = "org.objectweb.speedo.rt.query.parser.ejbql";
143:
144: private static Logger logger = null;
145:
146: static {
147: logger = Monolog.initialize().getLogger(LOGGER_NAME);
148: }
149:
150: public EJBQLTest(String name) {
151: super (name);
152: }
153:
154: public void testAll() {
155: logger.log(BasicLevel.DEBUG, "EJBQL Test - javacc grammar");
156: for (int i = 0; i < filters.length; i++) {
157: String filter = filters[i];
158: logger.log(BasicLevel.DEBUG, "Testing: " + filter);
159: try {
160: new EJBQL(new CharArrayReader(filter.toCharArray()))
161: .EJBQL();
162: } catch (Throwable e) {
163: logger
164: .log(BasicLevel.ERROR, "Parsing of: " + filter,
165: e);
166: fail("Parsing of: " + filter);
167: }
168:
169: }
170: }
171: }
|