/** * Asserts than a database expectExists or does not exist. If keyName is null, checks an entity * database. If keyName is non-null, checks a secondary database. */ void assertDbExists( boolean expectExists, Environment env, String entityClassName, String keyName) { /* * If the evolved metadata has not been written (e.g., we're in * read-only mode), then class evolution will not yet have created, * removed or renamed databases, and we cannot check their existence. */ if (newMetadataWritten) { PersistTestUtils.assertDbExists(expectExists, env, STORE_NAME, entityClassName, keyName); } }
/** * When Y is opened and X has a key with relatedEntity=Y.class, X should be opened automatically. * If X is not opened, foreign key constraints will not be enforced. [#15358] */ public void testAutoOpenRelatedEntity() throws DatabaseException { PrimaryIndex<Integer, RelatedY> priY; PrimaryIndex<Integer, RelatedX> priX; /* Opening X should create (and open) Y and enforce constraints. */ open(); priX = store.getPrimaryIndex(Integer.class, RelatedX.class); PersistTestUtils.assertDbExists(true, env, STORE_NAME, RelatedY.class.getName(), null); if (isTransactional) { /* Constraint enforcement requires transactions. */ try { priX.put(new RelatedX()); fail(); } catch (DatabaseException e) { assertTrue( "" + e.getMessage(), (e.getMessage().indexOf("foreign key not allowed: it is not present") >= 0) || (e.getMessage().indexOf("DB_FOREIGN_CONFLICT") >= 0)); } } priY = store.getPrimaryIndex(Integer.class, RelatedY.class); priY.put(new RelatedY()); priX.put(new RelatedX()); close(); /* Delete should cascade even when X is not opened explicitly. */ open(); priY = store.getPrimaryIndex(Integer.class, RelatedY.class); assertEquals(1, priY.count()); priY.delete(88); assertEquals(0, priY.count()); priX = store.getPrimaryIndex(Integer.class, RelatedX.class); assertEquals(0, priX.count()); /* Failed prior to [#15358] fix. */ close(); }
private void doSecondaryBulkLoad(boolean closeAndOpenNormally) throws DatabaseException { PrimaryIndex<Integer, RelatedX> priX; PrimaryIndex<Integer, RelatedY> priY; SecondaryIndex<Integer, Integer, RelatedX> secX; /* Open priX with SecondaryBulkLoad=true. */ StoreConfig config = new StoreConfig(); config.setAllowCreate(true); config.setSecondaryBulkLoad(true); open(config); /* Getting priX should not create the secondary index. */ priX = store.getPrimaryIndex(Integer.class, RelatedX.class); PersistTestUtils.assertDbExists(false, env, STORE_NAME, RelatedX.class.getName(), "key2"); /* We can put records that violate the secondary key constraint. */ priX.put(new RelatedX()); if (closeAndOpenNormally) { /* Open normally and attempt to populate the secondary. */ close(); open(); if (isTransactional && DbCompat.POPULATE_ENFORCES_CONSTRAINTS) { /* Constraint enforcement requires transactions. */ try { /* Before adding the foreign key, constraint is violated. */ priX = store.getPrimaryIndex(Integer.class, RelatedX.class); fail(); } catch (DatabaseException e) { assertTrue(e.toString(), e.toString().contains("foreign key not allowed")); } } /* Open priX with SecondaryBulkLoad=true. */ close(); open(config); /* Add the foreign key to avoid the constraint error. */ priY = store.getPrimaryIndex(Integer.class, RelatedY.class); priY.put(new RelatedY()); /* Open normally and the secondary will be populated. */ close(); open(); priX = store.getPrimaryIndex(Integer.class, RelatedX.class); PersistTestUtils.assertDbExists(true, env, STORE_NAME, RelatedX.class.getName(), "key2"); secX = store.getSecondaryIndex(priX, Integer.class, "key2"); } else { /* Get secondary index explicitly and it will be populated. */ if (isTransactional && DbCompat.POPULATE_ENFORCES_CONSTRAINTS) { /* Constraint enforcement requires transactions. */ try { /* Before adding the foreign key, constraint is violated. */ secX = store.getSecondaryIndex(priX, Integer.class, "key2"); fail(); } catch (DatabaseException e) { assertTrue(e.toString(), e.toString().contains("foreign key not allowed")); } } /* Add the foreign key. */ priY = store.getPrimaryIndex(Integer.class, RelatedY.class); priY.put(new RelatedY()); secX = store.getSecondaryIndex(priX, Integer.class, "key2"); PersistTestUtils.assertDbExists(true, env, STORE_NAME, RelatedX.class.getName(), "key2"); } RelatedX x = secX.get(88); assertNotNull(x); close(); }
public void testSubclassIndex() throws DatabaseException { EnvironmentConfig envConfig = new EnvironmentConfig(); envConfig.setAllowCreate(true); env = new Environment(envHome, envConfig); StoreConfig storeConfig = new StoreConfig(); storeConfig.setAllowCreate(true); EntityStore store = new EntityStore(env, "foo", storeConfig); PrimaryIndex<String, Employee> employeesById = store.getPrimaryIndex(String.class, Employee.class); employeesById.put(new Employee("1")); employeesById.put(new Manager("2", "a")); employeesById.put(new Manager("3", "a")); employeesById.put(new Manager("4", "b")); Employee e; Manager m; e = employeesById.get("1"); assertNotNull(e); assertTrue(!(e instanceof Manager)); /* Ensure DB exists BEFORE calling getSubclassIndex. [#15247] */ PersistTestUtils.assertDbExists(true, env, "foo", Employee.class.getName(), "dept"); /* Normal use: Subclass index for a key in the subclass. */ SecondaryIndex<String, String, Manager> managersByDept = store.getSubclassIndex(employeesById, Manager.class, String.class, "dept"); m = managersByDept.get("a"); assertNotNull(m); assertEquals("2", m.id); m = managersByDept.get("b"); assertNotNull(m); assertEquals("4", m.id); EntityCursor<Manager> managers = managersByDept.entities(); try { m = managers.next(); assertNotNull(m); assertEquals("2", m.id); m = managers.next(); assertNotNull(m); assertEquals("3", m.id); m = managers.next(); assertNotNull(m); assertEquals("4", m.id); m = managers.next(); assertNull(m); } finally { managers.close(); } /* Getting a subclass index for the entity class is also allowed. */ store.getSubclassIndex(employeesById, Employee.class, String.class, "other"); /* Getting a subclass index for a base class key is not allowed. */ try { store.getSubclassIndex(employeesById, Manager.class, String.class, "other"); fail(); } catch (IllegalArgumentException expected) { } store.close(); env.close(); env = null; }