KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.dba.mysql;
57
58 import java.sql.Connection JavaDoc;
59 import java.sql.ResultSet JavaDoc;
60 import java.sql.SQLException JavaDoc;
61 import java.sql.Statement JavaDoc;
62 import java.util.Collections JavaDoc;
63
64 import org.objectstyle.cayenne.access.DataNode;
65 import org.objectstyle.cayenne.access.QueryLogger;
66 import org.objectstyle.cayenne.dba.JdbcPkGenerator;
67 import org.objectstyle.cayenne.map.DbEntity;
68
69 /**
70  * @author Andrei Adamchik
71  */

72 public class MySQLPkGenerator extends JdbcPkGenerator {
73     /**
74      * Overrides superclass's implementation to perform locking of the
75      * primary key lookup table.
76      */

77     protected int pkFromDatabase(DataNode node, DbEntity ent)
78         throws Exception JavaDoc {
79
80         // must work directly with JDBC connection, since we
81
// must unlock the AUTO_PK_SUPPORT table in case of
82
// failures.... ah..JDBC is fun...
83

84         // chained SQL exception
85
SQLException JavaDoc exception = null;
86         int pk = -1;
87
88         Connection JavaDoc con = node.getDataSource().getConnection();
89         try {
90             Statement JavaDoc st = con.createStatement();
91
92             try {
93                 pk = getPrimaryKey(st, ent.getName());
94             } catch (SQLException JavaDoc pkEx) {
95                 exception = processSQLException(pkEx, exception);
96             } finally {
97                 // UNLOCK!
98
// THIS MUST BE EXECUTED NO MATTER WHAT, OR WE WILL LOCK THE PRIMARY KEY TABLE!!
99
try {
100                     String JavaDoc unlockString = "UNLOCK TABLES";
101                     QueryLogger.logQuery(QueryLogger.DEFAULT_LOG_LEVEL, unlockString, Collections.EMPTY_LIST);
102                     st.execute(unlockString);
103                 } catch (SQLException JavaDoc unlockEx) {
104                     exception = processSQLException(unlockEx, exception);
105                 } finally {
106                     // close statement
107
try {
108                         st.close();
109                     } catch (SQLException JavaDoc stClosingEx) {
110                         // ignoring...
111
}
112                 }
113             }
114         } catch (SQLException JavaDoc otherEx) {
115             exception = processSQLException(otherEx, exception);
116         } finally {
117             try {
118                 con.close();
119             } catch (SQLException JavaDoc closingEx) {
120                 // ignoring
121
}
122         }
123
124         // check errors
125
if (exception != null) {
126             throw exception;
127         }
128
129         return pk;
130     }
131     
132     /**
133      * Appends a new SQLException to the chain. If parent is null, uses the exception as the
134      * chain root.
135      */

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