View Javadoc

1   /*
2    * SymmetricDS is an open source database synchronization solution.
3    *   
4    * Copyright (C) Chris Henson <chenson42@users.sourceforge.net>
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 3 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, see
18   * <http://www.gnu.org/licenses/>.
19   */
20  
21  package org.jumpmind.symmetric.model;
22  
23  import java.util.Date;
24  
25  import org.apache.ddlutils.model.Column;
26  import org.apache.ddlutils.model.Table;
27  
28  /***
29   * Maps to the table sync audit table which tracks the history of sync trigger
30   * creation. <p/> This table also tracks the columns and the primary keys as of
31   * the create date so that if the table definition changes while we still have
32   * events to process (as may be the case when distributing events to remote
33   * locations), then we still have the history of what the columns and primary
34   * keys were at the time.
35   */
36  public class TriggerHistory {
37  
38      private int triggerHistoryId;
39  
40      private int triggerId;
41  
42      private String sourceTableName;
43  
44      private String sourceSchemaName;
45  
46      private String sourceCatalogName;
47  
48      private Date createTime;
49  
50      private String columnNames;
51  
52      private String pkColumnNames;
53  
54      private String nameForInsertTrigger;
55  
56      private String nameForUpdateTrigger;
57  
58      private String nameForDeleteTrigger;
59  
60      private Date inactiveTime;
61  
62      /***
63       * This is a hash based on the tablename, column names, and column data
64       * types. It is used to effectively version a table so we know when it
65       * changes.
66       */
67      private int tableHash;
68      
69      /***
70       * This is a hash based on the values in the trigger configuration table.
71       */
72      private long triggerRowHash;
73  
74      private TriggerReBuildReason lastTriggerBuildReason;
75  
76      public TriggerHistory() {
77          createTime = new Date();
78      }
79  
80      public TriggerHistory(String tableName, String pkColumnNames, String columnNames) {
81          this.sourceTableName = tableName;
82          this.pkColumnNames = pkColumnNames;
83          this.columnNames = columnNames;
84      }
85      
86      public TriggerHistory(Table table, Trigger trigger) {
87          this(table,trigger,null);
88      }
89  
90      public TriggerHistory(Table table, Trigger trigger, TriggerReBuildReason reason) {
91          this();
92          this.sourceTableName = table.getName();
93          this.lastTriggerBuildReason = reason;
94          this.columnNames = getCommaDeliminatedColumns(trigger.orderColumnsForTable(table));
95          this.sourceSchemaName = trigger.getSourceSchemaName();
96          this.sourceCatalogName = trigger.getSourceCatalogName();
97          this.triggerId = trigger.getTriggerId();
98          this.pkColumnNames = getCommaDeliminatedColumns(table.getPrimaryKeyColumns());
99          this.triggerRowHash = trigger.getHashedValue();
100         // set primary key equal to all the columns to make data sync work for
101         // tables
102         // with no primary keys
103         if (pkColumnNames == null) {
104             pkColumnNames = columnNames;
105         }
106 
107         tableHash = calculateTableHashFor(table);
108     }
109 
110     public static int calculateTableHashFor(Table table) {
111         final int PRIME = 31;
112         int result = 1;
113         result = PRIME * result + table.getName().hashCode();
114         result = PRIME * result + calculateHashForColumns(PRIME, table.getColumns());
115         result = PRIME * result + calculateHashForColumns(PRIME, table.getPrimaryKeyColumns());
116         return result;
117     }
118 
119     private static int calculateHashForColumns(final int PRIME, Column[] cols) {
120         int result = 1;
121         if (cols != null && cols.length > 0) {
122             for (Column column : cols) {
123                 result = PRIME * result + column.getName().hashCode();
124                 result = PRIME * result + column.getType().hashCode();
125                 result = PRIME * result + column.getSizeAsInt();
126             }
127         }
128         return result;
129     }
130 
131     private String getCommaDeliminatedColumns(Column[] cols) {
132         StringBuilder columns = new StringBuilder();
133         if (cols != null && cols.length > 0) {
134             for (Column column : cols) {
135                 columns.append(column.getName());
136                 columns.append(",");
137             }
138             columns.replace(columns.length() - 1, columns.length(), "");
139             return columns.toString();
140         } else {
141             return null;
142         }
143     }
144 
145     public String getTriggerNameForDmlType(DataEventType type) {
146         switch (type) {
147         case INSERT:
148             return getNameForInsertTrigger();
149         case UPDATE:
150             return getNameForUpdateTrigger();
151         case DELETE:
152             return getNameForDeleteTrigger();
153         }
154         throw new IllegalStateException();
155     }
156 
157     public int getTableHash() {
158         return tableHash;
159     }
160 
161     public void setTableHash(int tableHash) {
162         this.tableHash = tableHash;
163     }
164 
165     public String getSourceTableName() {
166         return sourceTableName;
167     }
168 
169     public void setSourceTableName(String tableName) {
170         this.sourceTableName = tableName;
171     }
172 
173     public String getColumnNames() {
174         return columnNames;
175     }
176 
177     public void setColumnNames(String allColumnData) {
178         this.columnNames = allColumnData;
179     }
180 
181     public Date getCreateTime() {
182         return createTime;
183     }
184 
185     public void setCreateTime(Date createTime) {
186         this.createTime = createTime;
187     }
188 
189     public TriggerReBuildReason getLastTriggerBuildReason() {
190         return lastTriggerBuildReason;
191     }
192 
193     public void setLastTriggerBuildReason(TriggerReBuildReason lastTriggerBuildReason) {
194         this.lastTriggerBuildReason = lastTriggerBuildReason;
195     }
196 
197     public String getPkColumnNames() {
198         return pkColumnNames;
199     }
200 
201     public void setPkColumnNames(String pkColumnData) {
202         this.pkColumnNames = pkColumnData;
203     }
204 
205     public int getTriggerHistoryId() {
206         return triggerHistoryId;
207     }
208 
209     public void setTriggerHistoryId(int tableSyncAuditId) {
210         this.triggerHistoryId = tableSyncAuditId;
211     }
212 
213     public String getNameForDeleteTrigger() {
214         return nameForDeleteTrigger;
215     }
216 
217     public void setNameForDeleteTrigger(String nameForDeleteTrigger) {
218         this.nameForDeleteTrigger = nameForDeleteTrigger;
219     }
220 
221     public String getNameForInsertTrigger() {
222         return nameForInsertTrigger;
223     }
224 
225     public void setNameForInsertTrigger(String nameForInsertTrigger) {
226         this.nameForInsertTrigger = nameForInsertTrigger;
227     }
228 
229     public String getNameForUpdateTrigger() {
230         return nameForUpdateTrigger;
231     }
232 
233     public void setNameForUpdateTrigger(String nameForUpdateTrigger) {
234         this.nameForUpdateTrigger = nameForUpdateTrigger;
235     }
236 
237     public String getSourceSchemaName() {
238         return sourceSchemaName;
239     }
240 
241     public void setSourceSchemaName(String schemaName) {
242         this.sourceSchemaName = schemaName;
243     }
244 
245     public int getTriggerId() {
246         return triggerId;
247     }
248 
249     public void setTriggerId(int triggerId) {
250         this.triggerId = triggerId;
251     }
252 
253     public Date getInactiveTime() {
254         return inactiveTime;
255     }
256 
257     public void setInactiveTime(Date inactiveTime) {
258         this.inactiveTime = inactiveTime;
259     }
260 
261     public String getSourceCatalogName() {
262         return sourceCatalogName;
263     }
264 
265     public void setSourceCatalogName(String sourceCatalogName) {
266         this.sourceCatalogName = sourceCatalogName;
267     }
268 
269     public long getTriggerRowHash() {
270         return triggerRowHash;
271     }
272 
273     public void setTriggerRowHash(long triggerRowHash) {
274         this.triggerRowHash = triggerRowHash;
275     }
276 
277 }