001: /*
002: * Copyright (C) 2006 Rob Manning
003: * manningr@users.sourceforge.net
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * as published by the Free Software Foundation; either version 2
008: * of the License, or any later version.
009: *
010: * This program is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU General Public License for more details.
014: *
015: * You should have received a copy of the GNU General Public License
016: * along with this program; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
018: */
019: package net.sourceforge.squirrel_sql.fw.dialects;
020:
021: import java.sql.SQLException;
022: import java.sql.Types;
023: import java.util.List;
024:
025: import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
026: import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
027: import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData;
028: import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
029: import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo;
030:
031: /**
032: * An extension to the standard Hibernate HSQL dialect
033: */
034:
035: public class McKoiDialect extends org.hibernate.dialect.HSQLDialect
036: implements HibernateDialect {
037:
038: public McKoiDialect() {
039: super ();
040: registerColumnType(Types.BIGINT, "bigint");
041: registerColumnType(Types.BINARY, 2000000000, "binary($l)");
042: registerColumnType(Types.BINARY, "binary(2000000000)");
043: registerColumnType(Types.BIT, "bit");
044: registerColumnType(Types.BLOB, 2000000000, "blob");
045: registerColumnType(Types.BLOB, "blob(2000000000)");
046: registerColumnType(Types.BOOLEAN, "bit");
047: registerColumnType(Types.CHAR, 255, "char($l)");
048: registerColumnType(Types.CHAR, 1000000000, "varchar($l)");
049: registerColumnType(Types.CHAR, "varchar(1000000000)");
050: registerColumnType(Types.CLOB, 1000000000, "clob($l)");
051: registerColumnType(Types.CLOB, "clob(1000000000)");
052: registerColumnType(Types.DATE, "date");
053: registerColumnType(Types.DECIMAL, "decimal($p,$s)");
054: registerColumnType(Types.DOUBLE, "double($p)");
055: registerColumnType(Types.FLOAT, "float($p)");
056: registerColumnType(Types.INTEGER, "integer");
057: registerColumnType(Types.LONGVARBINARY, 2000000000,
058: "longvarbinary($l)");
059: registerColumnType(Types.LONGVARBINARY,
060: "longvarbinary(2000000000)");
061: registerColumnType(Types.LONGVARCHAR, 1000000000,
062: "longvarchar($l)");
063: registerColumnType(Types.LONGVARCHAR, "longvarchar(1000000000)");
064: registerColumnType(Types.NUMERIC, "numeric($p,$s)");
065: registerColumnType(Types.REAL, "real");
066: registerColumnType(Types.SMALLINT, "smallint");
067: registerColumnType(Types.TIME, "time");
068: registerColumnType(Types.TIMESTAMP, "timestamp");
069: // Don't use tinyint for now, even though Mckoi "supports" it. It's
070: // notion of tinyint is 7-bit (not 8-bit) so it is not compatible with
071: // other DBs and leads to overflow (resulting in negative values which
072: // are a corruption of the actual value inserted/updated). This is not
073: // a great work-around. I filed a bug report on the mailing list;
074: // hopefully it will get fixed soon.
075: registerColumnType(Types.TINYINT, "smallint");
076: registerColumnType(Types.VARBINARY, 2000000000, "varbinary($l)");
077: registerColumnType(Types.VARBINARY, "varbinary(2000000000)");
078: registerColumnType(Types.VARCHAR, 1000000000, "varchar($l)");
079: registerColumnType(Types.VARCHAR, "varchar(1000000000)");
080: }
081:
082: /* (non-Javadoc)
083: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#canPasteTo(net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType)
084: */
085: public boolean canPasteTo(IDatabaseObjectInfo info) {
086: boolean result = true;
087: DatabaseObjectType type = info.getDatabaseObjectType();
088: if (type.getName().equalsIgnoreCase("database")) {
089: result = false;
090: }
091: return result;
092: }
093:
094: /* (non-Javadoc)
095: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#supportsSchemasInTableDefinition()
096: */
097: public boolean supportsSchemasInTableDefinition() {
098: return false;
099: }
100:
101: /* (non-Javadoc)
102: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getLengthFunction()
103: */
104: public String getLengthFunction(int dataType) {
105: return "length";
106: }
107:
108: /* (non-Javadoc)
109: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxFunction()
110: */
111: public String getMaxFunction() {
112: return "max";
113: }
114:
115: /* (non-Javadoc)
116: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxPrecision(int)
117: */
118: public int getMaxPrecision(int dataType) {
119: return Integer.MAX_VALUE;
120: }
121:
122: /* (non-Javadoc)
123: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxScale(int)
124: */
125: public int getMaxScale(int dataType) {
126: return getMaxPrecision(dataType);
127: }
128:
129: /* (non-Javadoc)
130: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getPrecisionDigits(int, int)
131: */
132: public int getPrecisionDigits(int columnSize, int dataType) {
133: return columnSize;
134: }
135:
136: /* (non-Javadoc)
137: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getColumnLength(int, int)
138: */
139: public int getColumnLength(int columnSize, int dataType) {
140: return columnSize;
141: }
142:
143: /**
144: * The string which identifies this dialect in the dialect chooser.
145: *
146: * @return a descriptive name that tells the user what database this dialect
147: * is design to work with.
148: */
149: public String getDisplayName() {
150: return "McKoi";
151: }
152:
153: /**
154: * Returns boolean value indicating whether or not this dialect supports the
155: * specified database product/version.
156: *
157: * @param databaseProductName the name of the database as reported by
158: * DatabaseMetaData.getDatabaseProductName()
159: * @param databaseProductVersion the version of the database as reported by
160: * DatabaseMetaData.getDatabaseProductVersion()
161: * @return true if this dialect can be used for the specified product name
162: * and version; false otherwise.
163: */
164: public boolean supportsProduct(String databaseProductName,
165: String databaseProductVersion) {
166: if (databaseProductName == null) {
167: return false;
168: }
169: if (databaseProductName.trim().toLowerCase()
170: .startsWith("mckoi")) {
171: // We don't yet have the need to discriminate by version.
172: return true;
173: }
174: return false;
175: }
176:
177: /**
178: * Returns the SQL statement to use to add a column to the specified table
179: * using the information about the new column specified by info.
180: * @param info information about the new column such as type, name, etc.
181: *
182: * @return
183: * @throws UnsupportedOperationException if the database doesn't support
184: * adding columns after a table has already been created.
185: */
186: public String[] getColumnAddSQL(TableColumnInfo info)
187: throws UnsupportedOperationException {
188: return new String[] { DialectUtils.getColumnAddSQL(info, this ,
189: true, true, true) };
190: }
191:
192: /**
193: * Returns a boolean value indicating whether or not this database dialect
194: * supports dropping columns from tables.
195: *
196: * @return true if the database supports dropping columns; false otherwise.
197: */
198: public boolean supportsDropColumn() {
199: // TODO: need to verify this
200: return true;
201: }
202:
203: /**
204: * Returns the SQL that forms the command to drop the specified colum in the
205: * specified table.
206: *
207: * @param tableName the name of the table that has the column
208: * @param columnName the name of the column to drop.
209: * @return
210: * @throws UnsupportedOperationException if the database doesn't support
211: * dropping columns.
212: */
213: public String getColumnDropSQL(String tableName, String columnName) {
214: // TODO: Need to verify this
215: return DialectUtils.getColumnDropSQL(tableName, columnName);
216: }
217:
218: /**
219: * Returns the SQL that forms the command to drop the specified table. If
220: * cascade contraints is supported by the dialect and cascadeConstraints is
221: * true, then a drop statement with cascade constraints clause will be
222: * formed.
223: *
224: * @param iTableInfo the table to drop
225: * @param cascadeConstraints whether or not to drop any FKs that may
226: * reference the specified table.
227: * @return the drop SQL command.
228: */
229: public List<String> getTableDropSQL(ITableInfo iTableInfo,
230: boolean cascadeConstraints, boolean isMaterializedView) {
231: // TODO: Need to verify this
232: return DialectUtils.getTableDropSQL(iTableInfo, false,
233: cascadeConstraints, false, DialectUtils.CASCADE_CLAUSE,
234: false);
235: }
236:
237: /**
238: * Returns the SQL that forms the command to add a primary key to the
239: * specified table composed of the given column names.
240: *
241: * alter table foo add constraint pk_foo primary key (pkcol)
242: *
243: * @param pkName the name of the constraint
244: * @param columnNames the columns that form the key
245: * @return
246: */
247: public String[] getAddPrimaryKeySQL(String pkName,
248: TableColumnInfo[] columns, ITableInfo ti) {
249: return new String[] { DialectUtils.getAddPrimaryKeySQL(ti,
250: pkName, columns, false) };
251: }
252:
253: /**
254: * Returns a boolean value indicating whether or not this dialect supports
255: * adding comments to columns.
256: *
257: * @return true if column comments are supported; false otherwise.
258: */
259: public boolean supportsColumnComment() {
260: return false;
261: }
262:
263: /**
264: * Returns the SQL statement to use to add a comment to the specified
265: * column of the specified table.
266: * @param info information about the column such as type, name, etc.
267: * @return
268: * @throws UnsupportedOperationException if the database doesn't support
269: * annotating columns with a comment.
270: */
271: public String getColumnCommentAlterSQL(TableColumnInfo info)
272: throws UnsupportedOperationException {
273: int featureId = DialectUtils.COLUMN_COMMENT_ALTER_TYPE;
274: String msg = DialectUtils
275: .getUnsupportedMessage(this , featureId);
276: throw new UnsupportedOperationException(msg);
277: }
278:
279: /**
280: * Returns a boolean value indicating whether or not this database dialect
281: * supports changing a column from null to not-null and vice versa.
282: *
283: * @return true if the database supports dropping columns; false otherwise.
284: */
285: public boolean supportsAlterColumnNull() {
286: return false;
287: }
288:
289: /**
290: * Returns the SQL used to alter the specified column to not allow null
291: * values
292: *
293: * @param info the column to modify
294: * @return the SQL to execute
295: */
296: public String getColumnNullableAlterSQL(TableColumnInfo info) {
297: int featureId = DialectUtils.COLUMN_NULL_ALTER_TYPE;
298: String msg = DialectUtils
299: .getUnsupportedMessage(this , featureId);
300: throw new UnsupportedOperationException(msg);
301: }
302:
303: /**
304: * Returns a boolean value indicating whether or not this database dialect
305: * supports renaming columns.
306: *
307: * @return true if the database supports changing the name of columns;
308: * false otherwise.
309: */
310: public boolean supportsRenameColumn() {
311: return false;
312: }
313:
314: /**
315: * Returns the SQL that is used to change the column name.
316: *
317: *
318: * @param from the TableColumnInfo as it is
319: * @param to the TableColumnInfo as it wants to be
320: *
321: * @return the SQL to make the change
322: */
323: public String getColumnNameAlterSQL(TableColumnInfo from,
324: TableColumnInfo to) {
325: int featureId = DialectUtils.COLUMN_NAME_ALTER_TYPE;
326: String msg = DialectUtils
327: .getUnsupportedMessage(this , featureId);
328: throw new UnsupportedOperationException(msg);
329: }
330:
331: /**
332: * Returns a boolean value indicating whether or not this dialect supports
333: * modifying a columns type.
334: *
335: * @return true if supported; false otherwise
336: */
337: public boolean supportsAlterColumnType() {
338: return false;
339: }
340:
341: /**
342: * Returns the SQL that is used to change the column type.
343: *
344: * @param from the TableColumnInfo as it is
345: * @param to the TableColumnInfo as it wants to be
346: *
347: * @return the SQL to make the change
348: * @throw UnsupportedOperationException if the database doesn't support
349: * modifying column types.
350: */
351: public List<String> getColumnTypeAlterSQL(TableColumnInfo from,
352: TableColumnInfo to) throws UnsupportedOperationException {
353: int featureId = DialectUtils.COLUMN_TYPE_ALTER_TYPE;
354: String msg = DialectUtils
355: .getUnsupportedMessage(this , featureId);
356: throw new UnsupportedOperationException(msg);
357: }
358:
359: /**
360: * Returns a boolean value indicating whether or not this database dialect
361: * supports changing a column's default value.
362: *
363: * @return true if the database supports modifying column defaults; false
364: * otherwise
365: */
366: public boolean supportsAlterColumnDefault() {
367: return true;
368: }
369:
370: /**
371: * Returns the SQL command to change the specified column's default value
372: *
373: * @param info the column to modify and it's default value.
374: * @return SQL to make the change
375: */
376: public String getColumnDefaultAlterSQL(TableColumnInfo info) {
377: String alterClause = DialectUtils.ALTER_COLUMN_CLAUSE;
378: String defaultClause = DialectUtils.SET_CLAUSE;
379: return DialectUtils.getColumnDefaultAlterSQL(this , info,
380: alterClause, false, defaultClause);
381: }
382:
383: /**
384: * Returns the SQL command to drop the specified table's primary key.
385: *
386: * @param pkName the name of the primary key that should be dropped
387: * @param tableName the name of the table whose primary key should be
388: * dropped
389: * @return
390: */
391: public String getDropPrimaryKeySQL(String pkName, String tableName) {
392: return DialectUtils.getDropPrimaryKeySQL(pkName, tableName,
393: false, false);
394: }
395:
396: /**
397: * Returns the SQL command to drop the specified table's foreign key
398: * constraint.
399: *
400: * @param fkName the name of the foreign key that should be dropped
401: * @param tableName the name of the table whose foreign key should be
402: * dropped
403: * @return
404: */
405: public String getDropForeignKeySQL(String fkName, String tableName) {
406: return DialectUtils.getDropForeignKeySQL(fkName, tableName);
407: }
408:
409: /**
410: * Returns the SQL command to create the specified table.
411: *
412: * @param tables the tables to get create statements for
413: * @param md the metadata from the ISession
414: * @param prefs preferences about how the resultant SQL commands should be
415: * formed.
416: * @param isJdbcOdbc whether or not the connection is via JDBC-ODBC bridge.
417: *
418: * @return the SQL that is used to create the specified table
419: */
420: public List<String> getCreateTableSQL(List<ITableInfo> tables,
421: ISQLDatabaseMetaData md, CreateScriptPreferences prefs,
422: boolean isJdbcOdbc) throws SQLException {
423: return DialectUtils.getCreateTableSQL(tables, md, this, prefs,
424: isJdbcOdbc);
425: }
426:
427: }
|