提供した例とまったく同じように見える内部DSL(現在のリリース)を作成する方法はありません。
この回答からまだ持っているマクロを使用すると、(比較的高速に)取得できる最も近いものは次のとおりです。
select(Min(StockPrices.Open), Max(StockPrices.Open))
.from(StockPrices)
ソリューションのreal
作成にはかなりの時間がかかります。あなたがそれを喜んでするなら、あなたはマクロを使ってかなり遠くまで来ることができます(単純なトピックではありません)。
まったく同じ構文が本当に必要な場合は、「無料」で日食ベースのエディタを使用してDSLを作成できるXTextのようなものをお勧めします。
上記の例に必要なコード(前述のマクロは含まれていません):
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