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

com.stratio.cassandra.lucene.column.Column.scala Maven / Gradle / Ivy

There is a newer version: 3.11.3.0
Show newest version
/*
 * Copyright (C) 2014 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.cassandra.lucene.column

import java.nio.ByteBuffer
import java.util.Date
import java.util.regex.Pattern

import com.google.common.base.MoreObjects
import com.stratio.cassandra.lucene.IndexException
import com.stratio.cassandra.lucene.column.Column._
import org.apache.cassandra.db.marshal.{AbstractType, SimpleDateType}
import org.apache.commons.lang3.StringUtils
import org.apache.commons.lang3.StringUtils.EMPTY

/** A cell of a CQL3 logic column, which in most cases is different from a storage engine column.
  *
  * @param cell the name of the base cell
  * @param udt the UDT suffix
  * @param map the map suffix
  * @param value    the optional value
  * @author Andres de la Pena `[email protected]`
  */
case class Column(cell: String,
    udt: String = EMPTY,
    map: String = EMPTY,
    value: Option[_] = None) {

  if (StringUtils.isBlank(cell)) throw new IndexException("Cell name shouldn't be blank")

  /** The columns mapper name, composed by cell name and UDT names, without map names. */
  lazy val mapper: String = cell.concat(udt)

  /** The columns field name, composed by cell name, UDT names and map names. */
  lazy val field: String = mapper.concat(map)

  /** Returns `true` if the value is not defined, `false` otherwise. */
  def isEmpty: Boolean = value.isEmpty

  /** Returns the value, or null if it is not defined. */
  def valueOrNull: Any = value.orNull

  /** Returns a copy of this with the specified name appended to the list of UDT names. */
  def withUDTName(name: String): Column = copy(udt = udt + UDT_SEPARATOR + name)

  /** Returns a copy of this with the specified name appended to the list of map names. */
  def withMapName(name: String): Column = copy(map = map + MAP_SEPARATOR + name)

  /** Returns a copy of this with the specified value. */
  def withValue[B](value: B): Column = copy(value = Option(value))

  /** Returns a copy of this with the specified decomposed value. */
  def withValue(bb: ByteBuffer, t: AbstractType[_]): Column = withValue(compose(bb, t))

  /** Returns the name for fields. */
  def fieldName(field: String): String = field.concat(map)

  /** Returns a [[Columns]] composed by this and the specified column. */
  def +(column: Column): Columns = Columns(this, column)

  /** Returns a [[Columns]] composed by this and the specified columns. */
  def +(columns: Columns): Columns = this :: columns

  /** @inheritdoc */
  override def toString: String =
    MoreObjects.toStringHelper(this)
      .add("cell", cell)
      .add("field", field)
      .add("value", value)
      .toString
}

/** Companion object for [[Column]]. */
object Column {

  /** The name suffix for CQL map keys. */
  val MAP_KEY_SUFFIX: String = "_key"

  /** The name suffix for CQL map values. */
  val MAP_VALUE_SUFFIX: String = "_value"

  private val UDT_SEPARATOR = "."
  private val MAP_SEPARATOR = "$"

  private[this] val UDT_PATTERN = Pattern.quote(UDT_SEPARATOR)

  def apply(cell: String): Column = new Column(cell = cell)

  def parseCellName(name: String): String = {
    val udtSuffixStart = name.indexOf(UDT_SEPARATOR)
    if (udtSuffixStart < 0) {
      val mapSuffixStart = name.indexOf(MAP_SEPARATOR)
      if (mapSuffixStart < 0) name else name.substring(0, mapSuffixStart)
    } else name.substring(0, udtSuffixStart)
  }

  def parseMapperName(name: String): String = {
    val mapSuffixStart = name.indexOf(MAP_SEPARATOR)
    if (mapSuffixStart < 0) name else name.substring(0, mapSuffixStart)
  }

  def parseUdtNames(name: String): List[String] = {
    val udtSuffixStart = name.indexOf(UDT_SEPARATOR)
    if (udtSuffixStart < 0) Nil else {
      val mapSuffixStart = name.indexOf(MAP_SEPARATOR)
      val udtSuffix = if (mapSuffixStart < 0) {
        name.substring(udtSuffixStart + 1)
      } else {
        name.substring(udtSuffixStart + 1, mapSuffixStart)
      }
      udtSuffix.split(UDT_PATTERN).toList
    }
  }

  def compose(bb: ByteBuffer, t: AbstractType[_]): Any = t match {
    case sdt: SimpleDateType => new Date(sdt.toTimeInMillis(bb))
    case _ => t.compose(bb)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy