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  import java.util.stream.Collectors;
27  
28  import com.healthmarketscience.jackcess.Database;
29  import com.healthmarketscience.jackcess.Index;
30  import com.healthmarketscience.jackcess.Row;
31  import com.healthmarketscience.jackcess.Table;
32  import com.healthmarketscience.jackcess.impl.RowImpl;
33  import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
34  import junit.framework.TestCase;
35  import static com.healthmarketscience.jackcess.TestUtil.*;
36  
37  /**
38   *
39   * @author James Ahlborn
40   */
41  public class JoinerTest extends TestCase {
42  
43    public JoinerTest(String name) {
44      super(name);
45    }
46  
47    public void testJoiner() throws Exception
48    {
49      for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX)) {
50  
51        Database db = openCopy(testDB);
52        Table t1 = db.getTable("Table1");
53        Table t2 = db.getTable("Table2");
54        Table t3 = db.getTable("Table3");
55  
56        Index t1t2 = t1.getIndex("Table2Table1");
57        Index t1t3 = t1.getIndex("Table3Table1");
58  
59        Index t2t1 = t1t2.getReferencedIndex();
60        assertSame(t2, t2t1.getTable());
61        Joiner t2t1Join = Joiner.create(t2t1);
62  
63        assertSame(t2, t2t1Join.getFromTable());
64        assertSame(t2t1, t2t1Join.getFromIndex());
65        assertSame(t1, t2t1Join.getToTable());
66        assertSame(t1t2, t2t1Join.getToIndex());
67  
68        doTestJoiner(t2t1Join, createT2T1Data());
69  
70        Index t3t1 = t1t3.getReferencedIndex();
71        assertSame(t3, t3t1.getTable());
72        Joiner t3t1Join = Joiner.create(t3t1);
73  
74        assertSame(t3, t3t1Join.getFromTable());
75        assertSame(t3t1, t3t1Join.getFromIndex());
76        assertSame(t1, t3t1Join.getToTable());
77        assertSame(t1t3, t3t1Join.getToIndex());
78  
79        doTestJoiner(t3t1Join, createT3T1Data());
80  
81        doTestJoinerDelete(t2t1Join);
82      }
83    }
84  
85    private static void doTestJoiner(
86        Joiner join, Map<Integer,List<Row>> expectedData)
87      throws Exception
88    {
89      final Set<String> colNames = new HashSet<String>(
90          Arrays.asList("id", "data"));
91  
92      Joiner revJoin = join.createReverse();
93      for(Row row : join.getFromTable()) {
94        Integer id = row.getInt("id");
95  
96        List<Row> joinedRows = join.findRows(row).stream()
97          .collect(Collectors.toList());
98  
99        List<Row> expectedRows = expectedData.get(id);
100       assertEquals(expectedData.get(id), joinedRows);
101 
102       if(!expectedRows.isEmpty()) {
103         assertTrue(join.hasRows(row));
104         assertEquals(expectedRows.get(0), join.findFirstRow(row));
105 
106         assertEquals(row, revJoin.findFirstRow(expectedRows.get(0)));
107       } else {
108         assertFalse(join.hasRows(row));
109         assertNull(join.findFirstRow(row));
110       }
111 
112       List<Row> expectedRows2 = new ArrayList<Row>();
113       for(Row tmpRow : expectedRows) {
114         Row tmpRow2 = new RowImpl(tmpRow);
115         tmpRow2.keySet().retainAll(colNames);
116         expectedRows2.add(tmpRow2);
117       }
118 
119       joinedRows = join.findRows(row).setColumnNames(colNames)
120         .stream().collect(Collectors.toList());
121 
122       assertEquals(expectedRows2, joinedRows);
123 
124       if(!expectedRows2.isEmpty()) {
125         assertEquals(expectedRows2.get(0), join.findFirstRow(row, colNames));
126       } else {
127         assertNull(join.findFirstRow(row, colNames));
128       }
129     }
130   }
131 
132   private static void doTestJoinerDelete(Joiner t2t1Join) throws Exception
133   {
134     assertEquals(4, countRows(t2t1Join.getToTable()));
135 
136     Row row = createExpectedRow("id", 1);
137     assertTrue(t2t1Join.hasRows(row));
138 
139     assertTrue(t2t1Join.deleteRows(row));
140 
141     assertFalse(t2t1Join.hasRows(row));
142     assertFalse(t2t1Join.deleteRows(row));
143 
144     assertEquals(2, countRows(t2t1Join.getToTable()));
145     for(Row t1Row : t2t1Join.getToTable()) {
146       assertFalse(t1Row.get("otherfk1").equals(1));
147     }
148   }
149 
150   private static Map<Integer,List<Row>> createT2T1Data()
151   {
152     Map<Integer,List<Row>> data = new
153       HashMap<Integer,List<Row>>();
154 
155     data.put(0,
156              createExpectedTable(
157                  createExpectedRow("id", 0, "otherfk1", 0, "otherfk2", 10,
158                                    "data", "baz0", "otherfk3", 0)));
159 
160     data.put(1,
161              createExpectedTable(
162                  createExpectedRow("id", 1, "otherfk1", 1, "otherfk2", 11,
163                                    "data", "baz11", "otherfk3", 0),
164                  createExpectedRow("id", 2, "otherfk1", 1, "otherfk2", 11,
165                                    "data", "baz11-2", "otherfk3", 0)));
166 
167     data.put(2,
168              createExpectedTable(
169                  createExpectedRow("id", 3, "otherfk1", 2, "otherfk2", 13,
170                                    "data", "baz13", "otherfk3", 0)));
171 
172     return data;
173   }
174 
175   private static Map<Integer,List<Row>> createT3T1Data()
176   {
177     Map<Integer,List<Row>> data = new HashMap<Integer,List<Row>>();
178 
179     data.put(10,
180              createExpectedTable(
181                  createExpectedRow("id", 0, "otherfk1", 0, "otherfk2", 10,
182                                    "data", "baz0", "otherfk3", 0)));
183 
184     data.put(11,
185              createExpectedTable(
186                  createExpectedRow("id", 1, "otherfk1", 1, "otherfk2", 11,
187                                    "data", "baz11", "otherfk3", 0),
188                  createExpectedRow("id", 2, "otherfk1", 1, "otherfk2", 11,
189                                    "data", "baz11-2", "otherfk3", 0)));
190 
191     data.put(12,
192              createExpectedTable());
193 
194     data.put(13,
195              createExpectedTable(
196                  createExpectedRow("id", 3, "otherfk1", 2, "otherfk2", 13,
197                                    "data", "baz13", "otherfk3", 0)));
198 
199     return data;
200   }
201 
202 }