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

molecule.datalog.datomic.transaction.DatomicBase_JVM.scala Maven / Gradle / Ivy

There is a newer version: 0.12.1
Show newest version
package molecule.datalog.datomic.transaction

import java.lang.{Boolean => jBoolean}
import java.util.{UUID, ArrayList => jArrayList, List => jList}
import clojure.lang.Keyword
import molecule.base.error.ExecutionError
import molecule.boilerplate.ast.Model._
import molecule.core.marshalling.{ConnProxy, DatomicProxy}
import molecule.core.util.Executor._
import molecule.core.util.{ModelUtils, fns}
import molecule.datalog.datomic.facade.{DatomicConn_JVM, DatomicPeer}
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.concurrent.Future

trait DatomicBase_JVM extends DatomicDataType_JVM with ModelUtils {

  protected def initTxBase(elements: List[Element], idIndex: Int = 0): Unit = {
    nsFull = getInitialNs(elements)
    part = fns.partNs(nsFull).head
    lowest = idIndex
  }

  // Accumulate java insertion data
  final protected val stmts: jArrayList[jList[AnyRef]] = new jArrayList[jList[AnyRef]]()

  protected var nsFull: String = ""
  protected var part  : String = ""
  protected var tempId: Int    = 0
  protected var lowest: Int    = 0
  protected var e     : AnyRef = "" // Long or String (#db/id[db.part/user -1])
  protected var e0    : AnyRef = ""

  protected var ids            = Seq.empty[AnyRef]
  protected var filterElements = List.empty[Element]
  protected var data           = List.empty[(String, String, String, Seq[AnyRef], Boolean)]

  protected var stmt        : jList[AnyRef]       = null
  protected var backRefs    : Map[String, AnyRef] = Map.empty[String, AnyRef]
  protected val usedRefIds  : ListBuffer[AnyRef]  = new ListBuffer[AnyRef]
  protected val unusedRefIds: ListBuffer[AnyRef]  = new ListBuffer[AnyRef]

  protected lazy val add           = kw("db", "add")
  protected lazy val retract       = kw("db", "retract")
  protected lazy val retractEntity = kw("db", "retractEntity")
  protected lazy val dbId          = kw("db", "id")

  protected lazy val bigInt2java  = (v: Any) => v.asInstanceOf[BigInt].bigInteger
  protected lazy val bigDec2java  = (v: Any) => v.asInstanceOf[BigDecimal].bigDecimal
  protected lazy val char2java    = (v: Any) => v.toString
  protected lazy val byte2java    = (v: Any) => v.asInstanceOf[Byte].toInt
  protected lazy val short2java   = (v: Any) => v.asInstanceOf[Short].toInt
  protected lazy val boolean2java = (v: Any) => v.asInstanceOf[Boolean].asInstanceOf[jBoolean]


  protected def newId: String = {
    tempId = lowest - 1
    lowest = tempId
    "#db/id[" + part + " " + tempId + "]"
  }
  protected def kw(ns: String, attr: String) = Keyword.intern(ns, attr)

  protected def stmtList = new jArrayList[AnyRef](4)
  protected def appendStmt(
    op: Keyword,
    e: AnyRef,
    a: Keyword,
    v: AnyRef,
  ): Unit = {
    val addStmt = stmtList
    addStmt.add(op)
    addStmt.add(e)
    addStmt.add(a)
    addStmt.add(v)
    stmts.add(addStmt)
  }
  protected def addRetractEntityStmt(id: AnyRef) = {
    val stmt = new jArrayList[AnyRef](2)
    stmt.add(retractEntity)
    stmt.add(id)
    stmts.add(stmt)
  }


  // Connection pool ---------------------------------------------

  // todo: real solution
  private val connectionPool = mutable.HashMap.empty[UUID, Future[DatomicConn_JVM]]

  //  override def clearConnPool: Future[Unit] = Future {
  //    // logger.debug(s"Connection pool with ${connectionPool.size} connections cleared.")
  //    connectionPool.clear()
  //  }

  protected def getConn(proxy: ConnProxy): Future[DatomicConn_JVM] = {
    val futConn             = connectionPool.getOrElse(proxy.uuid, getFreshConn(proxy))
    val futConnTimeAdjusted = futConn.map { conn =>
      //      conn.updateAdhocDbView(proxy.adhocDbView)
      //      conn.updateTestDbView(proxy.testDbView, proxy.testDbStatus)
      conn
    }
    connectionPool(proxy.uuid) = futConnTimeAdjusted
    // logger.debug("connectionPool.size: " + connectionPool.size)
    futConnTimeAdjusted
  }

  private def getFreshConn(proxy: ConnProxy): Future[DatomicConn_JVM] = {
    proxy match {
      case proxy@DatomicProxy(protocol, dbIdentifier, _, _, _, _, _, _, _, _, _, _) =>
        protocol match {
          case "mem" =>
            DatomicPeer.recreateDb(proxy, protocol, dbIdentifier)
              .recover {
                case exc: Throwable => throw ExecutionError(exc.getMessage)
              }

          case "free" | "dev" | "pro" =>
            Future(DatomicPeer.connect(proxy, protocol, dbIdentifier))
              .recover {
                case exc: Throwable => throw ExecutionError(exc.getMessage)
              }

          case other => Future.failed(
            ExecutionError(s"\nCan't serve Peer protocol `$other`.")
          )
        }

      case _ => ???
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy