private void setStrategy(String name, DataNode dataNode) { dataNode.setSchemaUpdateStrategyName(name); try { dataNode.setSchemaUpdateStrategy( (SchemaUpdateStrategy) Class.forName(dataNode.getSchemaUpdateStrategyName()).newInstance()); } catch (Exception e) { throw new CayenneRuntimeException(e); } }
private void dropTables(DataMap map, DataNode dataNode, MockOperationObserver observer) { Collection<DbEntity> ent = map.getDbEntities(); Iterator<DbEntity> iterator = ent.iterator(); while (iterator.hasNext()) { Collection<String> collectionDrop = dataNode.getAdapter().dropTableStatements(iterator.next()); for (String s : collectionDrop) { SQLTemplate queryDrop = new SQLTemplate(Object.class, s); dataNode.performQueries(Collections.singletonList((Query) queryDrop), observer); } } }
public void testNoStandartSchema() { String template = "SELECT #result('ARTIST_ID' 'int') FROM ARTIST ORDER BY ARTIST_ID"; SQLTemplate query = new SQLTemplate(Object.class, template); MockOperationObserver observer = new MockOperationObserver(); DataMap map = node.getEntityResolver().getDataMap("sus-map"); DataNode dataNode = createDataNode(map); setStrategy(TestSchemaUpdateStrategy.class.getName(), dataNode); dataNode.performQueries(Collections.singletonList((Query) query), observer); assertTrue(dataNode.getSchemaUpdateStrategy() instanceof TestSchemaUpdateStrategy); }
private DataNode createDataNode(DataMap map) { Collection<DataMap> colection = new ArrayList<DataMap>(); colection.add(map); DataNode dataNode = new DataNode(); dataNode.setJdbcEventLogger(jdbcEventLogger); dataNode.setDataMaps(colection); dataNode.setAdapter(adapter); dataNode.setDataSource(dataSourceFactory.getSharedDataSource()); dataNode.setDataSourceFactory(node.getDataSourceFactory()); dataNode.setSchemaUpdateStrategyName(node.getSchemaUpdateStrategyName()); dataNode.setEntityResolver(new EntityResolver(colection)); return dataNode; }
private DbEntity createOneTable(DataNode dataNode) { DataMap map = node.getEntityResolver().getDataMap("sus-map"); Collection<DbEntity> ent = map.getDbEntities(); DbEntity entity = ent.iterator().next(); String template = dataNode.getAdapter().createTable(entity); SQLTemplate query = new SQLTemplate(Object.class, template); MockOperationObserver observer = new MockOperationObserver(); setStrategy(null, dataNode); dataNode.performQueries(Collections.singletonList((Query) query), observer); return entity; }
public void testMixedStrategyTableNoExist() throws Exception { String template = "SELECT #result('id' 'int') FROM SUS1"; SQLTemplate query = new SQLTemplate(Object.class, template); DataMap map = node.getEntityResolver().getDataMap("sus-map"); DataNode dataNode = createDataNode(map); int sizeDB = getNameTablesInDB(dataNode).size(); MockOperationObserver observer = new MockOperationObserver(); setStrategy(ThrowOnPartialOrCreateSchemaStrategy.class.getName(), dataNode); try { dataNode.performQueries(Collections.singletonList((Query) query), observer); Map<String, Boolean> nameTables = getNameTablesInDB(dataNode); assertTrue(nameTables.get("sus1") != null || nameTables.get("SUS1") != null); int sizeDB2 = getNameTablesInDB(dataNode).size(); assertEquals(2, sizeDB2 - sizeDB); dataNode.performQueries(Collections.singletonList((Query) query), observer); int sizeDB3 = getNameTablesInDB(dataNode).size(); assertEquals(sizeDB2, sizeDB3); } finally { DataNode dataNode2 = createDataNode(map); dataNode2.setSchemaUpdateStrategy( (SchemaUpdateStrategy) Class.forName(dataNode2.getSchemaUpdateStrategyName()).newInstance()); dropTables(map, dataNode2, observer); } assertEquals(getNameTablesInDB(dataNode).size(), sizeDB); }
@Override public Map<String, DataSource> dataSources() { Map<String, DataSource> dataSources = new HashMap<>(); for (DataNode n : runtime.getDataDomain().getDataNodes()) { // this method is used to seed a special kind of JdbcConnector. // But note that the DataSource here is attached to the DataNode // transaction, so reading source data will happen over the same // connection as writing target data. Hopefully such multiplexing // the connection works ok... dataSources.put(n.getName(), n.getDataSource()); } return dataSources; }
private void generateDBWithDBGeneratorStrategy( DataNode dataNode, SQLTemplate query, MockOperationObserver observer) { setStrategy(CreateIfNoSchemaStrategy.class.getName(), dataNode); dataNode.performQueries(Collections.singletonList((Query) query), observer); Map<String, Boolean> nameTables = getNameTablesInDB(dataNode); assertTrue(nameTables.get("sus1") != null || nameTables.get("SUS1") != null); }
private void tableExistfForThrowOnPartialAndMixStrategy(String strategy) throws Exception { String template = "SELECT #result('ARTIST_ID' 'int') FROM ARTIST ORDER BY ARTIST_ID"; SQLTemplate query = new SQLTemplate(Object.class, template); DataMap map = node.getEntityResolver().getDataMap("sus-map"); MockOperationObserver observer = new MockOperationObserver(); DataNode dataNode = createDataNode(map); int sizeDB = getNameTablesInDB(dataNode).size(); generateDBWithDBGeneratorStrategy(dataNode, query, observer); int sizeDB2 = getNameTablesInDB(dataNode).size(); assertEquals(2, sizeDB2 - sizeDB); try { DataNode dataNode2 = createDataNode(map); setStrategy(strategy, dataNode2); dataNode2.performQueries(Collections.singletonList((Query) query), observer); } finally { dropTables(map, dataNode, observer); } }
/** @since 3.0 */ @Override protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception { // handle CAY-588 - get connection that is separate from the connection in the // current transaction. // TODO (andrus, 7/6/2006) Note that this will still work in a pool with a single // connection, as PK generator is invoked early in the transaction, before the // connection is grabbed for commit... So maybe promote this to other adapters in // 3.0? Transaction transaction = Transaction.getThreadTransaction(); Transaction.bindThreadTransaction(null); try { Connection connection = node.getDataSource().getConnection(); try { CallableStatement statement = connection.prepareCall("{call auto_pk_for_table(?, ?)}"); try { statement.setString(1, entity.getName()); statement.setInt(2, super.getPkCacheSize()); // can't use "executeQuery" // per http://jtds.sourceforge.net/faq.html#expectingResultSet statement.execute(); if (statement.getMoreResults()) { ResultSet rs = statement.getResultSet(); try { if (rs.next()) { return rs.getLong(1); } else { throw new CayenneRuntimeException( "Error generating pk for DbEntity " + entity.getName()); } } finally { rs.close(); } } else { throw new CayenneRuntimeException( "Error generating pk for DbEntity " + entity.getName() + ", no result set from stored procedure."); } } finally { statement.close(); } } finally { connection.close(); } } finally { Transaction.bindThreadTransaction(transaction); } }
public void testDBGeneratorStrategy() throws Exception { String template = "SELECT #result('id' 'int') FROM SUS1"; SQLTemplate query = new SQLTemplate(Object.class, template); DataMap map = node.getEntityResolver().getDataMap("sus-map"); DataNode dataNode = createDataNode(map); int sizeDB = getNameTablesInDB(dataNode).size(); MockOperationObserver observer = new MockOperationObserver(); try { generateDBWithDBGeneratorStrategy(dataNode, query, observer); int sizeDB2 = getNameTablesInDB(dataNode).size(); assertEquals(2, sizeDB2 - sizeDB); dataNode.performQueries(Collections.singletonList((Query) query), observer); int sizeDB3 = getNameTablesInDB(dataNode).size(); assertEquals(sizeDB2, sizeDB3); } finally { DataNode dataNode2 = createDataNode(map); dataNode2.setSchemaUpdateStrategy( (SchemaUpdateStrategy) Class.forName(dataNode2.getSchemaUpdateStrategyName()).newInstance()); dropTables(map, dataNode2, observer); } assertEquals(getNameTablesInDB(dataNode).size(), sizeDB); }
public void testThrowOnPartialStrategyTableNoExist() throws Exception { String template = "SELECT #result('ARTIST_ID' 'int') FROM ARTIST ORDER BY ARTIST_ID"; SQLTemplate query = new SQLTemplate(Object.class, template); DataMap map = node.getEntityResolver().getDataMap("sus-map"); MockOperationObserver observer = new MockOperationObserver(); DataNode dataNode = createDataNode(map); setStrategy(ThrowOnPartialSchemaStrategy.class.getName(), dataNode); try { dataNode.performQueries(Collections.singletonList((Query) query), observer); } catch (CayenneRuntimeException e) { assertNotNull(e); } try { dataNode.performQueries(Collections.singletonList((Query) query), observer); } catch (CayenneRuntimeException e) { assertNotNull(e); } }
private Map<String, Boolean> getNameTablesInDB(DataNode dataNode) { String tableLabel = dataNode.getAdapter().tableTypeForTable(); Connection con = null; Map<String, Boolean> nameTables = new HashMap<String, Boolean>(); try { con = dataNode.getDataSource().getConnection(); ResultSet rs = con.getMetaData().getTables(null, null, "%", new String[] {tableLabel}); while (rs.next()) { String name = rs.getString("TABLE_NAME"); nameTables.put(name, false); } rs.close(); } catch (SQLException e) { throw new CayenneRuntimeException(e); } finally { try { con.close(); } catch (SQLException e) { throw new CayenneRuntimeException(e); } } return nameTables; }
/** * Runs JDBC update over a Connection obtained from DataNode. Returns a number of objects returned * from update. * * @throws SQLException in case of query failure. */ public int runUpdate(DataNode node, String sql) throws SQLException { adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST); Connection con = node.getDataSource().getConnection(); try { Statement upd = con.createStatement(); try { return upd.executeUpdate(sql); } finally { upd.close(); } } finally { con.close(); } }
/** * Performs primary key generation ignoring cache. Generates a range of primary keys as specified * by "pkCacheSize" bean property. * * <p>This method is called internally from "generatePkForDbEntity" and then generated range of * key values is saved in cache for performance. Subclasses that implement different primary key * generation solutions should override this method, not "generatePkForDbEntity". * * @since 3.0 */ protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception { String select = "SELECT #result('NEXT_ID' 'long' 'NEXT_ID') " + "FROM AUTO_PK_SUPPORT " + "WHERE TABLE_NAME = '" + entity.getName() + '\''; // run queries via DataNode to utilize its transactional behavior List<Query> queries = new ArrayList<Query>(2); queries.add(new SQLTemplate(entity, select)); queries.add(new SQLTemplate(entity, pkUpdateString(entity.getName()))); PkRetrieveProcessor observer = new PkRetrieveProcessor(entity.getName()); node.performQueries(queries, observer); return observer.getId(); }
/** Checks if AUTO_PK_TABLE already exists in the database. */ protected boolean autoPkTableExists(DataNode node) throws SQLException { Connection con = node.getDataSource().getConnection(); boolean exists = false; try { DatabaseMetaData md = con.getMetaData(); ResultSet tables = md.getTables(null, null, "AUTO_PK_SUPPORT", null); try { exists = tables.next(); } finally { tables.close(); } } finally { // return connection to the pool con.close(); } return exists; }
private void withOneTableForThrowOnPartialAndMixStrategy(String strategy) { DbEntity entity = null; String template = "SELECT #result('ARTIST_ID' 'int') FROM ARTIST ORDER BY ARTIST_ID"; SQLTemplate query = new SQLTemplate(Object.class, template); DataMap map = node.getEntityResolver().getDataMap("sus-map"); MockOperationObserver observer = new MockOperationObserver(); DataNode dataNode = createDataNode(map); DataNode dataNode2 = createDataNode(map); try { int sizeDB = getNameTablesInDB(dataNode).size(); entity = createOneTable(dataNode); int sizeDB2 = getNameTablesInDB(dataNode).size(); assertEquals(1, sizeDB2 - sizeDB); setStrategy(strategy, dataNode2); dataNode2.performQueries(Collections.singletonList((Query) query), observer); } catch (CayenneRuntimeException e) { assertNotNull(e); } try { dataNode2.performQueries(Collections.singletonList((Query) query), observer); } catch (CayenneRuntimeException e) { assertNotNull(e); } finally { if (entity != null) { Collection<String> template2 = dataNode.getAdapter().dropTableStatements(entity); Iterator<String> it = template2.iterator(); List<Query> list = new ArrayList<Query>(); while (it.hasNext()) { SQLTemplate q = new SQLTemplate(Object.class, it.next()); list.add(q); } dataNode.performQueries(list, observer); } } }
@Override public DataNode createDataNode(DataNodeDescriptor nodeDescriptor) throws Exception { DataNode dataNode = new DataNode(nodeDescriptor.getName()); dataNode.setJdbcEventLogger(jdbcEventLogger); dataNode.setRowReaderFactory(rowReaderFactory); dataNode.setBatchTranslatorFactory(batchTranslatorFactory); dataNode.setDataSourceLocation(nodeDescriptor.getParameters()); DataSource dataSource = dataSourceFactory.getDataSource(nodeDescriptor); dataNode.setDataSourceFactory(nodeDescriptor.getDataSourceFactoryType()); dataNode.setDataSource(dataSource); // schema update strategy String schemaUpdateStrategyType = nodeDescriptor.getSchemaUpdateStrategyType(); if (schemaUpdateStrategyType == null) { dataNode.setSchemaUpdateStrategy(defaultSchemaUpdateStrategy); dataNode.setSchemaUpdateStrategyName(defaultSchemaUpdateStrategy.getClass().getName()); } else { SchemaUpdateStrategy strategy = objectFactory.newInstance(SchemaUpdateStrategy.class, schemaUpdateStrategyType); dataNode.setSchemaUpdateStrategyName(schemaUpdateStrategyType); dataNode.setSchemaUpdateStrategy(strategy); } // DbAdapter dataNode.setAdapter(adapterFactory.createAdapter(nodeDescriptor, dataSource)); return dataNode; }
/** * Uses PostgresActionBuilder to create the right action. * * @since 1.2 */ @Override public SQLAction getAction(Query query, DataNode node) { return query.createSQLAction(new PostgresActionBuilder(this, node.getEntityResolver())); }