public StoreObject merge() { boolean alreadySetDatabaseObject = false; // first pass for (StoreObject store : this.storeObjects) { copySchemaInfo(store); } // second pass for (StoreObject store : this.storeObjects) { if (store.getSchema().getVersion() == targetStore.getSchema().getVersion() && !alreadySetDatabaseObject) { BaseSchema targetSchema = targetStore.getSchema(); targetSchema.clearObjects(); targetSchema.addObjects(mergeDatabaseObjects(store.getSchema().getObjects())); alreadySetDatabaseObject = true; } mergePatches(store.getPatches()); mergeExistQueries(store.getExistQueries()); mergeDropStatements(store.getDropStatements()); } return this.targetStore; }
protected void mergeExistQueries(List<SQLObject> queries) { for (SQLObject query : queries) { validateSQLObject(queries, query); targetStore.addExistQuery(query); } }
protected void mergeDropStatements(List<SQLObject> queries) { for (SQLObject query : queries) { validateSQLObject(queries, query); targetStore.addDropStatement(query); } }
protected String getDropSQL(DatabaseObjectType type, String name) { SQLObject foundDropQuery = null; String sqlStatement = "DROP " + type.toString() + " " + name; for (SQLObject dropQuery : catalogStore.getDropStatements()) { if (type == dropQuery.getType()) { foundDropQuery = dropQuery; break; } } if (foundDropQuery != null && foundDropQuery.getSql() != null && !foundDropQuery.getSql().isEmpty()) { String dropStatement = foundDropQuery.getSql(); StringBuffer sqlBuffer = new StringBuffer(dropStatement.length() + name.length()); int identifier = dropStatement.indexOf('?'); sqlBuffer .append(dropStatement.substring(0, identifier)) .append(name) .append(dropStatement.substring(identifier + 1)); sqlStatement = sqlBuffer.toString(); } return sqlStatement; }
protected PreparedStatement getExistQuery(Connection conn, DatabaseObjectType type) throws SQLException { PreparedStatement pstmt = null; for (SQLObject existQuery : catalogStore.getExistQueries()) { if (type.equals(existQuery.getType())) { pstmt = conn.prepareStatement(existQuery.getSql()); break; } } return pstmt; }
protected void mergePatches(List<SchemaPatch> patches) { final List<DatabaseObject> objects = new ArrayList<>(); Collections.sort(patches); for (SchemaPatch patch : patches) { validatePatch(patches, patch); objects.clear(); List<DatabaseObject> tempObjects = new ArrayList<>(); tempObjects.addAll(patch.getObjects()); patch.clearObjects(); patch.addObjects(mergeDatabaseObjects(tempObjects)); targetStore.addPatch(patch); } }
public void dropBaseSchema(Connection conn) { if (!isLoaded()) { throw new TajoInternalError("Schema files are not loaded yet."); } List<DatabaseObject> failedObjects = new ArrayList<>(); Statement stmt = null; try { stmt = conn.createStatement(); } catch (SQLException e) { throw new TajoInternalError(e); } for (DatabaseObject object : catalogStore.getSchema().getObjects()) { try { if (DatabaseObjectType.TABLE == object.getType() || DatabaseObjectType.SEQUENCE == object.getType() || DatabaseObjectType.VIEW == object.getType()) { stmt.executeUpdate(getDropSQL(object.getType(), object.getName())); } } catch (SQLException e) { failedObjects.add(object); } } CatalogUtil.closeQuietly(stmt); if (failedObjects.size() > 0) { StringBuffer errorMessage = new StringBuffer(64); errorMessage.append("Failed to drop database objects "); for (int idx = 0; idx < failedObjects.size(); idx++) { DatabaseObject object = failedObjects.get(idx); errorMessage.append(object.getType().toString()).append(" ").append(object.getName()); if ((idx + 1) < failedObjects.size()) { errorMessage.append(','); } } LOG.warn(errorMessage.toString()); } }
public void createBaseSchema(Connection conn) { Statement stmt; if (!isLoaded()) { throw new TajoInternalError("Database schema files are not loaded."); } try { stmt = conn.createStatement(); } catch (SQLException e) { throw new TajoInternalError(e); } for (DatabaseObject object : catalogStore.getSchema().getObjects()) { try { String[] params; if (DatabaseObjectType.INDEX == object.getType()) { params = new String[2]; params[0] = object.getDependsOn(); params[1] = object.getName(); } else { params = new String[1]; params[0] = object.getName(); } if (checkExistence(conn, object.getType(), params)) { LOG.info("Skip to create " + object.getName() + " databse object. Already exists."); } else { stmt.executeUpdate(object.getSql()); LOG.info(object.getName() + " " + object.getType() + " is created."); } } catch (SQLException e) { throw new TajoInternalError(e); } } CatalogUtil.closeQuietly(stmt); }
public boolean isInitialized(Connection conn) { if (!isLoaded()) { throw new TajoInternalError("Database schema files are not loaded."); } boolean result = true; for (DatabaseObject object : catalogStore.getSchema().getObjects()) { try { if (DatabaseObjectType.INDEX == object.getType()) { result &= checkExistence(conn, object.getType(), object.getDependsOn(), object.getName()); } else { result &= checkExistence(conn, object.getType(), object.getName()); } } catch (SQLException e) { throw new TajoInternalError(e); } if (!result) { break; } } return result; }
protected void copySchemaInfo(StoreObject sourceStore) { if (sourceStore.getSchema().getSchemaName() != null && !sourceStore.getSchema().getSchemaName().isEmpty()) { if (targetStore.getSchema().getSchemaName() != null && !targetStore.getSchema().getSchemaName().isEmpty() && !targetStore .getSchema() .getSchemaName() .equalsIgnoreCase(sourceStore.getSchema().getSchemaName())) { throw new TajoInternalError( "different schema names are specified. One is " + sourceStore.getSchema().getSchemaName() + " and other is " + targetStore.getSchema().getSchemaName()); } if (targetStore.getSchema().getSchemaName() == null || targetStore.getSchema().getSchemaName().isEmpty()) { targetStore.getSchema().setSchemaName(sourceStore.getSchema().getSchemaName()); } } if (sourceStore.getSchema().getVersion() > -1 && targetStore.getSchema().getVersion() < sourceStore.getSchema().getVersion()) { targetStore.getSchema().setVersion(sourceStore.getSchema().getVersion()); } }
protected boolean checkExistence(Connection conn, DatabaseObjectType type, String... params) throws SQLException { boolean result = false; DatabaseMetaData metadata = null; PreparedStatement pstmt = null; BaseSchema baseSchema = catalogStore.getSchema(); if (params == null || params.length < 1) { throw new IllegalArgumentException("checkExistence function needs at least one argument."); } switch (type) { case DATA: metadata = conn.getMetaData(); ResultSet data = metadata.getUDTs( null, baseSchema.getSchemaName() != null && !baseSchema.getSchemaName().isEmpty() ? baseSchema.getSchemaName().toUpperCase() : null, params[0].toUpperCase(), null); result = data.next(); CatalogUtil.closeQuietly(data); break; case FUNCTION: metadata = conn.getMetaData(); ResultSet functions = metadata.getFunctions( null, baseSchema.getSchemaName() != null && !baseSchema.getSchemaName().isEmpty() ? baseSchema.getSchemaName().toUpperCase() : null, params[0].toUpperCase()); result = functions.next(); CatalogUtil.closeQuietly(functions); break; case INDEX: if (params.length != 2) { throw new IllegalArgumentException( "Finding index object is needed two strings, table name and index name"); } pstmt = getExistQuery(conn, type); if (pstmt != null) { result = checkExistenceByQuery(pstmt, baseSchema, params); } else { metadata = conn.getMetaData(); ResultSet indexes = metadata.getIndexInfo( null, baseSchema.getSchemaName() != null && !baseSchema.getSchemaName().isEmpty() ? baseSchema.getSchemaName().toUpperCase() : null, params[0].toUpperCase(), false, true); while (indexes.next()) { if (indexes.getString("INDEX_NAME").equals(params[1].toUpperCase())) { result = true; break; } } CatalogUtil.closeQuietly(indexes); } break; case TABLE: pstmt = getExistQuery(conn, type); if (pstmt != null) { result = checkExistenceByQuery(pstmt, baseSchema, params); } else { metadata = conn.getMetaData(); ResultSet tables = metadata.getTables( null, baseSchema.getSchemaName() != null && !baseSchema.getSchemaName().isEmpty() ? baseSchema.getSchemaName().toUpperCase() : null, params[0].toUpperCase(), new String[] {"TABLE"}); result = tables.next(); CatalogUtil.closeQuietly(tables); } break; case DOMAIN: case OPERATOR: case RULE: case SEQUENCE: case TRIGGER: case VIEW: pstmt = getExistQuery(conn, type); if (pstmt == null) { throw new TajoInternalError( "Finding " + type + " type of database object is not supported on this database system."); } result = checkExistenceByQuery(pstmt, baseSchema, params); break; } return result; }