Skip to content

Commit

Permalink
support optional uuid columns
Browse files Browse the repository at this point in the history
  • Loading branch information
AugustNagro committed Jun 19, 2024
1 parent 2822529 commit 45eac35
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 81 deletions.
16 changes: 15 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ val testcontainersVersion = "0.40.12"

lazy val root = project
.in(file("."))
.aggregate(magnum, magnumPg)
.aggregate(magnum, magnumPg, magnumMySql)

lazy val magnum = project
.in(file("magnum"))
Expand Down Expand Up @@ -74,3 +74,17 @@ lazy val magnumPg = project
"com.dimafeng" %% "testcontainers-scala-postgresql" % testcontainersVersion % Test
)
)

lazy val magnumMySql = project
.in(file("magnum-mysql"))
.dependsOn(magnum)
.settings(
Test / fork := true,
publish / skip := false,
libraryDependencies ++= Seq(
"mysql" % "mysql-connector-java" % "8.0.32" % Test,
"org.scalameta" %% "munit" % "0.7.29" % Test,
"com.dimafeng" %% "testcontainers-scala-munit" % testcontainersVersion % Test,
"com.dimafeng" %% "testcontainers-scala-mysql" % testcontainersVersion % Test
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.augustnagro.magnum.mysql

import com.augustnagro.magnum.DbCodec

import java.sql.{PreparedStatement, ResultSet, Types}
import java.util.UUID

object MySqlCodec:

given VarCharUUIDCodec: DbCodec[UUID] with
def queryRepr: String = "?"
val cols: IArray[Int] = IArray(Types.VARCHAR)
def readSingle(rs: ResultSet, pos: Int): UUID = {
val uuidString = rs.getString(pos)
uuidString match
case null => null
case x => UUID.fromString(x)
}
def writeSingle(entity: UUID, ps: PreparedStatement, pos: Int): Unit =
ps.setString(pos, entity.toString)
11 changes: 11 additions & 0 deletions magnum-mysql/src/test/resources/mysql-user.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
drop table if exists mag_user;

create table mag_user (
id bigint auto_increment primary key,
social_id varchar(36)
);

insert into mag_user (social_id) values
('d06443a6-3efb-46c4-a66a-a80a8a9a5388'),
('529b6c6d-7228-4da5-81d7-13b706f78ddb'),
(null);
80 changes: 80 additions & 0 deletions magnum-mysql/src/test/scala/MySqlCodecTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import com.dimafeng.testcontainers.MySQLContainer
import com.dimafeng.testcontainers.munit.fixtures.TestContainersFixtures
import com.mysql.cj.jdbc.MysqlDataSource
import munit.FunSuite
import org.testcontainers.utility.DockerImageName

import java.nio.file.{Files, Path}
import javax.sql.DataSource
import scala.util.Using.Manager
import com.augustnagro.magnum.mysql.MySqlCodec.VarCharUUIDCodec
import com.augustnagro.magnum.*

import java.util.UUID

class MySqlCodecTests extends FunSuite, TestContainersFixtures {

case class MagUserCreator(
socialId: Option[UUID]
) derives DbCodec

@Table(MySqlDbType, SqlNameMapper.CamelToSnakeCase)
case class MagUser(
@Id id: Long,
socialId: Option[UUID]
) derives DbCodec

val userRepo = Repo[MagUserCreator, MagUser, Long]

test("select nullable uuid"):
connect(ds()):
val users = userRepo.findAll
assert(users.exists(_.socialId.isEmpty))
assert(
users.exists(
_.socialId.contains(
UUID.fromString("529b6c6d-7228-4da5-81d7-13b706f78ddb")
)
)
)

test("insert uuid"):
connect(ds()):
val uuid = UUID.randomUUID()
val uc = MagUserCreator(socialId = Some(uuid))
userRepo.insert(uc)
val users = userRepo.findAll
assert(users.exists(_.socialId.contains(uuid)))

test("insert null uuid"):
connect(ds()):
val existingNullCount = userRepo.findAll.count(_.socialId.isEmpty)
val uc = MagUserCreator(socialId = None)
userRepo.insert(uc)
val newNullCount = userRepo.findAll.count(_.socialId.isEmpty)
assertEquals(newNullCount, existingNullCount + 1)

val mySqlContainer = ForAllContainerFixture(
MySQLContainer
.Def(dockerImageName = DockerImageName.parse("mysql:8.0.32"))
.createContainer()
)

override def munitFixtures: Seq[Fixture[_]] =
super.munitFixtures :+ mySqlContainer

def ds(): DataSource =
val mySql = mySqlContainer()
val ds = MysqlDataSource()
ds.setURL(mySql.jdbcUrl)
ds.setUser(mySql.username)
ds.setPassword(mySql.password)
ds.setAllowMultiQueries(true)
val userSql =
Files.readString(Path.of(getClass.getResource("/mysql-user.sql").toURI))
Manager(use =>
val con = use(ds.getConnection)
use(con.prepareStatement(userSql)).execute()
).get
ds
}
2 changes: 1 addition & 1 deletion magnum/src/main/scala/com/augustnagro/magnum/DbCodec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ object DbCodec:

given UUIDCodec: DbCodec[UUID] with
def queryRepr: String = "?"
val cols: IArray[Int] = IArray(Types.JAVA_OBJECT)
val cols: IArray[Int] = IArray(Types.OTHER)
def readSingle(rs: ResultSet, pos: Int): UUID =
rs.getObject(pos, classOf[UUID])
def writeSingle(entity: UUID, ps: PreparedStatement, pos: Int): Unit =
Expand Down
27 changes: 18 additions & 9 deletions magnum/src/test/resources/clickhouse-person.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ create table person (
first_name Nullable(String),
last_name String not null,
is_admin Bool not null,
created DateTime not null default now()
created DateTime not null default now(),
social_id Nullable(UUID)
)
engine = MergeTree()
order by created;
Expand All @@ -16,54 +17,62 @@ insert into person values
'George',
'Washington',
true,
toDateTime('2023-03-05 02:26:00')
toDateTime('2023-03-05 02:26:00'),
toUUID('d06443a6-3efb-46c4-a66a-a80a8a9a5388')
),
(
toUUID('12970806-606d-42ff-bb9c-3187bbd360dd'),
'Alexander',
'Hamilton',
true,
toDateTime('2023-03-05 02:27:00')
toDateTime('2023-03-05 02:27:00'),
toUUID('529b6c6d-7228-4da5-81d7-13b706f78ddb')
),
(
toUUID('834a2bd2-6842-424f-97e0-fe5ed02c3653'),
'John',
'Adams',
true,
toDateTime('2023-03-05 02:28:00')
toDateTime('2023-03-05 02:28:00'),
null
),
(
toUUID('60492bb2-fe02-4d02-9c6d-ae03fa6f2243'),
'Benjamin',
'Franklin',
true,
toDateTime('2023-03-05 02:29:00')
toDateTime('2023-03-05 02:29:00'),
null
),
(
toUUID('2244eef4-b581-4305-824f-efe8f70e6bb7'),
'John',
'Jay',
true,
toDateTime('2023-03-05 02:30:00')
toDateTime('2023-03-05 02:30:00'),
null
),
(
toUUID('fb3c479a-0521-4f06-b6ad-218db867518c'),
'Thomas',
'Jefferson',
true,
toDateTime('2023-03-05 02:31:00')
toDateTime('2023-03-05 02:31:00'),
null
),
(
toUUID('8fefe1d8-20eb-44a0-84da-d328334e1e11'),
'James',
'Madison',
true,
toDateTime('2023-03-05 02:32:00')
toDateTime('2023-03-05 02:32:00'),
null
),
(
toUUID('8a2d842a-0d03-463c-8c34-43b38120f9e4'),
null,
'Nagro',
false,
toDateTime('2023-03-05 02:33:00')
toDateTime('2023-03-05 02:33:00'),
null
);
21 changes: 11 additions & 10 deletions magnum/src/test/resources/h2-person.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ create table person (
first_name varchar(50),
last_name varchar(50) not null,
is_admin boolean not null,
created timestamp default current_timestamp
created timestamp default current_timestamp,
social_id UUID
);

insert into person (first_name, last_name, is_admin, created) values
('George', 'Washington', true, now()),
('Alexander', 'Hamilton', true, now()),
('John', 'Adams', true, now()),
('Benjamin', 'Franklin', true, now()),
('John', 'Jay', true, now()),
('Thomas', 'Jefferson', true, now()),
('James', 'Madison', true, now()),
(null, 'Nagro', false, now());
insert into person (first_name, last_name, is_admin, created, social_id) values
('George', 'Washington', true, now(), 'd06443a6-3efb-46c4-a66a-a80a8a9a5388'),
('Alexander', 'Hamilton', true, now(), '529b6c6d-7228-4da5-81d7-13b706f78ddb'),
('John', 'Adams', true, now(), null),
('Benjamin', 'Franklin', true, now(), null),
('John', 'Jay', true, now(), null),
('Thomas', 'Jefferson', true, now(), null),
('James', 'Madison', true, now(), null),
(null, 'Nagro', false, now(), null);
21 changes: 11 additions & 10 deletions magnum/src/test/resources/pg-person.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ create table person (
first_name varchar(50),
last_name varchar(50) not null,
is_admin boolean not null,
created timestamptz not null default now()
created timestamptz not null default now(),
social_id UUID
);

insert into person (first_name, last_name, is_admin, created) values
('George', 'Washington', true, now()),
('Alexander', 'Hamilton', true, now()),
('John', 'Adams', true, now()),
('Benjamin', 'Franklin', true, now()),
('John', 'Jay', true, now()),
('Thomas', 'Jefferson', true, now()),
('James', 'Madison', true, now()),
(null, 'Nagro', false, timestamp '1997-08-12');
insert into person (first_name, last_name, is_admin, created, social_id) values
('George', 'Washington', true, now(), 'd06443a6-3efb-46c4-a66a-a80a8a9a5388'),
('Alexander', 'Hamilton', true, now(), '529b6c6d-7228-4da5-81d7-13b706f78ddb'),
('John', 'Adams', true, now(), null),
('Benjamin', 'Franklin', true, now(), null),
('John', 'Jay', true, now(), null),
('Thomas', 'Jefferson', true, now(), null),
('James', 'Madison', true, now(), null),
(null, 'Nagro', false, timestamp '1997-08-12', null);
Loading

0 comments on commit 45eac35

Please sign in to comment.