From f4e0518cc29c516490e74dbc819e75fa11adc7b1 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 3 Sep 2014 15:38:43 -0500 Subject: [PATCH 01/16] Implement regexp excludes, close some connections, don't specify size if it is the max --- .../certifi/audittablegen/ChangeSourceFactory.java | 14 +++++++++++++- .../java/net/certifi/audittablegen/ColumnDef.java | 5 +++++ .../java/net/certifi/audittablegen/GenericDMR.java | 1 + .../net/certifi/audittablegen/PostgresqlDMR.java | 6 +++++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java index bbb9fa0..70c78a0 100644 --- a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java +++ b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java @@ -19,6 +19,8 @@ package net.certifi.audittablegen; import java.util.*; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; import org.apache.commons.collections.map.CaseInsensitiveMap; import org.apache.commons.lang3.exception.ContextedRuntimeException; import org.slf4j.Logger; @@ -133,10 +135,20 @@ Boolean isPatternMatch(String str, String pattern) { //TODO: this is where regexp or wildcard pattern matching should go if (pattern.isEmpty() || pattern.equals("*") - || pattern.toLowerCase().equals(str.toLowerCase())) { + || pattern.toLowerCase().equals(str.toLowerCase()) ) { return Boolean.TRUE; } + try { + Pattern p = Pattern.compile( pattern, Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CASE ); + if ( p != null && p.matcher( str ).matches() ) return Boolean.TRUE; + + } catch( IllegalArgumentException x) { + + logger.warn( "Invalid Regexp " + x.getMessage() ); + } + + return Boolean.FALSE; } diff --git a/src/main/java/net/certifi/audittablegen/ColumnDef.java b/src/main/java/net/certifi/audittablegen/ColumnDef.java index f0d8ac1..c2f0daf 100644 --- a/src/main/java/net/certifi/audittablegen/ColumnDef.java +++ b/src/main/java/net/certifi/audittablegen/ColumnDef.java @@ -95,4 +95,9 @@ public void setDataTypeDef(DataTypeDef dataTypeDef) { this.dataTypeDef = dataTypeDef; } + @Override + public String toString() { + return "ColumnDef{" + "name=" + name + ", typeName=" + typeName + ", sqlType=" + sqlType + ", size=" + size + ", decimalSize=" + decimalSize + ", dataTypeDef=" + dataTypeDef + ", sourceMeta=" + sourceMeta + '}'; + } + } diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index 1a2ef6b..a4f20be 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -405,6 +405,7 @@ public Map getDataTypes (){ } + conn.close(); } catch (SQLException e) { throw Throwables.propagate(e); } diff --git a/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java b/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java index e13520d..aa87e16 100644 --- a/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java +++ b/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java @@ -133,6 +133,7 @@ public List getColumns (String tableName){ throw new RuntimeException("No results for DatabaseMetaData.getColumns(" + verifiedSchema + "." + tableName + ")"); } while (rs.next()){ + ColumnDef columnDef = new ColumnDef(); Map columnMetaData = new CaseInsensitiveMap(); for (int i = 1; i <= metaDataColumnCount; i++){ @@ -148,7 +149,7 @@ public List getColumns (String tableName){ columnDef.setTypeName(type_name); } columnDef.setSqlType(rs.getInt("DATA_TYPE")); - columnDef.setSize(rs.getInt("COLUMN_SIZE")); + columnDef.setSize( Integer.MAX_VALUE == rs.getInt("COLUMN_SIZE") ? 0 : rs.getInt("COLUMN_SIZE") ); //if a column is maxed don't specify the size columnDef.setDecimalSize(rs.getInt("DECIMAL_DIGITS")); columnDef.setSourceMeta(columnMetaData); @@ -159,8 +160,11 @@ public List getColumns (String tableName){ throw new RuntimeException("Missing DATA_TYPE definition for data type " + columnDef.getTypeName()); } columns.add(columnDef); + if ( tableName.equals("hiera" ) ) System.out.println( columnDef.toString() ); + } + conn.close(); } catch (SQLException e) { throw Throwables.propagate(e); From 93c98a95131231d6b2d41c41d647caa65064160a Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 3 Sep 2014 16:24:26 -0500 Subject: [PATCH 02/16] Always generate is distinct tests for update trigger --- src/main/java/net/certifi/audittablegen/GenericDMR.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index a4f20be..a0e35bc 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -844,7 +844,7 @@ String getCreateTriggerSQL(List op) { ////////////////////// //generate the when clause for the update trigger - if (columns.size() > whenColumns.size() ){ + if ( true /* columns.size() > whenColumns.size() */ ){ //some columns excluded from update updateConditional.append("AND ("); boolean firstCol = true; From 253053622561960a9b8e1d185616286d26f629f3 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 3 Sep 2014 16:25:12 -0500 Subject: [PATCH 03/16] Remove Logging --- src/main/java/net/certifi/audittablegen/PostgresqlDMR.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java b/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java index aa87e16..4d2734d 100644 --- a/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java +++ b/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java @@ -160,7 +160,6 @@ public List getColumns (String tableName){ throw new RuntimeException("Missing DATA_TYPE definition for data type " + columnDef.getTypeName()); } columns.add(columnDef); - if ( tableName.equals("hiera" ) ) System.out.println( columnDef.toString() ); } From fd69c3fc20c0853208ccecc45b4f195eadd27437 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Thu, 4 Sep 2014 15:52:25 -0500 Subject: [PATCH 04/16] the iddatatype configuration was falling through to the userdatatype --- src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java index 70c78a0..c8de638 100644 --- a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java +++ b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java @@ -79,6 +79,7 @@ public class ChangeSourceFactory { break; case iddatatype: auditIdTypeName = attrib.getValue(); + break; case userdatatype: auditUserTypeName = attrib.getValue(); break; From 92d6a9ce111b094189b4c6dc315b64a8f31b2892 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Thu, 4 Sep 2014 15:53:27 -0500 Subject: [PATCH 05/16] bigserials in data should result in bigints in the audit tables --- .../certifi/audittablegen/PostgresqlDMR.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java b/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java index 4d2734d..720934d 100644 --- a/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java +++ b/src/main/java/net/certifi/audittablegen/PostgresqlDMR.java @@ -142,12 +142,18 @@ public List getColumns (String tableName){ columnDef.setName(rs.getString("COLUMN_NAME")); String type_name = rs.getString("TYPE_NAME"); - if ( type_name.equalsIgnoreCase("serial")){ - columnDef.setTypeName("int4"); - } - else { - columnDef.setTypeName(type_name); - } + switch( type_name.toLowerCase() ) { + case "serial": + columnDef.setTypeName("int4"); + break; + case "bigserial": + columnDef.setTypeName("int8"); + break; + default: + columnDef.setTypeName(type_name); + break; + } + columnDef.setSqlType(rs.getInt("DATA_TYPE")); columnDef.setSize( Integer.MAX_VALUE == rs.getInt("COLUMN_SIZE") ? 0 : rs.getInt("COLUMN_SIZE") ); //if a column is maxed don't specify the size columnDef.setDecimalSize(rs.getInt("DECIMAL_DIGITS")); From 1f42fb074f9e47ad7ba52d5d46dad8f0c8d13fa6 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 10 Sep 2014 10:07:53 -0500 Subject: [PATCH 06/16] Do initial population of audit tables --- .../audittablegen/ChangeSourceFactory.java | 54 ++++++++++- .../certifi/audittablegen/DBChangeType.java | 1 + .../certifi/audittablegen/DBChangeUnit.java | 19 +++- .../net/certifi/audittablegen/GenericDMR.java | 91 ++++++++++++++++++- 4 files changed, 161 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java index c8de638..8d4e0d2 100644 --- a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java +++ b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java @@ -343,8 +343,60 @@ List getDBChangeList(TableDef baseTableDef){ //end of table tableChangeUnits.add(new DBChangeUnit(DBChangeType.end)); + + // populate the table + tableChangeUnits.add( new DBChangeUnit(DBChangeType.begin) ); + workUnit = new DBChangeUnit(DBChangeType.fillAuditTable); + workUnit.tableName = auditTableName; + tableChangeUnits.add(workUnit); + + // fill all columns on the base table + for (ColumnDef baseColumn : baseTableDef.getColumns()) { + workUnit = new DBChangeUnit(DBChangeType.addColumn); + workUnit.setColumnName(baseColumn.getName()); + workUnit.setTableName(auditTableName); + workUnit.setTypeName(baseColumn.getTypeName()); + workUnit.setSize(baseColumn.getSize()); + workUnit.setDecimalSize(baseColumn.getDecimalSize()); + tableChangeUnits.add(workUnit); + } + + //action + workUnit = new DBChangeUnit(DBChangeType.addTriggerAction); + workUnit.setColumnName(auditActionColumn); + workUnit.setTableName(baseTableName); + workUnit.setAuditTableName(auditTableName); + tableChangeUnits.add(workUnit); + + //user + workUnit = new DBChangeUnit(DBChangeType.addTriggerUser); + workUnit.setColumnName(auditUserColumn); + workUnit.setTableName(baseTableName); + workUnit.setAuditTableName(auditTableName); + tableChangeUnits.add(workUnit); + + //timestamp + workUnit = new DBChangeUnit(DBChangeType.addTriggerTimeStamp); + workUnit.setColumnName(auditTimeStampColumn); + workUnit.setTableName(baseTableName); + workUnit.setAuditTableName(auditTableName); + tableChangeUnits.add(workUnit); + + //sessionuser + if (!sessionUserSQL.isEmpty()) { + workUnit = new DBChangeUnit(DBChangeType.addTriggerSessionUser); + workUnit.setColumnName(sessionUserColumn); + workUnit.setTableName(baseTableName); + workUnit.setAuditTableName(auditTableName); + tableChangeUnits.add(workUnit); } - else { + + workUnit = new DBChangeUnit(DBChangeType.end); + workUnit.setTableName(baseTableName); + workUnit.setAuditTableName(auditTableName); + tableChangeUnits.add(workUnit); + + } else { //alter table //there might not be any changes, so store up any changes in //a temporary list, and evaluate. diff --git a/src/main/java/net/certifi/audittablegen/DBChangeType.java b/src/main/java/net/certifi/audittablegen/DBChangeType.java index cec5573..7ff0e20 100644 --- a/src/main/java/net/certifi/audittablegen/DBChangeType.java +++ b/src/main/java/net/certifi/audittablegen/DBChangeType.java @@ -41,5 +41,6 @@ public enum DBChangeType { addTriggerUser, addTriggerTimeStamp, addTriggerSessionUser, + fillAuditTable, notSet; } diff --git a/src/main/java/net/certifi/audittablegen/DBChangeUnit.java b/src/main/java/net/certifi/audittablegen/DBChangeUnit.java index 0e2edbd..3f1802b 100644 --- a/src/main/java/net/certifi/audittablegen/DBChangeUnit.java +++ b/src/main/java/net/certifi/audittablegen/DBChangeUnit.java @@ -290,6 +290,7 @@ else if ( workListTag == DBChangeType.notSet){ case alterTable: case createTriggers: case dropTriggers: + case fillAuditTable: if (!beginTag){ //begin tag missing. //could be implied, but treat as error condition. @@ -312,7 +313,8 @@ else if (workListTag != DBChangeType.notSet){ valid = false; } else if (workListTag != DBChangeType.createTable - && workListTag != DBChangeType.alterTable) { + && workListTag != DBChangeType.alterTable + && workListTag != DBChangeType.fillAuditTable ) { logger.info ("improperly formed List. Unit{%s} not of valid for {%s} at element %d", unit.getChangeType().toString(), workListTag.toString(), i); valid = false; @@ -340,6 +342,18 @@ else if (workListTag != DBChangeType.createTable case fireOnInsert: case fireOnUpdate: case fireOnDelete: + if (beginTag == false){ + logger.info ("improperly formed List. Missing [begin] before element %d", i); + } + if (workListTag != DBChangeType.createTriggers){ + throw new RuntimeException ("improperly formed List. Unit{" + + unit.getChangeType().toString() + "} not of valid for {" + + workListTag.toString() +"}"); + } + else { + valid = validateUnit(unit, parentUnit); + } + break; case addTriggerAction: case addTriggerTimeStamp: case addTriggerUser: @@ -347,7 +361,8 @@ else if (workListTag != DBChangeType.createTable if (beginTag == false){ logger.info ("improperly formed List. Missing [begin] before element %d", i); } - if (workListTag != DBChangeType.createTriggers){ + if (workListTag != DBChangeType.createTriggers + && workListTag != DBChangeType.fillAuditTable ){ throw new RuntimeException ("improperly formed List. Unit{" + unit.getChangeType().toString() + "} not of valid for {" + workListTag.toString() +"}"); diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index a0e35bc..672275f 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -551,6 +551,7 @@ public void readDBChangeList(List units) { case alterTable: case createTriggers: case dropTriggers: + case fillAuditTable: workListType = unit.getChangeType(); workList.add(unit); break; @@ -607,6 +608,9 @@ public void executeChanges() { break; case dropTriggers: query = getDropTriggerSQL(op); + break; + case fillAuditTable: + query = getFillAuditTableSQL(op); break; default: //should not get here if the list is valid, unless a new changetype @@ -626,10 +630,95 @@ public void executeChanges() { } } + String getFillAuditTableSQL(List op) { + + StringBuilder builder = new StringBuilder(); + StringBuilder select = new StringBuilder(); + + boolean firstCol = true; + String schema; + + if (verifiedSchema != null){ + schema = verifiedSchema + "."; + } + else { + schema = ""; + } + + for (DBChangeUnit unit : op) { + switch (unit.changeType) { + case begin: + //nothinig + break; + + case end: + builder.append(")").append(System.lineSeparator()); + select.append(" from ").append(schema).append(unit.tableName).append(System.lineSeparator()); + builder.append(select); + break; + + case fillAuditTable: + builder.append("insert into ").append(schema).append(unit.tableName).append(" (").append(System.lineSeparator()); + select.append("select ").append(System.lineSeparator()); + break; + + case addColumn: + case addTriggerAction: + case addTriggerUser: + case addTriggerTimeStamp: + case addTriggerSessionUser: + if (!firstCol){ + builder.append(", "); + select.append(", "); + } + else { + firstCol = false; + } + + builder.append(unit.columnName).append(" "); + builder.append(System.lineSeparator()); + + switch( unit.changeType ) { + case addColumn: + select.append(unit.columnName).append(" "); + select.append(System.lineSeparator()); + break; + case addTriggerAction: + select.append("'L' "); + select.append(System.lineSeparator()); + break; + case addTriggerTimeStamp: + select.append("now() "); + select.append(System.lineSeparator()); + break; + case addTriggerUser: + select.append("user "); + select.append(System.lineSeparator()); + break; + case addTriggerSessionUser: + logger.error("unimplemented DBChangeUnit '{}' for fillAuditTable operation", unit.getChangeType().toString()); + return null; + + } + + break; + + default: + //should not get here if the list is valid, unless a new changetype + //was added that this DMR does not know about. If which case - fail. + logger.error("unimplemented DBChangeUnit '{}' for fillAuditTable operation", unit.getChangeType().toString()); + return null; + } + } + + return builder.toString(); + + } + String getCreateTableSQL(List op) { StringBuilder builder = new StringBuilder(); - StringBuilder constraints = new StringBuilder(); + StringBuilder constraints = new StringBuilder(); DataTypeDef dataTypeDef = null; boolean firstCol = true; String schema; From d3d7c652b1df3a41ea8f91819142f9cb6287b2c6 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 10 Sep 2014 10:16:47 -0500 Subject: [PATCH 07/16] Make action a char(1) --- .../java/net/certifi/audittablegen/ChangeSourceFactory.java | 2 +- src/main/java/net/certifi/audittablegen/GenericDMR.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java index 8d4e0d2..fab88fe 100644 --- a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java +++ b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java @@ -308,7 +308,7 @@ List getDBChangeList(TableDef baseTableDef){ workUnit.setColumnName(auditActionColumn); workUnit.setTableName(auditTableName); workUnit.setTypeName(auditActionTypeName); //insert, update, or delete - workUnit.setSize(6); + workUnit.setSize(1); workUnit.setDecimalSize(0); tableChangeUnits.add(workUnit); diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index 672275f..f9a3460 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -974,9 +974,9 @@ String getCreateTriggerSQL(List op) { ////////////////////// //generate the insert column valuues for the trigger(s) - insertDetail.append(" SELECT 'insert', user, now()"); - updateDetail.append(" SELECT 'update', user, now()"); - deleteDetail.append(" SELECT 'delete', user, now()"); + insertDetail.append(" SELECT 'I', user, now()"); + updateDetail.append(" SELECT 'U', user, now()"); + deleteDetail.append(" SELECT 'D', user, now()"); if (sessionUserColumn != null){ insertDetail.append(", ").append(this.getSessionUserSQL()); updateDetail.append(", ").append(this.getSessionUserSQL()); From b392594e25f47c3c2015c227d0235ad0d9907ca1 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 10 Sep 2014 12:36:52 -0500 Subject: [PATCH 08/16] If a column is added updated the audit tables --- .../audittablegen/ChangeSourceFactory.java | 14 +++++++-- .../certifi/audittablegen/DBChangeUnit.java | 9 ++++++ .../net/certifi/audittablegen/GenericDMR.java | 29 ++++++++++++++++++- .../net/certifi/audittablegen/TableDef.java | 15 +++++++++- 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java index fab88fe..e13e335 100644 --- a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java +++ b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java @@ -347,7 +347,8 @@ List getDBChangeList(TableDef baseTableDef){ // populate the table tableChangeUnits.add( new DBChangeUnit(DBChangeType.begin) ); workUnit = new DBChangeUnit(DBChangeType.fillAuditTable); - workUnit.tableName = auditTableName; + workUnit.setAuditTableName( auditTableName ); + workUnit.setTypeName( baseTableName ); tableChangeUnits.add(workUnit); // fill all columns on the base table @@ -402,7 +403,9 @@ List getDBChangeList(TableDef baseTableDef){ //a temporary list, and evaluate. alterTableChangeUnits.add(new DBChangeUnit(DBChangeType.begin)); workUnit = new DBChangeUnit(DBChangeType.alterTable); - workUnit.setTableName(auditTableName); + workUnit.setTableName(baseTableName); + workUnit.setAuditTableName( auditTableName ); + workUnit.setTableDef( baseTableDef ); alterTableChangeUnits.add(workUnit); //to make this a little easier, get a map for the column list @@ -525,6 +528,7 @@ else if (auditColumn.getTypeName().equalsIgnoreCase(baseColumn.getTypeName()) //new column workUnit = new DBChangeUnit(DBChangeType.addColumn); workUnit.setTableName(auditTableName); + workUnit.setAuditTableName( auditTableName ); workUnit.setColumnName(baseColumn.getName()); workUnit.setTypeName(baseColumn.getTypeName()); workUnit.setSize(baseColumn.getSize()); @@ -534,7 +538,11 @@ else if (auditColumn.getTypeName().equalsIgnoreCase(baseColumn.getTypeName()) } //end of table - alterTableChangeUnits.add(new DBChangeUnit(DBChangeType.end)); + workUnit = new DBChangeUnit( DBChangeType.end ); + workUnit.setTableName( baseTableName ); + workUnit.setAuditTableName( auditTableName ); + workUnit.setTableDef( baseTableDef ); + alterTableChangeUnits.add( workUnit ); //add the workUnits to the return value if (!renameColumnChangeUnits.isEmpty()){ diff --git a/src/main/java/net/certifi/audittablegen/DBChangeUnit.java b/src/main/java/net/certifi/audittablegen/DBChangeUnit.java index 3f1802b..9bf4745 100644 --- a/src/main/java/net/certifi/audittablegen/DBChangeUnit.java +++ b/src/main/java/net/certifi/audittablegen/DBChangeUnit.java @@ -41,8 +41,17 @@ public class DBChangeUnit { int size = 0; int decimalSize = 0; Boolean identity = Boolean.FALSE; + TableDef tableDef = null; //DataTypeDef dataTypeDef = null; + public TableDef getTableDef() { + return tableDef; + } + + public void setTableDef(TableDef tableDef) { + this.tableDef = tableDef; + } + public DBChangeUnit( DBChangeType changeType) { this.changeType = changeType; } diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index f9a3460..a95b706 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -792,6 +792,9 @@ String getAlterTableSQL(List op) { StringBuilder constraints = new StringBuilder(); DataTypeDef dataTypeDef = null; boolean firstCol = true; + boolean firstUpdateCol = true; + StringBuilder updateSQL = new StringBuilder(); + String schema; if (verifiedSchema != null){ @@ -808,9 +811,23 @@ String getAlterTableSQL(List op) { break; case end: builder.append(constraints); + if ( firstUpdateCol != true ) { + updateSQL.append(System.lineSeparator()).append( "from ").append(schema).append(unit.getTableName()).append( " orig").append(System.lineSeparator()); + updateSQL.append( "inner join ").append(schema).append(unit.getAuditTableName()).append(" audit" ).append(System.lineSeparator()); + + ColumnDef primaryKey = unit.getTableDef().getPrimaryKey(); + + if ( primaryKey != null ) { + updateSQL.append( "on audit.").append( primaryKey.getName() ).append( " = orig." ).append( primaryKey.getName() ); + } else { + logger.warn( "Table " + unit.getTableName() + " has no primary key, can not update audit table data"); + updateSQL = new StringBuilder(); + } + } + builder.append( updateSQL ); break; case alterTable: - builder.append("ALTER TABLE ").append(schema).append(unit.tableName).append(System.lineSeparator()); + builder.append("ALTER TABLE ").append(schema).append(unit.getAuditTableName()).append(System.lineSeparator()); break; case addColumn: if (!firstCol){ @@ -828,6 +845,16 @@ String getAlterTableSQL(List op) { } else { builder.append(unit.columnName).append(" ").append(unit.typeName); + + if ( firstUpdateCol ) { + firstUpdateCol = false; + + updateSQL.append(";").append( System.lineSeparator() ).append( "update ").append(schema).append(unit.getAuditTableName()).append(System.lineSeparator()).append( "set "); + updateSQL.append( unit.getColumnName() ).append( " = orig." ).append( unit.getColumnName() ); + } else { + + updateSQL.append(System.lineSeparator()).append( " , " ).append( unit.getColumnName() ).append( " = orig. " ).append( unit.getColumnName() ); + } // if (dataTypeDef.create_params != null && unit.size > 0){ if (dataTypeDef.createWithSize && unit.size > 0){ builder.append(" (").append(unit.size); diff --git a/src/main/java/net/certifi/audittablegen/TableDef.java b/src/main/java/net/certifi/audittablegen/TableDef.java index 61afe8e..17cb0ae 100644 --- a/src/main/java/net/certifi/audittablegen/TableDef.java +++ b/src/main/java/net/certifi/audittablegen/TableDef.java @@ -63,5 +63,18 @@ public List getColumns() { public void setColumns(List columns) { this.columns = columns; } - + + public ColumnDef getPrimaryKey() { + + for ( ColumnDef colDef : columns ) { + + if ( "YES".equals( colDef.sourceMeta.get( "is_autoincrement" ) ) ) { + + return colDef; + } + + } + + return null; + } } From 554807063907843b5f634d7e8127a2970e4f5ba6 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 10 Sep 2014 15:03:18 -0500 Subject: [PATCH 09/16] use audit table name --- pom.xml | 2 +- src/main/java/net/certifi/audittablegen/GenericDMR.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3c5ba73..35903b4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ net.certifi AuditTableGen - 0.1.0-SNAPSHOT + 0.1.1-SNAPSHOT jar AuditTableGen diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index a95b706..a6c92cd 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -658,7 +658,7 @@ String getFillAuditTableSQL(List op) { break; case fillAuditTable: - builder.append("insert into ").append(schema).append(unit.tableName).append(" (").append(System.lineSeparator()); + builder.append("insert into ").append(schema).append(unit.getAuditTableName()).append(" (").append(System.lineSeparator()); select.append("select ").append(System.lineSeparator()); break; From 53eea1428ed3540ddb7caa06dd5458962b5ed59a Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 10 Sep 2014 15:08:28 -0500 Subject: [PATCH 10/16] Throw RuntimeExcpetion on SQLException --- src/main/java/net/certifi/audittablegen/GenericDMR.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index a6c92cd..134708d 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -1178,6 +1178,7 @@ public void executeUpdate (String query){ } catch (SQLException ex) { logger.error("Update failed...", ex); + throw new RuntimeException( "Error applying AuditTable SQL", ex ); } } From 194ca7b7b77cf0ca49412d66a40420c000d8c8c6 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 10 Sep 2014 15:33:58 -0500 Subject: [PATCH 11/16] Make 0.1.1 release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 35903b4..6c8eb2a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ net.certifi AuditTableGen - 0.1.1-SNAPSHOT + 0.1.1 jar AuditTableGen From 3499bc23ecc1ccd392d3bf7d4177695d139a2abc Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Wed, 10 Sep 2014 15:34:41 -0500 Subject: [PATCH 12/16] Make 0.1.2 SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6c8eb2a..152383a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ net.certifi AuditTableGen - 0.1.1 + 0.1.2-SNAPSHOT jar AuditTableGen From 50805fe98584e013eb598d917b035c19355d1ab2 Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Tue, 23 Sep 2014 14:13:59 -0500 Subject: [PATCH 13/16] Make sure if no fields update, we still return the new row from the trigger function. --- src/main/java/net/certifi/audittablegen/GenericDMR.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index 134708d..3a4c58a 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -1033,6 +1033,7 @@ String getCreateTriggerSQL(List op) { builder.append(" ELSEIF (TG_OP = 'UPDATE' ").append(updateConditional).append(System.lineSeparator()); builder.append(updateDetail); builder.append(" END IF;").append(System.lineSeparator()); + builder.append(" RETURN NEW;"); // This should only happen on an update that does not update anything builder.append("END").append(System.lineSeparator()); builder.append(triggerReference).append(" LANGUAGE plpgsql;").append(System.lineSeparator()); From f89617ed2b627506abbd16d8eee40f7a34dd970f Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Mon, 3 Nov 2014 12:50:15 -0600 Subject: [PATCH 14/16] Generate a more efficient update statement when new columns are added --- src/main/java/net/certifi/audittablegen/GenericDMR.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index 3a4c58a..0b75fbd 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -813,12 +813,11 @@ String getAlterTableSQL(List op) { builder.append(constraints); if ( firstUpdateCol != true ) { updateSQL.append(System.lineSeparator()).append( "from ").append(schema).append(unit.getTableName()).append( " orig").append(System.lineSeparator()); - updateSQL.append( "inner join ").append(schema).append(unit.getAuditTableName()).append(" audit" ).append(System.lineSeparator()); ColumnDef primaryKey = unit.getTableDef().getPrimaryKey(); if ( primaryKey != null ) { - updateSQL.append( "on audit.").append( primaryKey.getName() ).append( " = orig." ).append( primaryKey.getName() ); + updateSQL.append( "where audit.").append( primaryKey.getName() ).append( " = orig." ).append( primaryKey.getName() ); } else { logger.warn( "Table " + unit.getTableName() + " has no primary key, can not update audit table data"); updateSQL = new StringBuilder(); @@ -849,11 +848,11 @@ String getAlterTableSQL(List op) { if ( firstUpdateCol ) { firstUpdateCol = false; - updateSQL.append(";").append( System.lineSeparator() ).append( "update ").append(schema).append(unit.getAuditTableName()).append(System.lineSeparator()).append( "set "); + updateSQL.append(";").append( System.lineSeparator() ).append( "update ").append(schema).append(unit.getAuditTableName()).append( " as audit").append(System.lineSeparator()).append( "set "); updateSQL.append( unit.getColumnName() ).append( " = orig." ).append( unit.getColumnName() ); } else { - updateSQL.append(System.lineSeparator()).append( " , " ).append( unit.getColumnName() ).append( " = orig. " ).append( unit.getColumnName() ); + updateSQL.append(System.lineSeparator()).append( " , " ).append( unit.getColumnName() ).append( " = orig." ).append( unit.getColumnName() ); } // if (dataTypeDef.create_params != null && unit.size > 0){ if (dataTypeDef.createWithSize && unit.size > 0){ From 6852d667c3b42f27017e6171ba25f27c317d07ce Mon Sep 17 00:00:00 2001 From: kraftwerk2020 Date: Mon, 3 Nov 2014 12:51:26 -0600 Subject: [PATCH 15/16] update version to 0.1.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 152383a..b10446c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ net.certifi AuditTableGen - 0.1.2-SNAPSHOT + 0.1.3 jar AuditTableGen From 8183cc78434c64fd19e691844dd439dfadab7353 Mon Sep 17 00:00:00 2001 From: cservin Date: Wed, 18 Mar 2015 09:06:31 -0500 Subject: [PATCH 16/16] various sql fixes --- nbactions.xml | 80 +++++++++---------- pom.xml | 2 +- .../audittablegen/ChangeSourceFactory.java | 1 + .../net/certifi/audittablegen/GenericDMR.java | 31 ++++--- 4 files changed, 60 insertions(+), 54 deletions(-) diff --git a/nbactions.xml b/nbactions.xml index c1e221c..3aeffe1 100644 --- a/nbactions.xml +++ b/nbactions.xml @@ -1,40 +1,40 @@ - - - - run - - process-classes - org.codehaus.mojo:exec-maven-plugin:1.2:exec - - - -classpath %classpath net.certifi.audittablegen.AuditTableGen -d capturagp -s localhost --driver postgresql url jdbc:postgresql://localhost:5432/capturagp?searchpath=public -u postgres -p -xxx --schema public - java - runtime - - - - debug - - process-classes - org.codehaus.mojo:exec-maven-plugin:1.2:exec - - - -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath net.certifi.audittablegen.AuditTableGen -d capturagp -s localhost --driver postgresql url jdbc:postgresql://localhost:5432/capturagp?searchpath=public -u postgres -p -xxx --schema public - java - runtime - true - - - - profile - - process-classes - org.codehaus.mojo:exec-maven-plugin:1.2:exec - - - -classpath %classpath net.certifi.audittablegen.AuditTableGen -d capturagp -s localhost --driver postgresql url jdbc:postgresql://localhost:5432/capturagp?searchpath=public -u postgres -p -xxx --schema public - ${profiler.java} - profile - - - + + + + run + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2:exec + + + -classpath %classpath net.certifi.audittablegen.AuditTableGen -d postgres -s localhost --driver postgresql url jdbc:postgresql://localhost:5432/postgres?searchpath=public -u cservin -p -xxx --schema audit_table + java + runtime + + + + debug + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2:exec + + + -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath net.certifi.audittablegen.AuditTableGen -d postgres -s localhost --driver postgresql url jdbc:postgresql://localhost:5432/postgres?searchpath=public -u cservin -p -xxx --schema audit_table + java + runtime + true + + + + profile + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2:exec + + + -classpath %classpath net.certifi.audittablegen.AuditTableGen -d postgres -s localhost --driver postgresql url jdbc:postgresql://localhost:5432/postgres?searchpath=public -u cservin -p -xxx --schema audit_table + ${profiler.java} + profile + + + diff --git a/pom.xml b/pom.xml index b10446c..43c8822 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ net.certifi AuditTableGen - 0.1.3 + 0.1.4 jar AuditTableGen diff --git a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java index e13e335..a2aea56 100644 --- a/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java +++ b/src/main/java/net/certifi/audittablegen/ChangeSourceFactory.java @@ -459,6 +459,7 @@ List getDBChangeList(TableDef baseTableDef){ workUnit = new DBChangeUnit(DBChangeType.addColumn); workUnit.setColumnName(sessionUserColumn); workUnit.setTableName(auditTableName); + workUnit.setAuditTableName( auditTableName ); workUnit.setTypeName(sessionUserTypeName); workUnit.setSize(sessionUserDataSize); workUnit.setDecimalSize(0); diff --git a/src/main/java/net/certifi/audittablegen/GenericDMR.java b/src/main/java/net/certifi/audittablegen/GenericDMR.java index 0b75fbd..b52b4aa 100644 --- a/src/main/java/net/certifi/audittablegen/GenericDMR.java +++ b/src/main/java/net/certifi/audittablegen/GenericDMR.java @@ -844,18 +844,9 @@ String getAlterTableSQL(List op) { } else { builder.append(unit.columnName).append(" ").append(unit.typeName); - - if ( firstUpdateCol ) { - firstUpdateCol = false; - - updateSQL.append(";").append( System.lineSeparator() ).append( "update ").append(schema).append(unit.getAuditTableName()).append( " as audit").append(System.lineSeparator()).append( "set "); - updateSQL.append( unit.getColumnName() ).append( " = orig." ).append( unit.getColumnName() ); - } else { - - updateSQL.append(System.lineSeparator()).append( " , " ).append( unit.getColumnName() ).append( " = orig." ).append( unit.getColumnName() ); - } -// if (dataTypeDef.create_params != null && unit.size > 0){ - if (dataTypeDef.createWithSize && unit.size > 0){ + +// if (dataTypeDef.create_params != null && unit.size > 0){ + if (dataTypeDef.createWithSize && unit.size > 0){ builder.append(" (").append(unit.size); if (unit.decimalSize > 0){ @@ -863,6 +854,20 @@ String getAlterTableSQL(List op) { } builder.append(") "); } + + // don't genereate update sql for altering the audit table + if ( ! unit.tableName.equals( unit.auditTableName) ) { + if ( firstUpdateCol ) { + firstUpdateCol = false; + + updateSQL.append(";").append( System.lineSeparator() ).append( "update ").append(schema).append(unit.getAuditTableName()).append( " as audit").append(System.lineSeparator()).append( "set "); + updateSQL.append( unit.getColumnName() ).append( " = orig." ).append( unit.getColumnName() ); + } else { + + updateSQL.append(System.lineSeparator()).append( " , " ).append( unit.getColumnName() ).append( " = orig." ).append( unit.getColumnName() ); + } + } + if (!unit.foreignTable.isEmpty()){ builder.append("REFERENCES ").append(unit.foreignTable).append(" (").append(unit.columnName).append(")"); //constraints.append("CONSTRAINT ").append(unit.columnName).append(" REFERENCES ").append(unit.foreignTable); @@ -1213,7 +1218,7 @@ public int getMaxUserNameLength() { public DataTypeDef getDataType (String typeName){ Map dtds = this.getDataTypes(); - + if (dtds.containsKey(typeName)){ return dtds.get(typeName); }