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

com.stratio.crossdata.driver.querybuilder.RunnableQuery.scala Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2015 Stratio (http://stratio.com)
 *
 * 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 com.stratio.crossdata.driver.querybuilder

import com.stratio.crossdata.driver.querybuilder.dslentities.{And, CombinationInfo, SortCriteria, XDQLStatement}

object RunnableQuery {

  implicit class RunnableQueryAsExpression(runnableQuery: RunnableQuery) extends Expression {
    override private[querybuilder] def toXDQL: String = s"( ${runnableQuery.toXDQL})"
  }

  implicit class RunnableQueryAsRelation(runnableQuery: RunnableQuery) extends Relation {
    override private[querybuilder] def toXDQL: String = s"( ${runnableQuery.toXDQL})"
  }

}

abstract class RunnableQuery protected(protected val context: String => String,
                                       protected val projections: Seq[Expression],
                                       protected val relation: Relation,
                                       protected val filters: Option[Predicate] = None,
                                       protected val groupingExpressions: Seq[Expression] = Seq.empty,
                                       protected val havingExpressions: Option[Predicate] = None,
                                       protected val ordering: Option[SortCriteria] = None,
                                       protected val limit: Option[Int] = None,
                                       protected val composition: Option[CombinationInfo] = None
                                        ) extends Combinable {

  def where(condition: String): this.type = where(XDQLStatement(condition))

  // It has to be abstract (simple runnable query has transitions) and concrete
  // implementations (grouped, limited, sorted...) should return their own type
  def where(condition: Predicate): this.type

  protected def combinePredicates(newCondition: Predicate): Predicate =
    filters.map(And(_, newCondition)).getOrElse(newCondition)

  override private[querybuilder] def toXDQL: String = {
    def stringfy[T](head: String, elements: Seq[T], element2str: T => String): String =
      elements.headOption.fold("")(_ => s"$head ${elements.map(element2str) mkString ", "}")

    def stringfyXDQL(head: String, elements: Seq[CrossdataSQLStatement]) =
      stringfy[CrossdataSQLStatement](head, elements, _.toXDQL)

    //Intentionally this way spaced
    context {
      s"""
         |SELECT ${projections map (_.toXDQL) mkString ", "}
         | FROM ${relation.toXDQL}
         | ${stringfyXDQL(" WHERE", filters.toSeq)}
         |${stringfyXDQL(" GROUP BY", groupingExpressions)}
         |${stringfyXDQL(" HAVING", havingExpressions.toSeq)}
         |${stringfyXDQL("", ordering.toSeq)}
         |${stringfy[Int](" LIMIT", limit.toSeq, _.toString)}
         |${composition.fold("")(_.toXDQL)}
     """.stripMargin.replace(System.lineSeparator(), "")
    }
  }

  def build: String = toXDQL

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy