001: /*
002: * JdbcIndexReader.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.db;
013:
014: import java.sql.ResultSet;
015: import java.sql.SQLException;
016: import java.util.Collection;
017: import workbench.storage.DataStore;
018: import workbench.util.StringUtil;
019:
020: /**
021: *
022: * @author support@sql-workbench.net
023: */
024: public class JdbcIndexReader implements IndexReader {
025: protected DbMetadata metaData;
026:
027: public JdbcIndexReader(DbMetadata meta) {
028: this .metaData = meta;
029: }
030:
031: public void indexInfoProcessed() {
032: // nothing to do, as we are using the driver's call
033: }
034:
035: /**
036: * Return information about the indexes defined for the given table.
037: *
038: * @throws java.sql.SQLException
039: */
040: public ResultSet getIndexInfo(TableIdentifier table, boolean unique)
041: throws SQLException {
042: return this .metaData.getSqlConnection().getMetaData()
043: .getIndexInfo(table.getCatalog(), table.getSchema(),
044: table.getTableName(), unique, false);
045: }
046:
047: /**
048: * Return the SQL to re-create the indexes defined for the table.
049: *
050: * @param table
051: * @param indexDefinition
052: * @param tableNameToUse
053: * @return SQL Script to create indexes
054: */
055: public StringBuilder getIndexSource(TableIdentifier table,
056: DataStore indexDefinition, String tableNameToUse) {
057: if (indexDefinition == null)
058: return new StringBuilder(0);
059: int count = indexDefinition.getRowCount();
060: if (count == 0)
061: return StringUtil.emptyBuffer();
062: StringBuilder idx = new StringBuilder();
063: String template = this .metaData.metaSqlMgr.getIndexTemplate();
064:
065: int idxCount = 0;
066: for (int i = 0; i < count; i++) {
067: String idx_name = indexDefinition.getValue(i, 0).toString();
068: String unique = indexDefinition.getValue(i, 1).toString();
069: String is_pk = indexDefinition.getValue(i, 2).toString();
070: String definition = indexDefinition.getValue(i, 3)
071: .toString();
072: String type = indexDefinition.getValueAsString(i,
073: DbMetadata.COLUMN_IDX_TABLE_INDEXLIST_TYPE);
074: if (type == null || type.startsWith("NORMAL"))
075: type = "";
076:
077: // TODO: some DBMS return a column list with ascending/descending information (e.g. LASTNAME A, FIRSTNAME A)
078: // but for some DBMS this is not valid SQL
079:
080: // But the returned definition cannot easily be parsed for this situation
081: // because it might also be a function (that contains a comma in the value list)
082: // or complex expression (e.g. CASE ...) which would even be harder to analyze
083: // So I'll leave the expression as it is...
084:
085: // Only add non-PK Indexes here. The indexes related to the PK constraints
086: // are usually auto-created when the PK is defined, so there is no need
087: // to re-create a CREATE INDEX statement for them.
088: if ("NO".equalsIgnoreCase(is_pk)) {
089: idxCount++;
090: String sql = StringUtil.replace(template,
091: MetaDataSqlManager.TABLE_NAME_PLACEHOLDER,
092: (tableNameToUse == null ? table.getTableName()
093: : tableNameToUse));
094: if ("YES".equalsIgnoreCase(unique)) {
095: sql = StringUtil.replace(sql,
096: MetaDataSqlManager.UNIQUE_PLACEHOLDER,
097: "UNIQUE ");
098: } else {
099: sql = StringUtil.replace(sql,
100: MetaDataSqlManager.UNIQUE_PLACEHOLDER, "");
101: }
102: sql = StringUtil
103: .replace(
104: sql,
105: MetaDataSqlManager.INDEX_TYPE_PLACEHOLDER,
106: type);
107: sql = StringUtil.replace(sql,
108: MetaDataSqlManager.COLUMN_LIST_PLACEHOLDER,
109: definition);
110: sql = StringUtil.replace(sql,
111: MetaDataSqlManager.INDEX_NAME_PLACEHOLDER,
112: idx_name);
113: idx.append(sql);
114: idx.append(";\n");
115: }
116: }
117: if (idxCount > 0)
118: idx.append("\n");
119: return idx;
120: }
121:
122: /**
123: * Build the SQL statement to create an Index on the given table.
124: *
125: * @param aTable - The table name for which the index should be constructed
126: * @param indexName - The name of the Index
127: * @param unique - Should the index be unique
128: * @param columnList - The columns that should build the index
129: *
130: * @return the SQL statement to create the index
131: */
132: public String buildCreateIndexSql(TableIdentifier aTable,
133: String indexName, boolean unique, String[] columnList) {
134: if (columnList == null)
135: return StringUtil.EMPTY_STRING;
136: int count = columnList.length;
137: if (count == 0)
138: return StringUtil.EMPTY_STRING;
139: String template = this .metaData.metaSqlMgr.getIndexTemplate();
140: StringBuilder cols = new StringBuilder(count * 25);
141:
142: for (int i = 0; i < count; i++) {
143: if (columnList[i] == null || columnList[i].length() == 0)
144: continue;
145: if (cols.length() > 0)
146: cols.append(',');
147: cols.append(columnList[i]);
148: }
149:
150: String sql = StringUtil.replace(template,
151: MetaDataSqlManager.TABLE_NAME_PLACEHOLDER, aTable
152: .getTableExpression(this .metaData
153: .getWbConnection()));
154: sql = StringUtil.replace(sql,
155: MetaDataSqlManager.INDEX_TYPE_PLACEHOLDER, "");
156: if (unique) {
157: sql = StringUtil.replace(sql,
158: MetaDataSqlManager.UNIQUE_PLACEHOLDER, "UNIQUE ");
159: } else {
160: sql = StringUtil.replace(sql,
161: MetaDataSqlManager.UNIQUE_PLACEHOLDER, "");
162: }
163: sql = StringUtil.replace(sql,
164: MetaDataSqlManager.COLUMN_LIST_PLACEHOLDER, cols
165: .toString());
166: sql = StringUtil.replace(sql,
167: MetaDataSqlManager.INDEX_NAME_PLACEHOLDER, indexName);
168: return sql;
169: }
170:
171: /**
172: *
173: * @param table
174: * @param indexDefinitions
175: */
176: public void processIndexList(TableIdentifier table,
177: Collection<IndexDefinition> indexDefinitions) {
178: // Nothing implemented
179: }
180:
181: }
|