All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.squeryl.dsl.ast.QueryExpressionNode.scala Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright 2010 Maxime Lévesque
 * 
 * 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.squeryl.dsl.ast

import org.squeryl.internals._
import org.squeryl.dsl.{QueryYield, AbstractQuery}
import scala.collection.mutable.ListBuffer

class QueryExpressionNode[R](_query: AbstractQuery[R],
                             _queryYield:QueryYield[R],
                             val subQueries: Iterable[QueryableExpressionNode],
                             val views: Iterable[ViewExpressionNode[_]])
  extends QueryExpressionElements
    with QueryableExpressionNode {

  def tableExpressions: Iterable[QueryableExpressionNode] = 
    List(views.filter(v => ! v.inhibited),
         subQueries.filter(v => ! v.inhibited)).flatten

  def isJoinForm = _queryYield.joinExpressions != Nil

  val (whereClause, havingClause, groupByClause, orderByClause) =
     _queryYield.queryElements

  private var _selectList: Iterable[SelectElement] = Iterable.empty

  private var _sample: Option[AnyRef] = None

  private def _isPrimitiveType(o: AnyRef) =
    FieldMetaData._isSupportedFieldType.handleType(o.getClass, None)

  def isUseableAsSubquery: Boolean =
    _sample match {
      case None => org.squeryl.internals.Utils.throwError("method cannot be called before initialization")
      case Some(p:Product) =>
        if(p.getClass.getName.startsWith("scala.Tuple")) {
          val z = (for(i <- 0 to (p.productArity - 1)) yield p.productElement(i))
          ! z.exists(o => _isPrimitiveType(o.asInstanceOf[AnyRef]))
        }
        else
          true
      case Some(a:AnyRef) => ! _isPrimitiveType(a)
    }


  def sample:AnyRef = _sample.get

  def owns(aSample: AnyRef) = 
    _sample != None && _sample.get.eq(aSample)
  
  def getOrCreateSelectElement(fmd: FieldMetaData, forScope: QueryExpressionElements) = org.squeryl.internals.Utils.throwError("implement me")

  override def toString = {
    val sb = new StringBuffer
    sb.append('QueryExpressionNode + "[")
    if(_query.isRoot)
      sb.append("root:")
    sb.append(id)
    sb.append("]")
    sb.append(":rsm="+_query.resultSetMapper)
    sb.toString
  }

  override def children = {
    val lb = ListBuffer[ExpressionNode]();
    lb ++= selectList
    lb ++= views
    lb ++= subQueries
    lb ++= tableExpressions.filter(e=> e.joinExpression != None).map(_.joinExpression.get)  
    lb ++= whereClause
    lb ++= groupByClause
    lb ++= havingClause
    lb ++= orderByClause      
    lb.toList
  }

  def isChild(q: QueryableExpressionNode):Boolean =
    views.find(n => n == q) != None

  def selectDistinct = _query.selectDistinct

  def isForUpdate = _query.isForUpdate

  def page = _query.page

  def alias = "q" + uniqueId.get

  def getOrCreateAllSelectElements(forScope: QueryExpressionElements): Iterable[SelectElement] = {
    _selectList.map(se => new ExportedSelectElement(se))
  }

  def setOutExpressionNodesAndSample(sl: Iterable[SelectElement], s: AnyRef) = {
    _selectList = sl
    _sample = Some(s)

    if(_query.isRoot) {

      var jdbcIndex = 1
      for(oen <- selectList) {
        oen.prepareMapper(jdbcIndex)
        jdbcIndex += 1
      }

      var idGen = 0
      visitDescendants((node,parent,i) => {
        node.parent = parent

        if(node.isInstanceOf[UniqueIdInAliaseRequired]) {
          val nxn = node.asInstanceOf[UniqueIdInAliaseRequired]
          nxn.uniqueId = Some(idGen)
          idGen += 1
        }
      })
    }
  }

  def selectList: Iterable[SelectElement] = _selectList

  def doWrite(sw: StatementWriter) = {
    val isNotRoot = parent != None

    if(isNotRoot) {
      sw.write("(")
      sw.indent(1)
    }
    sw.databaseAdapter.writeQuery(this, sw)
    if(isNotRoot) {
      sw.unindent(1)
      sw.write(") ")
    }
  }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy