Skip to content

Commit

Permalink
DataSource initialization shuold be lazy (#3141)
Browse files Browse the repository at this point in the history
* Make contexts slightly more lazy. DataSource should not be created immediately.

* Make infix tree-print correctly
  • Loading branch information
deusaquilus authored Nov 25, 2024
1 parent 39cd637 commit ee30130
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,25 @@ trait ContextTranslateProto {
extractor: Extractor[T] = identityExtractor,
prettyPrint: Boolean = false
)(executionInfo: ExecutionInfo, dc: Runner): TranslateResult[String] =
push(prepareParams(statement, prepare)) { params =>
val query =
if (params.nonEmpty) {
params.foldLeft(statement) { case (expanded, param) =>
expanded.replaceFirst("\\?", param)
try {
push(prepareParams(statement, prepare)) { params =>
val query =
if (params.nonEmpty) {
params.foldLeft(statement) { case (expanded, param) =>
expanded.replaceFirst("\\?", param)
}
} else {
statement
}
} else {
statement
}

if (prettyPrint)
idiom.format(query)
else
query
if (prettyPrint)
idiom.format(query)
else
query
}
} catch {
case e: Exception =>
wrap("<!-- Cannot display parameters due to preparation error: " + e.getMessage + " -->\n" + statement)
}

def translateBatchQuery(
Expand Down
22 changes: 19 additions & 3 deletions quill-engine/src/main/scala/io/getquill/AstPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ object AstPrinter {
}
}

class AstPrinter(traceOpinions: Boolean, traceAstSimple: Boolean, traceQuats: QuatTrace) extends pprint.Walker {
class AstPrinter(
traceOpinions: Boolean = false,
traceAstSimple: Boolean = false,
traceQuats: QuatTrace = QuatTrace.None
) extends pprint.Walker {
val defaultWidth: Int = 150
val defaultHeight: Int = Integer.MAX_VALUE
val defaultIndent: Int = 2
Expand Down Expand Up @@ -83,7 +87,8 @@ class AstPrinter(traceOpinions: Boolean, traceAstSimple: Boolean, traceQuats: Qu
def apply(list: Any*): treemake = Content(list.toList.map(Elem.apply))
}

override def treeify(x: Any, escapeUnicode: Boolean, showFieldNames: Boolean): Tree =
override def treeify(x: Any, escapeUnicode: Boolean, showFieldNames: Boolean): Tree = {
def treeify1(x: Any) = treeify(x, escapeUnicode, showFieldNames)
x match {
case ast: Ast if (traceAstSimple) =>
Tree.Literal("" + ast) // Do not blow up if it is null
Expand Down Expand Up @@ -117,7 +122,16 @@ class AstPrinter(traceOpinions: Boolean, traceAstSimple: Boolean, traceQuats: Qu

case s: ScalarValueLift => Tree.Apply("ScalarValueLift", treemake(s.name, s.source).withQuat(s.bestQuat).make)

case p: Property if (traceOpinions) =>
case i: Infix =>
TreeApplyList(
"Infix",
List(
Tree.KeyValue("parts", ltree(i.parts.map(treeify1(_)))),
Tree.KeyValue("params", ltree(i.params.map(treeify1(_))))
)
)

case p: Property =>
TreeApplyList(
"Property",
l(treeify(p.ast, escapeUnicode, showFieldNames)) ++ l(treeify(p.name, escapeUnicode, showFieldNames)) ++
Expand Down Expand Up @@ -153,10 +167,12 @@ class AstPrinter(traceOpinions: Boolean, traceAstSimple: Boolean, traceQuats: Qu

case _ => super.treeify(x, escapeUnicode, showFieldNames)
}
}

private def TreeApplyList(prefix: String, body: List[Tree]) = Tree.Apply(prefix, body.iterator)

private def l(trees: Tree*): List[Tree] = List[Tree](trees: _*)
private def ltree(trees: List[Tree]) = Tree.Apply("List", trees.iterator)

def apply(x: Any): fansi.Str =
fansi.Str.join(this.tokenize(x).toSeq)
Expand Down
25 changes: 16 additions & 9 deletions quill-jdbc-zio/src/main/scala/io/getquill/jdbczio/Quill.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@ import java.sql.{Connection, SQLException}
import javax.sql.DataSource

object Quill {
class Postgres[+N <: NamingStrategy](val naming: N, override val ds: DataSource)
class Postgres[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource)
extends Quill[PostgresDialect, N]
with PostgresJdbcTypes[PostgresDialect, N]
with PostgresJsonExtensions {
val idiom: PostgresDialect = PostgresDialect
val dsDelegate = new PostgresZioJdbcContext[N](naming)
lazy val ds: DataSource = dataSourceInput
}

/** Postgres ZIO Context without JDBC Encoders */
class PostgresLite[+N <: NamingStrategy](val naming: N, override val ds: DataSource)
class PostgresLite[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource)
extends Quill[PostgresDialect, N]
with PostgresJdbcTypes[PostgresDialect, N] {
val idiom: PostgresDialect = PostgresDialect
val dsDelegate = new PostgresZioJdbcContext[N](naming)
lazy val ds: DataSource = dataSourceInput
}

object Postgres {
Expand All @@ -37,59 +39,64 @@ object Quill {
ZLayer.fromFunction((ds: javax.sql.DataSource) => new Postgres[N](naming, ds))
}

class SqlServer[+N <: NamingStrategy](val naming: N, override val ds: DataSource)
class SqlServer[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource)
extends Quill[SQLServerDialect, N]
with SqlServerJdbcTypes[SQLServerDialect, N] {
val idiom: SQLServerDialect = SQLServerDialect
val dsDelegate = new SqlServerZioJdbcContext[N](naming)
lazy val ds: DataSource = dataSourceInput
}
object SqlServer {
def apply[N <: NamingStrategy](naming: N, ds: DataSource) = new SqlServer[N](naming, ds)
def fromNamingStrategy[N <: NamingStrategy: Tag](naming: N): ZLayer[javax.sql.DataSource, Nothing, SqlServer[N]] =
ZLayer.fromFunction((ds: javax.sql.DataSource) => new SqlServer[N](naming, ds))
}

class H2[+N <: NamingStrategy](val naming: N, override val ds: DataSource)
class H2[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource)
extends Quill[H2Dialect, N]
with H2JdbcTypes[H2Dialect, N] {
val idiom: H2Dialect = H2Dialect
val dsDelegate = new H2ZioJdbcContext[N](naming)
val idiom: H2Dialect = H2Dialect
val dsDelegate = new H2ZioJdbcContext[N](naming)
lazy val ds: DataSource = dataSourceInput
}
object H2 {
def apply[N <: NamingStrategy](naming: N, ds: DataSource) = new H2[N](naming, ds)
def fromNamingStrategy[N <: NamingStrategy: Tag](naming: N): ZLayer[javax.sql.DataSource, Nothing, H2[N]] =
ZLayer.fromFunction((ds: javax.sql.DataSource) => new H2[N](naming, ds))
}

class Mysql[+N <: NamingStrategy](val naming: N, override val ds: DataSource)
class Mysql[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource)
extends Quill[MySQLDialect, N]
with MysqlJdbcTypes[MySQLDialect, N] {
val idiom: MySQLDialect = MySQLDialect
val dsDelegate = new MysqlZioJdbcContext[N](naming)
lazy val ds: DataSource = dataSourceInput
}
object Mysql {
def apply[N <: NamingStrategy](naming: N, ds: DataSource) = new Mysql[N](naming, ds)
def fromNamingStrategy[N <: NamingStrategy: Tag](naming: N): ZLayer[javax.sql.DataSource, Nothing, Mysql[N]] =
ZLayer.fromFunction((ds: javax.sql.DataSource) => new Mysql[N](naming, ds))
}

class Sqlite[+N <: NamingStrategy](val naming: N, override val ds: DataSource)
class Sqlite[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource)
extends Quill[SqliteDialect, N]
with SqliteJdbcTypes[SqliteDialect, N] {
val idiom: SqliteDialect = SqliteDialect
val dsDelegate = new SqliteZioJdbcContext[N](naming)
lazy val ds: DataSource = dataSourceInput
}
object Sqlite {
def apply[N <: NamingStrategy](naming: N, ds: DataSource) = new Sqlite[N](naming, ds)
def fromNamingStrategy[N <: NamingStrategy: Tag](naming: N): ZLayer[javax.sql.DataSource, Nothing, Sqlite[N]] =
ZLayer.fromFunction((ds: javax.sql.DataSource) => new Sqlite[N](naming, ds))
}

class Oracle[+N <: NamingStrategy](val naming: N, override val ds: DataSource)
class Oracle[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource)
extends Quill[OracleDialect, N]
with OracleJdbcTypes[OracleDialect, N] {
val idiom: OracleDialect = OracleDialect
val dsDelegate = new OracleZioJdbcContext[N](naming)
lazy val ds: DataSource = dataSourceInput
}
object Oracle {
def apply[N <: NamingStrategy](naming: N, ds: DataSource) = new Oracle[N](naming, ds)
Expand Down
6 changes: 4 additions & 2 deletions quill-jdbc/src/main/scala/io/getquill/H2JdbcContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import com.typesafe.config.Config
import io.getquill.context.jdbc.{JdbcContext, H2JdbcContextBase}
import io.getquill.util.LoadConfig

class H2JdbcContext[+N <: NamingStrategy](val naming: N, val dataSource: DataSource with Closeable)
class H2JdbcContext[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource with Closeable)
extends JdbcContext[H2Dialect, N]
with H2JdbcContextBase[H2Dialect, N] {
override val idiom: H2Dialect = H2Dialect
override val idiom: H2Dialect = H2Dialect
override lazy val dataSource: DataSource with Closeable = dataSourceInput

def this(naming: N, config: JdbcContextConfig) = this(naming, config.dataSource)
def this(naming: N, config: Config) = this(naming, JdbcContextConfig(config))
def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix))
Expand Down
6 changes: 4 additions & 2 deletions quill-jdbc/src/main/scala/io/getquill/MysqlJdbcContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import com.typesafe.config.Config
import io.getquill.context.jdbc.{JdbcContext, MysqlJdbcContextBase}
import io.getquill.util.LoadConfig

class MysqlJdbcContext[+N <: NamingStrategy](val naming: N, val dataSource: DataSource with Closeable)
class MysqlJdbcContext[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource with Closeable)
extends JdbcContext[MySQLDialect, N]
with MysqlJdbcContextBase[MySQLDialect, N] {
override val idiom: MySQLDialect = MySQLDialect
override val idiom: MySQLDialect = MySQLDialect
override lazy val dataSource: DataSource with Closeable = dataSourceInput

def this(naming: N, config: JdbcContextConfig) = this(naming, config.dataSource)
def this(naming: N, config: Config) = this(naming, JdbcContextConfig(config))
def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix))
Expand Down
6 changes: 4 additions & 2 deletions quill-jdbc/src/main/scala/io/getquill/OracleJdbcContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import io.getquill.context.jdbc.{JdbcContext, OracleJdbcContextBase}
import io.getquill.util.LoadConfig
import javax.sql.DataSource

class OracleJdbcContext[+N <: NamingStrategy](val naming: N, val dataSource: DataSource with Closeable)
class OracleJdbcContext[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource with Closeable)
extends JdbcContext[OracleDialect, N]
with OracleJdbcContextBase[OracleDialect, N] {
override val idiom: OracleDialect = OracleDialect
override val idiom: OracleDialect = OracleDialect
override lazy val dataSource: DataSource with Closeable = dataSourceInput

def this(naming: N, config: JdbcContextConfig) = this(naming, config.dataSource)
def this(naming: N, config: Config) = this(naming, JdbcContextConfig(config))
def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import com.typesafe.config.Config
import io.getquill.context.jdbc.{JdbcContext, PostgresJdbcContextBase}
import io.getquill.util.LoadConfig

class PostgresJdbcContext[+N <: NamingStrategy](val naming: N, val dataSource: DataSource with Closeable)
class PostgresJdbcContext[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource with Closeable)
extends JdbcContext[PostgresDialect, N]
with PostgresJdbcContextBase[PostgresDialect, N] {
override val idiom: PostgresDialect = PostgresDialect
override val idiom: PostgresDialect = PostgresDialect
override lazy val dataSource: DataSource with Closeable = dataSourceInput

def this(naming: N, config: JdbcContextConfig) = this(naming, config.dataSource)
def this(naming: N, config: Config) = this(naming, JdbcContextConfig(config))
def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import com.typesafe.config.Config
import io.getquill.context.jdbc.{JdbcContext, SqlServerJdbcContextBase}
import io.getquill.util.LoadConfig

class SqlServerJdbcContext[+N <: NamingStrategy](val naming: N, val dataSource: DataSource with Closeable)
class SqlServerJdbcContext[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource with Closeable)
extends JdbcContext[SQLServerDialect, N]
with SqlServerJdbcContextBase[SQLServerDialect, N] {
override val idiom: SQLServerDialect = SQLServerDialect
override val idiom: SQLServerDialect = SQLServerDialect
override lazy val dataSource: DataSource with Closeable = dataSourceInput

def this(naming: N, config: JdbcContextConfig) = this(naming, config.dataSource)
def this(naming: N, config: Config) = this(naming, JdbcContextConfig(config))
def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix))
Expand Down
6 changes: 4 additions & 2 deletions quill-jdbc/src/main/scala/io/getquill/SqliteJdbcContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import com.typesafe.config.Config
import io.getquill.context.jdbc.{JdbcContext, SqliteJdbcContextBase}
import io.getquill.util.LoadConfig

class SqliteJdbcContext[+N <: NamingStrategy](val naming: N, val dataSource: DataSource with Closeable)
class SqliteJdbcContext[+N <: NamingStrategy](val naming: N, dataSourceInput: => DataSource with Closeable)
extends JdbcContext[SqliteDialect, N]
with SqliteJdbcContextBase[SqliteDialect, N] {
override val idiom: SqliteDialect = SqliteDialect
override val idiom: SqliteDialect = SqliteDialect
override lazy val dataSource: DataSource with Closeable = dataSourceInput

def this(naming: N, config: JdbcContextConfig) = this(naming, config.dataSource)
def this(naming: N, config: Config) = this(naming, JdbcContextConfig(config))
def this(naming: N, configPrefix: String) = this(naming, LoadConfig(configPrefix))
Expand Down

0 comments on commit ee30130

Please sign in to comment.