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

jp.co.bizreach.dynamodb4s.DynamoScanBuilder.scala Maven / Gradle / Ivy

There is a newer version: 0.0.9
Show newest version
package jp.co.bizreach.dynamodb4s

import com.amazonaws.services.dynamodbv2.model.{AttributeValue, ScanRequest, Select}
import jp.co.bizreach.dynamodb4s.DynamoTable._
import scala.collection.JavaConverters._
import scala.reflect.ClassTag

case class DynamoScanBuilder[T <: DynamoTable](
  private val _table: T,
  private val _attributes: T => Seq[DynamoProperty[_]],
  private val _filterExpression: Option[String] = None,
  private val _valueMap: Map[String, Any] = Map.empty,
  private val _limit: Int = 1000){

  def select(f: T => Seq[DynamoProperty[_]]): DynamoScanBuilder[T] = this.copy(_attributes = t => (_attributes(t) ++ f(t)))

  def limit(i: Int): DynamoScanBuilder[T] = this.copy(_limit = i)

  def filter(expression: String, values: (String, Any)*): DynamoScanBuilder[T] =
    this.copy(_filterExpression = Some(expression), _valueMap = _valueMap ++ values)

  def foreach[E](mapper: (T, DynamoRow) => E)(implicit db: awscala.dynamodbv2.DynamoDB): Unit = {
    var lastKeyEvaluated: java.util.Map[String, AttributeValue] = null

    do {
      val result = db.scan(createRequest(_attributes(_table).map(_.name), lastKeyEvaluated))
      val items  = result.getItems
      items.asScala.foreach { item =>
        mapper(_table, new DynamoRow(item))
      }

      lastKeyEvaluated = result.getLastEvaluatedKey

    } while(lastKeyEvaluated != null)
  }

  def as[E <: AnyRef](f: E => Unit)(implicit db: awscala.dynamodbv2.DynamoDB, c: ClassTag[E]): Unit = {
    var lastKeyEvaluated: java.util.Map[String, AttributeValue] = null

    do {
      val result = db.scan(createRequest(c.runtimeClass.getDeclaredFields.map(_.getName), lastKeyEvaluated))
      val items  = result.getItems
      val tableInfo = getTableInfo(_table)
      val clazz  = c.runtimeClass
      val fields = clazz.getDeclaredFields

      items.asScala.map { x =>
        val c = clazz.getConstructors()(0)
        val args = c.getParameterTypes.map { x =>
          if(x == classOf[Int]) new Integer(0) else null
        }
        val o = c.newInstance(args: _*)
        fields.foreach { f =>
          f.setAccessible(true)
          val t = f.getType
          val attribute = x.get(f.getName)
          val property = tableInfo.getDynamoProperty(f.getName)
          if(t == classOf[Option[_]]){
            f.set(o, Option(getAttributeValue(attribute)).map(property.convert))
          } else {
            f.set(o, property.convert(getAttributeValue(attribute)))
          }
        }
        f(o.asInstanceOf[E])
      }

      lastKeyEvaluated = result.getLastEvaluatedKey

    } while(lastKeyEvaluated != null)
  }

  protected def createRequest(attributes: Seq[String], lastKeyEvaluated: java.util.Map[String, AttributeValue]): ScanRequest = {
    val req = new ScanRequest()
      .withTableName(_table.table)
      .withLimit(_limit)
      .withExclusiveStartKey(lastKeyEvaluated)

    _filterExpression match {
      case Some(expression) => {
        req.withFilterExpression(expression)
        if(_valueMap.nonEmpty){
          val valueMap = new java.util.HashMap[String, AttributeValue]()
          _valueMap.foreach { case (key, value) =>
            val attributeValue = new AttributeValue()
            value match {
              case x: String => attributeValue.setS(x)
              case x: Int => attributeValue.setN(x.toString)
            }
            valueMap.put(if(key.startsWith(":")) key else ":" + key, attributeValue)
          }
          req.withExpressionAttributeValues(valueMap)
        }
      }
      case None => {
        req.withSelect(Select.SPECIFIC_ATTRIBUTES)
        req.withAttributesToGet(attributes: _*)
      }
    }


    req
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy