1 8 9 package je; 10 11 import java.io.File ; 12 import java.io.Serializable ; 13 import java.util.HashSet ; 14 import java.util.Iterator ; 15 import java.util.Set ; 16 17 import com.sleepycat.bind.EntryBinding; 18 import com.sleepycat.bind.serial.SerialBinding; 19 import com.sleepycat.bind.serial.StoredClassCatalog; 20 import com.sleepycat.bind.tuple.StringBinding; 21 import com.sleepycat.je.Database; 22 import com.sleepycat.je.DatabaseConfig; 23 import com.sleepycat.je.DatabaseEntry; 24 import com.sleepycat.je.DatabaseException; 25 import com.sleepycat.je.Environment; 26 import com.sleepycat.je.EnvironmentConfig; 27 import com.sleepycat.je.ForeignKeyDeleteAction; 28 import com.sleepycat.je.ForeignMultiKeyNullifier; 29 import com.sleepycat.je.OperationStatus; 30 import com.sleepycat.je.SecondaryConfig; 31 import com.sleepycat.je.SecondaryCursor; 32 import com.sleepycat.je.SecondaryDatabase; 33 import com.sleepycat.je.SecondaryMultiKeyCreator; 34 import com.sleepycat.je.Transaction; 35 36 39 public class ToManyExample { 40 41 private Environment env; 42 private Database catalogDb; 43 private Database animalDb; 44 private Database personDb; 45 private SecondaryDatabase personByEmail; 46 private SecondaryDatabase personByAnimal; 47 private EntryBinding keyBinding; 48 private EntryBinding dataBinding; 49 50 53 public static void main(String [] args) { 54 55 if (args.length != 2 || !"-h".equals(args[0])) { 56 System.out.println("Usage: java " + 57 ToManyExample.class.getName() + 58 " -h ENV_HOME"); 59 System.exit(1); 60 } 61 String homeDir = args[1]; 62 63 try { 64 ToManyExample example = new ToManyExample(homeDir); 65 example.exec(); 66 example.close(); 67 } catch (DatabaseException e) { 68 e.printStackTrace(); 69 } 70 } 71 72 75 private ToManyExample(String homeDir) throws DatabaseException { 76 77 78 EnvironmentConfig envConfig = new EnvironmentConfig(); 79 envConfig.setAllowCreate(true); 80 envConfig.setTransactional(true); 81 env = new Environment(new File (homeDir), envConfig); 82 83 84 Transaction txn = env.beginTransaction(null, null); 85 try { 86 87 DatabaseConfig dbConfig = new DatabaseConfig(); 88 dbConfig.setAllowCreate(true); 89 dbConfig.setTransactional(true); 90 91 92 catalogDb = env.openDatabase(txn, "catalog", dbConfig); 93 StoredClassCatalog catalog = new StoredClassCatalog(catalogDb); 94 dataBinding = new SerialBinding(catalog, null); 95 keyBinding = new StringBinding(); 96 97 98 animalDb = env.openDatabase(txn, "animal", dbConfig); 99 personDb = env.openDatabase(txn, "person", dbConfig); 100 101 105 SecondaryConfig secConfig = new SecondaryConfig(); 106 secConfig.setAllowCreate(true); 107 secConfig.setTransactional(true); 108 109 113 secConfig.setSortedDuplicates(false); 114 secConfig.setMultiKeyCreator(new EmailKeyCreator()); 115 personByEmail = env.openSecondaryDatabase(txn, "personByEmail", 116 personDb, secConfig); 117 118 124 secConfig.setSortedDuplicates(true); 125 secConfig.setMultiKeyCreator(new AnimalKeyCreator()); 126 secConfig.setForeignMultiKeyNullifier(new AnimalKeyNullifier()); 127 secConfig.setForeignKeyDatabase(animalDb); 128 secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.NULLIFY); 129 personByAnimal = env.openSecondaryDatabase(txn, "personByAnimal", 130 personDb, secConfig); 131 132 txn.commit(); 133 } catch (DatabaseException e) { 134 txn.abort(); 135 throw e; 136 } catch (RuntimeException e) { 137 txn.abort(); 138 throw e; 139 } 140 } 141 142 145 private void close() throws DatabaseException { 146 147 if (personByEmail != null) { 148 personByEmail.close(); 149 } 150 if (personByAnimal != null) { 151 personByAnimal.close(); 152 } 153 if (catalogDb != null) { 154 catalogDb.close(); 155 } 156 if (personDb != null) { 157 personDb.close(); 158 } 159 if (animalDb != null) { 160 animalDb.close(); 161 } 162 if (env != null) { 163 env.close(); 164 } 165 } 166 167 171 private void exec() 172 throws DatabaseException { 173 174 System.out.println 175 ("\nInsert some animals."); 176 Animal dogs = insertAndPrintAnimal("dogs", true); 177 Animal fish = insertAndPrintAnimal("fish", false); 178 Animal horses = insertAndPrintAnimal("horses", true); 179 Animal donkeys = insertAndPrintAnimal("donkeys", true); 180 181 System.out.println 182 ("\nInsert a new empty person."); 183 Person kathy = new Person(); 184 kathy.name = "Kathy"; 185 putPerson(kathy); 186 printPerson("Kathy"); 187 188 System.out.println 189 ("\nAdd favorites/addresses and update the record."); 190 kathy.favoriteAnimals.add(horses.name); 191 kathy.favoriteAnimals.add(dogs.name); 192 kathy.favoriteAnimals.add(fish.name); 193 kathy.emailAddresses.add("kathy@kathy.com"); 194 kathy.emailAddresses.add("kathy@yahoo.com"); 195 putPerson(kathy); 196 printPerson("Kathy"); 197 198 System.out.println 199 ("\nChange favorites and addresses and update the person record."); 200 kathy.favoriteAnimals.remove(fish.name); 201 kathy.favoriteAnimals.add(donkeys.name); 202 kathy.emailAddresses.add("kathy@gmail.com"); 203 kathy.emailAddresses.remove("kathy@yahoo.com"); 204 putPerson(kathy); 205 printPerson("Kathy"); 206 207 System.out.println 208 ("\nInsert another person with some of the same favorites."); 209 Person mark = new Person(); 210 mark.favoriteAnimals.add(dogs.name); 211 mark.favoriteAnimals.add(horses.name); 212 mark.name = "Mark"; 213 putPerson(mark); 214 printPerson("Mark"); 215 216 System.out.println 217 ("\nPrint by favorite animal index."); 218 printByIndex(personByAnimal); 219 220 System.out.println 221 ("\nPrint by email address index."); 222 printByIndex(personByEmail); 223 224 System.out.println 225 ("\nDelete 'dogs' and print again by favorite animal index."); 226 deleteAnimal(dogs.name); 227 printPerson("Kathy"); 228 printPerson("Mark"); 229 printByIndex(personByAnimal); 230 231 System.out.println 232 ("\nDelete both records and print again (should print nothing)."); 233 deletePerson("Kathy"); 234 deletePerson("Mark"); 235 printPerson("Kathy"); 236 printPerson("Mark"); 237 printByIndex(personByAnimal); 238 printByIndex(personByEmail); 239 } 240 241 244 private Animal insertAndPrintAnimal(String name, boolean furry) 245 throws DatabaseException { 246 247 Animal animal = new Animal(); 248 animal.name = name; 249 animal.furry = furry; 250 251 DatabaseEntry key = new DatabaseEntry(); 252 keyBinding.objectToEntry(name, key); 253 254 DatabaseEntry data = new DatabaseEntry(); 255 dataBinding.objectToEntry(animal, data); 256 257 OperationStatus status = animalDb.putNoOverwrite(null, key, data); 258 if (status == OperationStatus.SUCCESS) { 259 System.out.println(animal); 260 } else { 261 System.out.println("Animal was not inserted: " + name + 262 " (" + status + ')'); 263 } 264 265 return animal; 266 } 267 268 271 private boolean deleteAnimal(String name) 272 throws DatabaseException { 273 274 DatabaseEntry key = new DatabaseEntry(); 275 keyBinding.objectToEntry(name, key); 276 277 OperationStatus status = animalDb.delete(null, key); 278 return status == OperationStatus.SUCCESS; 279 } 280 281 284 private void printPerson(String name) 285 throws DatabaseException { 286 287 DatabaseEntry key = new DatabaseEntry(); 288 keyBinding.objectToEntry(name, key); 289 290 DatabaseEntry data = new DatabaseEntry(); 291 292 OperationStatus status = personDb.get(null, key, data, null); 293 if (status == OperationStatus.SUCCESS) { 294 Person person = (Person) dataBinding.entryToObject(data); 295 person.name = (String ) keyBinding.entryToObject(key); 296 System.out.println(person); 297 } else { 298 System.out.println("Person not found: " + name); 299 } 300 } 301 302 305 private void printByIndex(SecondaryDatabase secDb) 306 throws DatabaseException { 307 308 DatabaseEntry secKey = new DatabaseEntry(); 309 DatabaseEntry priKey = new DatabaseEntry(); 310 DatabaseEntry priData = new DatabaseEntry(); 311 312 SecondaryCursor cursor = secDb.openSecondaryCursor(null, null); 313 try { 314 while (cursor.getNext(secKey, priKey, priData, null) == 315 OperationStatus.SUCCESS) { 316 Person person = (Person) dataBinding.entryToObject(priData); 317 person.name = (String ) keyBinding.entryToObject(priKey); 318 System.out.println("Index key [" + 319 keyBinding.entryToObject(secKey) + 320 "] maps to primary key [" + 321 person.name + ']'); 322 } 323 } finally { 324 cursor.close(); 325 } 326 } 327 328 331 private void putPerson(Person person) 332 throws DatabaseException { 333 334 DatabaseEntry key = new DatabaseEntry(); 335 keyBinding.objectToEntry(person.name, key); 336 337 DatabaseEntry data = new DatabaseEntry(); 338 dataBinding.objectToEntry(person, data); 339 340 personDb.put(null, key, data); 341 } 342 343 346 private boolean deletePerson(String name) 347 throws DatabaseException { 348 349 DatabaseEntry key = new DatabaseEntry(); 350 keyBinding.objectToEntry(name, key); 351 352 OperationStatus status = personDb.delete(null, key); 353 return status == OperationStatus.SUCCESS; 354 } 355 356 359 private static class Person implements Serializable { 360 361 362 private transient String name; 363 364 365 private Set favoriteAnimals = new HashSet (); 366 367 368 private Set emailAddresses = new HashSet (); 369 370 public String toString() { 371 return "Person {" + 372 "\n Name: " + name + 373 "\n FavoriteAnimals: " + favoriteAnimals + 374 "\n EmailAddresses: " + emailAddresses + 375 "\n}"; 376 } 377 } 378 379 382 private static class Animal implements Serializable { 383 384 385 private transient String name; 386 387 388 private boolean furry; 389 390 public String toString() { 391 return "Animal {" + 392 "\n Name: " + name + 393 "\n Furry: " + furry + 394 "\n}"; 395 } 396 } 397 398 402 private class EmailKeyCreator implements SecondaryMultiKeyCreator { 403 404 public void createSecondaryKeys(SecondaryDatabase secondary, 405 DatabaseEntry primaryKey, 406 DatabaseEntry primaryData, 407 Set results) 408 throws DatabaseException { 409 410 Person person = (Person) dataBinding.entryToObject(primaryData); 411 copyKeysToEntries(person.emailAddresses, results); 412 } 413 } 414 415 419 private class AnimalKeyCreator implements SecondaryMultiKeyCreator { 420 421 public void createSecondaryKeys(SecondaryDatabase secondary, 422 DatabaseEntry primaryKey, 423 DatabaseEntry primaryData, 424 Set results) 425 throws DatabaseException { 426 427 Person person = (Person) dataBinding.entryToObject(primaryData); 428 copyKeysToEntries(person.favoriteAnimals, results); 429 } 430 } 431 432 436 private void copyKeysToEntries(Set keys, Set entries) { 437 438 for (Iterator i = keys.iterator(); i.hasNext();) { 439 DatabaseEntry entry = new DatabaseEntry(); 440 keyBinding.objectToEntry(i.next(), entry); 441 entries.add(entry); 442 } 443 } 444 445 451 private class AnimalKeyNullifier implements ForeignMultiKeyNullifier { 452 453 public boolean nullifyForeignKey(SecondaryDatabase secondary, 454 DatabaseEntry primaryKey, 455 DatabaseEntry primaryData, 456 DatabaseEntry secKey) 457 throws DatabaseException { 458 459 Person person = (Person) dataBinding.entryToObject(primaryData); 460 String key = (String ) keyBinding.entryToObject(secKey); 461 if (person.favoriteAnimals.remove(key)) { 462 dataBinding.objectToEntry(person, primaryData); 463 return true; 464 } else { 465 return false; 466 } 467 } 468 } 469 } 470 | Popular Tags |