001: package org.apache.ojb.odmg;
002:
003: /* Copyright 2002-2005 The Apache Software Foundation
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: import java.util.Collection;
019: import java.util.Iterator;
020: import java.util.List;
021:
022: import org.apache.ojb.junit.ODMGTestCase;
023: import org.apache.ojb.odmg.shared.PersonImpl;
024: import org.apache.ojb.odmg.shared.TestClassA;
025: import org.apache.ojb.odmg.shared.TestClassB;
026: import org.odmg.OQLQuery;
027: import org.odmg.Transaction;
028:
029: /**
030: * @author Matthew.Baird
031: *
032: * Illustrates a problem with OJB SQL Generation:
033: *
034: * 1. OJB will generate the following SQL when items are mapped to the same table:
035: *
036: * SELECT A0.FATHER_ID,A0.MOTHER_ID,A0.LASTNAME,A0.FIRSTNAME,A0.ID
037: * FROM FAMILY_MEMBER A0
038: * INNER JOIN FAMILY_MEMBER A2 ON A0.FATHER_ID=A2.ID
039: * INNER JOIN FAMILY_MEMBER A1 ON A0.MOTHER_ID=A1.ID
040: * WHERE A1.ID = ? OR (A2.ID = ? )
041: *
042: * When it should generate:
043: * SELECT A0.FATHER_ID,A0.MOTHER_ID,A0.LASTNAME,A0.FIRSTNAME,A0.ID
044: * FROM FAMILY_MEMBER A0
045: * WHERE A0.FATHER_ID = ? OR (A0.MOTHER_ID = ? )
046: *
047: * or:
048: * SELECT A0.FATHER_ID,A0.MOTHER_ID,A0.LASTNAME,A0.FIRSTNAME,A0.ID
049: * FROM FAMILY_MEMBER A0
050: * LEFT OUTER JOIN FAMILY_MEMBER A1 ON A0.MOTHER_ID=A1.ID
051: * LEFT OUTER JOIN FAMILY_MEMBER A2 ON A0.FATHER_ID=A2.ID
052: * WHERE A1.ID = ? OR (A2.ID = ?)
053: *
054: */
055: public class OQLOrOnForeignKeyTest extends ODMGTestCase {
056: public static void main(String[] args) {
057: String[] arr = { OQLOrOnForeignKeyTest.class.getName() };
058: junit.textui.TestRunner.main(arr);
059: }
060:
061: public OQLOrOnForeignKeyTest(String name) {
062: super (name);
063: }
064:
065: private void deleteData(Class target) throws Exception {
066: Transaction tx = odmg.newTransaction();
067: tx.begin();
068: OQLQuery query = odmg.newOQLQuery();
069: query.create("select allStuff from " + target.getName());
070: Collection allTargets = (Collection) query.execute();
071: Iterator it = allTargets.iterator();
072: while (it.hasNext()) {
073: database.deletePersistent(it.next());
074: }
075: tx.commit();
076: }
077:
078: /**
079: * test joins on same table
080: *
081: * @throws Exception
082: */
083: public void testOrReferenceOnSameTable() throws Exception {
084: deleteData(PersonImpl.class);
085:
086: PersonImpl jimmy = new PersonImpl();
087: PersonImpl joe = new PersonImpl();
088: PersonImpl father = new PersonImpl();
089: PersonImpl mother = new PersonImpl();
090: OQLQuery query;
091: List persons;
092:
093: mother.setFirstname("mom");
094: father.setFirstname("dad");
095:
096: jimmy.setMother(mother);
097: jimmy.setFirstname("jimmy");
098:
099: joe.setFather(father);
100: joe.setFirstname("joe");
101:
102: Transaction tx = odmg.newTransaction();
103: tx.begin();
104: database.makePersistent(father);
105: database.makePersistent(mother);
106: database.makePersistent(jimmy);
107: database.makePersistent(joe);
108: tx.commit();
109:
110: // read using id
111: tx = odmg.newTransaction();
112: tx.begin();
113: query = odmg.newOQLQuery();
114: query.create("select person from " + PersonImpl.class.getName()
115: + " where (mother.id=$1 or father.id=$2)");
116: query.bind(new Integer(mother.getId()));
117: query.bind(new Integer(father.getId()));
118: persons = (List) query.execute();
119: assertEquals(2, persons.size());
120: tx.commit();
121:
122: // read using firstname
123: tx = odmg.newTransaction();
124: tx.begin();
125: query = odmg.newOQLQuery();
126: query
127: .create("select person from "
128: + PersonImpl.class.getName()
129: + " where (mother.firstname=$1 or father.firstname=$2)");
130: query.bind("mom");
131: query.bind("dad");
132: persons = (List) query.execute();
133: assertEquals(2, persons.size());
134: tx.commit();
135: }
136:
137: public void testOrReferenceOnDifferentTables() throws Exception {
138: deleteData(TestClassA.class);
139: deleteData(TestClassB.class);
140:
141: TestClassA a1 = new TestClassA();
142: TestClassA a2 = new TestClassA();
143:
144: TestClassB b1 = new TestClassB();
145: TestClassB b2 = new TestClassB();
146: a1.setB(b1);
147: a2.setB(b2);
148:
149: Transaction tx = odmg.newTransaction();
150: tx.begin();
151: database.makePersistent(a1);
152: database.makePersistent(a2);
153: database.makePersistent(b1);
154: database.makePersistent(b2);
155: tx.commit();
156: tx = odmg.newTransaction();
157: tx.begin();
158: // get the right values
159: OQLQuery query = odmg.newOQLQuery();
160: query.create("select a from " + TestClassA.class.getName());
161: List As = (List) query.execute();
162: Iterator asIterator = As.iterator();
163: TestClassA temp = null;
164:
165: temp = (TestClassA) asIterator.next();
166: String bID1 = temp.getB().getOid();
167: temp = (TestClassA) asIterator.next();
168: String bID2 = temp.getB().getOid();
169:
170: query = odmg.newOQLQuery();
171: query.create("select a from " + TestClassA.class.getName()
172: + " where (b.oid=$1 or b.oid=$2)");
173: query.bind(bID1);
174: query.bind(bID2);
175: As = (List) query.execute();
176: assertTrue(As.size() == 2);
177: tx.commit();
178: }
179: }
|