package com.txtr.hibernatedelta.generator;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import javax.xml.bind.JAXBException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.ImmutableList;
import com.txtr.hibernatedelta.DatabaseWithIndexes;
import com.txtr.hibernatedelta.generator.customer2.Customer;
import com.txtr.hibernatedelta.model.HibernateDatabase;
import com.txtr.hibernatedelta.model.HibernateIndexNames;
import com.txtr.hibernatedelta.validator.EntityValidator;
public class UpdateSqlGeneratorTest {
@Test
public void testAddTable() throws Exception {
Assert.assertEquals("CREATE TABLE Customer (catalog_id NUMBER(19, 0) NOT NULL, id NUMBER(19, 0) NOT NULL, name VARCHAR2(255 CHAR), street VARCHAR2(255 CHAR));\n" +
"CREATE UNIQUE INDEX CUSTOMER0 ON Customer(id) parallel 3 nologging;\n" +
"CREATE INDEX CUSTOMER1 ON Customer(catalog_id) parallel 3 nologging;\n" +
"ALTER TABLE Customer ADD CONSTRAINT CUSTOMER0P PRIMARY KEY (id);\n" +
"ALTER TABLE Customer ADD CONSTRAINT Customer1F FOREIGN KEY (catalog_id) REFERENCES Customer (id) DEFERRABLE INITIALLY DEFERRED;",
ensureLines(getChanges("emptySchema.xml", "emptyIndexNames.xml", "schema2.xml", "indexNames2.xml", ImmutableList.<Class<?>>of(Customer.class)),
"CREATE UNIQUE INDEX CUSTOMER0 ON Customer(id) parallel 3 nologging;",
"CREATE INDEX CUSTOMER1 ON Customer(catalog_id) parallel 3 nologging;"
));
}
//not deterministic
private String ensureLines(String changes, String line1, String line2) {
return StringUtils.replace(changes, line2 + "\n" + line1, line1 + "\n" + line2);
}
@Test
public void testAddColumn() throws Exception {
Assert.assertEquals("ALTER TABLE Customer ADD street VARCHAR2(255 CHAR);\n" +
"ALTER TABLE Customer ADD id NUMBER(19, 0) NOT NULL;\n" +
"ALTER TABLE Customer ADD catalog_id NUMBER(19, 0) NOT NULL;\n" +
"CREATE INDEX CUSTOMER1 ON Customer(catalog_id) parallel 3 nologging;\n" +
"CREATE UNIQUE INDEX CUSTOMER0 ON Customer(id) parallel 3 nologging;\n" +
"ALTER TABLE Customer ADD CONSTRAINT CUSTOMER0P PRIMARY KEY (id);\n" +
"ALTER TABLE Customer ADD CONSTRAINT Customer1F FOREIGN KEY (catalog_id) REFERENCES Customer (id) DEFERRABLE INITIALLY DEFERRED;",
ensureLines(getChanges("schema1.xml", "emptyIndexNames.xml", "schema2.xml", "indexNames2.xml", ImmutableList.<Class<?>>of(Customer.class)),
"CREATE INDEX CUSTOMER1 ON Customer(catalog_id) parallel 3 nologging;",
"CREATE UNIQUE INDEX CUSTOMER0 ON Customer(id) parallel 3 nologging;"
));
}
@Test
public void testRemoveColumn() throws Exception {
Assert.assertEquals(
"ALTER TABLE Customer DROP CONSTRAINT Customer1F;\n" +
"ALTER TABLE Customer DROP PRIMARY KEY;\n" +
"DROP INDEX CUSTOMER1;\n" +
"DROP INDEX CUSTOMER0;\n" +
"ALTER TABLE Customer DROP COLUMN street;\n" +
"ALTER TABLE Customer DROP COLUMN id;\n" +
"ALTER TABLE Customer DROP COLUMN catalog_id;",
ensureLines(getChanges("schema2.xml", "emptyIndexNames.xml", "schema1.xml", "emptyIndexNames.xml", ImmutableList.<Class<?>>of(com.txtr.hibernatedelta.generator.customer1.Customer.class)),
"DROP INDEX CUSTOMER1;",
"DROP INDEX CUSTOMER0;"
));
}
@Test
public void testRemoveTable() throws Exception {
Assert.assertEquals(
"ALTER TABLE Customer DROP CONSTRAINT Customer1F;\n" +
"ALTER TABLE Customer DROP PRIMARY KEY;\n" +
"DROP INDEX CUSTOMER0;\n" +
"DROP INDEX CUSTOMER1;\n" +
"ALTER TABLE Customer DROP COLUMN street;\n" +
"ALTER TABLE Customer DROP COLUMN id;\n" +
"ALTER TABLE Customer DROP COLUMN catalog_id;\n" +
"ALTER TABLE Customer DROP COLUMN name;\n" +
"DROP TABLE Customer;",
ensureLines(getChanges("schema2.xml", "emptyIndexNames.xml", "emptySchema2.xml", "emptyIndexNames.xml", ImmutableList.<Class<?>>of()),
"DROP INDEX CUSTOMER0;",
"DROP INDEX CUSTOMER1;"
));
}
public String getChanges(String schema, String indexNames, String newSchema, String newIndexNames, ImmutableList<Class<?>> entities) throws Exception {
URL names = getResource(indexNames);
DatabaseWithIndexes newDatabase = new EntityValidator().verify(entities, names);
String sql = new BackendSqlGenerator().createUpdateAgainstCommittedSchema(getResource(schema), newDatabase, names).trim();
assertSchema(newSchema, newDatabase.getDatabase());
assertIndexNames(newIndexNames, newDatabase.getIndexNames());
return sql;
}
private void assertIndexNames(String newIndexNames, HibernateIndexNames indexNames) throws JAXBException, IOException {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
BackendSqlGenerator.getIndexMarshaller().marshal(indexNames, stream);
Assert.assertEquals(IOUtils.toString(getResource(newIndexNames)), stream.toString().trim());
}
private void assertSchema(String newSchema, HibernateDatabase database) throws JAXBException, IOException {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
BackendSqlGenerator.getSchemaMarshaller().marshal(database, stream);
Assert.assertEquals(IOUtils.toString(getResource(newSchema)), stream.toString().trim());
}
private URL getResource(String indexNames) {
return getClass().getClassLoader().getResource(indexNames);
}
}