001/**
002 * Copyright 2015 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package core.tut.pori.dao.clause;
017
018import java.util.ArrayList;
019import java.util.Iterator;
020import java.util.List;
021
022/**
023 * Create and SQL sub-clause with AND prefix. WHERE AND (CLAUSE [OR] CLAUSE [OR] ...), 
024 * the inner operation ([OR]) depends on the type of the clause provided as a sub-clause.
025 * 
026 * Note: not adding any clauses will make this clause a no-op.
027 */
028public class AndSubClause extends WhereClause{
029  private List<WhereClause> _whereClauses = null;
030  private SQLType[] _types = null;
031  private Object[] _values = null;
032  private int _valueCount = 0;
033
034  /**
035   * 
036   * @param clauses
037   */
038  public AndSubClause(WhereClause[] clauses){
039    _whereClauses = new ArrayList<>(clauses.length);
040    if(clauses != null){
041      for(int i=0;i<clauses.length;++i){
042        addWhereClause(clauses[i]);
043      }
044    }
045  }
046  
047  /**
048   * 
049   */
050  public AndSubClause(){
051    _whereClauses = new ArrayList<>();
052  }
053  
054  /**
055   * 
056   * @param clause
057   */
058  public void addWhereClause(WhereClause clause){
059    Object[] values = clause.getValues();
060    if(values != null){
061      _values = null; // not valid anymore
062      _types = null;  // not valid anymore
063      _valueCount+=values.length;
064    }
065    _whereClauses.add(clause);
066  }
067
068  @Override
069  public SQLType[] getValueTypes() {
070    createArrays();
071    return _types;
072  }
073
074  @Override
075  public Object[] getValues() {
076    createArrays();
077    return _values;
078  }
079  
080  /**
081   * helper for creating (combining sub-clause) arrays if needed
082   */
083  protected void createArrays(){
084    if(_values == null && _valueCount > 0){
085      _values = new Object[_valueCount];
086      _types = new SQLType[_valueCount];
087      int index = 0;
088      for(Iterator<WhereClause> iter = _whereClauses.iterator();iter.hasNext();){
089        WhereClause clause = iter.next();
090        Object[] values = clause.getValues();
091        if(values != null){
092          SQLType[] types = clause.getValueTypes();
093          for(int i=0;i<values.length;++i){
094            _values[index] = values[i];
095            _types[index++] = types[i]; //set and increase for next addition
096          } // for values
097        } // if values
098      } // for clauses
099    } // if
100  }
101
102  @Override
103  public void toSQLString(StringBuilder sql) {
104    int size = _whereClauses.size();
105    if(size > 0){
106      sql.append('(');
107      _whereClauses.get(0).toSQLString(sql);
108      for(int i=1;i<size;++i){
109        WhereClause clause = _whereClauses.get(i);
110        sql.append(clause.getClauseType().toClauseString());
111        clause.toSQLString(sql);
112      }
113      sql.append(')');
114    }
115  }
116
117  @Override
118  public ClauseType getClauseType() {
119    return ClauseType.AND;
120  }   
121}