1 8 9 package com.sleepycat.collections.test; 10 11 import java.util.Map ; 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 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 [] ACTION_LABELS = { 44 "ABORT", 45 "NULLIFY", 46 "CASCADE", 47 }; 48 49 public static void main(String [] args) 50 throws Exception { 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 { 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 storeMap1; 85 private Map storeMap2; 86 private Map indexMap1; 87 private Map indexMap2; 88 private ForeignKeyDeleteAction onDelete; 89 90 public ForeignKeyTest(TestEnv testEnv, ForeignKeyDeleteAction onDelete, 91 String 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 { 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 e) { 130 System.out.println("Ignored exception during tearDown: " + e); 131 } finally { 132 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 { 150 151 try { 152 createViews(); 153 writeAndRead(); 154 } catch (Exception e) { 155 throw ExceptionUnwrapper.unwrap(e); 156 } 157 } 158 159 private void createDatabase() 160 throws Exception { 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 file) 173 throws Exception { 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 keyName, 184 Database primary, 185 String file, 186 Database foreignStore) 187 throws Exception { 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 { 208 209 storeMap1 = factory.newMap(store1, String .class, 210 MarshalledObject.class, true); 211 storeMap2 = factory.newMap(store2, String .class, 212 MarshalledObject.class, true); 213 indexMap1 = factory.newMap(index1, String .class, 214 MarshalledObject.class, true); 215 indexMap2 = factory.newMap(index2, String .class, 216 MarshalledObject.class, true); 217 } 218 219 private void writeAndRead() 220 throws Exception { 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 250 251 if (onDelete == ForeignKeyDeleteAction.ABORT) { 252 253 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 268 269 o2 = new MarshalledObject("data2", "pk2", "", ""); 270 assertNotNull(storeMap2.put(null, o2)); 271 assertEquals(o2, storeMap2.get("pk2")); 272 273 275 276 assertNull(indexMap2.get("pk1")); 277 278 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 288 289 assertNotNull(storeMap1.remove("pk1")); 290 assertNull(storeMap1.get("pk1")); 291 assertNull(indexMap1.get("ik1")); 292 293 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 306 307 assertNotNull(storeMap1.remove("pk1")); 308 assertNull(storeMap1.get("pk1")); 309 assertNull(indexMap1.get("ik1")); 310 311 312 313 assertNull(storeMap2.get("pk2")); 314 assertNull(indexMap2.get("pk1")); 315 316 } else { 317 throw new IllegalStateException (); 318 } 319 320 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 |