Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestInsert: Don't wrap inherited ID types #143

Merged
merged 3 commits into from
Oct 21, 2024
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
21 changes: 20 additions & 1 deletion init/data/test-tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,23 @@ create table "table-with-generated-columns"
WHEN name = 'a' THEN 'a-name'
ELSE 'some-name'
END) STORED
)
);


CREATE TABLE issue142
(
tabellkode TEXT NOT NULL ,
CONSTRAINT tabell_pk PRIMARY KEY (tabellkode)
);

CREATE TABLE issue142_2
(
tabellkode TEXT NOT NULL,
CONSTRAINT tabell2_pk PRIMARY KEY (tabellkode),
CONSTRAINT tabell2_tabell_fk FOREIGN KEY (tabellkode) REFERENCES issue142 (tabellkode)
);

INSERT INTO issue142 (tabellkode)
VALUES ('aa'),
('bb')
;
5 changes: 3 additions & 2 deletions typo-scripts/src/scala/scripts/GeneratedAdventureWorks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ object GeneratedAdventureWorks {
val selector = Selector.ExcludePostgresInternal
val typoLogger = TypoLogger.Console
val metadb = Await.result(MetaDb.fromDb(typoLogger, ds, selector, schemaMode = SchemaMode.MultiSchema), Duration.Inf)
val openEnumSelector = Selector.relationNames("title", "title_domain", "issue142")
val relationNameToOpenEnum = Await.result(
OpenEnum.find(
ds,
typoLogger,
Selector.All,
openEnumSelector = Selector.relationNames("title", "title_domain"),
openEnumSelector = openEnumSelector,
metaDb = metadb
),
Duration.Inf
Expand All @@ -58,7 +59,7 @@ object GeneratedAdventureWorks {
case (_, "firstname") => "adventureworks.userdefined.FirstName"
case ("sales.creditcard", "creditcardid") => "adventureworks.userdefined.CustomCreditcardId"
},
openEnums = Selector.relationNames("title", "title_domain"),
openEnums = openEnumSelector,
generateMockRepos = !Selector.relationNames("purchaseorderdetail"),
enablePrimaryKeyType = !Selector.relationNames("billofmaterials"),
enableTestInserts = Selector.All,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* File has been automatically generated by `typo`.
*
* IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
*/
package adventureworks
package public
package issue142

import typo.dsl.Path
import typo.dsl.SqlExpr.FieldLikeNoHkt
import typo.dsl.SqlExpr.IdField
import typo.dsl.Structure.Relation

trait Issue142Fields {
def tabellkode: IdField[Issue142Id, Issue142Row]
}

object Issue142Fields {
lazy val structure: Relation[Issue142Fields, Issue142Row] =
new Impl(Nil)

private final class Impl(val _path: List[Path])
extends Relation[Issue142Fields, Issue142Row] {

override lazy val fields: Issue142Fields = new Issue142Fields {
override def tabellkode = IdField[Issue142Id, Issue142Row](_path, "tabellkode", None, None, x => x.tabellkode, (row, value) => row.copy(tabellkode = value))
}

override lazy val columns: List[FieldLikeNoHkt[?, Issue142Row]] =
List[FieldLikeNoHkt[?, Issue142Row]](fields.tabellkode)

override def copy(path: List[Path]): Impl =
new Impl(path)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* File has been automatically generated by `typo`.
*
* IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
*/
package adventureworks
package public
package issue142

import anorm.Column
import anorm.ParameterMetaData
import anorm.ToStatement
import java.sql.Types
import play.api.libs.json.JsValue
import play.api.libs.json.Reads
import play.api.libs.json.Writes

/** Type for the primary key of table `public.issue142`. It has some known values:
* - aa
* - bb
*/
sealed abstract class Issue142Id(val value: String)

object Issue142Id {
def apply(underlying: String): Issue142Id =
ByName.getOrElse(underlying, Unknown(underlying))
case object aa extends Issue142Id("aa")
case object bb extends Issue142Id("bb")
case class Unknown(override val value: String) extends Issue142Id(value)
val All: List[Issue142Id] = List(aa, bb)
val ByName: Map[String, Issue142Id] = All.map(x => (x.value, x)).toMap

implicit lazy val arrayColumn: Column[Array[Issue142Id]] = Column.columnToArray[String](Column.columnToString, implicitly).map(_.map(Issue142Id.apply))
implicit lazy val arrayToStatement: ToStatement[Array[Issue142Id]] = ToStatement.arrayToParameter(ParameterMetaData.StringParameterMetaData).contramap(_.map(_.value))
implicit lazy val column: Column[Issue142Id] = Column.columnToString.map(Issue142Id.apply)
implicit lazy val ordering: Ordering[Issue142Id] = Ordering.by(_.value)
implicit lazy val parameterMetadata: ParameterMetaData[Issue142Id] = new ParameterMetaData[Issue142Id] {
override def sqlType: String = "text"
override def jdbcType: Int = Types.OTHER
}
implicit lazy val reads: Reads[Issue142Id] = Reads[Issue142Id]{(value: JsValue) => value.validate(Reads.StringReads).map(Issue142Id.apply)}
implicit lazy val text: Text[Issue142Id] = new Text[Issue142Id] {
override def unsafeEncode(v: Issue142Id, sb: StringBuilder) = Text.stringInstance.unsafeEncode(v.value, sb)
override def unsafeArrayEncode(v: Issue142Id, sb: StringBuilder) = Text.stringInstance.unsafeArrayEncode(v.value, sb)
}
implicit lazy val toStatement: ToStatement[Issue142Id] = ToStatement.stringToStatement.contramap(_.value)
implicit lazy val writes: Writes[Issue142Id] = Writes[Issue142Id](value => Writes.StringWrites.writes(value.value))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* File has been automatically generated by `typo`.
*
* IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
*/
package adventureworks
package public
package issue142

import java.sql.Connection
import typo.dsl.DeleteBuilder
import typo.dsl.SelectBuilder
import typo.dsl.UpdateBuilder

trait Issue142Repo {
def delete: DeleteBuilder[Issue142Fields, Issue142Row]
def deleteById(tabellkode: Issue142Id)(implicit c: Connection): Boolean
def deleteByIds(tabellkodes: Array[Issue142Id])(implicit c: Connection): Int
def insert(unsaved: Issue142Row)(implicit c: Connection): Issue142Row
def insertStreaming(unsaved: Iterator[Issue142Row], batchSize: Int = 10000)(implicit c: Connection): Long
def select: SelectBuilder[Issue142Fields, Issue142Row]
def selectAll(implicit c: Connection): List[Issue142Row]
def selectById(tabellkode: Issue142Id)(implicit c: Connection): Option[Issue142Row]
def selectByIds(tabellkodes: Array[Issue142Id])(implicit c: Connection): List[Issue142Row]
def selectByIdsTracked(tabellkodes: Array[Issue142Id])(implicit c: Connection): Map[Issue142Id, Issue142Row]
def update: UpdateBuilder[Issue142Fields, Issue142Row]
def upsert(unsaved: Issue142Row)(implicit c: Connection): Issue142Row
def upsertBatch(unsaved: Iterable[Issue142Row])(implicit c: Connection): List[Issue142Row]
/* NOTE: this functionality is not safe if you use auto-commit mode! it runs 3 SQL statements */
def upsertStreaming(unsaved: Iterator[Issue142Row], batchSize: Int = 10000)(implicit c: Connection): Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* File has been automatically generated by `typo`.
*
* IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
*/
package adventureworks
package public
package issue142

import anorm.BatchSql
import anorm.NamedParameter
import anorm.ParameterValue
import anorm.SqlStringInterpolation
import java.sql.Connection
import scala.annotation.nowarn
import typo.dsl.DeleteBuilder
import typo.dsl.SelectBuilder
import typo.dsl.SelectBuilderSql
import typo.dsl.UpdateBuilder

class Issue142RepoImpl extends Issue142Repo {
override def delete: DeleteBuilder[Issue142Fields, Issue142Row] = {
DeleteBuilder(""""public"."issue142"""", Issue142Fields.structure)
}
override def deleteById(tabellkode: Issue142Id)(implicit c: Connection): Boolean = {
SQL"""delete from "public"."issue142" where "tabellkode" = ${ParameterValue(tabellkode, null, Issue142Id.toStatement)}""".executeUpdate() > 0
}
override def deleteByIds(tabellkodes: Array[Issue142Id])(implicit c: Connection): Int = {
SQL"""delete
from "public"."issue142"
where "tabellkode" = ANY(${tabellkodes})
""".executeUpdate()

}
override def insert(unsaved: Issue142Row)(implicit c: Connection): Issue142Row = {
SQL"""insert into "public"."issue142"("tabellkode")
values (${ParameterValue(unsaved.tabellkode, null, Issue142Id.toStatement)})
returning "tabellkode"
"""
.executeInsert(Issue142Row.rowParser(1).single)

}
override def insertStreaming(unsaved: Iterator[Issue142Row], batchSize: Int = 10000)(implicit c: Connection): Long = {
streamingInsert(s"""COPY "public"."issue142"("tabellkode") FROM STDIN""", batchSize, unsaved)(Issue142Row.text, c)
}
override def select: SelectBuilder[Issue142Fields, Issue142Row] = {
SelectBuilderSql(""""public"."issue142"""", Issue142Fields.structure, Issue142Row.rowParser)
}
override def selectAll(implicit c: Connection): List[Issue142Row] = {
SQL"""select "tabellkode"
from "public"."issue142"
""".as(Issue142Row.rowParser(1).*)
}
override def selectById(tabellkode: Issue142Id)(implicit c: Connection): Option[Issue142Row] = {
SQL"""select "tabellkode"
from "public"."issue142"
where "tabellkode" = ${ParameterValue(tabellkode, null, Issue142Id.toStatement)}
""".as(Issue142Row.rowParser(1).singleOpt)
}
override def selectByIds(tabellkodes: Array[Issue142Id])(implicit c: Connection): List[Issue142Row] = {
SQL"""select "tabellkode"
from "public"."issue142"
where "tabellkode" = ANY(${tabellkodes})
""".as(Issue142Row.rowParser(1).*)

}
override def selectByIdsTracked(tabellkodes: Array[Issue142Id])(implicit c: Connection): Map[Issue142Id, Issue142Row] = {
val byId = selectByIds(tabellkodes).view.map(x => (x.tabellkode, x)).toMap
tabellkodes.view.flatMap(id => byId.get(id).map(x => (id, x))).toMap
}
override def update: UpdateBuilder[Issue142Fields, Issue142Row] = {
UpdateBuilder(""""public"."issue142"""", Issue142Fields.structure, Issue142Row.rowParser)
}
override def upsert(unsaved: Issue142Row)(implicit c: Connection): Issue142Row = {
SQL"""insert into "public"."issue142"("tabellkode")
values (
${ParameterValue(unsaved.tabellkode, null, Issue142Id.toStatement)}
)
on conflict ("tabellkode")
do nothing
returning "tabellkode"
"""
.executeInsert(Issue142Row.rowParser(1).single)

}
override def upsertBatch(unsaved: Iterable[Issue142Row])(implicit c: Connection): List[Issue142Row] = {
def toNamedParameter(row: Issue142Row): List[NamedParameter] = List(
NamedParameter("tabellkode", ParameterValue(row.tabellkode, null, Issue142Id.toStatement))
)
unsaved.toList match {
case Nil => Nil
case head :: rest =>
new anorm.adventureworks.ExecuteReturningSyntax.Ops(
BatchSql(
s"""insert into "public"."issue142"("tabellkode")
values ({tabellkode})
on conflict ("tabellkode")
do nothing
returning "tabellkode"
""",
toNamedParameter(head),
rest.map(toNamedParameter)*
)
).executeReturning(Issue142Row.rowParser(1).*)
}
}
/* NOTE: this functionality is not safe if you use auto-commit mode! it runs 3 SQL statements */
override def upsertStreaming(unsaved: Iterator[Issue142Row], batchSize: Int = 10000)(implicit c: Connection): Int = {
SQL"""create temporary table issue142_TEMP (like "public"."issue142") on commit drop""".execute(): @nowarn
streamingInsert(s"""copy issue142_TEMP("tabellkode") from stdin""", batchSize, unsaved)(Issue142Row.text, c): @nowarn
SQL"""insert into "public"."issue142"("tabellkode")
select * from issue142_TEMP
on conflict ("tabellkode")
do nothing
;
drop table issue142_TEMP;""".executeUpdate()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* File has been automatically generated by `typo`.
*
* IF YOU CHANGE THIS FILE YOUR CHANGES WILL BE OVERWRITTEN.
*/
package adventureworks
package public
package issue142

import java.sql.Connection
import scala.annotation.nowarn
import typo.dsl.DeleteBuilder
import typo.dsl.DeleteBuilder.DeleteBuilderMock
import typo.dsl.DeleteParams
import typo.dsl.SelectBuilder
import typo.dsl.SelectBuilderMock
import typo.dsl.SelectParams
import typo.dsl.UpdateBuilder
import typo.dsl.UpdateBuilder.UpdateBuilderMock
import typo.dsl.UpdateParams

class Issue142RepoMock(map: scala.collection.mutable.Map[Issue142Id, Issue142Row] = scala.collection.mutable.Map.empty) extends Issue142Repo {
override def delete: DeleteBuilder[Issue142Fields, Issue142Row] = {
DeleteBuilderMock(DeleteParams.empty, Issue142Fields.structure, map)
}
override def deleteById(tabellkode: Issue142Id)(implicit c: Connection): Boolean = {
map.remove(tabellkode).isDefined
}
override def deleteByIds(tabellkodes: Array[Issue142Id])(implicit c: Connection): Int = {
tabellkodes.map(id => map.remove(id)).count(_.isDefined)
}
override def insert(unsaved: Issue142Row)(implicit c: Connection): Issue142Row = {
val _ = if (map.contains(unsaved.tabellkode))
sys.error(s"id ${unsaved.tabellkode} already exists")
else
map.put(unsaved.tabellkode, unsaved)

unsaved
}
override def insertStreaming(unsaved: Iterator[Issue142Row], batchSize: Int = 10000)(implicit c: Connection): Long = {
unsaved.foreach { row =>
map += (row.tabellkode -> row)
}
unsaved.size.toLong
}
override def select: SelectBuilder[Issue142Fields, Issue142Row] = {
SelectBuilderMock(Issue142Fields.structure, () => map.values.toList, SelectParams.empty)
}
override def selectAll(implicit c: Connection): List[Issue142Row] = {
map.values.toList
}
override def selectById(tabellkode: Issue142Id)(implicit c: Connection): Option[Issue142Row] = {
map.get(tabellkode)
}
override def selectByIds(tabellkodes: Array[Issue142Id])(implicit c: Connection): List[Issue142Row] = {
tabellkodes.flatMap(map.get).toList
}
override def selectByIdsTracked(tabellkodes: Array[Issue142Id])(implicit c: Connection): Map[Issue142Id, Issue142Row] = {
val byId = selectByIds(tabellkodes).view.map(x => (x.tabellkode, x)).toMap
tabellkodes.view.flatMap(id => byId.get(id).map(x => (id, x))).toMap
}
override def update: UpdateBuilder[Issue142Fields, Issue142Row] = {
UpdateBuilderMock(UpdateParams.empty, Issue142Fields.structure, map)
}
override def upsert(unsaved: Issue142Row)(implicit c: Connection): Issue142Row = {
map.put(unsaved.tabellkode, unsaved): @nowarn
unsaved
}
override def upsertBatch(unsaved: Iterable[Issue142Row])(implicit c: Connection): List[Issue142Row] = {
unsaved.map { row =>
map += (row.tabellkode -> row)
row
}.toList
}
/* NOTE: this functionality is not safe if you use auto-commit mode! it runs 3 SQL statements */
override def upsertStreaming(unsaved: Iterator[Issue142Row], batchSize: Int = 10000)(implicit c: Connection): Int = {
unsaved.foreach { row =>
map += (row.tabellkode -> row)
}
unsaved.size
}
}
Loading
Loading