KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > platform > database > MySQL4Platform


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.platform.database;
23
24 import java.io.*;
25 import java.util.*;
26 import oracle.toplink.essentials.exceptions.ValidationException;
27 import oracle.toplink.essentials.expressions.ExpressionOperator;
28 import oracle.toplink.essentials.internal.databaseaccess.FieldTypeDefinition;
29 import oracle.toplink.essentials.internal.expressions.FunctionExpression;
30 import oracle.toplink.essentials.internal.helper.*;
31 import oracle.toplink.essentials.queryframework.ValueReadQuery;
32
33 /**
34  * <p><b>Purpose</b>: Provides MySQL specific behaviour.
35  * <p><b>Responsibilities</b>:<ul>
36  * <li> Native SQL for Date, Time, & Timestamp.
37  * <li> Native sequencing.
38  * <li> Mapping of class types to database types for the schema framework.
39  * <li> Pessimistic locking.
40  * <li> Platform specific operators.
41  * </ul>
42  *
43  * @since OracleAS TopLink 10<i>g</i> (10.1.3)
44  */

45 public class MySQL4Platform extends DatabasePlatform {
46
47     /**
48      * INTERNAL:
49      * Appends an MySQL specific date if usesNativeSQL is true otherwise use the ODBC format.
50      * Native FORMAT: 'YYYY-MM-DD'
51      */

52     protected void appendDate(java.sql.Date JavaDoc date, Writer writer) throws IOException {
53         if (usesNativeSQL()) {
54             writer.write("'");
55             writer.write(Helper.printDate(date));
56             writer.write("'");
57         } else {
58             super.appendDate(date, writer);
59         }
60     }
61
62     /**
63      * INTERNAL:
64      * Appends an MySQL specific time if usesNativeSQL is true otherwise use the ODBC format.
65      * Native FORMAT: 'HH:MM:SS'.
66      */

67     protected void appendTime(java.sql.Time JavaDoc time, Writer writer) throws IOException {
68         if (usesNativeSQL()) {
69             writer.write("'");
70             writer.write(Helper.printTime(time));
71             writer.write("'");
72         } else {
73             super.appendTime(time, writer);
74         }
75     }
76
77     /**
78      * INTERNAL:
79      * Appends an MySQL specific Timestamp, if usesNativeSQL is true otherwise use the ODBC format.
80      * Native Format: 'YYYY-MM-DD HH:MM:SS'
81      */

82     protected void appendTimestamp(java.sql.Timestamp JavaDoc timestamp, Writer writer) throws IOException {
83         if (usesNativeSQL()) {
84             writer.write("'");
85             writer.write(Helper.printTimestampWithoutNanos(timestamp));
86             writer.write("'");
87         } else {
88             super.appendTimestamp(timestamp, writer);
89         }
90     }
91
92     /**
93      * INTERNAL:
94      * Appends an MySQL specific Timestamp, if usesNativeSQL is true otherwise use the ODBC format.
95      * Native Format: 'YYYY-MM-DD HH:MM:SS'
96      */

97     protected void appendCalendar(Calendar calendar, Writer writer) throws IOException {
98         if (usesNativeSQL()) {
99             writer.write("'");
100             writer.write(Helper.printCalendarWithoutNanos(calendar));
101             writer.write("'");
102         } else {
103             super.appendCalendar(calendar, writer);
104         }
105     }
106
107     /**
108      * INTERNAL:
109      * Return the mapping of class types to database types for the schema framework.
110      */

111     protected Hashtable buildFieldTypes() {
112         Hashtable fieldTypeMapping;
113
114         fieldTypeMapping = new Hashtable();
115         fieldTypeMapping.put(Boolean JavaDoc.class, new FieldTypeDefinition("TINYINT(1) default 0", false));
116
117         fieldTypeMapping.put(Integer JavaDoc.class, new FieldTypeDefinition("INTEGER", false));
118         fieldTypeMapping.put(Long JavaDoc.class, new FieldTypeDefinition("BIGINT", false));
119         fieldTypeMapping.put(Float JavaDoc.class, new FieldTypeDefinition("FLOAT"));
120         fieldTypeMapping.put(Double JavaDoc.class, new FieldTypeDefinition("DOUBLE"));
121         fieldTypeMapping.put(Short JavaDoc.class, new FieldTypeDefinition("SMALLINT", false));
122         fieldTypeMapping.put(Byte JavaDoc.class, new FieldTypeDefinition("TINYINT", false));
123         fieldTypeMapping.put(java.math.BigInteger JavaDoc.class, new FieldTypeDefinition("BIGINT", false));
124         fieldTypeMapping.put(java.math.BigDecimal JavaDoc.class, new FieldTypeDefinition("DECIMAL",38));
125         fieldTypeMapping.put(Number JavaDoc.class, new FieldTypeDefinition("DECIMAL",38));
126
127         fieldTypeMapping.put(String JavaDoc.class, new FieldTypeDefinition("VARCHAR", 255));
128         fieldTypeMapping.put(Character JavaDoc.class, new FieldTypeDefinition("CHAR", 1));
129
130         fieldTypeMapping.put(Byte JavaDoc[].class, new FieldTypeDefinition("BLOB", 64000));
131         fieldTypeMapping.put(Character JavaDoc[].class, new FieldTypeDefinition("TEXT", 64000));
132         fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("BLOB", 64000));
133         fieldTypeMapping.put(char[].class, new FieldTypeDefinition("TEXT", 64000));
134         fieldTypeMapping.put(java.sql.Blob JavaDoc.class, new FieldTypeDefinition("BLOB", 64000));
135         fieldTypeMapping.put(java.sql.Clob JavaDoc.class, new FieldTypeDefinition("TEXT", 64000));
136         
137         fieldTypeMapping.put(java.sql.Date JavaDoc.class, new FieldTypeDefinition("DATE", false));
138         fieldTypeMapping.put(java.sql.Time JavaDoc.class, new FieldTypeDefinition("TIME", false));
139         fieldTypeMapping.put(java.sql.Timestamp JavaDoc.class, new FieldTypeDefinition("DATETIME", false));
140
141         return fieldTypeMapping;
142     }
143
144     /**
145      * INTERNAL:
146      * Build the identity query for native sequencing.
147      */

