Skip to content
This repository was archived by the owner on Oct 14, 2018. It is now read-only.

Quill 1.0.1 support with java.time. #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
25 changes: 24 additions & 1 deletion src/main/scala/com/geirsson/codegen/Codegen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ case class CodegenOptions(
@HelpMessage("only tested with postgresql") jdbcDriver: String = "org.postgresql.Driver",
@HelpMessage(
"top level imports of generated file"
) imports: String = """import io.getquill.WrappedValue""",
) imports: String = """""",
@HelpMessage(
"package name for generated classes"
) `package`: String = "tables",
Expand Down Expand Up @@ -140,8 +140,31 @@ case class Codegen(options: CodegenOptions, namingStrategy: NamingStrategy) {
s"""|package ${options.`package`}
|${options.imports}
|
|/**
| * Generated using [[https://github.com/olafurpg/scala-db-codegen scala-db-codegen]]
| * - Number of tables: ${tables.size}
| * - Database URL: ${options.url}
| * - Database schema: ${options.schema}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea!

| * - Database user: ${options.user}
| */
|//noinspection ScalaStyle
|object Tables {
|
| /**
| * Quill used to have this trait before v1, but it's still useful to keep.
| * Examples are: pattern matching on wrapped type and conversion to JSON objects.
| */
| trait WrappedValue[T] extends Any with WrappedType { self: AnyVal =>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since WrappedValue is static, could we move it somewhere outside the generated code?

  • Easiest solution would probably be to put this into a separate source file and link to from the readme for people to copy-paste into their project.
  • Another solution is put it into a separate project in the build and publish to Maven.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A separate file maybe? I think a separate project is a bit overkill for only 7 lines of code. If we generate two files (one dynamic and one static) in the same package, then the generated code is fully stand-alone valid Scala code and users won't need to manually fix imports and such. What do you think?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a "staticFile: Option[File]" option where we write static contents if the setting is configured. WDYT?

| type Type = T
| def value: T
| override def toString = s"$$value"
| }
|
| trait WrappedType extends Any {
| type Type
| def value: Type
| }
|
|$body
|}
""".stripMargin
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/geirsson/codegen/TypeMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ object TypeMap {
"varchar" -> "String",
"serial" -> "Int",
"bigserial" -> "Long",
"timestamp" -> "java.util.Date",
"timestamp" -> "java.time.LocalDateTime", // Since Quill 1.0.1, the scalajs-java-time library supports java time.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay \o/

I haven't tried scalajs-java-time yet, seems to still be a wip. However, I'm happy to change the default since I suspect the scalajs use-case is not important for all quill users. Worst case, it's still still possible to override this in case you want java.util.Date.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't have any experience with scalajs-java-time. I assume the quill maintainers did this with good reasons and I am very happy with their choice. Just like you said, there is always a way to override the defaults so I think we're safe doing this. 👍

"bytea" -> "Array[Byte]", // PostgreSQL
"uuid" -> "java.util.UUID", // H2, PostgreSQL
"json" -> "String" // PostgreSQL
Expand Down
3 changes: 2 additions & 1 deletion src/test/scala/com/geirsson/codegen/CodegenTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class CodegenTest extends FunSuite {
| id integer unique not null,
| article_unique_id uuid,
| author_id integer,
| is_published boolean
| is_published boolean,
| published_at timestamp
|);
|
|ALTER TABLE article
Expand Down
40 changes: 33 additions & 7 deletions src/test/scala/com/geirsson/codegen/Tables.scala
Original file line number Diff line number Diff line change
@@ -1,28 +1,54 @@
package com.geirsson.codegen
import io.getquill.WrappedValue

/**
* Generated using [[https://github.com/olafurpg/scala-db-codegen scala-db-codegen]]
* - Number of tables: 3
* - Database URL: jdbc:postgresql:postgres
* - Database schema: scala_db_codegen
* - Database user: postgres
*/
//noinspection ScalaStyle
object Tables {

/**
* Quill used to have this trait before v1, but it's still useful to keep.
* Examples are: pattern matching on wrapped type and conversion to JSON objects.
*/
trait WrappedValue[T] extends Any with WrappedType { self: AnyVal =>
type Type = T
def value: T
override def toString = s"$value"
}

trait WrappedType extends Any {
type Type
def value: Type
}

/////////////////////////////////////////////////////
// Article
/////////////////////////////////////////////////////
case class Article(id: Article.Id,
articleUniqueId: Option[Article.ArticleUniqueId],
authorId: Option[TestUser.Id],
isPublished: Option[Article.IsPublished])
isPublished: Option[Article.IsPublished],
publishedAt: Option[Article.PublishedAt])
object Article {
def create(id: Int,
articleUniqueId: Option[java.util.UUID],
authorId: Option[Int],
isPublished: Option[Boolean]): Article = {
isPublished: Option[Boolean],
publishedAt: Option[java.time.LocalDateTime]): Article = {
Article(Id(id),
articleUniqueId.map(ArticleUniqueId.apply),
authorId.map(TestUser.Id.apply),
isPublished.map(IsPublished.apply))
isPublished.map(IsPublished.apply),
publishedAt.map(PublishedAt.apply))
}
case class Id(value: Int) extends AnyVal with WrappedValue[Int]
case class ArticleUniqueId(value: java.util.UUID) extends AnyVal with WrappedValue[java.util.UUID]
case class IsPublished(value: Boolean) extends AnyVal with WrappedValue[Boolean]
case class Id(value: Int) extends AnyVal with WrappedValue[Int]
case class ArticleUniqueId(value: java.util.UUID) extends AnyVal with WrappedValue[java.util.UUID]
case class IsPublished(value: Boolean) extends AnyVal with WrappedValue[Boolean]
case class PublishedAt(value: java.time.LocalDateTime) extends AnyVal with WrappedValue[java.time.LocalDateTime]
}

/////////////////////////////////////////////////////
Expand Down