Search in sources :

Example 1 with InsertOrUpdateStatement

use of liquibase.statement.core.InsertOrUpdateStatement in project liquibase by liquibase.

the class LoadDataChange method generateStatements.

@Override
public SqlStatement[] generateStatements(Database database) {
    CSVReader reader = null;
    try {
        reader = getCSVReader();
        if (reader == null) {
            throw new UnexpectedLiquibaseException("Unable to read file " + this.getFile());
        }
        String[] headers = reader.readNext();
        if (headers == null) {
            throw new UnexpectedLiquibaseException("Data file " + getFile() + " was empty");
        }
        List<SqlStatement> statements = new ArrayList<SqlStatement>();
        boolean anyPreparedStatements = false;
        String[] line;
        // Start at '1' to take into account the header (already processed)
        int lineNumber = 1;
        boolean isCommentingEnabled = StringUtils.isNotEmpty(commentLineStartsWith);
        while ((line = reader.readNext()) != null) {
            lineNumber++;
            if (line.length == 0 || (line.length == 1 && StringUtils.trimToNull(line[0]) == null) || (isCommentingEnabled && isLineCommented(line))) {
                //nothing on this line
                continue;
            }
            // (Failure could indicate unquoted strings with commas, for example).
            if (line.length != headers.length) {
                throw new UnexpectedLiquibaseException("CSV file " + getFile() + " Line " + lineNumber + " has " + line.length + " values defined, Header has " + headers.length + ". Numbers MUST be equal (check for unquoted string with embedded commas)");
            }
            boolean needsPreparedStatement = false;
            List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
            for (int i = 0; i < headers.length; i++) {
                Object value = line[i];
                String columnName = headers[i].trim();
                ColumnConfig valueConfig = new ColumnConfig();
                ColumnConfig columnConfig = getColumnConfig(i, headers[i].trim());
                if (columnConfig != null) {
                    if ("skip".equalsIgnoreCase(columnConfig.getType())) {
                        continue;
                    }
                    // don't overwrite header name unless there is actually a value to override it with
                    if (columnConfig.getName() != null) {
                        columnName = columnConfig.getName();
                    }
                    valueConfig.setName(columnName);
                    if (columnConfig.getType() != null) {
                        if (columnConfig.getType().equalsIgnoreCase("BOOLEAN")) {
                            if (value.toString().equalsIgnoreCase("NULL")) {
                                valueConfig.setValue(null);
                            } else {
                                valueConfig.setValueBoolean(BooleanParser.parseBoolean(value.toString().toLowerCase()));
                            }
                        } else if (columnConfig.getType().equalsIgnoreCase("NUMERIC")) {
                            if (value.toString().equalsIgnoreCase("NULL")) {
                                valueConfig.setValue(null);
                            } else {
                                valueConfig.setValueNumeric(value.toString());
                            }
                        } else if (columnConfig.getType().toLowerCase().contains("date") || columnConfig.getType().toLowerCase().contains("time")) {
                            if (value.toString().equalsIgnoreCase("NULL")) {
                                valueConfig.setValue(null);
                            } else {
                                valueConfig.setValueDate(value.toString());
                            }
                        } else if (columnConfig.getType().equalsIgnoreCase("STRING")) {
                            if (value.toString().equalsIgnoreCase("NULL")) {
                                valueConfig.setValue(null);
                            } else {
                                valueConfig.setValue(value.toString());
                            }
                        } else if (columnConfig.getType().equalsIgnoreCase("COMPUTED")) {
                            if (value.toString().equalsIgnoreCase("NULL")) {
                                valueConfig.setValue(null);
                            } else {
                                liquibase.statement.DatabaseFunction function = new liquibase.statement.DatabaseFunction(value.toString());
                                valueConfig.setValueComputed(function);
                            }
                        } else if (columnConfig.getType().equalsIgnoreCase("SEQUENCE")) {
                            String sequenceName;
                            if (value.toString().equalsIgnoreCase("NULL")) {
                                sequenceName = columnConfig.getDefaultValue();
                                if (sequenceName == null) {
                                    throw new UnexpectedLiquibaseException("Must set a sequence name in the loadData column defaultValue attribute");
                                }
                            } else {
                                sequenceName = value.toString();
                            }
                            liquibase.statement.SequenceNextValueFunction function = new liquibase.statement.SequenceNextValueFunction(sequenceName);
                            valueConfig.setValueComputed(function);
                        } else if (columnConfig.getType().equalsIgnoreCase("BLOB")) {
                            if (value.toString().equalsIgnoreCase("NULL")) {
                                valueConfig.setValue(null);
                            } else {
                                valueConfig.setValueBlobFile(value.toString());
                                needsPreparedStatement = true;
                            }
                        } else if (columnConfig.getType().equalsIgnoreCase("CLOB")) {
                            if (value.toString().equalsIgnoreCase("NULL")) {
                                valueConfig.setValue(null);
                            } else {
                                valueConfig.setValueClobFile(value.toString());
                                needsPreparedStatement = true;
                            }
                        } else {
                            throw new UnexpectedLiquibaseException("loadData type of " + columnConfig.getType() + " is not supported.  Please use BOOLEAN, NUMERIC, DATE, STRING, COMPUTED, SEQUENCE or SKIP");
                        }
                    }
                } else {
                    if (columnName.contains("(") || columnName.contains(")") && database instanceof AbstractJdbcDatabase) {
                        columnName = ((AbstractJdbcDatabase) database).quoteObject(columnName, Column.class);
                    }
                    valueConfig.setName(columnName);
                    if (value == null || value.toString().equalsIgnoreCase("NULL")) {
                        // value is always going to be a string unless overridden by ColumnConfig
                        valueConfig.setValue((String) value);
                    } else {
                        valueConfig.setValue(value.toString());
                    }
                }
                columns.add(valueConfig);
            }
            if (needsPreparedStatement) {
                anyPreparedStatements = true;
                statements.add(new InsertExecutablePreparedStatement(database, getCatalogName(), getSchemaName(), getTableName(), columns, getChangeSet(), getResourceAccessor()));
            } else {
                InsertStatement insertStatement = this.createStatement(getCatalogName(), getSchemaName(), getTableName());
                for (ColumnConfig column : columns) {
                    String columnName = column.getName();
                    Object value = column.getValueObject();
                    if (value == null) {
                        value = "NULL";
                    }
                    insertStatement.addColumnValue(columnName, value);
                }
                statements.add(insertStatement);
            }
        }
        if (anyPreparedStatements) {
            return statements.toArray(new SqlStatement[statements.size()]);
        } else {
            InsertSetStatement statementSet = this.createStatementSet(getCatalogName(), getSchemaName(), getTableName());
            for (SqlStatement stmt : statements) {
                statementSet.addInsertStatement((InsertStatement) stmt);
            }
            if (database instanceof MSSQLDatabase || database instanceof MySQLDatabase || database instanceof PostgresDatabase) {
                List<InsertStatement> innerStatements = statementSet.getStatements();
                if (innerStatements != null && innerStatements.size() > 0 && innerStatements.get(0) instanceof InsertOrUpdateStatement) {
                    //cannot do insert or update in a single statement
                    return statementSet.getStatementsArray();
                }
                // we only return a single "statement" - it's capable of emitting multiple sub-statements, should the need arise, on generation.
                return new SqlStatement[] { statementSet };
            } else {
                return statementSet.getStatementsArray();
            }
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (UnexpectedLiquibaseException ule) {
        if (getChangeSet() != null && getChangeSet().getFailOnError() != null && !getChangeSet().getFailOnError()) {
            Logger log = LogFactory.getLogger();
            log.info("Change set " + getChangeSet().toString(false) + " failed, but failOnError was false.  Error: " + ule.getMessage());
            return new SqlStatement[0];
        } else {
            throw ule;
        }
    } finally {
        if (null != reader) {
            try {
                reader.close();
            } catch (IOException e) {
                ;
            }
        }
    }
}
Also used : InsertOrUpdateStatement(liquibase.statement.core.InsertOrUpdateStatement) ColumnConfig(liquibase.change.ColumnConfig) Logger(liquibase.logging.Logger) InsertStatement(liquibase.statement.core.InsertStatement) SqlStatement(liquibase.statement.SqlStatement) Column(liquibase.structure.core.Column) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) InsertExecutablePreparedStatement(liquibase.statement.InsertExecutablePreparedStatement) CSVReader(liquibase.util.csv.CSVReader) MySQLDatabase(liquibase.database.core.MySQLDatabase) IOException(java.io.IOException) AbstractJdbcDatabase(liquibase.database.AbstractJdbcDatabase) PostgresDatabase(liquibase.database.core.PostgresDatabase) InsertSetStatement(liquibase.statement.core.InsertSetStatement) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException)

Example 2 with InsertOrUpdateStatement

use of liquibase.statement.core.InsertOrUpdateStatement in project liquibase by liquibase.

the class LoadUpdateDataChange method generateRollbackStatements.

@Override
public SqlStatement[] generateRollbackStatements(Database database) throws RollbackImpossibleException {
    List<SqlStatement> statements = new ArrayList<SqlStatement>();
    SqlStatement[] forward = this.generateStatements(database);
    for (SqlStatement thisForward : forward) {
        InsertOrUpdateStatement thisInsert = (InsertOrUpdateStatement) thisForward;
        DeleteStatement delete = new DeleteStatement(getCatalogName(), getSchemaName(), getTableName());
        delete.setWhere(getWhere(thisInsert, database));
        statements.add(delete);
    }
    return statements.toArray(new SqlStatement[statements.size()]);
}
Also used : SqlStatement(liquibase.statement.SqlStatement) InsertOrUpdateStatement(liquibase.statement.core.InsertOrUpdateStatement) ArrayList(java.util.ArrayList) DeleteStatement(liquibase.statement.core.DeleteStatement)

Example 3 with InsertOrUpdateStatement

use of liquibase.statement.core.InsertOrUpdateStatement in project liquibase by liquibase.

the class InsertOrUpdateGeneratorMSSQLTest method getUpdate.

