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

render.Prefix.scala Maven / Gradle / Ivy

The newest version!
/*
* Copyright 2021 Kári Magnússon
*
* 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 kuzminki.render

import kuzminki.api.{Model, Join, KuzminkiError}
import kuzminki.column.ColInfo


sealed trait Prefix {
  val prefixWrap = "\"%s\".\"%s\""
  val tableWrap = "\"%s\" \"%s\""
  def pick(info: ColInfo): String
  def table(table: String): String
  def forSubquery(prefix: Prefix): Prefix
  def next(char: String) = {
    val az = Prefix.az
    az(az.indexOf(char) + 1)
  }
  def next2(char: String) = {
    val az = Prefix.az
    az(az.indexOf(char) + 2)
  }
}

object Prefix {

  def az = Vector("a", "b", "c", "d",
                  "e", "f", "g", "h",
                  "i", "k", "l", "m",
                  "n", "o", "p", "q",
                  "r", "s", "t", "v",
                  "x", "y", "z")

  def forModel[M <: Model](model: M) =
    new ModelPrefix(model.__name)

  def forJoin[A <: Model, B <: Model](join: Join[A, B]): Prefix =
    new JoinPrefix(join.a.__name, join.b.__name, "a", "b")
}

case class ModelPrefix(table: String) extends Prefix with Wrap {
  
  def pick(info: ColInfo) = wrap(info.name)
  def table(table: String) = wrap(table)
  
  def forSubquery(prefix: Prefix) = prefix match {
    case ModelPrefix(_)             => new SubqueryPrefix(table, "a")
    case SubqueryPrefix(_, last)    => new SubqueryPrefix(table, next(last))
    case JoinPrefix(_, _, _, last)  => new SubqueryPrefix(table, next(last))
  }
}

case class SubqueryPrefix(table: String, c: String) extends Prefix {
  
  def pick(info: ColInfo) = prefixWrap.format(c, info.name)
  def table(table: String) = tableWrap.format(table, c)
  
  def forSubquery(prefix: Prefix) = prefix match {
    case ModelPrefix(_)             => new SubqueryPrefix(table, next(c))
    case SubqueryPrefix(_, last)    => new SubqueryPrefix(table, next(last))
    case JoinPrefix(_, _, _, last)  => new SubqueryPrefix(table, next(last))
  }
}

case class JoinPrefix(tableA: String, tableB: String, a: String, b: String) extends Prefix {

  def pick(info: ColInfo) = info match {
      
    case ColInfo(name, table) if info.table == tableA =>
      prefixWrap.format(a, name)
    
    case ColInfo(name, table) if info.table == tableB =>
      prefixWrap.format(b, name)
    
    case ColInfo(name, table) =>
      throw KuzminkiError(
        s"column $name of table $table is not found in join($tableA, $tableB)"
      )
  }

  def table(table: String) = table match {
    
    case table if table == tableA =>
      tableWrap.format(table, a)
    
    case table if table == tableB =>
      tableWrap.format(table, b)
    
    case table =>
      throw KuzminkiError(
        s"table $table is not a member of join($tableA, $tableB)"
      )
  }

  def forSubquery(prefix: Prefix) = {
    val (na, nb) = prefix match {
      case ModelPrefix(_)           => (a, b)
      case SubqueryPrefix(_, last)  => (next(last), next2(last))
      case JoinPrefix(_, _, la, lb) => (next2(la), next2(lb))
    }
    JoinPrefix(tableA, tableB, na, nb)
  }
}




















© 2015 - 2024 Weber Informatics LLC | Privacy Policy