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.ArrayList;
024: import java.util.List;
025:
026: import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
027: import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
028: import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData;
029: import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
030: import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo;
031:
032: import org.hibernate.dialect.SAPDBDialect;
033:
034: public class MAXDBDialect extends SAPDBDialect implements
035: HibernateDialect {
036:
037: public MAXDBDialect() {
038: super ();
039: registerColumnType(Types.BIGINT, "fixed(19,0)");
040: registerColumnType(Types.BINARY, 8000, "char($l) byte");
041: registerColumnType(Types.BINARY, "long varchar byte");
042: registerColumnType(Types.BIT, "boolean");
043: registerColumnType(Types.BLOB, "long byte");
044: registerColumnType(Types.BOOLEAN, "boolean");
045: registerColumnType(Types.CLOB, "long varchar");
046: registerColumnType(Types.CHAR, 8000, "char($l) ascii");
047: registerColumnType(Types.CHAR, "long varchar ascii");
048: registerColumnType(Types.DECIMAL, "decimal($p,$s)");
049: registerColumnType(Types.DOUBLE, "double precision");
050: registerColumnType(Types.DATE, "date");
051: registerColumnType(Types.FLOAT, "float($p)");
052: registerColumnType(Types.INTEGER, "int");
053: registerColumnType(Types.LONGVARBINARY, 8000,
054: "varchar($l) byte");
055: registerColumnType(Types.LONGVARBINARY, "long byte");
056: registerColumnType(Types.LONGVARCHAR, "long ascii");
057: registerColumnType(Types.NUMERIC, "fixed($p,$s)");
058: registerColumnType(Types.REAL, "float($p)");
059: registerColumnType(Types.SMALLINT, "smallint");
060: registerColumnType(Types.TIME, "time");
061: registerColumnType(Types.TIMESTAMP, "timestamp");
062: registerColumnType(Types.TINYINT, "fixed(3,0)");
063: registerColumnType(Types.VARBINARY, "long byte");
064: registerColumnType(Types.VARCHAR, 8000, "varchar($l)");
065: registerColumnType(Types.VARCHAR, "long ascii");
066: }
067:
068: public boolean canPasteTo(IDatabaseObjectInfo info) {
069: boolean result = true;
070: DatabaseObjectType type = info.getDatabaseObjectType();
071: if (type.getName().equalsIgnoreCase("database")) {
072: result = false;
073: }
074: return result;
075: }
076:
077: public boolean supportsSchemasInTableDefinition() {
078: return true;
079: }
080:
081: public String getMaxFunction() {
082: return "max";
083: }
084:
085: public String getLengthFunction(int dataType) {
086: return "length";
087: }
088:
089: public int getMaxPrecision(int dataType) {
090: return 38;
091: }
092:
093: public int getMaxScale(int dataType) {
094: return getMaxPrecision(dataType);
095: }
096:
097: public int getPrecisionDigits(int columnSize, int dataType) {
098: return columnSize * 2;
099: }
100:
101: /* (non-Javadoc)
102: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getColumnLength(int, int)
103: */
104: public int getColumnLength(int columnSize, int dataType) {
105: // driver returns 8 for "long byte", yet it can store 2GB of data.
106: if (dataType == Types.LONGVARBINARY) {
107: return Integer.MAX_VALUE;
108: }
109: return columnSize;
110: }
111:
112: /**
113: * The string which identifies this dialect in the dialect chooser.
114: *
115: * @return a descriptive name that tells the user what database this dialect
116: * is design to work with.
117: */
118: public String getDisplayName() {
119: return "MaxDB";
120: }
121:
122: /**
123: * Returns boolean value indicating whether or not this dialect supports the
124: * specified database product/version.
125: *
126: * @param databaseProductName the name of the database as reported by
127: * DatabaseMetaData.getDatabaseProductName()
128: * @param databaseProductVersion the version of the database as reported by
129: * DatabaseMetaData.getDatabaseProductVersion()
130: * @return true if this dialect can be used for the specified product name
131: * and version; false otherwise.
132: */
133: public boolean supportsProduct(String databaseProductName,
134: String databaseProductVersion) {
135: if (databaseProductName == null) {
136: return false;
137: }
138: String lname = databaseProductName.trim().toLowerCase();
139: if (lname.startsWith("sap") || lname.startsWith("maxdb")) {
140: // We don't yet have the need to discriminate by version.
141: return true;
142: }
143: return false;
144: }
145:
146: /**
147: * Returns the SQL statement to use to add a column to the specified table
148: * using the information about the new column specified by info.
149: * @param info information about the new column such as type, name, etc.
150: *
151: * @return
152: * @throws UnsupportedOperationException if the database doesn't support
153: * adding columns after a table has already been created.
154: */
155: public String[] getColumnAddSQL(TableColumnInfo info)
156: throws UnsupportedOperationException {
157: ArrayList<String> result = new ArrayList<String>();
158: result.add(DialectUtils.getColumnAddSQL(info, this , true,
159: false, true));
160: if (info.getRemarks() != null && !"".equals(info.getRemarks())) {
161: result.add(getColumnCommentAlterSQL(info));
162: }
163: return result.toArray(new String[result.size()]);
164: }
165:
166: /**
167: * Returns a boolean value indicating whether or not this database dialect
168: * supports dropping columns from tables.
169: *
170: * @return true if the database supports dropping columns; false otherwise.
171: */
172: public boolean supportsDropColumn() {
173: return true;
174: }
175:
176: /**
177: * Returns the SQL that forms the command to drop the specified colum in the
178: * specified table.
179: *
180: * @param tableName the name of the table that has the column
181: * @param columnName the name of the column to drop.
182: * @return
183: * @throws UnsupportedOperationException if the database doesn't support
184: * dropping columns.
185: */
186: public String getColumnDropSQL(String tableName, String columnName) {
187: return DialectUtils.getColumnDropSQL(tableName, columnName);
188: }
189:
190: /**
191: * Returns the SQL that forms the command to drop the specified table. If
192: * cascade contraints is supported by the dialect and cascadeConstraints is
193: * true, then a drop statement with cascade constraints clause will be
194: * formed.
195: *
196: * @param iTableInfo the table to drop
197: * @param cascadeConstraints whether or not to drop any FKs that may
198: * reference the specified table.
199: * @return the drop SQL command.
200: */
201: public List<String> getTableDropSQL(ITableInfo iTableInfo,
202: boolean cascadeConstraints, boolean isMaterializedView) {
203: return DialectUtils.getTableDropSQL(iTableInfo, true,
204: cascadeConstraints, false, DialectUtils.CASCADE_CLAUSE,
205: false);
206: }
207:
208: /**
209: * Returns the SQL that forms the command to add a primary key to the
210: * specified table composed of the given column names.
211: *
212: * ALTER TABLE test ADD constraint test_pk PRIMARY KEY (notnullint)
213: *
214: * @param pkName the name of the constraint
215: * @param columnNames the columns that form the key
216: * @return
217: */
218: public String[] getAddPrimaryKeySQL(String pkName,
219: TableColumnInfo[] columns, ITableInfo ti) {
220: ArrayList<String> result = new ArrayList<String>();
221: for (int i = 0; i < columns.length; i++) {
222: TableColumnInfo info = columns[i];
223: result.add(getColumnNullableAlterSQL(info, false));
224: }
225: result.add(DialectUtils.getAddPrimaryKeySQL(ti, pkName,
226: columns, false));
227: return result.toArray(new String[result.size()]);
228: }
229:
230: /**
231: * Returns a boolean value indicating whether or not this dialect supports
232: * adding comments to columns.
233: *
234: * @return true if column comments are supported; false otherwise.
235: */
236: public boolean supportsColumnComment() {
237: return true;
238: }
239:
240: /**
241: * Returns the SQL statement to use to add a comment to the specified
242: * column of the specified table.
243: * @param info information about the column such as type, name, etc.
244: * @return
245: * @throws UnsupportedOperationException if the database doesn't support
246: * annotating columns with a comment.
247: */
248: public String getColumnCommentAlterSQL(TableColumnInfo info)
249: throws UnsupportedOperationException {
250: return DialectUtils.getColumnCommentAlterSQL(info);
251: }
252:
253: /**
254: * Returns a boolean value indicating whether or not this database dialect
255: * supports changing a column from null to not-null and vice versa.
256: *
257: * @return true if the database supports dropping columns; false otherwise.
258: */
259: public boolean supportsAlterColumnNull() {
260: return true;
261: }
262:
263: /**
264: * Returns the SQL used to alter the specified column to not allow null
265: * values
266: *
267: * ALTER TABLE table_name COLUMN column_name DEFAULT NULL
268: *
269: * ALTER TABLE table_name COLUMN column_name NOT NULL
270: *
271: * @param info the column to modify
272: * @return the SQL to execute
273: */
274: public String getColumnNullableAlterSQL(TableColumnInfo info) {
275: boolean nullable = info.isNullable().equalsIgnoreCase("YES");
276: return getColumnNullableAlterSQL(info, nullable);
277: }
278:
279: /**
280: * Returns the SQL used to alter the specified column to not allow null
281: * values
282: *
283: * ALTER TABLE table_name COLUMN column_name DEFAULT NULL
284: *
285: * ALTER TABLE table_name COLUMN column_name NOT NULL
286: *
287: * @param info the column to modify
288: * @param nullable whether or not the column should allow nulls
289: *
290: * @return the SQL to execute
291: */
292: public String getColumnNullableAlterSQL(TableColumnInfo info,
293: boolean nullable) {
294: StringBuffer result = new StringBuffer();
295: result.append("ALTER TABLE ");
296: result.append(info.getTableName());
297: result.append(" COLUMN ");
298: result.append(info.getColumnName());
299: if (nullable) {
300: result.append(" DEFAULT NULL");
301: } else {
302: result.append(" NOT NULL");
303: }
304: return result.toString();
305: }
306:
307: /**
308: * Returns a boolean value indicating whether or not this database dialect
309: * supports renaming columns.
310: *
311: * @return true if the database supports changing the name of columns;
312: * false otherwise.
313: */
314: public boolean supportsRenameColumn() {
315: return true;
316: }
317:
318: /**
319: * Returns the SQL that is used to change the column name.
320: *
321: * RENAME COLUMN table_name.column_name TO new_column_name
322: *
323: * @param from the TableColumnInfo as it is
324: * @param to the TableColumnInfo as it wants to be
325: *
326: * @return the SQL to make the change
327: */
328: public String getColumnNameAlterSQL(TableColumnInfo from,
329: TableColumnInfo to) {
330: return DialectUtils.getColumnRenameSQL(from, to);
331: }
332:
333: /**
334: * Returns a boolean value indicating whether or not this dialect supports
335: * modifying a columns type.
336: *
337: * @return true if supported; false otherwise
338: */
339: public boolean supportsAlterColumnType() {
340: return true;
341: }
342:
343: /**
344: * Returns the SQL that is used to change the column type.
345: *
346: * @param from the TableColumnInfo as it is
347: * @param to the TableColumnInfo as it wants to be
348: *
349: * @return the SQL to make the change
350: * @throw UnsupportedOperationException if the database doesn't support
351: * modifying column types.
352: */
353: public List<String> getColumnTypeAlterSQL(TableColumnInfo from,
354: TableColumnInfo to) throws UnsupportedOperationException {
355: String alterClause = DialectUtils.MODIFY_CLAUSE;
356: return DialectUtils.getColumnTypeAlterSQL(this , alterClause,
357: "", false, from, to);
358: }
359:
360: /**
361: * Returns a boolean value indicating whether or not this database dialect
362: * supports changing a column's default value.
363: *
364: * @return true if the database supports modifying column defaults; false
365: * otherwise
366: */
367: public boolean supportsAlterColumnDefault() {
368: return true;
369: }
370:
371: /**
372: * Returns the SQL command to change the specified column's default value
373: *
374: * alter table test column mychar drop default
375: *
376: * alter table test column mychar add default 'a default'
377: *
378: * @param info the column to modify and it's default value.
379: * @return SQL to make the change
380: */
381: public String getColumnDefaultAlterSQL(TableColumnInfo info) {
382: String alterClause = DialectUtils.COLUMN_CLAUSE;
383: String newDefault = info.getDefaultValue();
384: String defaultClause = null;
385: if (newDefault != null && !"".equals(newDefault)) {
386: defaultClause = DialectUtils.ADD_DEFAULT_CLAUSE;
387: } else {
388: defaultClause = DialectUtils.DROP_DEFAULT_CLAUSE;
389: }
390: return DialectUtils.getColumnDefaultAlterSQL(this , info,
391: alterClause, false, defaultClause);
392: }
393:
394: /**
395: * Returns the SQL command to drop the specified table's primary key.
396: *
397: * @param pkName the name of the primary key that should be dropped
398: * @param tableName the name of the table whose primary key should be
399: * dropped
400: * @return
401: */
402: public String getDropPrimaryKeySQL(String pkName, String tableName) {
403: return DialectUtils.getDropPrimaryKeySQL(pkName, tableName,
404: false, false);
405: }
406:
407: /**
408: * Returns the SQL command to drop the specified table's foreign key
409: * constraint.
410: *
411: * @param fkName the name of the foreign key that should be dropped
412: * @param tableName the name of the table whose foreign key should be
413: * dropped
414: * @return
415: */
416: public String getDropForeignKeySQL(String fkName, String tableName) {
417: return DialectUtils.getDropForeignKeySQL(fkName, tableName);
418: }
419:
420: /**
421: * Returns the SQL command to create the specified table.
422: *
423: * @param tables the tables to get create statements for
424: * @param md the metadata from the ISession
425: * @param prefs preferences about how the resultant SQL commands should be
426: * formed.
427: * @param isJdbcOdbc whether or not the connection is via JDBC-ODBC bridge.
428: *
429: * @return the SQL that is used to create the specified table
430: */
431: public List<String> getCreateTableSQL(List<ITableInfo> tables,
432: ISQLDatabaseMetaData md, CreateScriptPreferences prefs,
433: boolean isJdbcOdbc) throws SQLException {
434: return DialectUtils.getCreateTableSQL(tables, md, this, prefs,
435: isJdbcOdbc);
436: }
437:
438: }
|