@Test
public void getUpdate() {
    InsertOrUpdateGeneratorMSSQL generator = new InsertOrUpdateGeneratorMSSQL();
    MSSQLDatabase database = new MSSQLDatabase();
    InsertOrUpdateStatement statement = new InsertOrUpdateStatement("mycatalog", "myschema", "mytable", "pk_col1");
    statement.addColumnValue("col2", "value2");
    String where = "1 = 1";
    Class c = InsertOrUpdateGenerator.class.getClass();
    //InsertOrUpdateStatement insertOrUpdateStatement, Database database, String whereClause, SqlGeneratorChain sqlGeneratorChain
    String insertStatement = (String) invokePrivateMethod(generator, "getUpdateStatement", new Object[] { statement, database, where, null });
    Integer lineNumber = 0;
    String[] lines = insertStatement.split("\n");
    assertEquals("BEGIN", lines[lineNumber]);
    lineNumber++;
    assertTrue(lines[lineNumber].startsWith("UPDATE"));
    lineNumber++;
    assertEquals("END", lines[lineNumber]);
}
Also used : InsertOrUpdateStatement(liquibase.statement.core.InsertOrUpdateStatement) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) Test(org.junit.Test)

Example 4 with InsertOrUpdateStatement

use of liquibase.statement.core.InsertOrUpdateStatement in project liquibase by liquibase.

the class InsertOrUpdateGeneratorMSSQLTest method getRecordCheck.

@Test
public void getRecordCheck() {
    InsertOrUpdateGeneratorMSSQL generator = new InsertOrUpdateGeneratorMSSQL();
    MSSQLDatabase database = new MSSQLDatabase();
    InsertOrUpdateStatement statement = new InsertOrUpdateStatement("mycatalog", "myschema", "mytable", "pk_col1");
    statement.addColumnValue("pk_col1", "value1");
    statement.addColumnValue("col2", "value2");
    String where = "1 = 1";
    String recordCheck = (String) invokePrivateMethod(generator, "getRecordCheck", new Object[] { statement, database, where });
    Integer lineNumber = 0;
    String[] lines = recordCheck.split("\n");
    assertEquals("DECLARE @reccount integer", lines[lineNumber]);
    lineNumber++;
    assertEquals("SELECT @reccount = count(*) FROM [mycatalog].[myschema].[mytable] WHERE " + where, lines[lineNumber]);
    lineNumber++;
    assertEquals("IF @reccount = 0", lines[lineNumber]);
}
Also used : InsertOrUpdateStatement(liquibase.statement.core.InsertOrUpdateStatement) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) Test(org.junit.Test)

Example 5 with InsertOrUpdateStatement

use of liquibase.statement.core.InsertOrUpdateStatement in project liquibase by liquibase.

the class InsertOrUpdateGeneratorMSSQLTest method getInsert.

@Test
public void getInsert() {
    InsertOrUpdateGeneratorMSSQL generator = new InsertOrUpdateGeneratorMSSQL();
    MSSQLDatabase database = new MSSQLDatabase();
    InsertOrUpdateStatement statement = new InsertOrUpdateStatement("mycatalog", "myschema", "mytable", "pk_col1");
    statement.addColumnValue("pk_col1", "value1");
    statement.addColumnValue("col2", "value2");
    String where = "1 = 1";
    Class c = InsertOrUpdateGenerator.class.getClass();
    //InsertOrUpdateStatement insertOrUpdateStatement, Database database, SqlGeneratorChain sqlGeneratorChain
    String insertStatement = (String) invokePrivateMethod(generator, "getInsertStatement", new Object[] { statement, database, null });
    Integer lineNumber = 0;
    String[] lines = insertStatement.split("\n");
    assertEquals("BEGIN", lines[lineNumber]);
    lineNumber++;
    assertTrue(lines[lineNumber].startsWith("INSERT"));
    lineNumber++;
    assertEquals("END", lines[lineNumber]);
}
Also used : InsertOrUpdateStatement(liquibase.statement.core.InsertOrUpdateStatement) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) Test(org.junit.Test)

Aggregations

InsertOrUpdateStatement (liquibase.statement.core.InsertOrUpdateStatement)9 Test (org.junit.Test)6 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)5 OracleDatabase (liquibase.database.core.OracleDatabase)3 Sql (liquibase.sql.Sql)3 SqlStatement (liquibase.statement.SqlStatement)2 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 ColumnConfig (liquibase.change.ColumnConfig)1 AbstractJdbcDatabase (liquibase.database.AbstractJdbcDatabase)1 MySQLDatabase (liquibase.database.core.MySQLDatabase)1 PostgresDatabase (liquibase.database.core.PostgresDatabase)1 LiquibaseException (liquibase.exception.LiquibaseException)1 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)1 Logger (liquibase.logging.Logger)1 UnparsedSql (liquibase.sql.UnparsedSql)1 InsertExecutablePreparedStatement (liquibase.statement.InsertExecutablePreparedStatement)1 DeleteStatement (liquibase.statement.core.DeleteStatement)1 InsertSetStatement (liquibase.statement.core.InsertSetStatement)1