KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > collections > test > ForeignKeyTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2000,2006 Oracle. All rights reserved.
5  *
6  * $Id: ForeignKeyTest.java,v 1.30 2006/10/30 21:14:38 bostic Exp $
7  */

8
9 package com.sleepycat.collections.test;
10
11 import java.util.Map JavaDoc;
12
13 import junit.framework.Test;
14 import junit.framework.TestCase;
15 import junit.framework.TestSuite;
16
17 import com.sleepycat.bind.serial.StoredClassCatalog;
18 import com.sleepycat.bind.serial.TupleSerialMarshalledKeyCreator;
19 import com.sleepycat.bind.serial.test.MarshalledObject;
20 import com.sleepycat.collections.CurrentTransaction;
21 import com.sleepycat.collections.TupleSerialFactory;
22 import com.sleepycat.compat.DbCompat;
23 import com.sleepycat.je.Database;
24 import com.sleepycat.je.DatabaseConfig;
25 import com.sleepycat.je.DatabaseException;
26 import com.sleepycat.je.Environment;
27 import com.sleepycat.je.ForeignKeyDeleteAction;
28 import com.sleepycat.je.SecondaryConfig;
29 import com.sleepycat.je.SecondaryDatabase;
30 import com.sleepycat.util.ExceptionUnwrapper;
31 import com.sleepycat.util.RuntimeExceptionWrapper;
32
33 /**
34  * @author Mark Hayes
35  */

