by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
shrynx
@shrynx

yes that does work. Thank you !
i was able to figure out but i am still struggling with something like this

  val addPrices: Update[FruitPrice] = {
    val fruit: Fruits = Fruits.Apple
    val query = s"""
                INSERT INTO fruit_prices (price, vendor, fruit)
                VALUES (?, ?,  $fruit)
              """
    Update[FruitPrice](query)
  }

and this gives error

INSERT INTO fruit_prices (price, vendor, fruit)
                VALUES ('20.5', 'Some Vendor',   Apple)  was aborted: ERROR: column "Apple" does not exist

because of how the mapping uses entryName and the enum has UpperCase trait, the resultant query should be
with quote and capitalised

INSERT INTO fruit_prices (price, vendor, fruit)
                VALUES ('20.5', 'Some Vendor', 'APPLE')

when i hard code the string 'APPLE', it does work

shrynx
@shrynx
ahh never mind this is just string interpolation
thanks @tpolecat
Jente Hidskes
@Hjdskes

Hello folks! I'm running into an issue I don't understand, maybe you can show me what I am missing.

I have a case class with a number of fields, let's say case class Foo(a: A, b: B, c: C), where each field has a Read instance. Yet doobie can not infer a Read[Foo] instance. I have verified in a scratchpad that indeed Read[A], Read[B] and Read[C] instances exist. The peculiar thing is that if I comment out a: A in Foo, a Read[Foo] instance can be inferred. However, as I said, a Read[A] instance does exist! What am I missing?

Rob Norris
@tpolecat
@ trait A; trait B; trait C 
defined trait A
defined trait B
defined trait C

@ implicit def ra: Read[A] = ??? 
defined function ra

@ implicit def rb: Read[B] = ??? 
defined function rb

@ implicit def rc: Read[C] = ??? 
defined function rc

@ case class Foo(a: A, b: B, c: C) 
defined class Foo

@ def rf = Read[Foo] 
defined function rf
So that should work. Can you reproduce the issue minimally?
Paulius Imbrasas
@CremboC
is there any way to avoid the parameterization? So I want to just literally interpolate a variable into a sql statement?
Rob Norris
@tpolecat
sql"blah ${Fragment.const("foo")} fnord"
But obviously be careful, never do that with user-provided data.
Paulius Imbrasas
@CremboC
of course, thank you!
not really related, but are separate INSERTS in a single transaction are done in parallel in Postgres?
Rob Norris
@tpolecat
No, sessions are fundamentally sequential.
Paulius Imbrasas
@CremboC
thanks :thumbsup:
Sushovan
@sushovannits
Hi very new to entire scala. I am trying to figure out how do I do a select query and get a class object which has an extra field which is not present in db. Any help please
I have been going through the column vector mapping but not sure.
nigredo-tori
@nigredo-tori

@sushovannits, the easiest way would be to do something like

final case class MyClass(
  column1: Column1,
  ...
  columnN: ColumnN,
  extraField: ExtraField
)
val extraFieldValue: ExtraField = ???

val query = fr"SELECT column1, column2, ..., columnN"
  .query[(Column1, Column2, ..., ColumnN)]
  .map { case (c1, c2, ... cN) =>
    MyClass(c1, c2, ..., cN, extraFieldValue)
  }

That is, you read all the columns that are in the database, and manually convert the rows to your type. If you have to do this more than once, you might want a custom Read instance, but that's optional.

Sushovan
@sushovannits

@nigredo-tori thank you so much for replying. Yes I tried this but I do have to do for multiple times (for insert/update/select). I was trying to implement the Read instance like this:

implicit val pointRead: Read[Point] =
  Read[(Int, Int)].map { case (x, y) => new Point(x, y, x+y) }
// pointRead: Read[Point] = doobie.util.Read@e67456a

But I am a bit confused how to use the Read instance.
If Point is like

case class Point(x: Int, y: Int, extraNumberNotInDb : Int)

and I a do a query as:

sql"select x, y from point_table limit 1".Query[Point]..."

It still gives an error of The column index is out of range: 3, number of columns: 2.

Sushovan
@sushovannits
My bad :cry: the Read instance was not visible. Thanks for your help.
Jente Hidskes
@Hjdskes

@tpolecat Your scatchpad works just fine, as expected. I'm starting to believe that my issue has to do with my field a: A being a newtype over a refined NonEmptyFiniteString with an automatically generated Meta instance using newtype's Coercible, i.e., something like this:

import doobie.util.Read
import doobie.util.meta.Meta
import eu.timepit.refined.types.string.NonEmptyFiniteString
import io.estatico.newtype.Coercible

implicit def coercibleMeta[R, N](implicit ev: Coercible[Meta[R], Meta[N]], r: Meta[R]): Meta[N] = ev(r)

@newtype case class A(value: NonEmptyFiniteString[100])

trait B
trait C

implicit def ra: Read[A] = ???
implicit def rb: Read[B] = ???
implicit def rc: Read[C] = ???

case class Foo(a: A, b: B, c: C)

def rf = Read[Foo]

Although this also works. And as I said, in the actual code Read[A] does resolve, it's only Read[Foo] that does not when it has the field a: A...

sinanspd
@sinanspd
that's weird
can you try defining a coercibleRead and coerciblePut ?
Jente Hidskes
@Hjdskes
@sinanspd Sure :) Did you maybe mean coercibleRead and coercibleWrite, or CoercibleGet and coerciblePut?
sinanspd
@sinanspd
Actually I originally meant Read and Put. I don't know how common it is to have that combination but it works with newType because the requirements for your "read" and "write" are different. However I am just realizing you have a refined type inside a newtype (my bad, 3:30 am here ...), so I am not sure what the requirements will be.
is doobie-refined still a thing ? if so, does using that help? (also I missed the original conversation so, apologies if these were already covered)
Jente Hidskes
@Hjdskes
No worries @sinanspd, I appreciate you thinking with me! doobie-refined is still a thing (at least, AFAIK) and we're using that. Could you elaborate on "because the requirements for your "read" and "write" are different.", I'm not sure I understand what you're trying to say here.
sinanspd
@sinanspd

I'm not sure I understand what you're trying to say here.

Since when you are persisting this, I am assuming you will be unpacking the object. i.e. "insert (....) values (foo.a, foo.b) If that is the case, you only need to tell doobie how to persist that one column that is newtype (as opposed to the whole Write for the entire Foo), but when you are reading it, you are reading the entire Foo so you need a wider instruction such as Read

I personally like this, so I can have more focused instructions for updates but everyone has different preferences
Jente Hidskes
@Hjdskes
Aah yes, that makes sense
sinanspd
@sinanspd
So I get away with
 implicit def coerciblePut[N: Coercible[R, *], R: Put]: Put[N] = Put[R].contramap[N](_.repr.asInstanceOf[R])
 implicit def coercibleRead[N: Coercible[R, *], R: Read]: Read[N] = Read[R].map(_.asInstanceOf[N])
sinanspd
@sinanspd
However, to be frank, I usually use the refined types at the api level and they are usually loosened by the time I persist them, so I don't know how this is react to a refined type. I think you will still need to have a Put & Read in scope telling doobie what to do. Unfortunately, defining those generically for a refined type will look slightly uglier, possibly something along the lines Meta[T].xmap(refType.refine[P](_) match { ...}) (maybe ??) so I am hoping doobie-refined could provide those instances for you.
that being said, I tend to give bad advice at 4 in the morning, so I will shut up. Hopefully there was something at least somewhat useful here... good luck!
Jente Hidskes
@Hjdskes

Alright, something has resolved this. Perhaps a clean cache or something like that. However, now I'm getting

Error:(21, 4) could not find implicit value for parameter ev: doobie.util.Get[Option[java.time.LocalDate]]
Get[Option[LocalDate]]

I have import doobie.implicits.javatime._ imported, however, and this has worked fine before. This case is getting more and more mysterious...

Jente Hidskes
@Hjdskes
import java.time.LocalDate

import doobie.util.{Get, Read}
import doobie.implicits.javatime._

Read[LocalDate]
Get[LocalDate]
Read[Option[LocalDate]]
Get[Option[LocalDate]]
This breaks on the last line
Sushovan
@sushovannits

I need some more help to get my project going. I am following this:
tpolecat/doobie#718
I am trying to use something like:

sql"INSERT INTO demo (id, text) VALUES (1, 'hallo') RETURNING *".query[Demo].unique

But I keep getting the error "No results were returned by the query."
Please help.

Sushovan
@sushovannits

Basically I want to do:

sql"INSERT INTO demo (id, text) VALUES (1, 'hallo') RETURNING *, inc(id)".query[Demo].unique

as Demo has an extra property which is computed from id

Rob Norris
@tpolecat
Does it return rows when you run it in psql?
Sushovan
@sushovannits
Yes it does return rows when I run it in psql.
Sushovan
@sushovannits
Really stuck here and would be great if someone helps.
Lena BrĂ¼der
@lenalebt
So, it does not really help you, but I do have some code in my application that looks like the one you provided, and I can confirm this working. But I query as a tuple instead - this should not make a difference, but maybe you could try that?
    sql"""INSERT INTO tree_node_tags(id, customer_id, display_name, comment)
         |VALUES(${EntityId.random}, $customerId, $displayName, $comment)
         |RETURNING id, modified_date""".stripMargin.query[(EntityId, ZonedDateTime)]
^^that is my concrete snippet
I also am returning the changed values
Krisztian Lachata
@lachatak
hi channel. Is there any way in doobie to provide name for postgres queries?
Rob Norris
@tpolecat
Can you be more specific?
@sushovannits you should not be getting "no results were returned"
Is the problem that you're returning more columns than you have fields to hold in Demo?
Can you describe your problem in more detail?
Rob Norris
@tpolecat
@ sql"insert into person (name) values ('Steve') returning id, name, id > 3".query[Woozle].to[List].transact(xa).unsafeRunSync 
res6: List[Woozle] = List(Woozle(9, "Steve", true))
where
case class Woozle(n: Int, s: String, b: Boolean)