View Javadoc
1   /*
2   Copyright (c) 2011 James Ahlborn
3   
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7   
8       http://www.apache.org/licenses/LICENSE-2.0
9   
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16  
17  package com.healthmarketscience.jackcess.util;
18  
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.HashMap;
22  import java.util.HashSet;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import com.healthmarketscience.jackcess.Database;
28  import com.healthmarketscience.jackcess.Index;
29  import com.healthmarketscience.jackcess.Row;
30  import com.healthmarketscience.jackcess.Table;
31  import com.healthmarketscience.jackcess.impl.RowImpl;
32  import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
33  import junit.framework.TestCase;
34  import static com.healthmarketscience.jackcess.TestUtil.*;
35  
36  /**
37   *
38   * @author James Ahlborn
39   */
40  public class JoinerTest extends TestCase {
41  
42    public JoinerTest(String name) {
43      super(name);
44    }
45  
46    public void testJoiner() throws Exception
47    {
48      for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX)) {
49  
50        Database db = openCopy(testDB);
51        Table t1 = db.getTable("Table1");
52        Table t2 = db.getTable("Table2");
53        Table t3 = db.getTable("Table3");
54  
55        Index t1t2 = t1.getIndex("Table2Table1");
56        Index t1t3 = t1.getIndex("Table3Table1");
57  
58        Index t2t1 = t1t2.getReferencedIndex();
59        assertSame(t2, t2t1.getTable());
60        Joiner t2t1Join = Joiner.create(t2t1);
61  
62        assertSame(t2, t2t1Join.getFromTable());
63        assertSame(t2t1, t2t1Join.getFromIndex());
64        assertSame(t1, t2t1Join.getToTable());
65        assertSame(t1t2, t2t1Join.getToIndex());
66        
67        doTestJoiner(t2t1Join, createT2T1Data());
68        
69        Index t3t1 = t1t3.getReferencedIndex();
70        assertSame(t3, t3t1.getTable());
71        Joiner t3t1Join = Joiner.create(t3t1);
72  
73        assertSame(t3, t3t1Join.getFromTable());
74        assertSame(t3t1, t3t1Join.getFromIndex());
75        assertSame(t1, t3t1Join.getToTable());
76        assertSame(t1t3, t3t1Join.getToIndex());
77        
78        doTestJoiner(t3t1Join, createT3T1Data());      
79  
80        doTestJoinerDelete(t2t1Join);
81      }    
82    }
83  
84    private static void doTestJoiner(
85        Joiner join, Map<Integer,List<Row>> expectedData)
86      throws Exception
87    {
88      final Set<String> colNames = new HashSet<String>(
89          Arrays.asList("id", "data"));
90  
91      Joiner revJoin = join.createReverse();
92      for(Row row : join.getFromTable()) {
93        Integer id = row.getInt("id");
94  
95        List<Row> joinedRows =
96          new ArrayList<Row>();
97        for(Row t1Row : join.findRows(row)) {
98          joinedRows.add(t1Row);
99        }
100 
101       List<Row> expectedRows = expectedData.get(id);
102       assertEquals(expectedData.get(id), joinedRows);
103 
104       if(!expectedRows.isEmpty()) {
105         assertTrue(join.hasRows(row));
106         assertEquals(expectedRows.get(0), join.findFirstRow(row));
107 
108         assertEquals(row, revJoin.findFirstRow(expectedRows.get(0)));
109       } else {
110         assertFalse(join.hasRows(row));
111         assertNull(join.findFirstRow(row));
112       }
113       
114       List<Row> expectedRows2 = new ArrayList<Row>();
115       for(Row tmpRow : expectedRows) {
116         Row tmpRow2 = new RowImpl(tmpRow);
117         tmpRow2.keySet().retainAll(colNames);
118         expectedRows2.add(tmpRow2);
119       }
120       
121       joinedRows = new ArrayList<Row>();
122       for(Row t1Row : join.findRows(row).setColumnNames(colNames)) {
123         joinedRows.add(t1Row);
124       }
125 
126       assertEquals(expectedRows2, joinedRows);
127 
128       if(!expectedRows2.isEmpty()) {
129         assertEquals(expectedRows2.get(0), join.findFirstRow(row, colNames));
130       } else {
131         assertNull(join.findFirstRow(row, colNames));
132       }      
133     }
134   }
135 
136   private static void doTestJoinerDelete(Joiner t2t1Join) throws Exception
137   {
138     assertEquals(4, countRows(t2t1Join.getToTable()));
139 
140     Row row = createExpectedRow("id", 1);
141     assertTrue(t2t1Join.hasRows(row));
142 
143     assertTrue(t2t1Join.deleteRows(row));
144 
145     assertFalse(t2t1Join.hasRows(row));
146     assertFalse(t2t1Join.deleteRows(row));
147 
148     assertEquals(2, countRows(t2t1Join.getToTable()));
149     for(Row t1Row : t2t1Join.getToTable()) {
150       assertFalse(t1Row.get("otherfk1").equals(1));
151     }
152   }
153 
154   private static Map<Integer,List<Row>> createT2T1Data()
155   {
156     Map<Integer,List<Row>> data = new
157       HashMap<Integer,List<Row>>();
158 
159     data.put(0,
160              createExpectedTable(
161                  createExpectedRow("id", 0, "otherfk1", 0, "otherfk2", 10,
162                                    "data", "baz0", "otherfk3", 0)));
163 
164     data.put(1,
165              createExpectedTable(
166                  createExpectedRow("id", 1, "otherfk1", 1, "otherfk2", 11,
167                                    "data", "baz11", "otherfk3", 0),
168                  createExpectedRow("id", 2, "otherfk1", 1, "otherfk2", 11,
169                                    "data", "baz11-2", "otherfk3", 0)));
170 
171     data.put(2,
172              createExpectedTable(
173                  createExpectedRow("id", 3, "otherfk1", 2, "otherfk2", 13,
174                                    "data", "baz13", "otherfk3", 0)));
175 
176     return data;
177   }
178   
179   private static Map<Integer,List<Row>> createT3T1Data()
180   {
181     Map<Integer,List<Row>> data = new HashMap<Integer,List<Row>>();
182 
183     data.put(10,
184              createExpectedTable(
185                  createExpectedRow("id", 0, "otherfk1", 0, "otherfk2", 10,
186                                    "data", "baz0", "otherfk3", 0)));
187 
188     data.put(11,
189              createExpectedTable(
190                  createExpectedRow("id", 1, "otherfk1", 1, "otherfk2", 11,
191                                    "data", "baz11", "otherfk3", 0),
192                  createExpectedRow("id", 2, "otherfk1", 1, "otherfk2", 11,
193                                    "data", "baz11-2", "otherfk3", 0)));
194 
195     data.put(12,
196              createExpectedTable());
197 
198     data.put(13,
199              createExpectedTable(
200                  createExpectedRow("id", 3, "otherfk1", 2, "otherfk2", 13,
201                                    "data", "baz13", "otherfk3", 0)));
202 
203     return data;
204   }
205   
206 }