View Javadoc
1   /*
2   Copyright (c) 2016 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;
18  
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.LinkedHashMap;
22  import java.util.List;
23  import java.util.Map;
24  
25  import com.healthmarketscience.jackcess.Database.FileFormat;
26  import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
27  import com.healthmarketscience.jackcess.impl.DatabaseImpl;
28  import com.healthmarketscience.jackcess.impl.TableImpl;
29  import junit.framework.TestCase;
30  import static com.healthmarketscience.jackcess.TestUtil.*;
31  
32  /**
33   *
34   * @author James Ahlborn
35   */
36  public class TableUpdaterTest extends TestCase
37  {
38  
39    public TableUpdaterTest(String name) throws Exception {
40      super(name);
41    }
42  
43    public void testTableUpdating() throws Exception {
44      for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
45        Database db = create(fileFormat);
46  
47        doTestUpdating(db, false, true, null);
48   
49        db.close();
50      }    
51    }
52  
53    public void testTableUpdatingOneToOne() throws Exception {
54      for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
55        Database db = create(fileFormat);
56  
57        doTestUpdating(db, true, true, null);
58   
59        db.close();
60      }    
61    }
62  
63    public void testTableUpdatingNoEnforce() throws Exception {
64      for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
65        Database db = create(fileFormat);
66  
67        doTestUpdating(db, false, false, null);
68   
69        db.close();
70      }    
71    }
72  
73    public void testTableUpdatingNamedRelationship() throws Exception {
74      for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
75        Database db = create(fileFormat);
76  
77        doTestUpdating(db, false, true, "FKnun3jvv47l9kyl74h85y8a0if");
78   
79        db.close();
80      }    
81    }
82  
83    private void doTestUpdating(Database db, boolean oneToOne, boolean enforce, String relationshipName) 
84      throws Exception
85    {
86      Table t1 = new TableBuilder("TestTable")
87        .addColumn(new ColumnBuilder("id", DataType.LONG))
88        .toTable(db);
89        
90      Table t2 = new TableBuilder("TestTable2")
91        .addColumn(new ColumnBuilder("id2", DataType.LONG))
92        .toTable(db);
93  
94      int t1idxs = 1;
95      new IndexBuilder(IndexBuilder.PRIMARY_KEY_NAME)
96        .addColumns("id").setPrimaryKey()
97        .addToTable(t1);
98      new ColumnBuilder("data", DataType.TEXT)
99        .addToTable(t1);
100     new ColumnBuilder("bigdata", DataType.MEMO)
101       .addToTable(t1);
102 
103     new ColumnBuilder("data2", DataType.TEXT)
104       .addToTable(t2);
105     new ColumnBuilder("bigdata2", DataType.MEMO)
106       .addToTable(t2);
107 
108     int t2idxs = 0;
109     if(oneToOne) {
110       ++t2idxs;
111       new IndexBuilder(IndexBuilder.PRIMARY_KEY_NAME)
112         .addColumns("id2").setPrimaryKey()
113         .addToTable(t2);
114     }
115 
116     RelationshipBuilder rb = new RelationshipBuilder("TestTable", "TestTable2")
117       .addColumns("id", "id2");
118     if(enforce) {
119       ++t1idxs;
120       ++t2idxs;      
121       rb.setReferentialIntegrity()
122         .setCascadeDeletes();
123     }
124     
125     if (relationshipName != null) {
126       rb.setName(relationshipName);
127     }
128 
129     Relationship rel = rb.toRelationship(db);
130 
131     if (relationshipName == null) {
132       assertEquals("TestTableTestTable2", rel.getName());
133     } else {
134       assertEquals(relationshipName, rel.getName());
135     }
136     assertSame(t1, rel.getFromTable());
137     assertEquals(Arrays.asList(t1.getColumn("id")), rel.getFromColumns());
138     assertSame(t2, rel.getToTable());
139     assertEquals(Arrays.asList(t2.getColumn("id2")), rel.getToColumns());
140     assertEquals(oneToOne, rel.isOneToOne());
141     assertEquals(enforce, rel.hasReferentialIntegrity());
142     assertEquals(enforce, rel.cascadeDeletes());
143     assertFalse(rel.cascadeUpdates());
144     assertEquals(Relationship.JoinType.INNER, rel.getJoinType());
145 
146     assertEquals(t1idxs, t1.getIndexes().size());
147     assertEquals(1, ((TableImpl)t1).getIndexDatas().size());
148 
149     assertEquals(t2idxs, t2.getIndexes().size());
150     assertEquals((t2idxs > 0 ? 1 : 0), ((TableImpl)t2).getIndexDatas().size());
151 
152     ((DatabaseImpl)db).getPageChannel().startWrite();
153     try {
154 
155       for(int i = 0; i < 10; ++i) {
156         t1.addRow(i, "row" + i, "row-data" + i);
157       }
158 
159       for(int i = 0; i < 10; ++i) {
160         t2.addRow(i, "row2_" + i, "row-data2_" + i);
161       }
162 
163     } finally {
164       ((DatabaseImpl)db).getPageChannel().finishWrite();
165     }
166 
167     try {
168       t2.addRow(10, "row10", "row-data10");
169       if(enforce) {
170         fail("ConstraintViolationException should have been thrown");
171       } 
172     } catch(ConstraintViolationException cv) {
173       // success
174       if(!enforce) { throw cv; }
175     }
176 
177     Row r1 = CursorBuilder.findRowByPrimaryKey(t1, 5);
178     t1.deleteRow(r1);
179    
180     int id = 0;
181     for(Row r : t1) {
182       assertEquals(id, r.get("id"));
183       ++id;
184       if(id == 5) {
185         ++id;
186       }
187     }
188  
189     id = 0;
190     for(Row r : t2) {
191       assertEquals(id, r.get("id2"));
192       ++id;
193       if(enforce && (id == 5)) {
194         ++id;
195       }
196     }
197   }
198 
199   public void testInvalidUpdate() throws Exception
200   {
201     for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
202       Database db = create(fileFormat);
203 
204       Table t1 = new TableBuilder("TestTable")
205         .addColumn(new ColumnBuilder("id", DataType.LONG))
206         .toTable(db);
207 
208       try {
209         new ColumnBuilder("ID", DataType.TEXT)
210           .addToTable(t1);
211         fail("created table with no columns?");
212       } catch(IllegalArgumentException e) {
213         // success
214       }
215 
216       Table t2 = new TableBuilder("TestTable2")
217         .addColumn(new ColumnBuilder("id2", DataType.LONG))
218         .toTable(db);
219 
220       try {
221         new RelationshipBuilder(t1, t2)
222           .toRelationship(db);
223         fail("created rel with no columns?");
224       } catch(IllegalArgumentException e) {
225         // success
226       }
227 
228       try {
229         new RelationshipBuilder("TestTable", "TestTable2")
230           .addColumns("id", "id")
231           .toRelationship(db);
232         fail("created rel with wrong columns?");
233       } catch(IllegalArgumentException e) {
234         // success
235       }
236  
237       db.close();
238     }    
239   }
240 
241   public void testUpdateLargeTableDef() throws Exception
242   {
243     for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
244       Database db = create(fileFormat);
245 
246       final int numColumns = 89;
247 
248       Table t = new TableBuilder("test")
249         .addColumn(new ColumnBuilder("first", DataType.TEXT))
250         .toTable(db);
251 
252       List<String> colNames = new ArrayList<String>();
253       colNames.add("first");
254       for(int i = 0; i < numColumns; ++i) {
255         String colName = "MyColumnName" + i;
256         colNames.add(colName);
257         DataType type = (((i % 3) == 0) ? DataType.MEMO : DataType.TEXT);
258         new ColumnBuilder(colName, type)
259           .addToTable(t);
260       }
261 
262       List<String> row = new ArrayList<String>();
263       Map<String,Object> expectedRowData = new LinkedHashMap<String, Object>();
264       for(int i = 0; i < colNames.size(); ++i) {
265         String value = "" + i + " some row data";
266         row.add(value);
267         expectedRowData.put(colNames.get(i), value);
268       }
269 
270       t.addRow(row.toArray());
271 
272       t.reset();
273       assertEquals(expectedRowData, t.getNextRow());
274 
275       db.close();
276     }
277   } 
278 }