View Javadoc
1   /*
2   Copyright (c) 2014 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.List;
20  import java.util.Map;
21  
22  import static com.healthmarketscience.jackcess.Database.*;
23  import com.healthmarketscience.jackcess.Column;
24  import com.healthmarketscience.jackcess.ColumnBuilder;
25  import com.healthmarketscience.jackcess.CursorBuilder;
26  import com.healthmarketscience.jackcess.DataType;
27  import com.healthmarketscience.jackcess.Database;
28  import com.healthmarketscience.jackcess.IndexCursor;
29  import com.healthmarketscience.jackcess.Row;
30  import com.healthmarketscience.jackcess.Table;
31  import com.healthmarketscience.jackcess.TableBuilder;
32  import junit.framework.TestCase;
33  import static com.healthmarketscience.jackcess.TestUtil.*;
34  import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
35  
36  /**
37   *
38   * @author James Ahlborn
39   */
40  public class ColumnValidatorTest extends TestCase 
41  {
42  
43    public ColumnValidatorTest(String name) {
44      super(name);
45    }
46  
47    public void testValidate() throws Exception {
48      for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
49        Database db = create(fileFormat);
50  
51        ColumnValidatorFactory initFact = db.getColumnValidatorFactory();
52        assertNotNull(initFact);
53  
54        Table table = new TableBuilder("Test")
55          .addColumn(new ColumnBuilder("id", DataType.LONG).setAutoNumber(true))
56          .addColumn(new ColumnBuilder("data", DataType.TEXT))
57          .addColumn(new ColumnBuilder("num", DataType.LONG))
58          .setPrimaryKey("id")
59          .toTable(db);
60  
61        for(Column col : table.getColumns()) {
62          assertSame(SimpleColumnValidator.INSTANCE, col.getColumnValidator());
63        }
64  
65        int val = -1;
66        for(int i = 1; i <= 3; ++i) {
67          table.addRow(Column.AUTO_NUMBER, "row" + i, val++);
68        }
69  
70        table = null;
71  
72        // force table to be reloaded
73        clearTableCache(db);
74        
75        final ColumnValidator cv = new ColumnValidator() {
76          public Object validate(Column col, Object v1) {
77            Number num = (Number)v1;
78            if((num == null) || (num.intValue() < 0)) {
79              throw new IllegalArgumentException("not gonna happen");
80            }
81            return v1;
82          }
83        };
84              
85        ColumnValidatorFactory fact = new ColumnValidatorFactory() {
86          public ColumnValidator createValidator(Column col) {
87            Table t = col.getTable();
88            assertFalse(t.isSystem());
89            if(!"Test".equals(t.getName())) {
90              return null;
91            }
92  
93            if(col.getType() == DataType.LONG) {
94              return cv;
95            }
96  
97            return null;
98          }
99        };
100 
101       db.setColumnValidatorFactory(fact);
102 
103       table = db.getTable("Test");
104       
105       for(Column col : table.getColumns()) {
106         ColumnValidator cur = col.getColumnValidator();
107         assertNotNull(cur);
108         if("num".equals(col.getName())) {
109           assertSame(cv, cur);
110         } else {
111           assertSame(SimpleColumnValidator.INSTANCE, cur);
112         }
113       }
114       
115       Column idCol = table.getColumn("id");
116       Column dataCol = table.getColumn("data");
117       Column numCol = table.getColumn("num");
118 
119       try {
120         idCol.setColumnValidator(cv);
121         fail("IllegalArgumentException should have been thrown");
122       } catch(IllegalArgumentException e) {
123         // success
124       }
125       assertSame(SimpleColumnValidator.INSTANCE, idCol.getColumnValidator());
126       
127       try {
128         table.addRow(Column.AUTO_NUMBER, "row4", -3);
129         fail("IllegalArgumentException should have been thrown");
130       } catch(IllegalArgumentException e) {
131         assertEquals("not gonna happen", e.getMessage());
132       }
133 
134       table.addRow(Column.AUTO_NUMBER, "row4", 4);
135 
136       List<? extends Map<String, Object>> expectedRows =
137         createExpectedTable(
138             createExpectedRow("id", 1, "data", "row1", "num", -1),
139             createExpectedRow("id", 2, "data", "row2", "num", 0),
140             createExpectedRow("id", 3, "data", "row3", "num", 1),
141             createExpectedRow("id", 4, "data", "row4", "num", 4));
142       
143       assertTable(expectedRows, table);
144 
145       IndexCursor pkCursor = CursorBuilder.createPrimaryKeyCursor(table);
146       assertNotNull(pkCursor.findRowByEntry(1));
147       
148       pkCursor.setCurrentRowValue(dataCol, "row1_mod");
149 
150       assertEquals(createExpectedRow("id", 1, "data", "row1_mod", "num", -1),
151                    pkCursor.getCurrentRow());
152 
153       try {
154         pkCursor.setCurrentRowValue(numCol, -2);
155         fail("IllegalArgumentException should have been thrown");
156       } catch(IllegalArgumentException e) {
157         assertEquals("not gonna happen", e.getMessage());
158       }
159 
160       assertEquals(createExpectedRow("id", 1, "data", "row1_mod", "num", -1),
161                    pkCursor.getCurrentRow());
162 
163       Row row3 = CursorBuilder.findRowByPrimaryKey(table, 3);
164 
165       row3.put("num", -2);
166 
167       try {
168         table.updateRow(row3);
169         fail("IllegalArgumentException should have been thrown");
170       } catch(IllegalArgumentException e) {
171         assertEquals("not gonna happen", e.getMessage());
172       }
173 
174       assertEquals(createExpectedRow("id", 3, "data", "row3", "num", 1),
175                    CursorBuilder.findRowByPrimaryKey(table, 3));
176 
177       final ColumnValidator cv2 = new ColumnValidator() {
178         public Object validate(Column col, Object v1) {
179           Number num = (Number)v1;
180           if((num == null) || (num.intValue() < 0)) {
181             return 0;
182           }
183           return v1;
184         }
185       };
186 
187       numCol.setColumnValidator(cv2);
188 
189       table.addRow(Column.AUTO_NUMBER, "row5", -5);
190 
191       expectedRows =
192         createExpectedTable(
193             createExpectedRow("id", 1, "data", "row1_mod", "num", -1),
194             createExpectedRow("id", 2, "data", "row2", "num", 0),
195             createExpectedRow("id", 3, "data", "row3", "num", 1),
196             createExpectedRow("id", 4, "data", "row4", "num", 4),
197             createExpectedRow("id", 5, "data", "row5", "num", 0));
198       
199       assertTable(expectedRows, table);
200 
201       assertNotNull(pkCursor.findRowByEntry(3));
202       pkCursor.setCurrentRowValue(numCol, -10);
203 
204       assertEquals(createExpectedRow("id", 3, "data", "row3", "num", 0),
205                    pkCursor.getCurrentRow());
206       
207       db.close();
208     }
209   }  
210 }