AugustNagro / magnum

A 'new look' for database access in Scala
Apache License 2.0
153 stars 10 forks source link

Frag equivalent of sql interpolator? #35

Closed fdietze closed 4 weeks ago

fdietze commented 1 month ago

Hi, what is the equivalent Frag of writing sql"... $param"? I thought it would be Frag("... ? ", IArray(param)), but that doesn't return any result rows, because the param is probably not passed correctly to the db.

I'm using sqlite.

def getReplyIds(parent_id: Long)(using con: DbCon): Vector[Long] = {

  // this works
  val frag = sql"select id from post where parent_id = ${parent_id}"

  // this doesn't work:
  // val frag = Frag("select id from post where parent_id = ?", params = IArray(parent_id))

  frag.query[Long].run()
}

For context, I'm experimenting with sqlc to generate Scala functions from raw sql queries: https://github.com/fdietze/sqlc-gen-from-template

AugustNagro commented 4 weeks ago

Hi, Frag takes three arguments: https://github.com/AugustNagro/magnum/blob/master/magnum/src/main/scala/com/augustnagro/magnum/Frag.scala

You're missing the third writer: FragWriter argument (you do not want the default Frag.emptyWriter)

For an example on how to implement FragWriter, see for example https://github.com/AugustNagro/magnum/blob/master/magnum/src/main/scala/com/augustnagro/magnum/Spec.scala#L38

fdietze commented 3 weeks ago

For reference, this is what I came up with:

def fragWriter(params: Seq[Any]): FragWriter = { (preparedStatement, startPos) =>
  var i = 0
  val n = params.size
  while (i < n) {
    val param = params(i)
    param match {
      case param: Int    => preparedStatement.setInt(startPos + i, param)
      case param: Long   => preparedStatement.setLong(startPos + i, param)
      case param: String => preparedStatement.setString(startPos + i, param)
      case param: Double => preparedStatement.setDouble(startPos + i, param)
    }
    i += 1
  }
  startPos + params.size
}