Можно ли параметризовать запросы или параметры для Acolyte ScalaCompositeHandler? - PullRequest
0 голосов
/ 09 октября 2018

Справочная информация:

Я попытался выполнить заданный здесь вопрос, но не смог добиться успеха.Acolyte требует, чтобы вы определили запросы и параметры, которые вы хотите обрабатывать в выражении соответствия, а значения, используемые в выражениях соответствия, должны быть известны во время компиляции.(Однако обратите внимание, что этот ответ StackOverflow , по-видимому, позволяет обойти это ограничение).

Если это действительно невозможно, невозможность динамически определить параметры и запросы для Acolyte приведет кбыть, для моего случая использования, серьезным ограничением структуры.Я подозреваю, что это было бы ограничением и для других.

Один пользователь SO, который выступал за использование Acolyte в горстке вопросов, указанных в этом комментарии , что возможно динамическиопределить запросы и их ответы.Итак, я открыл этот вопрос как приглашение для кого-то показать, что это так.

Вопрос :

Используя Acolyte, я хочу иметь возможность инкапсулироватьлогика сопоставления запросов и генерации их ответов.Это желаемая функция, потому что я хочу, чтобы мой код был СУХИМ.Другими словами, я ищу что-то вроде следующего псевдокода:

def generateHandler(query: String, accountId: Int, parameters: Seq[String]): ScalaCompositeHandler = AcolyteDSL.handleQuery {
  parameters.foreach(p =>
    // Tell the handler to handle this specific parameter
    case acolyte.jdbc.QueryExecution(query, ExecutedParameter(accountId) :: ExecutedParameter(p) :: Nil) =>
      someResultFunction(p)
  )
}

Возможно ли это в Аколите?Если да, приведите пример.

1 Ответ

0 голосов
/ 11 октября 2018

Действительно возможно параметризовать запросы и / или параметры, используя сопоставление с образцом.

См. Пример кода ниже:

import java.sql.DriverManager

import acolyte.jdbc._
import acolyte.jdbc.Implicits._
import org.scalatest.FunSpec

class AcolyteTest extends FunSpec {
  describe("Using pattern matching to extract a query parameter") {
    it("should extract the parameter and make it usable for dynamic result returning") {
      val query = "SELECT someresult FROM someDB WHERE id = ?"

      val rows = RowLists.rowList1(classOf[String] -> "someresult")

      val handlerName = "testOneHandler"
      val handler = AcolyteDSL.handleQuery {
        case acolyte.jdbc.QueryExecution(`query`, ExecutedParameter(id) :: _) =>
          rows.append(id.toString)
      }

      Driver.register(handlerName, handler)
      val connection = DriverManager.getConnection(s"jdbc:acolyte:anything-you-want?handler=$handlerName")
      val preparedStatement = connection.prepareStatement(query)

      preparedStatement.setString(1, "hello world")
      val resultSet = preparedStatement.executeQuery()    
      resultSet.next()    
      assertResult(resultSet.getString(1))("hello world")

    }

    it("should support a slightly more complex example") {
      val firstResult = "The first result"
      val secondResult = "The second result"

      val query = "SELECT someresult FROM someDB WHERE id = ?"

      val rows = RowLists.rowList1(classOf[String] -> "someresult")

      val results: Map[String, RowList1.Impl[String]] = Map(
        "one" -> rows.append(firstResult),
        "two" -> rows.append(secondResult)
      )

      def getResult(parameter: String): QueryResult = {
        results.get(parameter) match {
          case Some(row) => row.asResult()
          case _ => acolyte.jdbc.QueryResult.Nil
        }
      }

      val handlerName = "testTwoHandler"
      val handler = AcolyteDSL.handleQuery {
        case acolyte.jdbc.QueryExecution(`query`, ExecutedParameter(id) :: _) =>
          getResult(id.toString)
      }

      Driver.register(handlerName, handler)
      val connection = DriverManager.getConnection(s"jdbc:acolyte:anything-you-want?handler=$handlerName")
      val preparedStatement = connection.prepareStatement(query)

      preparedStatement.setString(1, "one")
      val resultSetOne = preparedStatement.executeQuery()
      resultSetOne.next()
      assertResult(resultSetOne.getString(1))(firstResult)

      preparedStatement.setString(1, "two")
      val resultSetTwo = preparedStatement.executeQuery()
      resultSetTwo.next()
      assertResult(resultSetTwo.getString(1))(secondResult)
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...