Created
May 27, 2023 14:31
-
-
Save calvinlfer/9253c8d849dec9c83646bc49a74f6979 to your computer and use it in GitHub Desktop.
Virgil ideas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.kaizensolutions.virgil.nextlevel | |
import io.kaizensolutions.virgil.nextlevel.nextlevel.peopleTable | |
object nextlevel { | |
sealed trait Table { | |
type TableTag | |
} | |
object Table { | |
type WithTag[Tag] = Table { type TableTag = Tag } | |
sealed trait Source[ColTaggerFunction[_]] extends Table { | |
val tableName: String | |
val columns: ColTaggerFunction[TableTag] | |
} | |
def make[ColType, Rest <: ColumnSet](name: String)( | |
columnSet: ColumnSet.Cons[ColType, Rest] | |
): Table.Source[columnSet.ColumnsRepr] = | |
columnSet.makeTable(name) | |
} | |
// Need to store Writer + Reader proof | |
final case class Column[ColumnType](name: String) | |
object Column { | |
def int(name: String): Column[Int] = Column(name) | |
def string(name: String): Column[String] = Column(name) | |
def double(name: String): Column[Double] = Column(name) | |
def long(name: String): Column[Long] = Column(name) | |
def uuid(name: String): Column[java.util.UUID] = Column(name) | |
} | |
final case class ColumnFromTable[ColumnType, TableTag](name: String) | |
sealed trait ColumnSet { | |
// Type level function used to tag columns to a table | |
type ColumnsRepr[TableTag] | |
// Append | |
def :*:[A](head: Column[A]): ColumnSet | |
protected def mkColumns[Tag]: ColumnsRepr[Tag] | |
} | |
object ColumnSet { | |
type Finish = Finish.type | |
case object Finish extends ColumnSet { | |
override type ColumnsRepr[TableTag] = Unit | |
override def :*:[ColType](head: Column[ColType]): Cons[ColType, Finish] = Cons(head, Finish) | |
override protected def mkColumns[Tag]: ColumnsRepr[Tag] = () | |
} | |
final case class Cons[ColType, Rest <: ColumnSet](head: Column[ColType], rest: Rest) extends ColumnSet { self => | |
override type ColumnsRepr[TableTag] = (ColumnFromTable[ColType, TableTag], rest.ColumnsRepr[TableTag]) | |
override def :*:[AnotherColType](head: Column[AnotherColType]): Cons[AnotherColType, Cons[ColType, Rest]] = | |
Cons(head, self) | |
override protected def mkColumns[Tag]: ColumnsRepr[Tag] = | |
(ColumnFromTable[ColType, Tag](head.name), rest.mkColumns[Tag]) | |
def makeTable(name: String): Table.Source[ColumnsRepr] = | |
new Table.Source[ColumnsRepr] { | |
override type TableTag | |
override val tableName: String = name | |
override val columns: ColumnsRepr[TableTag] = self.mkColumns[TableTag] | |
} | |
} | |
object :*: { | |
def unapply[A, B](tuple: (A, B)): Some[(A, B)] = Some(tuple) | |
} | |
} | |
import ColumnSet._ | |
val peopleTable = | |
Table.make("people") { | |
Column.int("id") :*: | |
Column.string("first_name") :*: | |
Column.string("last_name") :*: | |
Finish | |
} | |
val (id: ColumnFromTable[Int, peopleTable.TableTag]) :*: | |
(firstName: ColumnFromTable[String, peopleTable.TableTag]) :*: | |
(lastName: ColumnFromTable[String, peopleTable.TableTag]) :*: _ = | |
peopleTable.columns | |
/** | |
* API | |
* | |
* val table = Table( column[String]("first_name) ~ column[Int]("age") ~ | |
* column[String]("email) ) | |
* | |
* val firstName ~ age ~ email ~ _ = table.columns | |
* | |
* Insert.into(table) .value(firstName, "John") .value(age, 42) .value(email, | |
* "[email protected]") | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment