save
This commit is contained in:
parent
1878d59821
commit
2d30969ec5
5 changed files with 68 additions and 70 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
|||
target/
|
||||
.bsp/
|
||||
.metals/
|
||||
.bloop/
|
||||
project/metals.sbt
|
|
@ -1 +1 @@
|
|||
sbt.version=1.10.2
|
||||
sbt.version=1.10.5
|
||||
|
|
8
project/project/metals.sbt
Normal file
8
project/project/metals.sbt
Normal file
|
@ -0,0 +1,8 @@
|
|||
// format: off
|
||||
// DO NOT EDIT! This file is auto-generated.
|
||||
|
||||
// This file enables sbt-bloop to create bloop config files.
|
||||
|
||||
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.6.0")
|
||||
|
||||
// format: on
|
|
@ -81,16 +81,16 @@ case class ConcatMap(query: Ast, alias: Ident, body: Ast) extends Query
|
|||
case class SortBy(query: Ast, alias: Ident, criterias: Ast, ordering: Ordering)
|
||||
extends Query
|
||||
|
||||
sealed trait Ordering extends Ast
|
||||
sealed trait Ordering extends Ast
|
||||
case class TupleOrdering(elems: List[Ordering]) extends Ordering
|
||||
|
||||
sealed trait PropertyOrdering extends Ordering
|
||||
case object Asc extends PropertyOrdering
|
||||
case object Desc extends PropertyOrdering
|
||||
case object AscNullsFirst extends PropertyOrdering
|
||||
case object DescNullsFirst extends PropertyOrdering
|
||||
case object AscNullsLast extends PropertyOrdering
|
||||
case object DescNullsLast extends PropertyOrdering
|
||||
case object Asc extends PropertyOrdering
|
||||
case object Desc extends PropertyOrdering
|
||||
case object AscNullsFirst extends PropertyOrdering
|
||||
case object DescNullsFirst extends PropertyOrdering
|
||||
case object AscNullsLast extends PropertyOrdering
|
||||
case object DescNullsLast extends PropertyOrdering
|
||||
|
||||
case class GroupBy(query: Ast, alias: Ident, body: Ast) extends Query
|
||||
|
||||
|
@ -154,7 +154,7 @@ case class Ident(name: String, visibility: Visibility) extends Ast {
|
|||
*/
|
||||
object Ident {
|
||||
def apply(name: String): Ident = Ident(name, Visibility.neutral)
|
||||
def unapply(p: Ident) = Some((p.name))
|
||||
def unapply(p: Ident) = Some((p.name))
|
||||
|
||||
object Opinionated {
|
||||
def apply(name: String, visibilityNew: Visibility): Ident =
|
||||
|
@ -188,7 +188,7 @@ sealed trait OpinionValues[T <: Opinion[T]] {
|
|||
sealed trait Visibility extends Opinion[Visibility]
|
||||
object Visibility extends OpinionValues[Visibility] {
|
||||
case object Visible extends Visibility with Opinion[Visibility]
|
||||
case object Hidden extends Visibility with Opinion[Visibility]
|
||||
case object Hidden extends Visibility with Opinion[Visibility]
|
||||
|
||||
inline override def neutral: Visibility = Visible
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ sealed trait Renameable extends Opinion[Renameable] {
|
|||
}
|
||||
}
|
||||
object Renameable extends OpinionValues[Renameable] {
|
||||
case object Fixed extends Renameable with Opinion[Renameable]
|
||||
case object Fixed extends Renameable with Opinion[Renameable]
|
||||
case object ByStrategy extends Renameable with Opinion[Renameable]
|
||||
|
||||
inline override def neutral: Renameable = ByStrategy
|
||||
|
@ -248,8 +248,8 @@ object Property {
|
|||
}
|
||||
}
|
||||
|
||||
sealed trait OptionOperation extends Ast
|
||||
case class OptionFlatten(ast: Ast) extends OptionOperation
|
||||
sealed trait OptionOperation extends Ast
|
||||
case class OptionFlatten(ast: Ast) extends OptionOperation
|
||||
case class OptionGetOrElse(ast: Ast, body: Ast) extends OptionOperation
|
||||
case class OptionFlatMap(ast: Ast, alias: Ident, body: Ast)
|
||||
extends OptionOperation
|
||||
|
@ -259,9 +259,9 @@ case class OptionForall(ast: Ast, alias: Ident, body: Ast)
|
|||
case class OptionExists(ast: Ast, alias: Ident, body: Ast)
|
||||
extends OptionOperation
|
||||
case class OptionContains(ast: Ast, body: Ast) extends OptionOperation
|
||||
case class OptionIsEmpty(ast: Ast) extends OptionOperation
|
||||
case class OptionNonEmpty(ast: Ast) extends OptionOperation
|
||||
case class OptionIsDefined(ast: Ast) extends OptionOperation
|
||||
case class OptionIsEmpty(ast: Ast) extends OptionOperation
|
||||
case class OptionNonEmpty(ast: Ast) extends OptionOperation
|
||||
case class OptionIsDefined(ast: Ast) extends OptionOperation
|
||||
case class OptionTableFlatMap(ast: Ast, alias: Ident, body: Ast)
|
||||
extends OptionOperation
|
||||
case class OptionTableMap(ast: Ast, alias: Ident, body: Ast)
|
||||
|
@ -270,15 +270,15 @@ case class OptionTableExists(ast: Ast, alias: Ident, body: Ast)
|
|||
extends OptionOperation
|
||||
case class OptionTableForall(ast: Ast, alias: Ident, body: Ast)
|
||||
extends OptionOperation
|
||||
object OptionNone extends OptionOperation
|
||||
case class OptionSome(ast: Ast) extends OptionOperation
|
||||
case class OptionApply(ast: Ast) extends OptionOperation
|
||||
case class OptionOrNull(ast: Ast) extends OptionOperation
|
||||
object OptionNone extends OptionOperation
|
||||
case class OptionSome(ast: Ast) extends OptionOperation
|
||||
case class OptionApply(ast: Ast) extends OptionOperation
|
||||
case class OptionOrNull(ast: Ast) extends OptionOperation
|
||||
case class OptionGetOrNull(ast: Ast) extends OptionOperation
|
||||
|
||||
sealed trait IterableOperation extends Ast
|
||||
case class MapContains(ast: Ast, body: Ast) extends IterableOperation
|
||||
case class SetContains(ast: Ast, body: Ast) extends IterableOperation
|
||||
sealed trait IterableOperation extends Ast
|
||||
case class MapContains(ast: Ast, body: Ast) extends IterableOperation
|
||||
case class SetContains(ast: Ast, body: Ast) extends IterableOperation
|
||||
case class ListContains(ast: Ast, body: Ast) extends IterableOperation
|
||||
|
||||
case class If(condition: Ast, `then`: Ast, `else`: Ast) extends Ast
|
||||
|
@ -318,7 +318,7 @@ sealed trait Action extends Ast
|
|||
|
||||
case class Update(query: Ast, assignments: List[Assignment]) extends Action
|
||||
case class Insert(query: Ast, assignments: List[Assignment]) extends Action
|
||||
case class Delete(query: Ast) extends Action
|
||||
case class Delete(query: Ast) extends Action
|
||||
|
||||
sealed trait ReturningAction extends Action {
|
||||
def action: Ast
|
||||
|
@ -358,11 +358,11 @@ object OnConflict {
|
|||
}
|
||||
|
||||
sealed trait Target
|
||||
case object NoTarget extends Target
|
||||
case object NoTarget extends Target
|
||||
case class Properties(props: List[Property]) extends Target
|
||||
|
||||
sealed trait Action
|
||||
case object Ignore extends Action
|
||||
case object Ignore extends Action
|
||||
case class Update(assignments: List[Assignment]) extends Action
|
||||
}
|
||||
//************************************************************
|
||||
|
@ -386,34 +386,15 @@ sealed trait ScalarLift extends Lift
|
|||
case class ScalarValueLift(
|
||||
name: String,
|
||||
liftId: String
|
||||
) extends ScalarLift {
|
||||
|
||||
def expandedLiftId: Option[(String, Int)] = {
|
||||
val idxStart = liftId.indexOf('[')
|
||||
val idxEnd = liftId.indexOf(']')
|
||||
if (idxStart != -1 && idxEnd != -1) {
|
||||
val idx = liftId.substring(idxStart + 1, idxEnd).toIntOption
|
||||
idx.map(i => liftId.substring(0, idxStart) -> i)
|
||||
} else None
|
||||
}
|
||||
}
|
||||
|
||||
case class ScalarQueryLift(name: String, liftId: String) extends ScalarLift {
|
||||
def at(idx: Int): ScalarValueLift =
|
||||
ScalarValueLift(s"${name}[$idx]", s"${liftId}[${idx}]")
|
||||
}
|
||||
) extends ScalarLift
|
||||
|
||||
object ScalarLift {
|
||||
given ToExpr[ScalarLift] with {
|
||||
def apply(l: ScalarLift)(using Quotes) = l match {
|
||||
case ScalarValueLift(n, id) =>
|
||||
'{ ScalarValueLift(${ Expr(n) }, ${ Expr(id) }) }
|
||||
case ScalarQueryLift(n, id) =>
|
||||
'{ ScalarQueryLift(${ Expr(n) }, ${ Expr(id) }) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed trait CaseClassLift extends Lift
|
||||
case class CaseClassQueryLift(name: String, liftId: String)
|
||||
extends CaseClassLift
|
||||
|
|
|
@ -1,39 +1,46 @@
|
|||
package minisql.dsl
|
||||
|
||||
import minisql.ast.{Ast, Entity, given}
|
||||
import scala.quoted.*
|
||||
import scala.compiletime.*
|
||||
import scala.compiletime.ops.string.*
|
||||
|
||||
trait Quoted[E] {
|
||||
type Ast
|
||||
sealed trait Dsl {
|
||||
def ast: Ast
|
||||
def liftings: Map[String, Any]
|
||||
}
|
||||
|
||||
object Quoted {
|
||||
def apply[_Ast <: String, E](
|
||||
_ast: Ast,
|
||||
_liftings: Map[String, Any]
|
||||
): Quoted[_Ast, E] =
|
||||
new Quoted[_Ast] {
|
||||
type Ast = _Ast
|
||||
def ast = _ast
|
||||
def liftings = _liftings
|
||||
trait Query[E] extends Dsl
|
||||
|
||||
class EntityQuery[E](val ast: Ast) extends Query
|
||||
|
||||
given FromExpr[EntityQuery[?]] with {
|
||||
def unapply(x: Expr[EntityQuery[?]])(using Quotes): Option[EntityQuery[?]] = {
|
||||
x match {
|
||||
case '{ EntityQuery(${ Expr(ast) }) } =>
|
||||
Some(EntityQuery(ast))
|
||||
case _ =>
|
||||
import quotes.reflect.*
|
||||
println(s"cannot unlift ${x.asTerm}")
|
||||
None
|
||||
}
|
||||
|
||||
inline def transform[A1 <: String, A2 <: String, A3 <: String](
|
||||
inline q1: Quoted[A1],
|
||||
inline q2: Quoted[A2]
|
||||
)(inline f: (A1, A2) => A3): Quoted[A3] =
|
||||
Quoted[A3](q1.liftings ++ q2.liftings)
|
||||
|
||||
}
|
||||
}
|
||||
given FromExpr[Dsl] with {
|
||||
def unapply(d: Expr[Dsl])(using Quotes): Option[Dsl] = d match {
|
||||
case '{ ($x: EntityQuery[?]) } => x.value
|
||||
}
|
||||
}
|
||||
|
||||
case class Foo()
|
||||
inline def query[E](inline table: String) =
|
||||
EntityQuery[E](Entity(table, Nil))
|
||||
|
||||
opaque type Query[E] <: Quoted[E] = Quoted[E]
|
||||
opaque type EntityQuery[E] <: Quoted[E] & Query[E] = Quoted[E]
|
||||
inline def compile(inline x: Dsl): Option[String] = ${ compileImpl('x) }
|
||||
|
||||
private def compileImpl(x: Expr[Dsl])(using Quotes): Expr[Option[String]] = {
|
||||
import quotes.reflect.*
|
||||
x.value match {
|
||||
case Some(xv) => '{ Some(${ Expr(xv.ast.toString()) }) }
|
||||
case None => '{ None }
|
||||
}
|
||||
|
||||
extension [E](e: EntityQuery[E]) {
|
||||
inline def map[E1](inline f: E => E1): EntityQuery[E1] = Quoted[]()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue