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

org.scanamo.query.QueryableKeyCondition.scala Maven / Gradle / Ivy

/*
 * Copyright 2019 Scanamo
 *
 * 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.scanamo.query

import org.scanamo.{ DynamoFormat, DynamoObject }
import org.scanamo.request.RequestCondition

trait QueryableKeyCondition[T] {
  def apply(t: T): RequestCondition
}

object QueryableKeyCondition {
  def apply[T](implicit Q: QueryableKeyCondition[T]): QueryableKeyCondition[T] = Q

  implicit def equalsKeyCondition[V: DynamoFormat]: QueryableKeyCondition[KeyEquals[V]] =
    new QueryableKeyCondition[KeyEquals[V]] {
      final def apply(t: KeyEquals[V]) =
        RequestCondition(
          s"#K = :${t.key.placeholder("")}",
          Map("#K" -> t.key.placeholder("")),
          Some(DynamoObject(t.key.placeholder("") -> t.v))
        )
    }

  implicit def hashAndRangeQueryCondition[H: DynamoFormat, R: DynamoFormat]
    : QueryableKeyCondition[AndQueryCondition[H, R]] =
    new QueryableKeyCondition[AndQueryCondition[H, R]] {
      final def apply(t: AndQueryCondition[H, R]) =
        RequestCondition(
          s"#K = :${t.hashCondition.key.placeholder("")} AND ${t.rangeCondition.keyConditionExpression("R")}",
          Map("#K" -> t.hashCondition.key.placeholder("")) ++ t.rangeCondition.key.attributeNames("#R"),
          Some(
            DynamoObject(t.hashCondition.key.placeholder("") -> t.hashCondition.v) <> DynamoObject(
              t.rangeCondition.attributes.toSeq: _*
            )
          )
        )
    }

  implicit def andEqualsKeyCondition[H: UniqueKeyCondition, R: UniqueKeyCondition](implicit
    HR: UniqueKeyCondition[AndEqualsCondition[H, R]]
  ): QueryableKeyCondition[AndEqualsCondition[H, R]] =
    new QueryableKeyCondition[AndEqualsCondition[H, R]] {
      final def apply(t: AndEqualsCondition[H, R]) = {
        val m: DynamoObject = HR.toDynamoObject(t)
        val charWithKey: Iterable[(String, String)] = m.keys.zipWithIndex map { case (k, v) =>
          (s"#${('A'.toInt + v).toChar}", k)
        }

        RequestCondition(
          charWithKey.map { case (char, key) => s"$char = :$key" }.mkString(" AND "),
          charWithKey.toMap,
          Some(m)
        )
      }
    }
}

case class Query[T](t: T)(implicit qkc: QueryableKeyCondition[T]) {
  def apply: RequestCondition = qkc.apply(t)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy