沒有辦法讓內部DSL(當前版本)與您提供的示例完全相同。
使用宏我仍然this answer過,最接近我能得到(相對較快)是:
select(Min(StockPrices.Open), Max(StockPrices.Open))
.from(StockPrices)
一個real
解決方案將需要相當長的時間來創建。如果你願意這樣做,你可以使用宏的(不是一個簡單的主題)很遠。
如果你真的想要完全相同的語法,我推薦像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看起來如何? 「Open,Close」和「Open.Close」是什麼意思? 「打開」是「StockPrices」的屬性? – EECOLOR 2013-03-26 20:29:56
對不起,這是一個錯字,我已經修復了我原來的帖子。我將把這個查詢翻譯成我們專有的腳本語言。不過,我根據你的代碼示例得到了這個想法,並開始閱讀關於宏的內容,讓我看看我從這裏走多遠。 – GammaVega 2013-03-28 18:00:49