36 public class ForeignKeyTest extends TestCase {
37
38     private static final ForeignKeyDeleteAction[] ACTIONS = {
39         ForeignKeyDeleteAction.ABORT,
40         ForeignKeyDeleteAction.NULLIFY,
41         ForeignKeyDeleteAction.CASCADE,
42     };
43     private static final String JavaDoc[] ACTION_LABELS = {
44         "ABORT",
45         "NULLIFY",
46         "CASCADE",
47     };
48
49     public static void main(String JavaDoc[] args)
50         throws Exception JavaDoc {
51
52         junit.framework.TestResult tr =
53             junit.textui.TestRunner.run(suite());
54         if (tr.errorCount() > 0 ||
55             tr.failureCount() > 0) {
56             System.exit(1);
57         } else {
58             System.exit(0);
59         }
60     }
61
62     public static Test suite()
63         throws Exception JavaDoc {
64
65         TestSuite suite = new TestSuite();
66         for (int i = 0; i < TestEnv.ALL.length; i += 1) {
67             for (int j = 0; j < ACTIONS.length; j += 1) {
68                 suite.addTest(new ForeignKeyTest(TestEnv.ALL[i],
69                                                  ACTIONS[j],
70                                                  ACTION_LABELS[j]));
71             }
72         }
73         return suite;
74     }
75
76     private TestEnv testEnv;
77     private Environment env;
78     private StoredClassCatalog catalog;
79     private TupleSerialFactory factory;
80     private Database store1;
81     private Database store2;
82     private SecondaryDatabase index1;
83     private SecondaryDatabase index2;
84     private Map JavaDoc storeMap1;
85     private Map JavaDoc storeMap2;
86     private Map JavaDoc indexMap1;
87     private Map JavaDoc indexMap2;
88     private ForeignKeyDeleteAction onDelete;
89
90     public ForeignKeyTest(TestEnv testEnv, ForeignKeyDeleteAction onDelete,
91                           String JavaDoc onDeleteLabel) {
92
93         super("ForeignKeyTest-" + testEnv.getName() + '-' + onDeleteLabel);
94
95         this.testEnv = testEnv;
96         this.onDelete = onDelete;
97     }
98
99     public void setUp()
100         throws Exception JavaDoc {
101
102         DbTestUtil.printTestName(getName());
103         env = testEnv.open(getName());
104
105         createDatabase();
106     }
107
108     public void tearDown() {
109
110         try {
111             if (index1 != null) {
112                 index1.close();
113             }
114             if (index2 != null) {
115                 index2.close();
116             }
117             if (store1 != null) {
118                 store1.close();
119             }
120             if (store2 != null) {
121                 store2.close();
122             }
123             if (catalog != null) {
124                 catalog.close();
125             }
126             if (env != null) {
127                 env.close();
128             }
129         } catch (Exception JavaDoc e) {
130             System.out.println("Ignored exception during tearDown: " + e);
131     } finally {
132             /* Ensure that GC can cleanup. */
133             env = null;
134         testEnv = null;
135             catalog = null;
136             store1 = null;
137             store2 = null;
138             index1 = null;
139             index2 = null;
140             factory = null;
141             storeMap1 = null;
142             storeMap2 = null;
143             indexMap1 = null;
144             indexMap2 = null;
145         }
146     }
147
148     public void runTest()
149         throws Exception JavaDoc {
150
151         try {
152             createViews();
153             writeAndRead();
154         } catch (Exception JavaDoc e) {
155             throw ExceptionUnwrapper.unwrap(e);
156         }
157     }
158
159     private void createDatabase()
160         throws Exception JavaDoc {
161
162         catalog = new StoredClassCatalog(openDb("catalog.db"));
163         factory = new TupleSerialFactory(catalog);
164         assertSame(catalog, factory.getCatalog());
165
166         store1 = openDb("store1.db");
167         store2 = openDb("store2.db");
168         index1 = openSecondaryDb(factory, "1", store1, "index1.db", null);
169         index2 = openSecondaryDb(factory, "2", store2, "index2.db", store1);
170     }
171
172     private Database openDb(String JavaDoc file)
173         throws Exception JavaDoc {
174
175         DatabaseConfig config = new DatabaseConfig();
176         config.setTransactional(testEnv.isTxnMode());
177         config.setAllowCreate(true);
178
179         return DbCompat.openDatabase(env, null, file, null, config);
180     }
181
182     private SecondaryDatabase openSecondaryDb(TupleSerialFactory factory,
183                                               String JavaDoc keyName,
184                                               Database primary,
185                                               String JavaDoc file,
186                                               Database foreignStore)
187         throws Exception JavaDoc {
188
189         TupleSerialMarshalledKeyCreator keyCreator =
190                 factory.getKeyCreator(MarshalledObject.class, keyName);
191
192         SecondaryConfig secConfig = new SecondaryConfig();
193         secConfig.setTransactional(testEnv.isTxnMode());
194         secConfig.setAllowCreate(true);
195         secConfig.setKeyCreator(keyCreator);
196         if (foreignStore != null) {
197             secConfig.setForeignKeyDatabase(foreignStore);
198             secConfig.setForeignKeyDeleteAction(onDelete);
199             secConfig.setForeignKeyNullifier(keyCreator);
200         }
201
202         return DbCompat.openSecondaryDatabase(env, null, file, null,
203                                               primary, secConfig);
204     }
205
206     private void createViews()
207         throws Exception JavaDoc {
208
209         storeMap1 = factory.newMap(store1, String JavaDoc.class,
210                                    MarshalledObject.class, true);
211         storeMap2 = factory.newMap(store2, String JavaDoc.class,
212                                    MarshalledObject.class, true);
213         indexMap1 = factory.newMap(index1, String JavaDoc.class,
214                                    MarshalledObject.class, true);
215         indexMap2 = factory.newMap(index2, String JavaDoc.class,
216                                    MarshalledObject.class, true);
217     }
218
219     private void writeAndRead()
220         throws Exception JavaDoc {
221
222         CurrentTransaction txn = CurrentTransaction.getInstance(env);
223         if (txn != null) {
224             txn.beginTransaction(null);
225         }
226
227         MarshalledObject o1 = new MarshalledObject("data1", "pk1", "ik1", "");
228         assertNull(storeMap1.put(null, o1));
229
230         assertEquals(o1, storeMap1.get("pk1"));
231         assertEquals(o1, indexMap1.get("ik1"));
232
233         MarshalledObject o2 = new MarshalledObject("data2", "pk2", "", "pk1");
234         assertNull(storeMap2.put(null, o2));
235
236         assertEquals(o2, storeMap2.get("pk2"));
237         assertEquals(o2, indexMap2.get("pk1"));
238
239         if (txn != null) {
240             txn.commitTransaction();
241             txn.beginTransaction(null);
242         }
243
244         /*
245          * store1 contains o1 with primary key "pk1" and index key "ik1".
246          *
247          * store2 contains o2 with primary key "pk2" and foreign key "pk1",
248          * which is the primary key of store1.
249          */

250
251         if (onDelete == ForeignKeyDeleteAction.ABORT) {
252
253             /* Test that we abort trying to delete a referenced key. */
254
255             try {
256                 storeMap1.remove("pk1");
257                 fail();
258             } catch (RuntimeExceptionWrapper expected) {
259                 assertTrue(expected.getCause() instanceof DatabaseException);
260                 if (txn != null) {
261                     txn.abortTransaction();
262                     txn.beginTransaction(null);
263                 }
264             }
265
266             /* Test that we can put a record into store2 with a null foreign
267              * key value. */

268
269             o2 = new MarshalledObject("data2", "pk2", "", "");
270             assertNotNull(storeMap2.put(null, o2));
271             assertEquals(o2, storeMap2.get("pk2"));
272
273             /* The index2 record should have been deleted since the key was set
274              * to null above. */

275
276             assertNull(indexMap2.get("pk1"));
277
278             /* Test that now we can delete the record in store1, since it is no
279              * longer referenced. */

280
281             assertNotNull(storeMap1.remove("pk1"));
282             assertNull(storeMap1.get("pk1"));
283             assertNull(indexMap1.get("ik1"));
284
285         } else if (onDelete == ForeignKeyDeleteAction.NULLIFY) {
286
287             /* Delete the referenced key. */
288
289             assertNotNull(storeMap1.remove("pk1"));
290             assertNull(storeMap1.get("pk1"));
291             assertNull(indexMap1.get("ik1"));
292
293             /* The store2 record should still exist, but should have an empty
294              * secondary key since it was nullified. */

295
296             o2 = (MarshalledObject) storeMap2.get("pk2");
297             assertNotNull(o2);
298             assertEquals("data2", o2.getData());
299             assertEquals("pk2", o2.getPrimaryKey());
300             assertEquals("", o2.getIndexKey1());
301             assertEquals("", o2.getIndexKey2());
302
303         } else if (onDelete == ForeignKeyDeleteAction.CASCADE) {
304
305             /* Delete the referenced key. */
306
307             assertNotNull(storeMap1.remove("pk1"));
308             assertNull(storeMap1.get("pk1"));
309             assertNull(indexMap1.get("ik1"));
310
311             /* The store2 record should have deleted also. */
312
313             assertNull(storeMap2.get("pk2"));
314             assertNull(indexMap2.get("pk1"));
315
316         } else {
317             throw new IllegalStateException JavaDoc();
318         }
319
320         /*
321          * Test that a foreign key value may not be used that is not present
322          * in the foreign store. "pk2" is not in store1 in this case.
323          */

324         MarshalledObject o3 = new MarshalledObject("data3", "pk3", "", "pk2");
325         try {
326             storeMap2.put(null, o3);
327             fail();
328         } catch (RuntimeExceptionWrapper expected) {
329             assertTrue(expected.getCause() instanceof DatabaseException);
330         }
331
332         if (txn != null) {
333             txn.commitTransaction();
334         }
335     }
336 }
337
338
Popular Tags