Compare commits

..

No commits in common. "2d30969ec50e9c7bdef80a248c34d6e25b3ad711" and "cf6aa999aec6d91ef9e44e44567977441a7504fa" have entirely different histories.

25 changed files with 105 additions and 119 deletions

2
.gitignore vendored
View file

@ -1,5 +1,3 @@
target/
.bsp/
.metals/
.bloop/
project/metals.sbt

View file

@ -1,4 +1,4 @@
version = "3.8.3"
version = "3.8.1"
style = defaultWithAlign
runner.dialect=scala3
maxColumn = 80

View file

@ -1,8 +1,9 @@
name := "minisql"
scalaVersion := "3.5.2"
scalaVersion := "3.5.0-RC4"
libraryDependencies ++= Seq(
)
scalacOptions ++= Seq("-experimental", "-language:experimental.namedTuples")
scalacOptions ++= Seq("-experimental")

View file

@ -1 +1 @@
sbt.version=1.10.5
sbt.version=1.10.0

View file

@ -1,8 +0,0 @@
// 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

View file

@ -0,0 +1 @@
jilen@jilendeiMac.2465

View file

@ -0,0 +1,28 @@
package minisql
import scala.collection.immutable.{Map => IMap}
import scala.quoted.*
import minisql.ast.{*, given}
import scala.deriving.*
import scala.compiletime.*
sealed trait Query[T] {
def ast: Ast
}
case class Column
case class EntityQuery[A](ast: Entity) extends Query
inline def compile(inline e: Ast): Unit = ${ compileImpl('e) }
private def compileImpl(e: Expr[Ast])(using Quotes) = {
import quotes.reflect.*
e.value match {
case Some(v) =>
report.info("Static:" + v.toString())
case None =>
report.info("Dynamic")
}
'{ () }
}

View file

@ -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,15 +386,34 @@ sealed trait ScalarLift extends Lift
case class ScalarValueLift(
name: String,
liftId: String
) extends ScalarLift
) 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}]")
}
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

View file

@ -68,9 +68,6 @@ private given FromExpr[Property] with {
)
} =>
Some(Property(a, n, r, v))
case o =>
println(s"Canot extrat ${o.show}:${x}")
None
}
}
@ -106,9 +103,6 @@ private given FromExpr[Query] with {
Some(Take(b, n))
case '{ SortBy(${ Expr(b) }, ${ Expr(p) }, ${ Expr(s) }, ${ Expr(o) }) } =>
Some(SortBy(b, p, s, o))
case o =>
println(s"Cannot extract ${o.show}")
None
}
}
@ -226,37 +220,17 @@ private given FromExpr[If] with {
}
}
private def extractTerm(using Quotes)(x: quotes.reflect.Term) = {
import quotes.reflect.*
def unwrapTerm(t: Term): Term = t match {
case Inlined(_, _, o) => unwrapTerm(o)
case Block(Nil, last) => last
case Typed(t, _) =>
unwrapTerm(t)
case Select(t, "$asInstanceOf$") =>
unwrapTerm(t)
case TypeApply(t, _) =>
unwrapTerm(t)
case o => o
}
val o = unwrapTerm(x)
println(s"From ========== ${x.show}")
println(s"To ========== ${o.show}")
o
}
private[minisql] given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
extension (e: Expr[Any]) {
def toTerm(using Quotes) = {
private def isAstType[t](using Quotes, Type[t]) = {
import quotes.reflect.*
e.asTerm
val t1 = TypeRepr.of[t].dealias.simplified
println(s"isAstType ${TypeRepr.of[t]} ===> ${t1}")
t1 <:< TypeRepr.of[Ast]
}
}
given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
def unapply(e: Expr[Ast])(using Quotes): Option[Ast] = {
extractTerm(e.toTerm).asExpr match {
e match {
case '{ $x: Query } => x.value
case '{ $x: ScalarValueLift } => x.value
case '{ $x: Property } => x.value
@ -268,7 +242,26 @@ given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
case '{ $x: Action } => x.value
case '{ $x: If } => x.value
case '{ $x: Infix } => x.value
case o => None
case '{ ($x: Ast).asInstanceOf } =>
unapply(x.asInstanceOf)
case '{ (${ x }: t1).asInstanceOf[t2] } if isAstType[t2] =>
unapply(x.asInstanceOf)
case o =>
import quotes.reflect.*
def unwrapInline(x: Term): Unit = x match {
case Inlined(_, bs, t) =>
unwrapInline(t)
case Typed(t, _) =>
unwrapInline(t)
case TypeApply(t, _) =>
unwrapInline(t)
// case Select(x, "$asInstanceOf$") =>
// unwrapInline(x)
case o =>
println(s"unwrapped term(${o.getClass}): ${o.show}")
}
unwrapInline(o.asTerm)
None
}
}
}

View file

@ -1,46 +0,0 @@
package minisql.dsl
import minisql.ast.{Ast, Entity, given}
import scala.quoted.*
import scala.compiletime.*
import scala.compiletime.ops.string.*
sealed trait Dsl {
def ast: Ast
}
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
}
}
}
given FromExpr[Dsl] with {
def unapply(d: Expr[Dsl])(using Quotes): Option[Dsl] = d match {
case '{ ($x: EntityQuery[?]) } => x.value
}
}
inline def query[E](inline table: String) =
EntityQuery[E](Entity(table, Nil))
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 }
}
}