KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > dba > mysql > MySQLPkGenerator


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.dba.mysql;
21
22 import java.sql.Connection JavaDoc;
23 import java.sql.ResultSet JavaDoc;
24 import java.sql.SQLException JavaDoc;
25 import java.sql.Statement JavaDoc;
26 import java.util.Collections JavaDoc;
27
28 import org.apache.cayenne.access.DataNode;
29 import org.apache.cayenne.access.QueryLogger;
30 import org.apache.cayenne.dba.JdbcPkGenerator;
31 import org.apache.cayenne.map.DbEntity;
32
33 /**
34  * @author Andrus Adamchik
35  */

36 public class MySQLPkGenerator extends JdbcPkGenerator {
37
38     protected String JavaDoc dropAutoPkString() {
39         return "DROP TABLE IF EXISTS AUTO_PK_SUPPORT";
40     }
41
42     /**
43      * Overrides superclass's implementation to perform locking of the primary key lookup
44      * table.
45      */

46     protected int pkFromDatabase(DataNode node, DbEntity ent) throws Exception JavaDoc {
47
48         // must work directly with JDBC connection, since we
49
// must unlock the AUTO_PK_SUPPORT table in case of
50
// failures.... ah..JDBC is fun...
51

52         // chained SQL exception
53
SQLException JavaDoc exception = null;
54         int pk = -1;
55
56         Connection JavaDoc con = node.getDataSource().getConnection();
57         try {
58             
59             if(con.getAutoCommit()) {
60                 con.setAutoCommit(false);
61             }
62             
63             Statement JavaDoc st = con.createStatement();
64
65             try {
66                 pk = getPrimaryKey(st, ent.getName());
67                 con.commit();
68             }
69             catch (SQLException JavaDoc pkEx) {
70                 
71                 try {
72                     con.rollback();
73                 }
74                 catch (SQLException JavaDoc e) {
75
76                 }
77                 
78                 exception = processSQLException(pkEx, exception);
79             }
80             finally {
81                 // UNLOCK!
82
// THIS MUST BE EXECUTED NO MATTER WHAT, OR WE WILL LOCK THE PRIMARY KEY
83
// TABLE!!
84
try {
85                     String JavaDoc unlockString = "UNLOCK TABLES";
86                     QueryLogger.logQuery(unlockString, Collections.EMPTY_LIST);
87                     st.execute(unlockString);
88                 }
89                 catch (SQLException JavaDoc unlockEx) {
90                     exception = processSQLException(unlockEx, exception);
91                 }
92                 finally {
93                     // close statement
94
try {
95                         st.close();
96                     }
97                     catch (SQLException JavaDoc stClosingEx) {
98                         // ignoring...
99
}
100                 }
101             }
102         }
103         catch (SQLException JavaDoc otherEx) {
104             exception = processSQLException(otherEx, exception);
105         }
106         finally {
107             try {
108                 con.close();
109             }
110             catch (SQLException JavaDoc closingEx) {
111                 // ignoring
112
}
113         }
114
115         // check errors
116
if (exception != null) {
117             throw exception;
118         }
119
120         return pk;
121     }
122
123     /**
124      * Appends a new SQLException to the chain. If parent is null, uses the exception as
125      * the chain root.
126      */

127     protected SQLException JavaDoc processSQLException(SQLException JavaDoc exception, SQLException JavaDoc parent) {
128         if (parent == null) {
129             return exception;
130         }
131
132         parent.setNextException(exception);
133         return parent;
134     }
135
136     protected String JavaDoc pkTableCreateString() {
137         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
138         buf.append("CREATE TABLE AUTO_PK_SUPPORT (").append(
139                 " TABLE_NAME CHAR(100) NOT NULL,").append(
140                 " NEXT_ID INTEGER NOT NULL, UNIQUE (TABLE_NAME)").append(")");
141
142         return buf.toString();
143     }
144
145     protected int getPrimaryKey(Statement JavaDoc statement, String JavaDoc entityName)
146             throws SQLException JavaDoc {
147         // lock
148
String JavaDoc lockString = "LOCK TABLES AUTO_PK_SUPPORT WRITE";
149         QueryLogger.logQuery(lockString, Collections.EMPTY_LIST);
150         statement.execute(lockString);
151
152         // select
153
int pk = -1;
154
155         String JavaDoc selectString = super.pkSelectString(entityName);
156         QueryLogger.logQuery(selectString, Collections.EMPTY_LIST);
157         ResultSet JavaDoc rs = statement.executeQuery(selectString);
158         try {
159             if (!rs.next()) {
160                 throw new SQLException JavaDoc("No rows for '" + entityName + "'");
161             }
162
163             pk = rs.getInt(1);
164
165             if (rs.next()) {
166                 throw new SQLException JavaDoc("More than one row for '" + entityName + "'");
167             }
168         }
169         finally {
170             try {
171                 rs.close();
172             }
173             catch (Exception JavaDoc ex) {
174                 // ignoring...
175
}
176         }
177
178         // update
179
String JavaDoc updateString = super.pkUpdateString(entityName) + " AND NEXT_ID = " + pk;
180         QueryLogger.logQuery(updateString, Collections.EMPTY_LIST);
181         int updated = statement.executeUpdate(updateString);
182         // optimistic lock failure...
183
if (updated != 1) {
184             throw new SQLException JavaDoc("Error updating PK count '"
185                     + entityName
186                     + "': "
187                     + updated);
188         }
189
190         return pk;
191     }
192 }
193
Popular Tags