gpt4 book ai didi

sql - Scala SQL DSL(内部/外部)

转载 作者:行者123 更新时间:2023-12-02 05:09:58 24 4
gpt4 key购买 nike

我一直在研究 scala,主要是关于如何构建类似于 C# LINQ/SQL 的 DSL。使用 C# LINQ 查询提供程序后,很容易引入我们自己的自定义查询提供程序,它将 LINQ 查询转换为我们自己的专有数据存储脚本。我在 scala 中寻找类似的东西,例如。

 val query = select Min(Close), Max(Close)
from StockPrices
where open > 0

首先,这甚至有可能使用内部 DSL 在 Scala 中实现。

在这方面的任何想法/想法都非常感谢。

我在 Scala 领域还是个新手,但开始研究 Scala MetaProgramming & Slick。我对 Slick 的提示是我想让我的 DSL 接近 SQL 查询——类似于上面的语法。

最佳答案

没有办法拥有与您提供的示例完全一样的内部 DSL(当前版本)。

使用我仍然拥有的宏 this answer ,我能得到的最接近(相对较快)的是:

select(Min(StockPrices.Open), Max(StockPrices.Open))
.from(StockPrices)

真正的 解决方案需要相当长的时间来创建。如果您愿意这样做,您可以使用宏(不是一个简单的主题)走得很远。

如果你真的想要完全相同的语法,我推荐类似 XText 的语法允许您使用基于 Eclipse 的编辑器“免费”创建 DSL。

上述示例所需的代码(我没有包含提到的宏):

trait SqlElement {
def toString(): String
}

trait SqlMethod extends SqlElement {
protected val methodName: String
protected val arguments: Seq[String]

override def toString() = {
val argumentsString = arguments mkString ","
s"$methodName($argumentsString)"
}
}

case class Select(elements: Seq[SqlElement]) extends SqlElement {
override def toString() = s"SELECT ${elements mkString ", "}"
}

case class From(table: Metadata) extends SqlElement {
private val tableName = table.name
override def toString() = s"FROM $tableName"
}
case class Min(element: Metadata) extends SqlMethod {
val methodName = "Min"
val arguments = Seq(element.name)
}
case class Max(element: Metadata) extends SqlMethod {
val methodName = "Max"
val arguments = Seq(element.name)
}

class QueryBuilder(elements: Seq[SqlElement]) {
def this(element: SqlElement) = this(Seq(element))

def from(o: Metadata) = new QueryBuilder(elements :+ From(o))
def where(element: SqlElement) = new QueryBuilder(elements :+ element)
override def toString() = elements mkString ("\n")
}

def select(args: SqlElement*) = new QueryBuilder(Select(args))

trait Column
object Column extends Column

object tables {

object StockPrices$ {
val Open: Column = Column
val Close: Column = Column
}
val StockPrices = StockPrices$
}

然后使用它:

import tables._
import StockPrices._

select(Min(StockPrices.Open), Max(StockPrices.Open))
.from(StockPrices)
.toString

关于sql - Scala SQL DSL(内部/外部),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15643796/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com