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

json array implicits for doobie #132

Merged
merged 13 commits into from
Jul 12, 2024
Merged

json array implicits for doobie #132

merged 13 commits into from
Jul 12, 2024

Conversation

salamonpavel
Copy link
Contributor

Introduced package for postgres related implicits for working with Circe's Json.
Closes #111

Copy link

github-actions bot commented Jul 9, 2024

JaCoCo slick module code coverage report - scala 2.13.11

Overall Project 87.73% 🍏

There is no coverage information present for the Files changed

Copy link

github-actions bot commented Jul 10, 2024

JaCoCo core module code coverage report - scala 2.13.11

Overall Project 57.44% 🍏

There is no coverage information present for the Files changed

Copy link

github-actions bot commented Jul 10, 2024

JaCoCo doobie module code coverage report - scala 2.13.11

Overall Project 70.6% -16.46% 🍏
Files changed 56.19%

File Coverage
package.scala 42.04% -59.18%

.temap(pgArray => pgArrayToListOfJson(pgArray))
}

implicit val jsonbArrayPut: Put[List[Json]] = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

what about JSONB get utils?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems to work for both :D

Copy link
Collaborator

Choose a reason for hiding this comment

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

really?

because the GET implements json[]:

  implicit val jsonArrayGet: Get[List[Json]] = {
    Get.Advanced
      .other[PgArray](
        NonEmptyList.of("json[]")
      )
      .temap(pgArray => pgArrayToListOfJson(pgArray))
  }

perhaps for the sake of consistency in the naming we should either: implement the second one with jsonb[] or name this one somehow so that it's understandable that it's also for JSONB GET?

Copy link
Collaborator

Choose a reason for hiding this comment

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

or just something like this :D

implicit val jsonbArrayGet: Get[List[Json]] = jsonArrayGet

Copy link
Contributor

Choose a reason for hiding this comment

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

I would just mention it in the comments (documentation) of the classes. Which btw, is missing somewhat 👼

Copy link
Collaborator

Choose a reason for hiding this comment

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

discussed on a call

Copy link
Contributor Author

@salamonpavel salamonpavel Jul 11, 2024

Choose a reason for hiding this comment

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

implemented like this after discussion on a call

// to be used for both json[] and jsonb[] as it handles well both and we want to avoid collision
// when resolving implicits
implicit val jsonOrJsonbArrayGet: Get[List[Json]] = {
    Get.Advanced
      .other[PgArray](
        NonEmptyList.of("json[]")
      )
      .temap(pgArray => pgArrayToListOfJson(pgArray))
  }

Copy link
Contributor

Choose a reason for hiding this comment

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

Somwhat longer but acceptable, IMHO.


import scala.util.{Failure, Success, Try}

package object implicits {
Copy link
Collaborator

Choose a reason for hiding this comment

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

also, what about JSON/JSONB put and get? (these here are List of JSON/JSONB, so I'm talking about the non-array variant)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm okay! Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've made it available also in the implicits object so we can import everything from the same place.

CREATE OR REPLACE FUNCTION integration.retrieve_actors_jsonb(idUntil INT)
RETURNS TABLE(actors_jsonb JSONB[]) AS $$
BEGIN
RETURN QUERY SELECT a.actors_jsonb FROM integration.actors_json_seq AS a WHERE id <= idUntil;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I like the <= idea :)

val actorsAsJsonList = values.map(_.asJson)
Seq(
{
import za.co.absa.db.fadb.doobie.postgres.circe.implicits.jsonArrayPut
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't it enough now, to import once and on the top level?

Copy link
Contributor Author

@salamonpavel salamonpavel Jul 11, 2024

Choose a reason for hiding this comment

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

It would be enough to import it once on the top of the file alongside other imports had we had only json[] or jsonb[]. In this case though we have both and given the way implicits are resolved by their types the compiler is unable to figure out which one to use. That's why in this particular case the imports have to be scope using the curly braces for individual query fragments.

Maybe that's also the reason why doobie doesn't support the array variants by default...

Copy link
Contributor

Choose a reason for hiding this comment

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

Ooh, I missed that they a different import (the one letter difference). 😊
Tiny thing, if you would want to add an explanatory comment why the import is done like this

lsulak
lsulak previously approved these changes Jul 11, 2024
Copy link
Collaborator

@lsulak lsulak left a comment

Choose a reason for hiding this comment

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

I think it's good to go, last few details we discussed on a call. Once the CI checks pass, I'm happy for you to merge it (or wait for someone else from curation for additional review if you want)

lsulak
lsulak previously approved these changes Jul 11, 2024
benedeki
benedeki previously approved these changes Jul 11, 2024
Copy link
Contributor

@benedeki benedeki left a comment

Choose a reason for hiding this comment

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

I believe it's merge-able.
Unless you want to add the code comments, particularly ScalaDoc to the implicits.

val actorsAsJsonList = values.map(_.asJson)
Seq(
{
import za.co.absa.db.fadb.doobie.postgres.circe.implicits.jsonArrayPut
Copy link
Contributor

Choose a reason for hiding this comment

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

Ooh, I missed that they a different import (the one letter difference). 😊
Tiny thing, if you would want to add an explanatory comment why the import is done like this

.temap(pgArray => pgArrayToListOfJson(pgArray))
}

implicit val jsonbArrayPut: Put[List[Json]] = {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would just mention it in the comments (documentation) of the classes. Which btw, is missing somewhat 👼

@@ -69,7 +69,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
min-coverage-overall: ${{ env.coverage-overall }}
min-coverage-changed-files: ${{ env.coverage-changed-files }}
title: JaCoCo `model` module code coverage report - scala ${{ env.scalaLong }}
title: JaCoCo `core` module code coverage report - scala ${{ env.scalaLong }}
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for this fix, good boy scout 👍

.temap(pgArray => pgArrayToListOfJson(pgArray))
}

implicit val jsonbArrayPut: Put[List[Json]] = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Somwhat longer but acceptable, IMHO.

lsulak
lsulak previously approved these changes Jul 11, 2024
@AbsaOSS AbsaOSS deleted a comment from github-actions bot Jul 12, 2024
@AbsaOSS AbsaOSS deleted a comment from github-actions bot Jul 12, 2024
@lsulak lsulak merged commit 18b2106 into master Jul 12, 2024
6 of 7 checks passed
@lsulak lsulak deleted the feature/111-implicits branch July 12, 2024 07:58
@salamonpavel
Copy link
Contributor Author

Release notes:

  • Introduced implicits for storing and retrieving json and jsonb arrays from postgres using Circe's Json.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add JSON[] and JSONB[] support to doobie module
3 participants