Author: bodewig
Date: Thu Apr 24 04:17:38 2008
New Revision: 651219
URL: http://svn.apache.org/viewvc?rev=651219&view=rev
Log:
remove @author tags and tabs, Submitted by Andrus Adamchik, PR: 44853
Added:
ant/sandbox/antlibs/dbpatch/TODO (with props)
Modified:
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/AntDBPatchRunner.java
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchRunner.java
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchTask.java
Added: ant/sandbox/antlibs/dbpatch/TODO
URL:
http://svn.apache.org/viewvc/ant/sandbox/antlibs/dbpatch/TODO?rev=651219&view=auto
==============================================================================
--- ant/sandbox/antlibs/dbpatch/TODO (added)
+++ ant/sandbox/antlibs/dbpatch/TODO Thu Apr 24 04:17:38 2008
@@ -0,0 +1,14 @@
+
+What we need for release 1.0:
+
+* Unit tests
+* Documentation
+* Support for passing driver classpath ref
+* Support for alternative workflow that requires no index file,
+ and uses numbered patch files instead
+ (such workflow targets smaller projects with less commit concurrency).
+* Support for arbitrary patch tracking table schema for better portability.
+* Support for patch file update detection and optional re-run (confirmed
interactively).
+ This would allow to test partial patches, undo them manually and rerun again.
+* Support for multi-DB patches, with support for default patches that fit all
DB's, and minimal required overrides.
+
\ No newline at end of file
Propchange: ant/sandbox/antlibs/dbpatch/TODO
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/AntDBPatchRunner.java
URL:
http://svn.apache.org/viewvc/ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/AntDBPatchRunner.java?rev=651219&r1=651218&r2=651219&view=diff
==============================================================================
---
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/AntDBPatchRunner.java
(original)
+++
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/AntDBPatchRunner.java
Thu Apr 24 04:17:38 2008
@@ -26,36 +26,35 @@
/**
* A DataPatchRunner that uses Ant loggers.
- *
- * @author andrus
*/
class AntDBPatchRunner extends DBPatchRunner {
- private DBPatchTask parentTask;
+ private DBPatchTask parentTask;
- public AntDBPatchRunner(DBPatchTask parentTask, Connection connection,
- File patchIndex, String patchTableName, String
patchReleaseId) {
- super(connection, patchIndex, patchTableName, patchReleaseId);
- this.parentTask = parentTask;
- }
-
- void log(String message) {
- parentTask.log(message);
- }
-
- void logVerbose(String message) {
- parentTask.log(message, Project.MSG_VERBOSE);
- }
-
- void applyPatch(String patchName) throws SQLException {
- File patchFile = new File(patchDir, patchName);
- if (!patchFile.isFile()) {
- throw new SQLException("Missing or invalid patch file: "
- + patchFile.getAbsolutePath());
- }
-
- logVerbose("Will run patch: " + patchName);
-
- parentTask.setSrc(patchFile);
- parentTask.runSQL();
- }
+ public AntDBPatchRunner(DBPatchTask parentTask, Connection connection,
+ File patchIndex, String patchTableName,
+ String patchReleaseId) {
+ super(connection, patchIndex, patchTableName, patchReleaseId);
+ this.parentTask = parentTask;
+ }
+
+ void log(String message) {
+ parentTask.log(message);
+ }
+
+ void logVerbose(String message) {
+ parentTask.log(message, Project.MSG_VERBOSE);
+ }
+
+ void applyPatch(String patchName) throws SQLException {
+ File patchFile = new File(patchDir, patchName);
+ if (!patchFile.isFile()) {
+ throw new SQLException("Missing or invalid patch file: "
+ + patchFile.getAbsolutePath());
+ }
+
+ logVerbose("Will run patch: " + patchName);
+
+ parentTask.setSrc(patchFile);
+ parentTask.runSQL();
+ }
}
Modified:
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchRunner.java
URL:
http://svn.apache.org/viewvc/ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchRunner.java?rev=651219&r1=651218&r2=651219&view=diff
==============================================================================
---
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchRunner.java
(original)
+++
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchRunner.java
Thu Apr 24 04:17:38 2008
@@ -33,182 +33,181 @@
/**
* A runner for the DataPatchTask.
- *
- * @author andrus
*/
abstract class DBPatchRunner {
- static final String PATCH_UTILITY_VERSION = "1.0.0";
+ static final String PATCH_UTILITY_VERSION = "1.0.0";
- private Connection connection;
- private File patchIndex;
- private String patchTableName;
- private String patchReleaseId;
- protected File patchDir;
-
- DBPatchRunner(Connection connection, File patchIndex,
- String patchTableName, String patchReleaseId) {
-
- this.connection = connection;
- this.patchTableName = patchTableName;
- this.patchReleaseId = patchReleaseId;
-
- this.patchIndex = patchIndex;
- this.patchDir = patchIndex.getParentFile();
-
- if (patchDir == null || !patchDir.isDirectory()) {
- throw new IllegalArgumentException("Invalid patch
directory: "
- + patchDir);
- }
- }
-
- abstract void log(String message);
-
- abstract void logVerbose(String message);
-
- void execute() throws SQLException, IOException {
-
- setupPatchTable();
-
- Collection patches = new LinkedHashSet();
- initNewPatchList(patches);
- int maxId = filterOutAppliedPatches(patches);
- applyPatches(patches, maxId + 1);
- }
-
- private void setupPatchTable() throws SQLException {
- String tableName = patchTableName;
- String schema = null;
-
- int dot = patchTableName.indexOf('.');
- if (dot > 0 && dot < patchTableName.length() - 1) {
- schema = patchTableName.substring(0, dot);
- tableName = patchTableName.substring(dot + 1);
- }
-
- boolean patchTableExists;
- ResultSet rs = connection.getMetaData().getTables(null, schema,
- tableName, null);
- try {
- patchTableExists = rs.next();
- } finally {
- rs.close();
- }
-
- if (!patchTableExists) {
- StringBuilder createTable = new StringBuilder();
- createTable.append("CREATE TABLE ");
- createTable.append(patchTableName);
- createTable.append(" (ID INTEGER NOT NULL,");
- createTable.append(" PATCH_NAME VARCHAR(100),");
- createTable.append(" PATCH_RELEASE_ID VARCHAR(20),");
- createTable.append(" APPLIED_TIMESTAMP TIMESTAMP,");
- createTable.append(" PATCH_UTILITY_VERSION
VARCHAR(20))");
-
- String createTableString = createTable.toString();
- logVerbose(createTableString);
-
- PreparedStatement st = connection
- .prepareStatement(createTableString);
- try {
- st.execute();
- } finally {
- st.close();
- }
- }
- }
-
- private void initNewPatchList(Collection patches) throws IOException {
- BufferedReader reader = new BufferedReader(new
FileReader(patchIndex));
-
- try {
- String line;
- while ((line = reader.readLine()) != null) {
- line = line.trim();
- if (line.length() == 0) {
- continue;
- }
-
- if (line.startsWith("#") ||
line.startsWith("//")) {
- continue;
- }
-
- patches.add(line);
- }
- } finally {
- reader.close();
- }
- }
-
- private int filterOutAppliedPatches(Collection patches) throws
SQLException {
- PreparedStatement st = connection
- .prepareStatement("SELECT ID, PATCH_NAME FROM "
- + patchTableName
- + " WHERE PATCH_RELEASE_ID = ?
ORDER BY ID");
-
- try {
- st.setString(1, patchReleaseId);
-
- int lastId = 0;
-
- ResultSet rs = st.executeQuery();
- try {
- while (rs.next()) {
- lastId = rs.getInt(1);
- String appliedPatch = rs.getString(2);
-
- if (patches.remove(appliedPatch)) {
- logVerbose("Previously applied
patch: " + appliedPatch
- + ", ignoring");
- }
- }
- } finally {
- rs.close();
- }
-
- return lastId;
-
- } finally {
- st.close();
- }
- }
-
- private void applyPatches(Collection patches, int startId)
- throws SQLException {
- if (patches.isEmpty()) {
- return;
- }
-
- PreparedStatement patchSt = connection
- .prepareStatement("INSERT INTO "
- + patchTableName
- + " (ID, PATCH_NAME,
PATCH_RELEASE_ID, APPLIED_TIMESTAMP, PATCH_UTILITY_VERSION) "
- + "VALUES (?, ?, ?, ?, ?)");
- try {
-
- Iterator it = patches.iterator();
- while (it.hasNext()) {
-
- String patch = (String) it.next();
-
- applyPatch(patch);
-
- // insert patch record...
- patchSt.setInt(1, startId++);
- patchSt.setString(2, patch);
- patchSt.setString(3, patchReleaseId);
- patchSt.setTimestamp(4, new Timestamp(System
- .currentTimeMillis()));
- patchSt.setString(5, PATCH_UTILITY_VERSION);
- patchSt.executeUpdate();
-
- // commit each patch record separately...
- connection.commit();
- }
- } finally {
- patchSt.close();
- }
- }
+ private Connection connection;
+ private File patchIndex;
+ private String patchTableName;
+ private String patchReleaseId;
+ protected File patchDir;
+
+ DBPatchRunner(Connection connection, File patchIndex,
+ String patchTableName, String patchReleaseId) {
+
+ this.connection = connection;
+ this.patchTableName = patchTableName;
+ this.patchReleaseId = patchReleaseId;
+
+ this.patchIndex = patchIndex;
+ this.patchDir = patchIndex.getParentFile();
+
+ if (patchDir == null || !patchDir.isDirectory()) {
+ throw new IllegalArgumentException("Invalid patch directory: "
+ + patchDir);
+ }
+ }
+
+ abstract void log(String message);
+
+ abstract void logVerbose(String message);
+
+ void execute() throws SQLException, IOException {
+
+ setupPatchTable();
+
+ Collection patches = new LinkedHashSet();
+ initNewPatchList(patches);
+ int maxId = filterOutAppliedPatches(patches);
+ applyPatches(patches, maxId + 1);
+ }
+
+ private void setupPatchTable() throws SQLException {
+ String tableName = patchTableName;
+ String schema = null;
+
+ int dot = patchTableName.indexOf('.');
+ if (dot > 0 && dot < patchTableName.length() - 1) {
+ schema = patchTableName.substring(0, dot);
+ tableName = patchTableName.substring(dot + 1);
+ }
+
+ boolean patchTableExists;
+ ResultSet rs = connection.getMetaData().getTables(null, schema,
+ tableName, null);
+ try {
+ patchTableExists = rs.next();
+ } finally {
+ rs.close();
+ }
+
+ if (!patchTableExists) {
+ StringBuilder createTable = new StringBuilder();
+ createTable.append("CREATE TABLE ");
+ createTable.append(patchTableName);
+ createTable.append(" (ID INTEGER NOT NULL,");
+ createTable.append(" PATCH_NAME VARCHAR(100),");
+ createTable.append(" PATCH_RELEASE_ID VARCHAR(20),");
+ createTable.append(" APPLIED_TIMESTAMP TIMESTAMP,");
+ createTable.append(" PATCH_UTILITY_VERSION VARCHAR(20))");
+
+ String createTableString = createTable.toString();
+ logVerbose(createTableString);
+
+ PreparedStatement st = connection
+ .prepareStatement(createTableString);
+ try {
+ st.execute();
+ } finally {
+ st.close();
+ }
+ }
+ }
+
+ private void initNewPatchList(Collection patches) throws IOException {
+ BufferedReader reader = new BufferedReader(new FileReader(patchIndex));
+
+ try {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ if (line.length() == 0) {
+ continue;
+ }
+
+ if (line.startsWith("#") || line.startsWith("//")) {
+ continue;
+ }
+
+ patches.add(line);
+ }
+ } finally {
+ reader.close();
+ }
+ }
+
+ private int filterOutAppliedPatches(Collection patches) throws
SQLException {
+ PreparedStatement st = connection
+ .prepareStatement("SELECT ID, PATCH_NAME FROM "
+ + patchTableName
+ + " WHERE PATCH_RELEASE_ID = ? ORDER BY ID");
+
+ try {
+ st.setString(1, patchReleaseId);
+
+ int lastId = 0;
+
+ ResultSet rs = st.executeQuery();
+ try {
+ while (rs.next()) {
+ lastId = rs.getInt(1);
+ String appliedPatch = rs.getString(2);
+
+ if (patches.remove(appliedPatch)) {
+ logVerbose("Previously applied patch: " + appliedPatch
+ + ", ignoring");
+ }
+ }
+ } finally {
+ rs.close();
+ }
+
+ return lastId;
+
+ } finally {
+ st.close();
+ }
+ }
+
+ private void applyPatches(Collection patches, int startId)
+ throws SQLException {
+ if (patches.isEmpty()) {
+ return;
+ }
+
+ PreparedStatement patchSt = connection
+ .prepareStatement("INSERT INTO "
+ + patchTableName
+ + " (ID, PATCH_NAME, PATCH_RELEASE_ID,"
+ + " APPLIED_TIMESTAMP, PATCH_UTILITY_VERSION) "
+ + "VALUES (?, ?, ?, ?, ?)");
+ try {
+
+ Iterator it = patches.iterator();
+ while (it.hasNext()) {
+
+ String patch = (String) it.next();
+
+ applyPatch(patch);
+
+ // insert patch record...
+ patchSt.setInt(1, startId++);
+ patchSt.setString(2, patch);
+ patchSt.setString(3, patchReleaseId);
+ patchSt.setTimestamp(4, new Timestamp(System
+ .currentTimeMillis()));
+ patchSt.setString(5, PATCH_UTILITY_VERSION);
+ patchSt.executeUpdate();
+
+ // commit each patch record separately...
+ connection.commit();
+ }
+ } finally {
+ patchSt.close();
+ }
+ }
- abstract void applyPatch(String patchName) throws SQLException;
+ abstract void applyPatch(String patchName) throws SQLException;
}
Modified:
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchTask.java
URL:
http://svn.apache.org/viewvc/ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchTask.java?rev=651219&r1=651218&r2=651219&view=diff
==============================================================================
---
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchTask.java
(original)
+++
ant/sandbox/antlibs/dbpatch/src/main/org/apache/ant/dbpatch/DBPatchTask.java
Thu Apr 24 04:17:38 2008
@@ -28,82 +28,82 @@
/**
* An Ant task that supports maintaining evolving database schema via
- * incremental SQL "patches". Patches are written in a native SQL dialect o the
+ * incremental SQL "patches". Patches are written in a native SQL dialect of
the
* target database. Patch status is tracked via a special
- *
- * @author andrus
*/
// many things are cloned from SQLExec Ant task...
public class DBPatchTask extends SQLExec {
- static final String PATCH_TABLE_NAME = "patch_tracking";
+ static final String PATCH_TABLE_NAME = "patch_tracking";
- protected String patchReleaseId;
- protected File patchIndex;
- protected String patchTableName;
-
- /**
- * A required file that stores an index of patch SQL files in the order
they
- * should be applied.
- */
- public void setPatchIndex(File patchIndex) {
- this.patchIndex = patchIndex;
- }
-
- /**
- * An optional attribute specifying the table name to store database
- * patches. Default value is "patch_tracking".
- */
- public void setPatchTableName(String patchTableName) {
- this.patchTableName = patchTableName;
- }
-
- /**
- * An optional release ID String that defines patch files namespace.
- */
- public void setPatchReleaseId(String patchReleaseId) {
- this.patchReleaseId = patchReleaseId;
- }
-
- public void execute() throws BuildException {
- validate();
- initDefaults();
-
- Connection connection = getConnection();
- try {
- DBPatchRunner runner = new AntDBPatchRunner(this,
connection,
- patchIndex, patchTableName,
patchReleaseId);
- runner.execute();
- } catch (SQLException e) {
- throw new BuildException("SQL exception " +
e.getMessage(), e);
- } catch (IOException e) {
- throw new BuildException("IO exception " +
e.getMessage(), e);
- } finally {
- try {
- connection.close();
- } catch (SQLException ignore) {
- }
- }
- }
-
- void runSQL() throws BuildException {
- super.execute();
- }
-
- private void initDefaults() {
- if (patchTableName == null) {
- patchTableName = PATCH_TABLE_NAME;
- }
- }
-
- private void validate() throws BuildException {
- if (patchIndex == null) {
- throw new BuildException("No 'patchIndex' file
specified.");
- }
-
- if (!patchIndex.isFile()) {
- throw new BuildException("Invalid 'patchIndex' file
specified: "
- + patchIndex.getAbsolutePath());
- }
- }
+ protected String patchReleaseId;
+ protected File patchIndex;
+ protected String patchTableName;
+
+ /**
+ * A required file that stores an index of patch SQL files in the order
they
+ * should be applied.
+ */
+ public void setPatchIndex(File patchIndex) {
+ this.patchIndex = patchIndex;
+ }
+
+ /**
+ * An optional attribute specifying the table name to store database
+ * patches. Default value is "patch_tracking".
+ */
+ public void setPatchTableName(String patchTableName) {
+ this.patchTableName = patchTableName;
+ }
+
+ /**
+ * An optional release ID String that defines patch files namespace.
+ */
+ public void setPatchReleaseId(String patchReleaseId) {
+ this.patchReleaseId = patchReleaseId;
+ }
+
+ public void execute() throws BuildException {
+ validate();
+ initDefaults();
+
+ Connection connection = getConnection();
+ try {
+ DBPatchRunner runner = new AntDBPatchRunner(this, connection,
+ patchIndex,
+ patchTableName,
+ patchReleaseId);
+ runner.execute();
+ } catch (SQLException e) {
+ throw new BuildException("SQL exception " + e.getMessage(), e);
+ } catch (IOException e) {
+ throw new BuildException("IO exception " + e.getMessage(), e);
+ } finally {
+ try {
+ connection.close();
+ } catch (SQLException ignore) {
+ }
+ }
+ }
+
+ void runSQL() throws BuildException {
+ super.execute();
+ }
+
+ private void initDefaults() {
+ if (patchTableName == null) {
+ patchTableName = PATCH_TABLE_NAME;
+ }
+ }
+
+ private void validate() throws BuildException {
+ if (patchIndex == null) {
+ throw new BuildException("No 'patchIndex' file specified.");
+ }
+
+ if (!patchIndex.isFile()) {
+ throw new BuildException("Invalid 'patchIndex' file specified: "
+ + patchIndex.getAbsolutePath());
+ }
+ }
}