use of liquibase.database.OfflineConnection in project liquibase by liquibase.
the class DatabaseType method createDatabase.
public Database createDatabase(ClassLoader classLoader) {
logParameters();
validateParameters();
try {
DatabaseFactory databaseFactory = DatabaseFactory.getInstance();
if (databaseClass != null) {
Database databaseInstance = (Database) ClasspathUtils.newInstance(databaseClass, classLoader, Database.class);
databaseFactory.register(databaseInstance);
}
DatabaseConnection jdbcConnection;
if (getUrl().startsWith("offline:")) {
jdbcConnection = new OfflineConnection(getUrl(), new ClassLoaderResourceAccessor(classLoader));
} else {
Driver driver = (Driver) ClasspathUtils.newInstance(getDriver(), classLoader, Driver.class);
if (driver == null) {
throw new BuildException("Unable to create Liquibase Database instance. Could not instantiate the JDBC driver.");
}
Properties connectionProps = new Properties();
String user = getUser();
if (user != null && !user.isEmpty()) {
connectionProps.setProperty(USER, user);
}
String password = getPassword();
if (password != null && !password.isEmpty()) {
connectionProps.setProperty(PASSWORD, password);
}
ConnectionProperties connectionProperties = getConnectionProperties();
if (connectionProperties != null) {
connectionProps.putAll(connectionProperties.buildProperties());
}
Connection connection = driver.connect(getUrl(), connectionProps);
if (connection == null) {
throw new BuildException("Unable to create Liquibase Database instance. Could not connect to the database.");
}
jdbcConnection = new JdbcConnection(connection);
}
Database database = databaseFactory.findCorrectDatabaseImplementation(jdbcConnection);
String schemaName = getDefaultSchemaName();
if (schemaName != null) {
database.setDefaultSchemaName(schemaName);
}
String catalogName = getDefaultCatalogName();
if (catalogName != null) {
database.setDefaultCatalogName(catalogName);
}
String currentDateTimeFunction = getCurrentDateTimeFunction();
if (currentDateTimeFunction != null) {
database.setCurrentDateTimeFunction(currentDateTimeFunction);
}
database.setOutputDefaultSchema(isOutputDefaultSchema());
database.setOutputDefaultCatalog(isOutputDefaultCatalog());
String liquibaseSchemaName = getLiquibaseSchemaName();
if (liquibaseSchemaName != null) {
database.setLiquibaseSchemaName(liquibaseSchemaName);
}
String liquibaseCatalogName = getLiquibaseCatalogName();
if (liquibaseCatalogName != null) {
database.setLiquibaseCatalogName(liquibaseCatalogName);
}
String databaseChangeLogTableName = getDatabaseChangeLogTableName();
if (databaseChangeLogTableName != null) {
database.setDatabaseChangeLogTableName(databaseChangeLogTableName);
}
String databaseChangeLogLockTableName = getDatabaseChangeLogLockTableName();
if (databaseChangeLogLockTableName != null) {
database.setDatabaseChangeLogLockTableName(databaseChangeLogLockTableName);
}
String liquibaseTablespaceName = getLiquibaseTablespaceName();
if (liquibaseTablespaceName != null) {
database.setLiquibaseTablespaceName(liquibaseTablespaceName);
}
return database;
} catch (SQLException e) {
throw new BuildException("Unable to create Liquibase database instance. A JDBC error occurred. " + e.toString(), e);
} catch (DatabaseException e) {
throw new BuildException("Unable to create Liquibase database instance. " + e.toString(), e);
}
}
use of liquibase.database.OfflineConnection in project liquibase by liquibase.
the class CommandLineUtils method initializeDatabase.
/**
* Executes RawSqlStatements particular to each database engine to set the default schema for the given Database
*
* @param username The username used for the connection. Used with MSSQL databases
* @param defaultCatalogName Catalog name and schema name are similar concepts. Used if defaultCatalogName is null.
* @param defaultSchemaName Catalog name and schema name are similar concepts. Catalog is used with Oracle, DB2 and MySQL, and takes
* precedence over the schema name.
* @param database Which Database object is affected by the initialization.
* @throws DatabaseException
*/
public static void initializeDatabase(String username, String defaultCatalogName, String defaultSchemaName, Database database) throws DatabaseException {
if ((defaultCatalogName != null || defaultSchemaName != null) && !(database.getConnection() instanceof OfflineConnection)) {
if (database instanceof OracleDatabase) {
String schema = defaultCatalogName;
if (schema == null) {
schema = defaultSchemaName;
}
ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("ALTER SESSION SET CURRENT_SCHEMA=" + database.escapeObjectName(schema, Schema.class)));
} else if (database instanceof MSSQLDatabase && defaultSchemaName != null) {
boolean sql2005OrLater = true;
try {
sql2005OrLater = database.getDatabaseMajorVersion() >= 9;
} catch (DatabaseException e) {
// Assume SQL Server 2005 or later
}
if (sql2005OrLater && username != null) {
ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("IF USER_NAME() <> N'dbo'\r\n" + "BEGIN\r\n" + " DECLARE @sql [nvarchar](MAX)\r\n" + " SELECT @sql = N'ALTER USER ' + QUOTENAME(USER_NAME()) + N' WITH DEFAULT_SCHEMA = " + database.escapeStringForDatabase(database.escapeObjectName(username, DatabaseObject.class)) + "'\r\n" + " EXEC sp_executesql @sql\r\n" + "END"));
}
} else if (database instanceof PostgresDatabase && defaultSchemaName != null) {
ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("SET SEARCH_PATH TO " + database.escapeObjectName(defaultSchemaName, Schema.class)));
} else if (database instanceof DB2Database) {
String schema = defaultCatalogName;
if (schema == null) {
schema = defaultSchemaName;
}
ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("SET CURRENT SCHEMA " + schema));
} else if (database instanceof MySQLDatabase) {
String schema = defaultCatalogName;
if (schema == null) {
schema = defaultSchemaName;
}
ExecutorService.getInstance().getExecutor(database).execute(new RawSqlStatement("USE " + schema));
}
}
}
use of liquibase.database.OfflineConnection in project liquibase by liquibase.
the class JdbcExecutor method execute.
public Object execute(StatementCallback action, List<SqlVisitor> sqlVisitors) throws DatabaseException {
Scope.getCurrentScope().getLog(getClass()).fine("Executing with the '" + getName() + "' executor");
DatabaseConnection con = database.getConnection();
Statement stmt = null;
try {
if (con instanceof OfflineConnection) {
throw new DatabaseException("Cannot execute commands against an offline database");
}
stmt = ((JdbcConnection) con).getUnderlyingConnection().createStatement();
Statement stmtToUse = stmt;
return action.doInStatement(stmtToUse);
} catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
JdbcUtil.closeStatement(stmt);
stmt = null;
String url;
if (con.isClosed()) {
url = "CLOSED CONNECTION";
} else {
url = con.getURL();
}
throw new DatabaseException("Error executing SQL " + StringUtil.join(applyVisitors(action.getStatement(), sqlVisitors), "; on " + url) + ": " + ex.getMessage(), ex);
} finally {
JdbcUtil.closeStatement(stmt);
}
}
use of liquibase.database.OfflineConnection in project liquibase by liquibase.
the class ColumnSnapshotGenerator method setAutoIncrementDetails.
protected void setAutoIncrementDetails(Column column, Database database, DatabaseSnapshot snapshot) {
if ((column.getAutoIncrementInformation() != null) && (database instanceof MSSQLDatabase) && (database.getConnection() != null) && !(database.getConnection() instanceof OfflineConnection)) {
Map<String, Column.AutoIncrementInformation> autoIncrementColumns = (Map) snapshot.getScratchData("autoIncrementColumns");
if (autoIncrementColumns == null) {
autoIncrementColumns = new HashMap<>();
Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database);
try {
List<Map<String, ?>> rows = executor.queryForList(new RawSqlStatement("SELECT object_schema_name(object_id) AS schema_name, " + "object_name(object_id) AS table_name, name AS column_name, " + "CAST(seed_value AS bigint) AS start_value, " + "CAST(increment_value AS bigint) AS increment_by " + "FROM sys.identity_columns"));
for (Map row : rows) {
String schemaName = (String) row.get("SCHEMA_NAME");
String tableName = (String) row.get("TABLE_NAME");
String columnName = (String) row.get("COLUMN_NAME");
Long startValue = (Long) row.get("START_VALUE");
Long incrementBy = (Long) row.get("INCREMENT_BY");
Column.AutoIncrementInformation info = new Column.AutoIncrementInformation(startValue, incrementBy);
autoIncrementColumns.put(schemaName + "." + tableName + "." + columnName, info);
}
snapshot.setScratchData("autoIncrementColumns", autoIncrementColumns);
} catch (DatabaseException e) {
Scope.getCurrentScope().getLog(getClass()).info("Could not read identity information", e);
}
}
if ((column.getRelation() != null) && (column.getSchema() != null)) {
Column.AutoIncrementInformation autoIncrementInformation = autoIncrementColumns.get(column.getSchema().getName() + "." + column.getRelation().getName() + "." + column.getName());
if (autoIncrementInformation != null) {
column.setAutoIncrementInformation(autoIncrementInformation);
}
}
}
}
use of liquibase.database.OfflineConnection in project liquibase by liquibase.
the class OracleDatabase method setConnection.
@Override
public void setConnection(DatabaseConnection conn) {
// noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,
// HardCodedStringLiteral
// more reserved words not returned by driver
reservedWords.addAll(Arrays.asList("GROUP", "USER", "SESSION", "PASSWORD", "RESOURCE", "START", "SIZE", "UID", "DESC", "ORDER"));
Connection sqlConn = null;
if (!(conn instanceof OfflineConnection)) {
try {
/*
* Don't try to call getWrappedConnection if the conn instance is
* is not a JdbcConnection. This happens for OfflineConnection.
* see https://liquibase.jira.com/browse/CORE-2192
*/
if (conn instanceof JdbcConnection) {
sqlConn = ((JdbcConnection) conn).getWrappedConnection();
}
} catch (Exception e) {
throw new UnexpectedLiquibaseException(e);
}
if (sqlConn != null) {
tryProxySession(conn.getURL(), sqlConn);
try {
// noinspection HardCodedStringLiteral
reservedWords.addAll(Arrays.asList(sqlConn.getMetaData().getSQLKeywords().toUpperCase().split(",\\s*")));
} catch (SQLException e) {
// noinspection HardCodedStringLiteral
Scope.getCurrentScope().getLog(getClass()).info("Could get sql keywords on OracleDatabase: " + e.getMessage());
// can not get keywords. Continue on
}
try {
Method method = sqlConn.getClass().getMethod("setRemarksReporting", Boolean.TYPE);
method.setAccessible(true);
method.invoke(sqlConn, true);
} catch (Exception e) {
// noinspection HardCodedStringLiteral
Scope.getCurrentScope().getLog(getClass()).info("Could not set remarks reporting on OracleDatabase: " + e.getMessage());
// cannot set it. That is OK
}
CallableStatement statement = null;
try {
// noinspection HardCodedStringLiteral
statement = sqlConn.prepareCall("{call DBMS_UTILITY.DB_VERSION(?,?)}");
statement.registerOutParameter(1, Types.VARCHAR);
statement.registerOutParameter(2, Types.VARCHAR);
statement.execute();
String compatibleVersion = statement.getString(2);
if (compatibleVersion != null) {
Matcher majorVersionMatcher = Pattern.compile("(\\d+)\\.(\\d+)\\..*").matcher(compatibleVersion);
if (majorVersionMatcher.matches()) {
this.databaseMajorVersion = Integer.valueOf(majorVersionMatcher.group(1));
this.databaseMinorVersion = Integer.valueOf(majorVersionMatcher.group(2));
}
}
} catch (SQLException e) {
@SuppressWarnings("HardCodedStringLiteral") String message = "Cannot read from DBMS_UTILITY.DB_VERSION: " + e.getMessage();
// noinspection HardCodedStringLiteral
Scope.getCurrentScope().getLog(getClass()).info("Could not set check compatibility mode on OracleDatabase, assuming not running in any sort of compatibility mode: " + message);
} finally {
JdbcUtil.closeStatement(statement);
}
if (GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue() != null) {
int timeoutValue = GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue();
Scope.getCurrentScope().getLog(getClass()).fine("Setting DDL_LOCK_TIMEOUT value to " + timeoutValue);
String sql = "ALTER SESSION SET DDL_LOCK_TIMEOUT=" + timeoutValue;
PreparedStatement ddlLockTimeoutStatement = null;
try {
ddlLockTimeoutStatement = sqlConn.prepareStatement(sql);
ddlLockTimeoutStatement.execute();
} catch (SQLException sqle) {
Scope.getCurrentScope().getUI().sendErrorMessage("Unable to set the DDL_LOCK_TIMEOUT_VALUE: " + sqle.getMessage(), sqle);
Scope.getCurrentScope().getLog(getClass()).warning("Unable to set the DDL_LOCK_TIMEOUT_VALUE: " + sqle.getMessage(), sqle);
} finally {
JdbcUtil.closeStatement(ddlLockTimeoutStatement);
}
}
}
}
super.setConnection(conn);
}
Aggregations