Skip to content

Commit

Permalink
Merge pull request fordfrog#183 from awful-b/view_triggers
Browse files Browse the repository at this point in the history
Support of triggers for views was added + support of the clause 'INSTEAD OF'.
Fix for fordfrog#141
  • Loading branch information
avbasov committed Feb 19, 2016
2 parents e4cc793 + 073d57b commit 0c34f6a
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 71 deletions.
68 changes: 34 additions & 34 deletions src/main/java/cz/startnet/utils/pgdiff/PgDiffTriggers.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
*/
package cz.startnet.utils.pgdiff;

import cz.startnet.utils.pgdiff.schema.PgRelation;
import cz.startnet.utils.pgdiff.schema.PgSchema;
import cz.startnet.utils.pgdiff.schema.PgTable;
import cz.startnet.utils.pgdiff.schema.PgTrigger;
import java.io.PrintWriter;
import java.util.ArrayList;
Expand All @@ -30,17 +30,17 @@ public class PgDiffTriggers {
public static void createTriggers(final PrintWriter writer,
final PgSchema oldSchema, final PgSchema newSchema,
final SearchPathHelper searchPathHelper) {
for (final PgTable newTable : newSchema.getTables()) {
final PgTable oldTable;
for (final PgRelation newRelation : newSchema.getRels()) {
final PgRelation oldRelation;

if (oldSchema == null) {
oldTable = null;
oldRelation = null;
} else {
oldTable = oldSchema.getTable(newTable.getName());
oldRelation = oldSchema.getRelation(newRelation.getName());
}

// Add new triggers
for (final PgTrigger trigger : getNewTriggers(oldTable, newTable)) {
for (final PgTrigger trigger : getNewTriggers(oldRelation, newRelation)) {
searchPathHelper.outputSearchPath(writer);
writer.println();
writer.println(trigger.getCreationSQL());
Expand All @@ -59,18 +59,18 @@ public static void createTriggers(final PrintWriter writer,
public static void dropTriggers(final PrintWriter writer,
final PgSchema oldSchema, final PgSchema newSchema,
final SearchPathHelper searchPathHelper) {
for (final PgTable newTable : newSchema.getTables()) {
final PgTable oldTable;
for (final PgRelation newRelation : newSchema.getRels()) {
final PgRelation oldRelation;

if (oldSchema == null) {
oldTable = null;
oldRelation = null;
} else {
oldTable = oldSchema.getTable(newTable.getName());
oldRelation = oldSchema.getRelation(newRelation.getName());
}

// Drop triggers that no more exist or are modified
for (final PgTrigger trigger :
getDropTriggers(oldTable, newTable)) {
getDropTriggers(oldRelation, newRelation)) {
searchPathHelper.outputSearchPath(writer);
writer.println();
writer.println(trigger.getDropSQL());
Expand All @@ -81,20 +81,20 @@ public static void dropTriggers(final PrintWriter writer,
/**
* Returns list of triggers that should be dropped.
*
* @param oldTable original table
* @param newTable new table
* @param oldRelation original relation
* @param newRelation new relation
*
* @return list of triggers that should be dropped
*/
private static List<PgTrigger> getDropTriggers(final PgTable oldTable,
final PgTable newTable) {
private static List<PgTrigger> getDropTriggers(final PgRelation oldRelation,
final PgRelation newRelation) {
@SuppressWarnings("CollectionWithoutInitialCapacity")
final List<PgTrigger> list = new ArrayList<PgTrigger>();

if (newTable != null && oldTable != null) {
final List<PgTrigger> newTriggers = newTable.getTriggers();
if (newRelation != null && oldRelation != null) {
final List<PgTrigger> newTriggers = newRelation.getTriggers();

for (final PgTrigger oldTrigger : oldTable.getTriggers()) {
for (final PgTrigger oldTrigger : oldRelation.getTriggers()) {
if (!newTriggers.contains(oldTrigger)) {
list.add(oldTrigger);
}
Expand All @@ -107,22 +107,22 @@ private static List<PgTrigger> getDropTriggers(final PgTable oldTable,
/**
* Returns list of triggers that should be added.
*
* @param oldTable original table
* @param newTable new table
* @param oldRelation original relation
* @param newRelation new relation
*
* @return list of triggers that should be added
*/
private static List<PgTrigger> getNewTriggers(final PgTable oldTable,
final PgTable newTable) {
private static List<PgTrigger> getNewTriggers(final PgRelation oldRelation,
final PgRelation newRelation) {
@SuppressWarnings("CollectionWithoutInitialCapacity")
final List<PgTrigger> list = new ArrayList<PgTrigger>();

if (newTable != null) {
if (oldTable == null) {
list.addAll(newTable.getTriggers());
if (newRelation != null) {
if (oldRelation == null) {
list.addAll(newRelation.getTriggers());
} else {
for (final PgTrigger newTrigger : newTable.getTriggers()) {
if (!oldTable.getTriggers().contains(newTrigger)) {
for (final PgTrigger newTrigger : newRelation.getTriggers()) {
if (!oldRelation.getTriggers().contains(newTrigger)) {
list.add(newTrigger);
}
}
Expand All @@ -147,16 +147,16 @@ public static void alterComments(final PrintWriter writer,
return;
}

for (PgTable oldTable : oldSchema.getTables()) {
final PgTable newTable = newSchema.getTable(oldTable.getName());
for (PgRelation oldRelation : oldSchema.getRels()) {
final PgRelation newRelation = newSchema.getRelation(oldRelation.getName());

if (newTable == null) {
if (newRelation == null) {
continue;
}

for (final PgTrigger oldTrigger : oldTable.getTriggers()) {
for (final PgTrigger oldTrigger : oldRelation.getTriggers()) {
final PgTrigger newTrigger =
newTable.getTrigger(oldTrigger.getName());
newRelation.getTrigger(oldTrigger.getName());

if (newTrigger == null) {
continue;
Expand All @@ -175,7 +175,7 @@ public static void alterComments(final PrintWriter writer,
PgDiffUtils.getQuotedName(newTrigger.getName()));
writer.print(" ON ");
writer.print(PgDiffUtils.getQuotedName(
newTrigger.getTableName()));
newTrigger.getRelationName()));
writer.print(" IS ");
writer.print(newTrigger.getComment());
writer.println(';');
Expand All @@ -188,7 +188,7 @@ public static void alterComments(final PrintWriter writer,
PgDiffUtils.getQuotedName(newTrigger.getName()));
writer.print(" ON ");
writer.print(PgDiffUtils.getQuotedName(
newTrigger.getTableName()));
newTrigger.getRelationName()));
writer.println(" IS NULL;");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ public static void parse(final PgDatabase database,
trigger.setName(objectName);

if (parser.expectOptional("BEFORE")) {
trigger.setBefore(true);
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.before);
} else if (parser.expectOptional("AFTER")) {
trigger.setBefore(false);
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.after);
} else if (parser.expectOptional("INSTEAD OF")) {
trigger.setEventTimeQualification(PgTrigger.EventTimeQualification.instead_of);
}

boolean first = true;
Expand Down Expand Up @@ -70,9 +72,9 @@ public static void parse(final PgDatabase database,

parser.expect("ON");

final String tableName = parser.parseIdentifier();
final String relationName = parser.parseIdentifier();

trigger.setTableName(ParserUtils.getObjectName(tableName));
trigger.setRelationName(ParserUtils.getObjectName(relationName));

if (parser.expectOptional("FOR")) {
parser.expectOptional("EACH");
Expand Down Expand Up @@ -100,9 +102,9 @@ public static void parse(final PgDatabase database,
|| "_slony_denyaccess".equals(trigger.getName()));

if (!ignoreSlonyTrigger) {
final PgSchema tableSchema = database.getSchema(
ParserUtils.getSchemaName(tableName, database));
tableSchema.getTable(trigger.getTableName()).addTrigger(trigger);
final PgSchema schema = database.getSchema(
ParserUtils.getSchemaName(relationName, database));
schema.getRelation(trigger.getRelationName()).addTrigger(trigger);
}
}

Expand Down
85 changes: 56 additions & 29 deletions src/main/java/cz/startnet/utils/pgdiff/schema/PgTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

/**
* Stores trigger information.
Expand All @@ -17,6 +19,31 @@
*/
public class PgTrigger {

/**
* Enumeration of when, with respect to event, a trigger should fire.
* e.g. BEFORE, AFTER or INSTEAD OF an event.
*/
public enum EventTimeQualification {
before,
after,
instead_of;

private static final Map<EventTimeQualification, String> stringRepresentation;

static {
HashMap<EventTimeQualification, String> aMap = new HashMap<EventTimeQualification, String>();
aMap.put(EventTimeQualification.before, "BEFORE");
aMap.put(EventTimeQualification.after, "AFTER");
aMap.put(EventTimeQualification.instead_of, "INSTEAD OF");

stringRepresentation = Collections.unmodifiableMap(aMap);
}

public static String toString(EventTimeQualification eventTimeQualification) {
return stringRepresentation.get(eventTimeQualification);
}
}

/**
* Function name and arguments that should be fired on the trigger.
*/
Expand All @@ -26,14 +53,14 @@ public class PgTrigger {
*/
private String name;
/**
* Name of the table the trigger is defined on.
* Name of the relation the trigger is defined on.
*/
private String tableName;
private String relationName;
/**
* Whether the trigger should be fired BEFORE or AFTER action. Default is
* before.
* Whether the trigger should be fired BEFORE, AFTER or INSTEAD OF an event.
* Default is before.
*/
private boolean before = true;
private EventTimeQualification eventTimeQualification = EventTimeQualification.before;
/**
* Whether the trigger should be fired FOR EACH ROW or FOR EACH STATEMENT.
* Default is FOR EACH STATEMENT.
Expand Down Expand Up @@ -70,21 +97,21 @@ public class PgTrigger {
private String comment;

/**
* Setter for {@link #before}.
* Setter for {@link #eventTimeQualification}.
*
* @param before {@link #before}
* @param eventTimeQualification {@link #eventTimeQualification}
*/
public void setBefore(final boolean before) {
this.before = before;
public void setEventTimeQualification(final EventTimeQualification eventTimeQualification) {
this.eventTimeQualification = eventTimeQualification;
}

/**
* Getter for {@link #before}.
* Getter for {@link #eventTimeQualification}.
*
* @return {@link #before}
* @return {@link #eventTimeQualification}
*/
public boolean isBefore() {
return before;
public EventTimeQualification getEventTimeQualification() {
return eventTimeQualification;
}

/**
Expand Down Expand Up @@ -116,7 +143,7 @@ public String getCreationSQL() {
sbSQL.append(PgDiffUtils.getQuotedName(getName()));
sbSQL.append(System.getProperty("line.separator"));
sbSQL.append("\t");
sbSQL.append(isBefore() ? "BEFORE" : "AFTER");
sbSQL.append(EventTimeQualification.toString(getEventTimeQualification()));

boolean firstEvent = true;

Expand Down Expand Up @@ -169,7 +196,7 @@ public String getCreationSQL() {
}

sbSQL.append(" ON ");
sbSQL.append(PgDiffUtils.getQuotedName(getTableName()));
sbSQL.append(PgDiffUtils.getQuotedName(getRelationName()));
sbSQL.append(System.getProperty("line.separator"));
sbSQL.append("\tFOR EACH ");
sbSQL.append(isForEachRow() ? "ROW" : "STATEMENT");
Expand All @@ -192,7 +219,7 @@ public String getCreationSQL() {
sbSQL.append("COMMENT ON TRIGGER ");
sbSQL.append(PgDiffUtils.getQuotedName(name));
sbSQL.append(" ON ");
sbSQL.append(PgDiffUtils.getQuotedName(tableName));
sbSQL.append(PgDiffUtils.getQuotedName(relationName));
sbSQL.append(" IS ");
sbSQL.append(comment);
sbSQL.append(';');
Expand All @@ -208,7 +235,7 @@ public String getCreationSQL() {
*/
public String getDropSQL() {
return "DROP TRIGGER " + PgDiffUtils.getQuotedName(getName()) + " ON "
+ PgDiffUtils.getQuotedName(getTableName()) + ";";
+ PgDiffUtils.getQuotedName(getRelationName()) + ";";
}

/**
Expand Down Expand Up @@ -338,21 +365,21 @@ public void setOnTruncate(final boolean onTruncate) {
}

/**
* Setter for {@link #tableName}.
* Setter for {@link #relationName}.
*
* @param tableName {@link #tableName}
* @param relationName {@link #relationName}
*/
public void setTableName(final String tableName) {
this.tableName = tableName;
public void setRelationName(final String relationName) {
this.relationName = relationName;
}

/**
* Getter for {@link #tableName}.
* Getter for {@link #relationName}.
*
* @return {@link #tableName}
* @return {@link #relationName}
*/
public String getTableName() {
return tableName;
public String getRelationName() {
return relationName;
}

/**
Expand Down Expand Up @@ -399,15 +426,15 @@ public boolean equals(final Object object) {
equals = true;
} else if (object instanceof PgTrigger) {
final PgTrigger trigger = (PgTrigger) object;
equals = (before == trigger.isBefore())
equals = (eventTimeQualification == trigger.getEventTimeQualification())
&& (forEachRow == trigger.isForEachRow())
&& function.equals(trigger.getFunction())
&& name.equals(trigger.getName())
&& (onDelete == trigger.isOnDelete())
&& (onInsert == trigger.isOnInsert())
&& (onUpdate == trigger.isOnUpdate())
&& (onTruncate == trigger.isOnTruncate())
&& tableName.equals(trigger.getTableName());
&& relationName.equals(trigger.getRelationName());

if (equals) {
final List<String> sorted1 =
Expand All @@ -426,8 +453,8 @@ public boolean equals(final Object object) {

@Override
public int hashCode() {
return (getClass().getName() + "|" + before + "|" + forEachRow + "|"
return (getClass().getName() + "|" + eventTimeQualification + "|" + forEachRow + "|"
+ function + "|" + name + "|" + onDelete + "|" + onInsert + "|"
+ onUpdate + "|" + onTruncate + "|" + tableName).hashCode();
+ onUpdate + "|" + onTruncate + "|" + relationName).hashCode();
}
}
4 changes: 3 additions & 1 deletion src/test/java/cz/startnet/utils/pgdiff/PgDiffTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ public static Collection<?> parameters() {
{"drop_unlogged_table", false, false, false, false},
// Test scenarios where /**/ comments.
{"add_table_issue115", false, false, false, false},
{"add_column_issue134", false, false, false, false}
{"add_column_issue134", false, false, false, false},
// Tests view triggers (support for 'INSTEAD OF')
{"view_triggers", false, false, false, false}
});
}
/**
Expand Down
Loading

0 comments on commit 0c34f6a

Please sign in to comment.