Skip to content

Commit ba5710e

Browse files
NPCRUSnpcrusde
andauthored
Support schema name (#57)
Hello folks, here I tried to add support for `schemaName` into `INSERT`, `UPDATE`, `DELETE` and some sub variants of those. I feel 90% confused about most of the stuff I see in the repo so far, but I wanted to start somewhere, so I can gradually get a better understanding of what's going on. Here I implemented a `Table.resolve` function that should make a fully qualified table name + schema if present + apply mapping from config, maybe it can also be used further for #53 I also thought it's a good idea whenever `Table.Base` becomes `String` to be used as a fully qualified name to not do any further processing and mapping of this string Fixes #54 --------- Co-authored-by: nikitaglushchenko <[email protected]>
1 parent 4213f04 commit ba5710e

File tree

9 files changed

+323
-33
lines changed

9 files changed

+323
-33
lines changed

docs/reference.md

Lines changed: 179 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6276,7 +6276,7 @@ Buyer.select
62766276
62776277
## Schema
62786278
Additional tests to ensure schema mapping produces valid SQL
6279-
### Schema.schema
6279+
### Schema.schema.select
62806280
62816281
If your table belongs to a schema other than the default schema of your database,
62826282
you can specify this in your table definition with table.schemaName
@@ -6305,6 +6305,184 @@ Invoice.select
63056305
63066306
63076307
6308+
### Schema.schema.insert.columns
6309+
6310+
If your table belongs to a schema other than the default schema of your database,
6311+
you can specify this in your table definition with table.schemaName
6312+
6313+
```scala
6314+
Invoice.insert.columns(
6315+
_.total := 200.3,
6316+
_.vendor_name := "Huawei"
6317+
)
6318+
```
6319+
6320+
6321+
*
6322+
```sql
6323+
INSERT INTO otherschema.invoice (total, vendor_name) VALUES (?, ?)
6324+
```
6325+
6326+
6327+
6328+
*
6329+
```scala
6330+
1
6331+
```
6332+
6333+
6334+
6335+
### Schema.schema.insert.values
6336+
6337+
If your table belongs to a schema other than the default schema of your database,
6338+
you can specify this in your table definition with table.schemaName
6339+
6340+
```scala
6341+
Invoice.insert
6342+
.values(
6343+
Invoice[Sc](
6344+
id = 0,
6345+
total = 200.3,
6346+
vendor_name = "Huawei"
6347+
)
6348+
)
6349+
.skipColumns(_.id)
6350+
```
6351+
6352+
6353+
*
6354+
```sql
6355+
INSERT INTO otherschema.invoice (total, vendor_name) VALUES (?, ?)
6356+
```
6357+
6358+
6359+
6360+
*
6361+
```scala
6362+
1
6363+
```
6364+
6365+
6366+
6367+
### Schema.schema.update
6368+
6369+
If your table belongs to a schema other than the default schema of your database,
6370+
you can specify this in your table definition with table.schemaName
6371+
6372+
```scala
6373+
Invoice
6374+
.update(_.id === 1)
6375+
.set(
6376+
_.total := 200.3,
6377+
_.vendor_name := "Huawei"
6378+
)
6379+
```
6380+
6381+
6382+
*
6383+
```sql
6384+
UPDATE otherschema.invoice
6385+
SET
6386+
total = ?,
6387+
vendor_name = ?
6388+
WHERE
6389+
(invoice.id = ?)
6390+
```
6391+
6392+
6393+
6394+
*
6395+
```scala
6396+
1
6397+
```
6398+
6399+
6400+
6401+
### Schema.schema.delete
6402+
6403+
If your table belongs to a schema other than the default schema of your database,
6404+
you can specify this in your table definition with table.schemaName
6405+
6406+
```scala
6407+
Invoice.delete(_.id === 1)
6408+
```
6409+
6410+
6411+
*
6412+
```sql
6413+
DELETE FROM otherschema.invoice WHERE (invoice.id = ?)
6414+
```
6415+
6416+
6417+
6418+
*
6419+
```scala
6420+
1
6421+
```
6422+
6423+
6424+
6425+
### Schema.schema.insert into
6426+
6427+
If your table belongs to a schema other than the default schema of your database,
6428+
you can specify this in your table definition with table.schemaName
6429+
6430+
```scala
6431+
Invoice.insert.select(
6432+
i => (i.total, i.vendor_name),
6433+
Invoice.select.map(i => (i.total, i.vendor_name))
6434+
)
6435+
```
6436+
6437+
6438+
*
6439+
```sql
6440+
INSERT INTO
6441+
otherschema.invoice (total, vendor_name)
6442+
SELECT
6443+
invoice0.total AS res_0,
6444+
invoice0.vendor_name AS res_1
6445+
FROM
6446+
otherschema.invoice invoice0
6447+
```
6448+
6449+
6450+
6451+
*
6452+
```scala
6453+
4
6454+
```
6455+
6456+
6457+
6458+
### Schema.schema.join
6459+
6460+
If your table belongs to a schema other than the default schema of your database,
6461+
you can specify this in your table definition with table.schemaName
6462+
6463+
```scala
6464+
Invoice.select.join(Invoice)(_.id `=` _.id).map(_._1.id)
6465+
```
6466+
6467+
6468+
*
6469+
```sql
6470+
SELECT
6471+
invoice0.id AS res
6472+
FROM
6473+
otherschema.invoice invoice0
6474+
JOIN otherschema.invoice invoice1 ON (invoice0.id = invoice1.id)
6475+
```
6476+
6477+
6478+
6479+
*
6480+
```scala
6481+
Seq(2, 3, 4, 5, 6, 7, 8, 9)
6482+
```
6483+
6484+
6485+
63086486
## SubQuery
63096487
Queries that explicitly use subqueries (e.g. for `JOIN`s) or require subqueries to preserve the Scala semantics of the various operators
63106488
### SubQuery.sortTakeJoin

scalasql/query/src/Delete.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ object Delete {
2222
}
2323

2424
class Renderer(table: TableRef, expr: Expr[Boolean], prevContext: Context) {
25-
lazy val tableNameStr =
26-
SqlStr.raw(prevContext.config.tableNameMapper(Table.name(table.value)))
2725
implicit val implicitCtx: Context = Context.compute(prevContext, Nil, Some(table))
26+
lazy val tableNameStr =
27+
SqlStr.raw(Table.resolve(table.value))
2828

2929
def render() = sql"DELETE FROM $tableNameStr WHERE $expr"
3030
}

scalasql/query/src/From.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@ class TableRef(val value: Table.Base) extends From {
1515
def fromExprAliases(prevContext: Context): Seq[(Expr.Identity, SqlStr)] = Nil
1616

1717
def renderSql(name: SqlStr, prevContext: Context, liveExprs: LiveExprs) = {
18-
val schemaStr = value.schemaName match {
19-
case "" => ""
20-
case str => s"$str."
21-
}
22-
SqlStr.raw(schemaStr + prevContext.config.tableNameMapper(Table.name(value))) + sql" " + name
18+
val resolvedTable = Table.resolve(value)(prevContext)
19+
SqlStr.raw(resolvedTable + sql" " + name)
2320
}
2421
}
2522

scalasql/query/src/InsertColumns.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ object InsertColumns {
2424
protected def expr: V[Column] = WithSqlExpr.get(insert)
2525

2626
private[scalasql] override def renderSql(ctx: Context) =
27-
new Renderer(columns, ctx, valuesLists, Table.name(table.value)).render()
27+
new Renderer(columns, ctx, valuesLists, Table.resolve(table.value)(ctx)).render()
2828

2929
override protected def queryConstruct(args: Queryable.ResultSetIterator): Int =
3030
args.get(IntType)
@@ -48,7 +48,7 @@ object InsertColumns {
4848
SqlStr.commaSep
4949
)
5050
def render() = {
51-
sql"INSERT INTO ${SqlStr.raw(ctx.config.tableNameMapper(tableName))} ($columns) VALUES $values"
51+
sql"INSERT INTO ${SqlStr.raw(tableName)} ($columns) VALUES $values"
5252
}
5353
}
5454
}

scalasql/query/src/InsertSelect.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object InsertSelect {
2020
def table = insert.table
2121

2222
private[scalasql] override def renderSql(ctx: Context) =
23-
new Renderer(select, select.qr.walkExprs(columns), ctx, Table.name(table.value))
23+
new Renderer(select, select.qr.walkExprs(columns), ctx, Table.resolve(table.value)(ctx))
2424
.render()
2525

2626
override protected def queryConstruct(args: Queryable.ResultSetIterator): Int =
@@ -45,7 +45,7 @@ object InsertSelect {
4545

4646
lazy val selectSql = Renderable.renderSql(select).withCompleteQuery(false)
4747

48-
lazy val tableNameStr = SqlStr.raw(ctx.config.tableNameMapper(tableName))
48+
lazy val tableNameStr = SqlStr.raw(tableName)
4949
def render() = sql"INSERT INTO $tableNameStr ($columns) $selectSql"
5050
}
5151
}

scalasql/query/src/InsertValues.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ object InsertValues {
2222

2323
override private[scalasql] def renderSql(ctx: Context): SqlStr = {
2424
new Renderer(
25-
Table.name(insert.table.value),
25+
Table.resolve(insert.table.value)(ctx),
2626
Table.labels(insert.table.value),
2727
values,
2828
qr,
@@ -75,7 +75,7 @@ object InsertValues {
7575
lazy val values = SqlStr.join(valuesSqls, SqlStr.commaSep)
7676

7777
def render() = {
78-
sql"INSERT INTO ${SqlStr.raw(ctx.config.tableNameMapper(tableName))} ($columns) VALUES $values"
78+
sql"INSERT INTO ${SqlStr.raw(tableName)} ($columns) VALUES $values"
7979
}
8080
}
8181
}

scalasql/query/src/Table.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package scalasql.query
22

33
import scalasql.core.{DialectTypeMappers, Sc, Queryable, Expr}
4+
import scalasql.core.Context
45

56
/**
67
* In-code representation of a SQL table, associated with a given `case class` [[V]].
@@ -49,6 +50,13 @@ object Table {
4950
def name(t: Table.Base) = t.tableName
5051
def labels(t: Table.Base) = t.tableLabels
5152
def columnNameOverride[V[_[_]]](t: Table.Base)(s: String) = t.tableColumnNameOverride(s)
53+
def resolve(t: Table.Base)(implicit context: Context) = {
54+
val mappedTableName = context.config.tableNameMapper(t.tableName)
55+
t.schemaName match {
56+
case "" => mappedTableName
57+
case str => s"$str." + mappedTableName
58+
}
59+
}
5260
trait Base {
5361

5462
/**

scalasql/query/src/Update.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ object Update {
9494
implicit lazy val implicitCtx: Context = Context.compute(prevContext, froms, Some(table))
9595

9696
lazy val tableName =
97-
SqlStr.raw(implicitCtx.config.tableNameMapper(Table.name(table.value)))
97+
SqlStr.raw(Table.resolve(table.value))
9898

9999
lazy val updateList = set0.map { case assign =>
100100
val kStr = SqlStr.raw(prevContext.config.columnNameMapper(assign.column.name))

0 commit comments

Comments
 (0)