Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 144 additions & 15 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -6552,11 +6552,13 @@ Buyer.select


## Schema
Additional tests to ensure schema mapping produces valid SQL

If your table belongs to a schema other than the default schema of your database, you can specify this in your table definition with
`override def schemaName = "otherschema"`

### Schema.schema.select

If your table belongs to a schema other than the default schema of your database,
you can specify this in your table definition with table.schemaName


```scala
Invoice.select
Expand Down Expand Up @@ -6584,8 +6586,7 @@ Invoice.select

### Schema.schema.insert.columns

If your table belongs to a schema other than the default schema of your database,
you can specify this in your table definition with table.schemaName


```scala
Invoice.insert.columns(
Expand All @@ -6611,8 +6612,7 @@ Invoice.insert.columns(

### Schema.schema.insert.values

If your table belongs to a schema other than the default schema of your database,
you can specify this in your table definition with table.schemaName


```scala
Invoice.insert
Expand Down Expand Up @@ -6643,8 +6643,7 @@ Invoice.insert

### Schema.schema.update

If your table belongs to a schema other than the default schema of your database,
you can specify this in your table definition with table.schemaName


```scala
Invoice
Expand Down Expand Up @@ -6677,8 +6676,7 @@ Invoice

### Schema.schema.delete

If your table belongs to a schema other than the default schema of your database,
you can specify this in your table definition with table.schemaName


```scala
Invoice.delete(_.id === 1)
Expand All @@ -6701,8 +6699,7 @@ Invoice.delete(_.id === 1)

### Schema.schema.insert into

If your table belongs to a schema other than the default schema of your database,
you can specify this in your table definition with table.schemaName


```scala
Invoice.insert.select(
Expand Down Expand Up @@ -6734,8 +6731,7 @@ Invoice.insert.select(

### Schema.schema.join

If your table belongs to a schema other than the default schema of your database,
you can specify this in your table definition with table.schemaName


```scala
Invoice.select.join(Invoice)(_.id `=` _.id).map(_._1.id)
Expand All @@ -6760,6 +6756,139 @@ Invoice.select.join(Invoice)(_.id `=` _.id).map(_._1.id)



## EscapedTableName

If your table name is a reserved sql world, e.g. `order`, you can specify this in your table definition with
`override def escape = true`

### EscapedTableName.escape table name.select



```scala
Select.select
```


*
```sql
SELECT select0.id AS id, select0.name AS name
FROM "select" select0
```



*
```scala
Seq.empty[Select[Sc]]
```



### EscapedTableName.escape table name.delete



```scala
Select.delete(_ => true)
```


*
```sql
DELETE FROM "select" WHERE ?
```



*
```scala
0
```



### EscapedTableName.escape table name.join



```scala
Select.select.join(Select)(_.id `=` _.id)
```


*
```sql
SELECT
select0.id AS res_0_id,
select0.name AS res_0_name,
select1.id AS res_1_id,
select1.name AS res_1_name
FROM
"select" select0
JOIN "select" select1 ON (select0.id = select1.id)
```



*
```scala
Seq.empty[(Select[Sc], Select[Sc])]
```



### EscapedTableName.escape table name.update



```scala
Select.update(_ => true).set(_.name := "hello")
```


*
```sql
UPDATE "select" SET name = ?
```



*
```scala
0
```



### EscapedTableName.escape table name.insert



```scala
Select.insert.values(
Select[Sc](
id = 0,
name = "hello"
)
)
```


*
```sql
INSERT INTO "select" (id, name) VALUES (?, ?)
```



*
```scala
1
```



## SubQuery
Queries that explicitly use subqueries (e.g. for `JOIN`s) or require subqueries to preserve the Scala semantics of the various operators
### SubQuery.sortTakeJoin
Expand Down
7 changes: 5 additions & 2 deletions scalasql/core/src/Context.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ trait Context {
*/
def config: Config

def dialectConfig: DialectConfig

def withFromNaming(fromNaming: Map[Context.From, String]): Context
def withExprNaming(exprNaming: Map[Expr.Identity, SqlStr]): Context
}
Expand Down Expand Up @@ -56,7 +58,8 @@ object Context {
case class Impl(
fromNaming: Map[From, String],
exprNaming: Map[Expr.Identity, SqlStr],
config: Config
config: Config,
dialectConfig: DialectConfig
) extends Context {
def withFromNaming(fromNaming: Map[From, String]): Context = copy(fromNaming = fromNaming)

Expand Down Expand Up @@ -93,7 +96,7 @@ object Context {
.map { case (e, s) => (e, sql"${SqlStr.raw(newFromNaming(t), Array(e))}.$s") }
}

Context.Impl(newFromNaming, newExprNaming, prevContext.config)
Context.Impl(newFromNaming, newExprNaming, prevContext.config, prevContext.dialectConfig)
}

}
27 changes: 16 additions & 11 deletions scalasql/core/src/DbApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,22 @@ trait DbApi extends AutoCloseable {

object DbApi {

def unpackQueryable[R, Q](query: Q, qr: Queryable[Q, R], config: Config) = {
val ctx = Context.Impl(Map(), Map(), config)
def unpackQueryable[R, Q](
query: Q,
qr: Queryable[Q, R],
config: Config,
dialectConfig: DialectConfig
) = {
val ctx = Context.Impl(Map(), Map(), config, dialectConfig)
val flattened = SqlStr.flatten(qr.renderSql(query, ctx))
flattened
}

def renderSql[Q, R](query: Q, config: Config, castParams: Boolean = false)(
def renderSql[Q, R](query: Q, config: Config, dialectConfig: DialectConfig)(
implicit qr: Queryable[Q, R]
): String = {
val flattened = unpackQueryable(query, qr, config)
flattened.renderSql(castParams)
val flattened = unpackQueryable(query, qr, config, dialectConfig)
flattened.renderSql(dialectConfig.castParams)
}

/**
Expand Down Expand Up @@ -196,7 +201,7 @@ object DbApi {
lineNum: sourcecode.Line
): R = {

val flattened = unpackQueryable(query, qr, config)
val flattened = unpackQueryable(query, qr, config, dialect)
if (qr.isGetGeneratedKeys(query).nonEmpty)
updateGetGeneratedKeysSql(flattened)(qr.isGetGeneratedKeys(query).get, fileName, lineNum)
.asInstanceOf[R]
Expand Down Expand Up @@ -225,7 +230,7 @@ object DbApi {
fileName: sourcecode.FileName,
lineNum: sourcecode.Line
): Generator[R] = {
val flattened = unpackQueryable(query, qr, config)
val flattened = unpackQueryable(query, qr, config, dialect)
streamFlattened0(
r => {
qr.asInstanceOf[Queryable[Q, R]].construct(query, r) match {
Expand Down Expand Up @@ -276,7 +281,7 @@ object DbApi {
): Int = {
val flattened = SqlStr.flatten(sql)
runRawUpdate0(
flattened.renderSql(DialectConfig.castParams(dialect)),
flattened.renderSql(dialect.castParams),
flattenParamPuts(flattened),
fetchSize,
queryTimeoutSeconds,
Expand All @@ -296,7 +301,7 @@ object DbApi {
): IndexedSeq[R] = {
val flattened = SqlStr.flatten(sql)
runRawUpdateGetGeneratedKeys0(
flattened.renderSql(DialectConfig.castParams(dialect)),
flattened.renderSql(dialect.castParams),
flattenParamPuts(flattened),
fetchSize,
queryTimeoutSeconds,
Expand Down Expand Up @@ -382,7 +387,7 @@ object DbApi {
lineNum: sourcecode.Line
) = streamRaw0(
construct,
flattened.renderSql(DialectConfig.castParams(dialect)),
flattened.renderSql(dialect.castParams),
flattenParamPuts(flattened),
fetchSize,
queryTimeoutSeconds,
Expand Down Expand Up @@ -508,7 +513,7 @@ object DbApi {
def renderSql[Q, R](query: Q, castParams: Boolean = false)(
implicit qr: Queryable[Q, R]
): String = {
DbApi.renderSql(query, config, castParams)
DbApi.renderSql(query, config, dialect.withCastParams(castParams))
}

val savepointStack = collection.mutable.ArrayDeque.empty[java.sql.Savepoint]
Expand Down
4 changes: 2 additions & 2 deletions scalasql/core/src/DbClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ object DbClient {
def renderSql[Q, R](query: Q, castParams: Boolean = false)(
implicit qr: Queryable[Q, R]
): String = {
DbApi.renderSql(query, config, castParams)
DbApi.renderSql(query, config, dialect.withCastParams(castParams))
}

def transaction[T](block: DbApi.Txn => T): T = {
Expand Down Expand Up @@ -74,7 +74,7 @@ object DbClient {
def renderSql[Q, R](query: Q, castParams: Boolean = false)(
implicit qr: Queryable[Q, R]
): String = {
DbApi.renderSql(query, config, castParams)
DbApi.renderSql(query, config, dialect.withCastParams(castParams))
}

private def withConnection[T](f: DbClient.Connection => T): T = {
Expand Down
14 changes: 9 additions & 5 deletions scalasql/core/src/DialectConfig.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package scalasql.core

trait DialectConfig {
protected def dialectCastParams: Boolean
}
trait DialectConfig { that =>
def castParams: Boolean
def escape(str: String): String

def withCastParams(params: Boolean) = new DialectConfig {
def castParams: Boolean = params

def escape(str: String): String = that.escape(str)

object DialectConfig {
def castParams(d: DialectConfig) = d.dialectCastParams
}
}
2 changes: 1 addition & 1 deletion scalasql/query/src/Delete.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object Delete {
class Renderer(table: TableRef, expr: Expr[Boolean], prevContext: Context) {
implicit val implicitCtx: Context = Context.compute(prevContext, Nil, Some(table))
lazy val tableNameStr =
SqlStr.raw(Table.resolve(table.value))
SqlStr.raw(Table.fullIdentifier(table.value))

def render() = sql"DELETE FROM $tableNameStr WHERE $expr"
}
Expand Down
2 changes: 1 addition & 1 deletion scalasql/query/src/From.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TableRef(val value: Table.Base) extends From {
def fromExprAliases(prevContext: Context): Seq[(Expr.Identity, SqlStr)] = Nil

def renderSql(name: SqlStr, prevContext: Context, liveExprs: LiveExprs) = {
val resolvedTable = Table.resolve(value)(prevContext)
val resolvedTable = Table.fullIdentifier(value)(prevContext)
SqlStr.raw(resolvedTable + sql" " + name)
}
}
Expand Down
2 changes: 1 addition & 1 deletion scalasql/query/src/InsertColumns.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object InsertColumns {
protected def expr: V[Column] = WithSqlExpr.get(insert)

private[scalasql] override def renderSql(ctx: Context) =
new Renderer(columns, ctx, valuesLists, Table.resolve(table.value)(ctx)).render()
new Renderer(columns, ctx, valuesLists, Table.fullIdentifier(table.value)(ctx)).render()

override protected def queryConstruct(args: Queryable.ResultSetIterator): Int =
args.get(IntType)
Expand Down
Loading