View Javadoc
1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, and individual contributors by the @author
5      tags. See the COPYRIGHT.txt in the distribution for a full listing of
6      individual contributors.
7   
8      All GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
20   */
21  package goldengate.ftp.exec.database.model;
22  
23  import goldengate.common.database.DbPreparedStatement;
24  import goldengate.common.database.DbRequest;
25  import goldengate.common.database.DbSession;
26  import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
27  import goldengate.common.database.exception.GoldenGateDatabaseNoDataException;
28  import goldengate.common.database.exception.GoldenGateDatabaseSqlException;
29  
30  import java.sql.SQLException;
31  import java.util.concurrent.locks.ReentrantLock;
32  
33  import goldengate.ftp.exec.database.DbConstant;
34  import goldengate.ftp.exec.database.data.DbTransferLog;
35  
36  /**
37   * MySQL Database Model implementation
38   * @author Frederic Bregier
39   *
40   */
41  public class DbModelMysql extends goldengate.common.database.model.DbModelMysql {
42      /**
43       * Create the object and initialize if necessary the driver
44       * @param dbserver
45       * @param dbuser
46       * @param dbpasswd
47       * @throws GoldenGateDatabaseNoConnectionException
48       */
49      public DbModelMysql(String dbserver,
50              String dbuser, String dbpasswd) throws GoldenGateDatabaseNoConnectionException {
51          super(dbserver, dbuser, dbpasswd);
52      }
53      private final ReentrantLock lock = new ReentrantLock();
54  
55      @Override
56      public void createTables(DbSession session) throws GoldenGateDatabaseNoConnectionException {
57          // Create tables: configuration, hosts, rules, runner, cptrunner
58          String createTableH2 = "CREATE TABLE IF NOT EXISTS ";
59          String primaryKey = " PRIMARY KEY ";
60          String notNull = " NOT NULL ";
61  
62          DbRequest request = new DbRequest(session);
63          // TRANSLOG
64          String action = createTableH2 + DbTransferLog.table + "(";
65          DbTransferLog.Columns[] acolumns = DbTransferLog.Columns.values();
66          for (int i = 0; i < acolumns.length; i ++) {
67              action += acolumns[i].name() +
68                      DBType.getType(DbTransferLog.dbTypes[i]) + notNull + ", ";
69          }
70          // Several columns for primary key
71          action += " CONSTRAINT TRANSLOG_PK " + primaryKey + "(";
72          for (int i = DbTransferLog.NBPRKEY; i > 1; i--) {
73              action += acolumns[acolumns.length - i].name() + ",";
74          }
75          action += acolumns[acolumns.length - 1].name() + "))";
76          System.out.println(action);
77          try {
78              request.query(action);
79          } catch (GoldenGateDatabaseNoConnectionException e) {
80              e.printStackTrace();
81              return;
82          } catch (GoldenGateDatabaseSqlException e) {
83              e.printStackTrace();
84              return;
85          } finally {
86              request.close();
87          }
88          // Index TRANSLOG
89          action = "CREATE INDEX IDX_TRANSLOG ON "+ DbTransferLog.table + "(";
90          DbTransferLog.Columns[] icolumns = DbTransferLog.indexes;
91          for (int i = 0; i < icolumns.length-1; i ++) {
92              action += icolumns[i].name()+ ", ";
93          }
94          action += icolumns[icolumns.length-1].name()+ ")";
95          System.out.println(action);
96          try {
97              request.query(action);
98          } catch (GoldenGateDatabaseNoConnectionException e) {
99              e.printStackTrace();
100             return;
101         } catch (GoldenGateDatabaseSqlException e) {
102             return;
103         } finally {
104             request.close();
105         }
106 
107         // cptrunner
108         /*
109          * # Table to handle any number of sequences:
110             CREATE TABLE Sequences (
111               name VARCHAR(22) NOT NULL,
112               seq INT UNSIGNED NOT NULL,  # (or BIGINT)
113               PRIMARY KEY name
114             );
115 
116             # Create a Sequence:
117             INSERT INTO Sequences (name, seq) VALUES (?, 0);
118             # Drop a Sequence:
119             DELETE FROM Sequences WHERE name = ?;
120 
121             # Get a sequence number:
122             UPDATE Sequences
123               SET seq = LAST_INSERT_ID(seq + 1)
124               WHERE name = ?;
125             $seq = $db->LastInsertId();
126          */
127         action = "CREATE TABLE Sequences (name VARCHAR(22) NOT NULL PRIMARY KEY,"+
128               "seq BIGINT NOT NULL)";
129         System.out.println(action);
130         try {
131             request.query(action);
132         } catch (GoldenGateDatabaseNoConnectionException e) {
133             e.printStackTrace();
134             return;
135         } catch (GoldenGateDatabaseSqlException e) {
136             e.printStackTrace();
137             return;
138         } finally {
139             request.close();
140         }
141         action = "INSERT INTO Sequences (name, seq) VALUES ('"+DbTransferLog.fieldseq+"', "+
142             (DbConstant.ILLEGALVALUE + 1)+")";
143         System.out.println(action);
144         try {
145             request.query(action);
146         } catch (GoldenGateDatabaseNoConnectionException e) {
147             e.printStackTrace();
148             return;
149         } catch (GoldenGateDatabaseSqlException e) {
150             e.printStackTrace();
151             return;
152         } finally {
153             request.close();
154         }
155     }
156 
157     /*
158      * (non-Javadoc)
159      *
160      * @see openr66.databaseold.model.DbModel#resetSequence()
161      */
162     @Override
163     public void resetSequence(DbSession session, long newvalue) throws GoldenGateDatabaseNoConnectionException {
164         String action = "UPDATE Sequences SET seq = " + newvalue+
165             " WHERE name = '"+ DbTransferLog.fieldseq + "'";
166         DbRequest request = new DbRequest(session);
167         try {
168             request.query(action);
169         } catch (GoldenGateDatabaseNoConnectionException e) {
170             e.printStackTrace();
171             return;
172         } catch (GoldenGateDatabaseSqlException e) {
173             e.printStackTrace();
174             return;
175         } finally {
176             request.close();
177         }
178         System.out.println(action);
179     }
180 
181     /*
182      * (non-Javadoc)
183      *
184      * @see openr66.databaseold.model.DbModel#nextSequence()
185      */
186     @Override
187     public synchronized long nextSequence(DbSession dbSession)
188         throws GoldenGateDatabaseNoConnectionException,
189             GoldenGateDatabaseSqlException, GoldenGateDatabaseNoDataException {
190         lock.lock();
191         try {
192             long result = DbConstant.ILLEGALVALUE;
193             String action = "SELECT seq FROM Sequences WHERE name = '" +
194                 DbTransferLog.fieldseq + "' FOR UPDATE";
195             DbPreparedStatement preparedStatement = new DbPreparedStatement(
196                     dbSession);
197             try {
198                 dbSession.conn.setAutoCommit(false);
199             } catch (SQLException e1) {
200             }
201             try {
202                 preparedStatement.createPrepareStatement(action);
203                 // Limit the search
204                 preparedStatement.executeQuery();
205                 if (preparedStatement.getNext()) {
206                     try {
207                         result = preparedStatement.getResultSet().getLong(1);
208                     } catch (SQLException e) {
209                         throw new GoldenGateDatabaseSqlException(e);
210                     }
211                 } else {
212                     throw new GoldenGateDatabaseNoDataException(
213                             "No sequence found. Must be initialized first");
214                 }
215             } finally {
216                 preparedStatement.realClose();
217             }
218             action = "UPDATE Sequences SET seq = "+(result+1)+
219                 " WHERE name = '"+DbTransferLog.fieldseq+"'";
220             try {
221                 preparedStatement.createPrepareStatement(action);
222                 // Limit the search
223                 preparedStatement.executeUpdate();
224             } finally {
225                 preparedStatement.realClose();
226             }
227             return result;
228         } finally {
229             try {
230                 dbSession.conn.setAutoCommit(true);
231             } catch (SQLException e1) {
232             }
233             lock.unlock();
234         }
235     }
236 }