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

quasar.physical.mongodb.expression.docvar.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014–2017 SlamData Inc.
 *
 * 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 quasar.physical.mongodb.expression

import slamdata.Predef._
import quasar.jscore, jscore.JsFn
import quasar.physical.mongodb.{Bson, BsonField}

import scala.Some

import scalaz._, Scalaz._

final case class DocVar(name: DocVar.Name, deref: Option[BsonField]) {
  def path: List[BsonField.Name] = deref.toList.flatMap(_.flatten.toList)

  def isLetVar: Boolean = deref.exists(_.flatten.head.value.startsWith("$"))

  def startsWith(that: DocVar) = (this.name == that.name) && {
    (this.deref |@| that.deref)(_ startsWith (_)) getOrElse (that.deref.isEmpty)
  }

  // FIXME: This overloading is terrible, but would break many things to change,
  //        and we need to think about what is the right set of operators.
  @SuppressWarnings(Array("org.wartremover.warts.Overloading"))
  def \ (that: DocVar): Option[DocVar] = (this, that) match {
    case (DocVar(n1, f1), DocVar(n2, f2)) if (n1 == n2) =>
      val f3 = (f1 |@| f2)(_ \ _) orElse (f1) orElse (f2)

      Some(DocVar(n1, f3))

    case _ => None
  }

  def \\ (that: DocVar): DocVar = (this, that) match {
    case (DocVar(n1, f1), DocVar(_, f2)) =>
      val f3 = (f1 |@| f2)(_ \ _) orElse (f1) orElse (f2)

      DocVar(n1, f3)
  }

  def \ (field: BsonField): DocVar = copy(deref = Some(deref.map(_ \ field).getOrElse(field)))

  def toJs: JsFn = JsFn(JsFn.defaultName, this match {
    case DocVar(_, None)        => jscore.Ident(JsFn.defaultName)
    case DocVar(_, Some(deref)) => deref.toJs(jscore.Ident(JsFn.defaultName))
  })

  def bson: Bson = this match {
    case DocVar(DocVar.ROOT, Some(deref)) => Bson.Text(deref.asField)
    case DocVar(name,        deref) =>
      val root = BsonField.Name(name.name)
        Bson.Text(deref.map(root \ _).getOrElse(root).asVar)
  }
}

object DocVar {
  final case class Name(name: String) {
    def apply() = DocVar(this, None)

    def apply(field: BsonField) = DocVar(this, Some(field))

    def apply(leaves: List[BsonField.Name]) = DocVar(this, BsonField(leaves))

    def apply(deref: Option[BsonField]) = DocVar(this, deref)
    def unapply(v: DocVar): Some[Option[BsonField]] = Some(v.deref)
  }

  object Name {
    implicit val equal: Equal[Name] = Equal.equalA

    implicit val show: Show[Name] = Show.showFromToString
  }

  val ROOT    = Name("ROOT")
  val CURRENT = Name("CURRENT")

  implicit val equal: Equal[DocVar] = Equal.equalA

  implicit val show: Show[DocVar] = Show.shows {
    case DocVar(DocVar.ROOT, None) => "DocVar.ROOT()"
    case DocVar(DocVar.ROOT, Some(deref)) => s"DocField(${deref.shows})"
    case dv => s"DocVar(${dv.name.shows}, ${dv.deref.shows})"
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy