Package org.apache.ws.jaxme.sqls.impl

Source Code of org.apache.ws.jaxme.sqls.impl.SQLGeneratorImpl

/*
* Copyright 2003, 2004  The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.

*/
package org.apache.ws.jaxme.sqls.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.ws.jaxme.sqls.BinaryColumn;
import org.apache.ws.jaxme.sqls.BooleanConstraint;
import org.apache.ws.jaxme.sqls.Column;
import org.apache.ws.jaxme.sqls.ColumnReference;
import org.apache.ws.jaxme.sqls.CombinedConstraint;
import org.apache.ws.jaxme.sqls.Constraint;
import org.apache.ws.jaxme.sqls.DeleteStatement;
import org.apache.ws.jaxme.sqls.ForeignKey;
import org.apache.ws.jaxme.sqls.Function;
import org.apache.ws.jaxme.sqls.Index;
import org.apache.ws.jaxme.sqls.RawSQLCode;
import org.apache.ws.jaxme.sqls.SQLGenerator;
import org.apache.ws.jaxme.sqls.InsertStatement;
import org.apache.ws.jaxme.sqls.JoinReference;
import org.apache.ws.jaxme.sqls.Schema;
import org.apache.ws.jaxme.sqls.SelectStatement;
import org.apache.ws.jaxme.sqls.SelectTableReference;
import org.apache.ws.jaxme.sqls.SetStatement;
import org.apache.ws.jaxme.sqls.Statement;
import org.apache.ws.jaxme.sqls.StringColumn;
import org.apache.ws.jaxme.sqls.Table;
import org.apache.ws.jaxme.sqls.TableReference;
import org.apache.ws.jaxme.sqls.UpdateStatement;
import org.apache.ws.jaxme.sqls.Value;


/** <p>Default implementation of an SQL generator.</p>
*
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
*/
public class SQLGeneratorImpl implements SQLGenerator {
    private String statementTerminator, lineTerminator;
   
    public String getStatementTerminator() {
        return statementTerminator;
    }
   
    public void setStatementTerminator(String pStatementTerminator) {
        statementTerminator = pStatementTerminator;
    }
   
    public String getLineTerminator() {
        return lineTerminator;
    }
   
    public void setLineTerminator(String pLineTerminator) {
        lineTerminator = pLineTerminator;
    }
   
    protected String newStatement(String pStatement) {
        String s = getStatementTerminator();
        return s == null ? pStatement : pStatement + s;
    }
   
    public Collection getCreate(Schema pSchema) {
        if (pSchema.getName() == null) {
            // Default schema cannot be created
            return Collections.EMPTY_LIST;
        }
        List result = new ArrayList();
        result.add(newStatement("CREATE SCHEMA " + pSchema.getName()));
        return result;
    }
   
    public Collection getDrop(Schema pSchema) {
        if (pSchema.getName() == null) {
            // Default schema cannot be dropped
            return Collections.EMPTY_LIST;
        }
        List result = new ArrayList();
        result.add(newStatement("DROP SCHEMA " + pSchema.getName()));
        return result;
    }
   
    protected String getIndent() { return "  "; }
   
    protected String getTypeName(Column.Type pType) {
        if (pType.equals(Column.Type.BIGINT)) {
            return "BIGINT";
        } else if (pType.equals(Column.Type.BINARY)) {
            return "BINARY";
        } else if (pType.equals(Column.Type.BIT)) {
            return "BIT";
        } else if (pType.equals(Column.Type.CHAR)) {
            return "CHAR";
        } else if (pType.equals(Column.Type.DATE)) {
            return "DATE";
        } else if (pType.equals(Column.Type.DOUBLE)) {
            return "DOUBLE";
        } else if (pType.equals(Column.Type.FLOAT)) {
            return "FLOAT";
        } else if (pType.equals(Column.Type.INTEGER)) {
            return "INT";
        } else if (pType.equals(Column.Type.SMALLINT)) {
            return "SMALLINT";
        } else if (pType.equals(Column.Type.TIME)) {
            return "TIME";
        } else if (pType.equals(Column.Type.TIMESTAMP)) {
            return "TIMESTAMP";
        } else if (pType.equals(Column.Type.TINYINT)) {
            return "TINYINT";
        } else if (pType.equals(Column.Type.VARBINARY)) {
            return "VARBINARY";
        } else if (pType.equals(Column.Type.VARCHAR)) {
            return "VARCHAR";
        } else if (pType.equals(Column.Type.CLOB)) {
            return "CLOB";
        } else if (pType.equals(Column.Type.BLOB)) {
            return "BLOB";
        } else if (pType.equals(Column.Type.OTHER)) {
            return "BLOB";
        } else {
            throw new IllegalStateException("Unknown column type: " + pType);
        }
    }
   
    protected String getCreate(Column pColumn) {
        StringBuffer sb = new StringBuffer();
        sb.append(pColumn.getName()).append(" ");
        Column.Type type = pColumn.getType();
        Long length = null;
        if (type.equals(Column.Type.BINARY)
                ||  type.equals(Column.Type.VARBINARY)
                ||  type.equals(Column.Type.BLOB)
                ||  type.equals(Column.Type.OTHER)) {
            length = ((BinaryColumn) pColumn).getLength();
            if (length == null) {
                throw new IllegalStateException("The length of column " + pColumn.getQName() + " is not set.");
            }
        } else if (type.equals(Column.Type.CHAR)
                ||  type.equals(Column.Type.VARCHAR)
                ||  type.equals(Column.Type.CLOB)) {
            length = ((StringColumn) pColumn).getLength();
            if (length == null) {
                throw new IllegalStateException("The length of column " + pColumn.getQName() + " is not set.");
            }
        }
        sb.append(getTypeName(type));
        if (length != null) {
            sb.append("(").append(length).append(")");
        }
        if (!pColumn.isNullable()) {
            sb.append(" NOT NULL");
        }
        return sb.toString();
    }
   
    /** <p>Returns whether the primary key requires special handling
     * (in which case {@link #isPrimaryKeyPartOfCreateTable()} and
     * {@link #createPrimaryKeyAsPartOfCreateTable(Table)} are used)
     * or nor (in which case {@link #isUniqueIndexPartOfCreateTable()}
     * and {@link #createIndexAsPartOfCreateTable(Index)} apply).</p>
     */
    protected boolean isPrimaryKeyUniqueIndex() { return false; }
   
    /** <p>Returns whether a <code>CREATE TABLE</code> statement may contain
     * a <code>PRIMARY KEY</code> clause.</p>
     */
    protected boolean isPrimaryKeyPartOfCreateTable() { return false; }
   
    /** <p>Returns whether a <code>CREATE TABLE</code> statement may contain
     * a <code>UNIQUE</code> clause.</p>
     */
    protected boolean isUniqueIndexPartOfCreateTable() { return false; }
   
    /** <p>Returns whether a <code>CREATE TABLE</code> statement may contain
     * an <code>INDEX</code> clause.</p>
     */
    protected boolean isNonUniqueIndexPartOfCreateTable() { return false; }
   
    /** <p>Returns whether a <code>CREATE TABLE</code> statement may contain
     * a <code>FOREIGN KEY</code> clause.</p>
     */
    protected boolean isForeignKeyPartOfCreateTable() { return false; }
   
    protected String createPrimaryKeyAsPartOfCreateTable(Table pTable) {
        Index index = pTable.getPrimaryKey();
        if (index == null) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        sb.append("PRIMARY KEY").append(" (");
        boolean first = true;
        for (Iterator iter = index.getColumns();  iter.hasNext()) {
            if (first) {
                first = false;
            } else {
                sb.append(", ");
            }
            sb.append(((Column) iter.next()).getName().getName());
        }
        sb.append(")");
        return sb.toString();
    }
   
    protected String createIndexAsPartOfCreateTable(Index pIndex) {
        StringBuffer sb = new StringBuffer();
        sb.append(pIndex.isUnique() ? "UNIQUE" : "KEY").append(" (");
        boolean first = true;
        for (Iterator iter = pIndex.getColumns();  iter.hasNext()) {
            if (first) {
                first = false;
            } else {
                sb.append(", ");
            }
            sb.append(((Column) iter.next()).getName().getName());
        }
        sb.append(")");
        return sb.toString();
    }
   
    protected String createForeignKeyAsPartOfCreateTable(ForeignKey pKey) {
        StringBuffer sb = new StringBuffer();
        sb.append("FOREIGN KEY (");
        boolean first = true;
        Iterator iter = pKey.getColumnLinks();
        if (!iter.hasNext()) {
            throw new IllegalStateException("Foreign key on " +
                    pKey.getTable().getQName() +
                    " referencing " +
                    pKey.getReferencedTable().getQName() +
            " doesn't have any columns.");
        }
        while (iter.hasNext()) {
            ForeignKey.ColumnLink link = (ForeignKey.ColumnLink) iter.next();
            if (first) {
                first = false;
            } else {
                sb.append(", ");
            }
            sb.append(link.getLocalColumn().getName().getName());
        }
        sb.append(") REFERENCES ");
        sb.append(pKey.getReferencedTable().getQName());
        sb.append(" (");
        first = true;
        iter = pKey.getColumnLinks();
        while (iter.hasNext()) {
            ForeignKey.ColumnLink link = (ForeignKey.ColumnLink) iter.next();
            if (first) {
                first = false;
            } else {
                sb.append(", ");
            }
            sb.append(link.getReferencedColumn().getName().getName());
        }
        sb.append(")");
       
        ForeignKey.Mode deleteMode = pKey.getOnDelete();
        if (deleteMode != null) {
            if (ForeignKey.Mode.CASCADE.equals(deleteMode)) {
                sb.append(" ON DELETE CASCADE");
            } else if (ForeignKey.Mode.REJECT.equals(deleteMode)) {
                sb.append(" ON DELETE RESTRICT");
            } else if (ForeignKey.Mode.SETNULL.equals(deleteMode)) {
                sb.append(" ON DELETE SET NULL");
            } else {
                throw new IllegalStateException("Unknown foreign key mode for ON  DELETE: " + deleteMode);
            }
        }
        ForeignKey.Mode updateMode = pKey.getOnUpdate();
        if (updateMode != null) {
            if (ForeignKey.Mode.CASCADE.equals(updateMode)) {
                sb.append(" ON UPDATE CASCADE");
            } else if (ForeignKey.Mode.REJECT.equals(updateMode)) {
                sb.append(" ON UPDATE RESTRICT");
            } else {
                throw new IllegalStateException("Unknown foreign key mode for ON UPDATE: " + updateMode);
            }
        }
       
        return sb.toString();
    }
   
    protected String getCreateTableHeader(Table pTable) {
        return "CREATE TABLE " + pTable.getQName();
    }
   
    public Collection getCreate(Table pTable) {
        String lf = getLineTerminator() == null ? "" : getLineTerminator();
        String indent = lf == null ? "" : getIndent();
        StringBuffer sb = new StringBuffer();
        sb.append(getCreateTableHeader(pTable)).append(" (");
        String s = lf + indent;
        for (Iterator iter = pTable.getColumns();  iter.hasNext()) {
            sb.append(s).append(getCreate((Column) iter.next()));
            s = "," + lf + indent;
        }
       
        for (Iterator iter = pTable.getIndexes();  iter.hasNext()) {
            Index index = (Index) iter.next();
            String st;
            if (index.isPrimaryKey()  &&  !isPrimaryKeyUniqueIndex()) {
                if (!isPrimaryKeyPartOfCreateTable()) {
                    continue;
                }
                st = createPrimaryKeyAsPartOfCreateTable(pTable);
            } else if (index.isUnique()) {
                if (!isUniqueIndexPartOfCreateTable()) {
                    continue;
                }
                st = createIndexAsPartOfCreateTable(index);
            } else {
                if (!isNonUniqueIndexPartOfCreateTable()) {
                    continue;
                }
                st = createIndexAsPartOfCreateTable(index);
            }
            if (st != null) {
                sb.append(s).append(st);
            }
        }
        if (isForeignKeyPartOfCreateTable()) {
            for (Iterator iter = pTable.getForeignKeys();  iter.hasNext()) {
                ForeignKey key = (ForeignKey) iter.next();
                String st = createForeignKeyAsPartOfCreateTable(key);
                if (st != null) {
                    sb.append(s).append(st);
                }
            }
        }
        sb.append(lf).append(")").append(lf);
        List result = new ArrayList();
        result.add(newStatement(sb.toString()));
        return result;
    }
   
    public Collection getDrop(Table pTable) {
        List result = new ArrayList();
        result.add(newStatement("DROP TABLE " + pTable.getQName()));
        return result;
    }
   
    public String getInsertQuery(InsertStatement pQuery) {
        StringBuffer result = new StringBuffer();
        result.append("INSERT INTO ");
        result.append(getTableAlias(null, pQuery.getTableReference()));
        boolean first = true;
        for (Iterator iter = pQuery.getSetValues();  iter.hasNext()) {
            if (first) {
                result.append(" (");
                first = false;
            } else {
                result.append(", ");
            }
            SetStatement.SetValue setValue = (SetStatement.SetValue) iter.next();
            result.append(getColumnAlias(null, setValue.getColumnReference()));
        }
        if (!first) {
            result.append(")");
        }
        result.append(" VALUES (");
        first = true;
        for (Iterator iter = pQuery.getSetValues();  iter.hasNext()) {
            if (first) {
                first = false;
            } else {
                result.append(", ");
            }
            SetStatement.SetValue setValue = (SetStatement.SetValue) iter.next();
            result.append(getValue(setValue.getValue()));
        }
        result.append(")");
        return newStatement(result.toString());
    }
   
    protected String getValue(Value pValue) {
        Value.Type type = pValue.getType();
        Object o = pValue.getValue();
        if (Value.Type.BOOLEAN.equals(type)) {
            return o == null ? "null" : (((Boolean) o).booleanValue() ? "TRUE" : "FALSE");
        } else if (Value.Type.BYTE.equals(type)   ||
                Value.Type.SHORT.equals(type||
                Value.Type.INT.equals(type)    ||
                Value.Type.LONG.equals(type)   ||
                Value.Type.FLOAT.equals(type||
                Value.Type.DOUBLE.equals(type)) {
            return o == null ? "null" : o.toString();
        } else if (Value.Type.DATE.equals(type||
                Value.Type.DATETIME.equals(type||
                Value.Type.TIME.equals(type)) {
            throw new IllegalStateException("Date/time handling not yet implemented.");
        } else if (Value.Type.DATE.equals(type)) {
            throw new IllegalStateException("Date handling not yet implemented.");
        } else if (Value.Type.PLACEHOLDER.equals(type)) {
            return "?";
        } else if (Value.Type.STRING.equals(type)) {
            return o == null ? "null" : getEscapedString(o.toString());
        } else if (Value.Type.NULL.equals(type)) {
            return "null";
        } else {
            throw new IllegalStateException("Unknown value type: " + type);     
        }
    }
   
    protected String getUpdateQuery(UpdateStatement pQuery) {
        StringBuffer sb = new StringBuffer();
        sb.append("UPDATE ");
        sb.append(getTableAlias(null, pQuery.getTableReference()));
        sb.append(" SET ");
        boolean first = true;
        for (Iterator iter = pQuery.getSetValues();  iter.hasNext()) {
            UpdateStatement.SetValue setValue = (UpdateStatement.SetValue) iter.next();
            if (first) {
                first = false;
            } else {
                sb.append(", ");
            }
            sb.append(getColumnAlias(null, setValue.getColumnReference()));
            sb.append("=");
            sb.append(getValue(setValue.getValue()));
        }
        String s = getWhereClause(null, pQuery.getWhere());
        if (s != null) {
            sb.append(" WHERE ").append(s);
        }
        return newStatement(sb.toString());
    }
   
    protected String getDeleteQuery(DeleteStatement pQuery) {
        StringBuffer result = new StringBuffer("DELETE FROM ");
        result.append(getTableAlias(null, pQuery.getTableReference()));
        String s = getWhereClause(null, pQuery.getWhere());
        if (s != null) {
            result.append(" WHERE ");
            result.append(s);
        }
        return result.toString();
    }
   
    protected boolean isQualifiedColumn(SelectStatementMetaData pData, ColumnReference pColumn) {
        if (pData == null) {
            return false;
        }
        Integer num = (Integer) pData.getColumnNames().get(pColumn.getColumn().getName().toString().toUpperCase());
        if (num == null) {
            throw new IllegalStateException("Column not in map of column counts: "
                    + pColumn.getColumn().getName());
        }
        return num.intValue() > 1;
    }
   
    protected String getFunction(SelectStatementMetaData pData, Function f) {
        return f.getName() + '(' + getParts(pData, f.getParts()) + ')';
    }
   
    protected String getColumnAlias(SelectStatementMetaData pData, ColumnReference pColumn) {
        Column col = pColumn.getColumn();
        String s = col.getName().toString();
        if (col.isVirtual()) {
            VirtualColumn virtCol = (VirtualColumn) col;
            Object o = virtCol.getValue();
            if (o instanceof SelectStatement) {
                return "(" + getSelectQuery((SelectStatement) o, pData) + ") AS " + s;
            } else if (o instanceof Function) {
                return getFunction(pData, (Function) o) + " AS " + s;
            } else if (o instanceof String) {
                return ((String) o) + " AS " + s;
            } else {
                throw new IllegalStateException("Invalid type of VirtualColumn: " + o);
            }
        } else {
            if (isQualifiedColumn(pData, pColumn)) {
                TableReference tableReference = pColumn.getTableReference();
                if (tableReference.getAlias() != null) {
                    s = tableReference.getAlias().getName() + "." + s;
                } else {
                    s = tableReference.getTable().getName() + "." + s;
                }
            }
           
            if (pColumn.getAlias() != null) {
                s = s + " AS " + pColumn.getAlias().getName();
            }
        }
        return s;
    }
   
    protected String getColumnAlias(SelectStatementMetaData pData, ColumnReference[] pColumn) {
        StringBuffer sb = new StringBuffer("(");
        for (int i = 0;  i < pColumn.length;  i++) {
            if (i > 0) sb.append(", ");
            sb.append(getColumnAlias(pData, pColumn[i]));
        }
        sb.append(")");
        return sb.toString();
    }
   
    protected boolean isTableAliasUsingAs() { return true; }
   
    protected String getTableAlias(SelectStatementMetaData pData, TableReference pTable) {
        Table t = pTable.getTable();
        String tableName;
        Table.Name alias = pTable.getAlias();
        if (t instanceof ViewImpl) {
            ViewImpl v = (ViewImpl) t;
            tableName = "(" + getSelectQuery(v.getViewStatement(), pData) + ")";
        } else {
            tableName = pTable.getTable().getQName();
        }
        if (alias == null) {
            return tableName;
        } else {
            if (isTableAliasUsingAs()) {
                return tableName + " AS " + alias.getName();
            } else {
                return tableName + " " + alias.getName();
            }
        }
    }
   
    protected String getJoinAlias(SelectStatementMetaData pData, JoinReference pJoinReference) {
        StringBuffer result = new StringBuffer();
        if (pJoinReference.isLeftOuterJoin()) {
            result.append(" LEFT OUTER JOIN ");
        } else if (pJoinReference.isJoin()) {
            result.append(" JOIN ");
        } else {
            throw new IllegalStateException("Unknown join type");
        }
        result.append(getTableAlias(pData, pJoinReference));
        String s = getWhereClause(pData, pJoinReference.getOn());
        if (s != null) {
            result.append(" ON ");
            result.append(s);
        }
        return result.toString();
    }
   
    protected String getEscapedString(String s) {
        if (s.indexOf('\n') > -||  s.indexOf('\r') > -||  s.indexOf('\f') > -1) {
            throw new IllegalArgumentException("Don't know how to handle line or page terminators.");
        }
        if (s.indexOf('\'') > -1) {
            throw new IllegalArgumentException("Don't know how to handle the char ' in strings.");
        }
        return "'" + s + "'";
    }
   
    protected String getParts(SelectStatementMetaData pData, Iterator pParts) {
        StringBuffer sb = new StringBuffer();
        while (pParts.hasNext()) {
            if (sb.length() > 0) {
                sb.append(", ");
            }
            sb.append(getBooleanConstraintPart(pData, pParts.next()));
        }
        return sb.toString();
    }
   
    protected String getBooleanConstraintPart(SelectStatementMetaData pData, Object o) {
        if (o instanceof Value) {
            return getValue((Value) o);
        } else if (o instanceof ColumnReference) {
            return getColumnAlias(pData, (ColumnReference) o);
        } else if (o instanceof ColumnReference[]) {
            return getColumnAlias(pData, (ColumnReference[]) o);
        } else if (o instanceof SelectStatement) {
            return '(' + getSelectQuery((SelectStatement) o, pData) + ')';
        } else if (o instanceof RawSQLCode) {
            return ((RawSQLCode) o).getRawSQL();
        } else if (o instanceof Function) {
            return getFunction(pData, (Function) o);
        } else {
            throw new IllegalArgumentException("Invalid part of a boolean constraint: " + o.getClass().getName());
        }
    }
   
    protected String getBooleanConstraintType(BooleanConstraint.Type pType) {
        if (BooleanConstraint.Type.EQ.equals(pType)) {
            return "=";
        } else if (BooleanConstraint.Type.NE.equals(pType)) {
            return "<>";
        } else if (BooleanConstraint.Type.GT.equals(pType)) {
            return ">";
        } else if (BooleanConstraint.Type.LT.equals(pType)) {
            return "<";
        } else if (BooleanConstraint.Type.GE.equals(pType)) {
            return ">=";
        } else if (BooleanConstraint.Type.LE.equals(pType)) {
            return "<=";
        } else if (BooleanConstraint.Type.LIKE.equals(pType)) {
            return " LIKE ";
        } else {
            throw new IllegalArgumentException("Invalid type: " + pType);
        }
    }
   
    protected String getBooleanConstraint(SelectStatementMetaData pData,
            BooleanConstraint pConstraint) {
        BooleanConstraint.Type type = pConstraint.getType();
        Iterator parts = pConstraint.getParts();
        if (!parts.hasNext()) {
            throw new NullPointerException("A boolean constraint must have its parts set.");
        }
        if (BooleanConstraint.Type.IN.equals(type)) {
            Object o = parts.next();
            return getBooleanConstraintPart(pData, o) + " IN (" + getParts(pData, parts) + ')';
        }
        StringBuffer result = new StringBuffer();
        int expected;
        if (BooleanConstraint.Type.EXISTS.equals(type)) {
            SelectStatement selectStatement = (SelectStatement) parts.next();
            result.append("EXISTS(");
            result.append(getSelectQuery(selectStatement, pData));
            result.append(")");
            expected = 1;
        } else {
            result.append(getBooleanConstraintPart(pData, parts.next()));
            if (BooleanConstraint.Type.EQ.equals(type||
                    BooleanConstraint.Type.NE.equals(type||
                    BooleanConstraint.Type.GT.equals(type||
                    BooleanConstraint.Type.LT.equals(type||
                    BooleanConstraint.Type.GE.equals(type||
                    BooleanConstraint.Type.LE.equals(type||
                    BooleanConstraint.Type.LIKE.equals(type)) {
                expected = 2;
                if (!parts.hasNext()) {
                    throw new NullPointerException("The boolean constraint " + type +
                    " must have exactly two parts set.");
                }
                result.append(getBooleanConstraintType(type));
                result.append(getBooleanConstraintPart(pData, parts.next()));
            } else if (BooleanConstraint.Type.ISNULL.equals(type)) {
                expected = 1;
                result.append(" IS NULL");
            } else {
                throw new IllegalArgumentException("Invalid boolean constraint type: " + type);
            }
        }
        if (expected != &&  parts.hasNext()) {
            throw new NullPointerException("The boolean constraint " + type +
                    " must have exactly " + expected +
                    " parts set, but has " + pConstraint.getNumParts());
        }
        return result.toString();
    }
   
    protected String getCombinedConstraint(SelectStatementMetaData pData,
            CombinedConstraint pConstraint) {
        if (pConstraint.getNumParts() == 0) {
            return null;
        }
       
        List parts = new ArrayList();
        for (Iterator iter = pConstraint.getParts();  iter.hasNext()) {
            String s;
            Object o = iter.next();
            if (o == null) {
                throw new NullPointerException("A CombinedConstraints part must not be null");
            }
            if (o instanceof CombinedConstraint) {
                s = getCombinedConstraint(pData, (CombinedConstraint) o);
            } else if (o instanceof BooleanConstraint) {
                s = getBooleanConstraint(pData, (BooleanConstraint) o);           
            } else {
                throw new IllegalArgumentException("Invalid part: " + o.getClass().getName());
            }
            if (s != null) {
                parts.add(s);
            }
        }

        switch (parts.size()) {
            case 0: return null;
            case 1:
                if (pConstraint.isNOT()) {
                    return "NOT (" + parts.get(0) + ")";
                } else {
                    return (String) parts.get(0);
                }
            default:
                StringBuffer sb = new StringBuffer();
              if (pConstraint.isNOT()) {
                  sb.append("(NOT ");
              }
              for (int i = 0;  i < parts.size();  i++) {
                  if (i == 0) {
                      sb.append("(");
                  } else {
                      sb.append(" ");
                      sb.append(pConstraint.getType());
                      sb.append(" ");
                  }
                  sb.append(parts.get(i));
              }
              sb.append(")");
              if (pConstraint.isNOT()) {
                  sb.append(")");
              }
              return sb.toString();
        }
    }
   
    public String getConstraint(SelectStatementMetaData pData, Constraint pConstraint) {
        if (pConstraint instanceof CombinedConstraint) {
            return getWhereClause(pData, (CombinedConstraint) pConstraint);
        } else if (pConstraint instanceof BooleanConstraint) {
            return getBooleanConstraint(pData, (BooleanConstraint) pConstraint);
        } else {
            throw new IllegalArgumentException("Unknown constraint type: " +
                    pConstraint.getClass().getName());
        }
    }
   
    protected String getWhereClause(SelectStatementMetaData pData,
            CombinedConstraint pWhereClause) {
        return getCombinedConstraint(pData, pWhereClause);
    }
   
    protected String getSelectQuery(SelectStatement pQuery) {
        SelectStatementMetaData selectStatementMetaData = newSelectStatementMetaData(pQuery);
        return getSelectQuery(pQuery, selectStatementMetaData);
    }
   

    protected String getSelectQueryResultColumns(SelectStatement pQuery, SelectStatementMetaData pData) {
        StringBuffer sb = new StringBuffer();
        if (pQuery.isDistinct()) {
            sb.append(" DISTINCT");
        }
        Iterator columnIter = pQuery.getResultColumns();
        if (!columnIter.hasNext()) {
            sb.append(" *");
        } else {
            boolean first = true;
            do {
                ColumnReference column = (ColumnReference) columnIter.next();
                if (first) {
                    sb.append(" ");
                    first = false;
                } else {
                    sb.append(", ");
                }
                sb.append(getColumnAlias(pData, column));
            } while (columnIter.hasNext());
        }
        return sb.toString();
    }

    protected String getSelectQueryFromClause(SelectStatement pQuery, SelectStatementMetaData pData) {
        SelectTableReference selectTableReference = pQuery.getSelectTableReference();
        if (selectTableReference == null) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        sb.append(" FROM ");
        sb.append(getTableAlias(pData, selectTableReference));
        for (JoinReference joinReference = selectTableReference.getRightJoinedTableReference();
        joinReference != null;
        joinReference = joinReference.getRightJoinedTableReference()) {
            sb.append(getJoinAlias(pData, joinReference));              
        }
        return sb.toString();
    }

    protected String getSelectQueryConstraints(SelectStatement pQuery, SelectStatementMetaData pData,
                                               SelectStatementMetaData.LocalData pLocalData) {
        String s = getWhereClause(pData, pQuery.getWhere());
        if (pLocalData != null  &&  s != null  &&  s.length() > 0) {
          pLocalData.setWhereClause(true);
        }
        return s;
    }

    protected String getSelectQuery(SelectStatement pQuery, SelectStatementMetaData pData) {
        StringBuffer sb = new StringBuffer("SELECT");
        String s = getSelectQueryResultColumns(pQuery, pData);
        if (s != null) {
            sb.append(s);
        }

        s = getSelectQueryFromClause(pQuery, pData);
        if (s != null) {
            sb.append(s);
        }

        SelectStatementMetaData.LocalData localData = new SelectStatementMetaData.LocalData();
        s = getSelectQueryConstraints(pQuery, pData, localData);
        if (s != null  &&  s.length() > 0) {
            if (localData.hasWhereClause()) {
                sb.append(" WHERE ");
            }
            sb.append(s);
        }
       
        s = getSelectQueryOrderClause(pData, pQuery);
        if (s != null) {
            sb.append(s);
        }
        return sb.toString();
    }
   
    protected String getSelectQueryOrderClause(SelectStatementMetaData pData, SelectStatement pQuery) {
        StringBuffer sb = new StringBuffer();
        for (Iterator iter = pQuery.getOrderColumns();  iter.hasNext()) {
            SelectStatement.OrderColumn col = (SelectStatement.OrderColumn) iter.next();
            if (sb.length() == 0) {
                sb.append(" ORDER BY ");
            } else {
                sb.append(", ");
            }
            sb.append(getBooleanConstraintPart(pData, col.getColumn()));
            if (col.isDescending()) {
                sb.append(" DESC");
            }
        }
        return sb.toString();
    }
   
    public String getQuery(Statement pStatement) {
        String s;
        if (pStatement instanceof InsertStatement) {
            s = getInsertQuery((InsertStatement) pStatement);
        } else if (pStatement instanceof UpdateStatement) {
            s = getUpdateQuery((UpdateStatement) pStatement);
        } else if (pStatement instanceof DeleteStatement) {
            s =  getDeleteQuery((DeleteStatement) pStatement);
        } else if (pStatement instanceof SelectStatement) {
            s = getSelectQuery((SelectStatement) pStatement);
        } else {
            throw new IllegalArgumentException("The Statement is neither an INSERT, UPDATE, DELETE nor a SELECT statement.");
        }
        return newStatement(s);
    }
   
    public Collection getCreate(Schema pSchema, boolean pAll) {
        if (!pAll) { return getCreate(pSchema); }
        List result = new ArrayList();
        result.addAll(getCreate(pSchema));
        for (Iterator iter = pSchema.getTables();  iter.hasNext()) {
            Table table = (Table) iter.next();
            result.addAll(getCreate(table, true));
        }
        return result;
    }
   
    public Collection getDrop(Schema pSchema, boolean pAll) {
        if (!pAll) { return getDrop(pSchema); }
        List result = new ArrayList();
        List tables = new ArrayList();
        for (Iterator iter = pSchema.getTables();  iter.hasNext()) {
            tables.add(iter.next());
        }
        Collections.reverse(tables);
        for (Iterator iter = tables.iterator();  iter.hasNext()) {
            Table table = (Table) iter.next();
            result.addAll(getDrop(table, true));
        }
        result.addAll(getDrop(pSchema));
        return result;
    }
   
    public Collection getCreate(Table pTable, boolean pAll) {
        if (!pAll) { return getCreate(pTable); }
        List result = new ArrayList();
        result.addAll(getCreate(pTable));
        for (Iterator iter = pTable.getIndexes();  iter.hasNext()) {
            Index index = (Index) iter.next();
            if (index.isPrimaryKey() && !isPrimaryKeyUniqueIndex()) {
                if (isPrimaryKeyPartOfCreateTable()) {
                    continue;
                }
            } else if (index.isUnique()) {
                if (isUniqueIndexPartOfCreateTable()) {
                    continue;
                }
            } else {
                if (isNonUniqueIndexPartOfCreateTable()) {
                    continue;
                }
            }
            result.addAll(getCreate(index));
        }
        if (!isForeignKeyPartOfCreateTable()) {
            for (Iterator iter = pTable.getForeignKeys();  iter.hasNext()) {
                ForeignKey key = (ForeignKey) iter.next();
                result.addAll(getCreate(key));
            }
        }
        return result;
    }
   
    public Collection getDrop(Table pTable, boolean pAll) {
        if (!pAll) { return getDrop(pTable); }
        List result = new ArrayList();
        for (Iterator iter = pTable.getIndexes();  iter.hasNext()) {
            Index index = (Index) iter.next();
            result.addAll(getDrop(index));
        }
        for (Iterator iter = pTable.getForeignKeys();  iter.hasNext()) {
            ForeignKey key = (ForeignKey) iter.next();
            result.addAll(getDrop(key));
        }
        result.addAll(getDrop(pTable));
        return result;
    }
   
    public Collection getCreate(Index pIndex) {
        List result = new ArrayList();
        String s = createIndexAsPartOfCreateTable(pIndex);
        if (s != null) {
            StringBuffer sb = new StringBuffer();
            sb.append("CREATE");
            if (pIndex.isUnique()) {
                sb.append(" UNIQUE");
            }
            sb.append(" INDEX");
            sb.append(" ");
            sb.append(pIndex.getName());
            sb.append(" ON ").append(pIndex.getTable().getQName()).append(" (");
            boolean first = true;
            for (Iterator iter = pIndex.getColumns();  iter.hasNext()) {
                if (first) {
                    first = false;
                } else {
                    sb.append(", ");
                }
                sb.append(((Column) iter.next()).getName().getName());
            }
            sb.append(")");
            result.add(newStatement(sb.toString()));
        }
        return result;
    }
   
    public Collection getDrop(Index pIndex) {
        return Collections.EMPTY_SET;
    }
   
    public Collection getCreate(ForeignKey pKey) {
        List result = new ArrayList();
        String s = createForeignKeyAsPartOfCreateTable(pKey);
        if (s != null) {
            result.add(newStatement("CREATE " + s));
        }
        return result;
    }
   
    public Collection getDrop(ForeignKey pKey) {
        return Collections.EMPTY_SET;
    }
   
    protected SelectStatementMetaData newSelectStatementMetaData(SelectStatement pQuery) {
        return new SelectStatementMetaData(pQuery);
    }

    public String getWhereClause(SelectStatement pQuery) {
        SelectStatementMetaData metaData = newSelectStatementMetaData(pQuery);
        StringBuffer sb = new StringBuffer();

        SelectStatementMetaData.LocalData localData = new SelectStatementMetaData.LocalData();
        String s = getSelectQueryConstraints(pQuery, metaData, localData);
        if (s != null) {
            sb.append(s);
        }
       
        s = getSelectQueryOrderClause(metaData, pQuery);
        if (s != null) {
            sb.append(s);
        }

        return sb.toString();
    }

    public String getConstraint(Constraint pConstraint) {
        if (pConstraint instanceof CombinedConstraint) {
            CombinedConstraint cc = (CombinedConstraint) pConstraint;
            Statement st = cc.getConstrainedStatement();
            if (st instanceof SelectStatement) {
                SelectStatementMetaData selectStatementMetaData = newSelectStatementMetaData((SelectStatement) st);
                return getCombinedConstraint(selectStatementMetaData, cc);
            } else {
                return getCombinedConstraint(null, cc);
            }
        } else if (pConstraint instanceof BooleanConstraint) {
            BooleanConstraint bc = (BooleanConstraint) pConstraint;
            Statement st = bc.getConstrainedStatement();
            if (st instanceof SelectStatement) {
                SelectStatementMetaData selectStatementMetaData = newSelectStatementMetaData((SelectStatement) st);
                return getBooleanConstraint(selectStatementMetaData, bc);
            } else {
                return getBooleanConstraint(null, bc);
            }
        } else {
            throw new IllegalStateException("Invalid type of Constraint: " + pConstraint);
        }
    }
}
TOP

Related Classes of org.apache.ws.jaxme.sqls.impl.SQLGeneratorImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.