148     public ValueReadQuery buildSelectQueryForNativeSequence() {
149         ValueReadQuery selectQuery = new ValueReadQuery();
150         StringWriter writer = new StringWriter();
151         writer.write("SELECT LAST_INSERT_ID()");
152         selectQuery.setSQLString(writer.toString());
153         return selectQuery;
154     }
155
156     /**
157      * INTERNAL:
158      * Used for constraint deletion.
159      */

160     public String JavaDoc getConstraintDeletionString() {
161         return " DROP FOREIGN KEY ";
162     }
163     
164     /**
165      * INTERNAL:
166      * Used for pessimistic locking.
167      */

168     public String JavaDoc getSelectForUpdateString() {
169         return " FOR UPDATE";
170     }
171     
172     /**
173      * INTERNAL:
174      * This method returns the query to select the timestamp
175      * from the server for MySQL.
176      */

177     public ValueReadQuery getTimestampQuery() {
178         if (timestampQuery == null) {
179             timestampQuery = new ValueReadQuery();
180             timestampQuery.setSQLString("SELECT NOW()");
181         }
182         return timestampQuery;
183     }
184
185     /**
186      * Answers whether platform is MySQL
187      */

188     public boolean isMySQL() {
189         return true;
190     }
191
192     /**
193      * INTERNAL:
194      * Initialize any platform-specific operators
195      */

196     protected void initializePlatformOperators() {
197         super.initializePlatformOperators();
198         addOperator(logOperator());
199         addOperator(ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Atan2, "ATAN2"));
200         addOperator(ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Concat, "CONCAT"));
201         addOperator(todayOperator());
202         addOperator(toNumberOperator());
203         addOperator(toCharOperator());
204         addOperator(toDateOperator());
205         addOperator(dateToStringOperator());
206         addOperator(ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Nvl, "IFNULL"));
207         addOperator(ExpressionOperator.simpleTwoArgumentFunction(ExpressionOperator.Trunc, "TRUNCATE"));
208     }
209
210     /**
211      * INTERNAL:
212      * Create the 10 based log operator for this platform
213      */

214     protected ExpressionOperator logOperator() {
215         ExpressionOperator result = new ExpressionOperator();
216         result.setSelector(ExpressionOperator.Log);
217         Vector v = new Vector(2);
218         v.addElement("LOG(");
219         v.addElement(", 10)");
220         result.printsAs(v);
221         result.bePrefix();
222         result.setNodeClass(FunctionExpression.class);
223         return result;
224
225     }
226
227     /**
228      * INTERNAL:
229      * Build MySQL equivalent to TO_NUMBER.
230      */

231     protected ExpressionOperator toNumberOperator() {
232         ExpressionOperator exOperator = new ExpressionOperator();
233         exOperator.setType(ExpressionOperator.FunctionOperator);
234         exOperator.setSelector(ExpressionOperator.ToNumber);
235         Vector v = new Vector(2);
236         v.addElement("CONVERT(");
237         v.addElement(", SIGNED)");
238         exOperator.printsAs(v);
239         exOperator.bePrefix();
240         exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
241         return exOperator;
242     }
243
244     /**
245      * INTERNAL:
246      * Build MySQL equivalent to TO_DATE.
247      */

248     protected ExpressionOperator toDateOperator() {
249         ExpressionOperator exOperator = new ExpressionOperator();
250         exOperator.setType(ExpressionOperator.FunctionOperator);
251         exOperator.setSelector(ExpressionOperator.ToDate);
252         Vector v = new Vector(2);
253         v.addElement("CONVERT(");
254         v.addElement(", DATETIME)");
255         exOperator.printsAs(v);
256         exOperator.bePrefix();
257         exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
258         return exOperator;
259     }
260
261     /**
262      * INTERNAL:
263      * Build MySQL equivalent to TO_CHAR.
264      */

265     protected ExpressionOperator toCharOperator() {
266         ExpressionOperator exOperator = new ExpressionOperator();
267         exOperator.setType(ExpressionOperator.FunctionOperator);
268         exOperator.setSelector(ExpressionOperator.ToChar);
269         Vector v = new Vector(2);
270         v.addElement("CONVERT(");
271         v.addElement(", CHAR)");
272         exOperator.printsAs(v);
273         exOperator.bePrefix();
274         exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
275         return exOperator;
276     }
277
278     /**
279      * INTERNAL:
280      * Build MySQL equivalent to TO_CHAR.
281      */

282     protected ExpressionOperator dateToStringOperator() {
283         ExpressionOperator exOperator = new ExpressionOperator();
284         exOperator.setType(ExpressionOperator.FunctionOperator);
285         exOperator.setSelector(ExpressionOperator.DateToString);
286         Vector v = new Vector(2);
287         v.addElement("CONVERT(");
288         v.addElement(", CHAR)");
289         exOperator.printsAs(v);
290         exOperator.bePrefix();
291         exOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
292         return exOperator;
293     }
294
295     /**
296      * INTERNAL:
297      * Create the sysdate operator for this platform
298      */

299     protected ExpressionOperator todayOperator() {
300         ExpressionOperator result = new ExpressionOperator();
301         result.setSelector(ExpressionOperator.Today);
302         Vector v = new Vector(1);
303         v.addElement("SYSDATE()");
304         result.printsAs(v);
305         result.bePrefix();
306         result.setNodeClass(FunctionExpression.class);
307         return result;
308
309     }
310
311     /**
312      * INTERNAL:
313      * Create the current date operator for this platform
314      */

315     protected ExpressionOperator currentDateOperator() {
316         return ExpressionOperator.simpleFunctionNoParentheses(ExpressionOperator.currentDate, "CURRENT_DATE");
317     }
318
319     /**
320      * INTERNAL:
321      * Append the receiver's field 'identity' constraint clause to a writer
322      */

323     public void printFieldIdentityClause(Writer writer) throws ValidationException {
324         try {
325             writer.write(" AUTO_INCREMENT");
326         } catch (IOException ioException) {
327             throw ValidationException.fileError(ioException);
328         }
329     }
330
331     /**
332      * INTERNAL:
333      * If native sequencing is being used on Sybase then the values must be
334      * retrieved after the insert.
335      * This method is to be used *ONLY* by sequencing classes
336      */

337     public boolean shouldNativeSequenceAcquireValueAfterInsert() {
338         return true;
339     }
340
341     /**
342      * INTERNAL:
343      * JDBC defines an outer join syntax which many drivers do not support. So we normally avoid it.
344      */

345     public boolean shouldUseJDBCOuterJoinSyntax() {
346         return false;
347     }
348
349     /**
350      * INTERNAL:
351      * Return true if the receiver uses host sequence numbers, generated on the database.
352      * MySQL does through AUTO_INCREMENT field types.
353      */

354     public boolean supportsNativeSequenceNumbers() {
355         return true;
356     }
357
358     /**
359      * INTERNAL:
360      */

361     public boolean supportsGlobalTempTables() {
362         return true;
363     }
364
365     /**
366      * INTERNAL:
367      */

368     protected String JavaDoc getCreateTempTableSqlPrefix() {
369         return "CREATE TEMPORARY TABLE IF NOT EXISTS ";
370     }
371
372     /**
373      * INTERNAL:
374      */

375     public boolean shouldAlwaysUseTempStorageForModifyAll() {
376         return true;
377     }
378     
379     /**
380      * INTERNAL:
381      */

382     public void writeUpdateOriginalFromTempTableSql(Writer writer, DatabaseTable table,
383                                                     Collection pkFields,
384                                                     Collection assignedFields) throws IOException
385     {
386         writer.write("UPDATE ");
387         String JavaDoc tableName = table.getQualifiedName();
388         writer.write(tableName);
389         writer.write(", ");
390         String JavaDoc tempTableName = getTempTableForTable(table).getQualifiedName();
391         writer.write(tempTableName);
392         writeAutoAssignmentSetClause(writer, tableName, tempTableName, assignedFields);
393         writeAutoJoinWhereClause(writer, tableName, tempTableName, pkFields);
394     }
395
396     /**
397      * INTERNAL:
398      */

399     public void writeDeleteFromTargetTableUsingTempTableSql(Writer writer, DatabaseTable table, DatabaseTable targetTable,
400                                                         Collection pkFields,
401                                                         Collection targetPkFields) throws IOException
402     {
403         writer.write("DELETE FROM ");
404         String JavaDoc targetTableName = targetTable.getQualifiedName();
405         writer.write(targetTableName);
406         writer.write(" USING ");
407         writer.write(targetTableName);
408         writer.write(", ");
409         String JavaDoc tempTableName = getTempTableForTable(table).getQualifiedName();
410         writer.write(tempTableName);
411         writeJoinWhereClause(writer, targetTableName, tempTableName, targetPkFields, pkFields);
412     }
413 }
414
Popular Tags