kclay / rethink-scala

Scala Driver for RethinkDB
Other
100 stars 24 forks source link

update does not work #36

Closed shengc closed 9 years ago

shengc commented 9 years ago

again, trying the update from the 10 minute tutorial

table
  .filter(_ \ "name" === "Jean-Luc Picard")
  .update(author => (author \ "posts").toSeq[Post] append Post("Shakespeare", "What a piece of work is man..."))
  .run match {
  case Failure(error) =>
    throw error
  case Success(result) =>
    println(result)

This always hints me the error "the Inserted value must be object, not array". the argument type of update is Var => Typed, which does not suggest an arraytype is disallowed.

Also, adding another field to "Author" does not work...

table.update(Map("type" -> "fictional")).run

I dont know exactly how this should work, since Author is a case class, what would come out if a new field can be added ?

Last, the real time change does not work,

table.changes.map({ cursor => cursor.foreach { change: cursor.ChunkType => 
  println("old val: " + change.old)
  println("new val: " + change.new)
} })

I did successfully deleted a few documents in author table, but no changes are pushed to the console.

Thank you, I am almost done with the tutorial. Once that is ready, I will contribute it to the project, so that people in the future would get started more easily.

kclay commented 9 years ago

Looking here seems you can only pass an map or an expression that resolves to a map, so you can do the following

table
  .filter(_ \ "name" === "Jean-Luc Picard")
  .update(author => Map("posts"-> (author \ "posts").toSeq[Post] append Post("Shakespeare", "What a piece of work is man...")))
  .run match {
  case Failure(error) =>
    throw error
  case Success(result) =>
    println(result)

As for adding a field, the value is added to each required (it may help to load up the dataexplorer and verify quries there as well). But the reason why you are not getting the field is because the table is typed to Author so its returning your case class declared as Author which doesn't have the extra field. Normally in this case you would update your case class with the new fields to keep type-safety.

If you are just testing the waters since you extended Document you have some helper functions that can extract the underlying json so you can do something like this

import com.rethinkscala.Blocking.functional._

import com.rethinkscala.Document

import scala.util.Success

implicit val connection = Blocking(Version3(authKey = "foobar"))

case class Post(title: String, content: String)

case class Author(
                   name: String,
                   tvShow: String,
                   posts: List[Post]
                   ) extends Document

r.dbCreate("foo").run
r.db("foo").tableCreate("authors").run
val table = r.db("foo").table[Author]("authors")

table.insert(Author("foo","bar",List.empty)).run
>> scala.util.Try[com.rethinkscala.InsertResult] = Success(InsertResult(1,0,0,0,None,List(814886a0-2188-4e7d-966b-777a5ae6bc45),0,0))

// add another field
table.update(Map("type"->"functional")).run
>> scala.util.Try[com.rethinkscala.ChangeResult] = Success(ChangeResult(1,17,0,0,0,None,0,null))

// wont show the added fields since its not declared in the case class
val Success(authors) = table.run
>> authors: com.rethinkscala.net.DefaultCursor[Author] = DefaultCursor(Author(foo,bar,List()))

println((authors.head \ "type").as[String])
>>Some(functional)

As for change feeds , yes that feature isn't supported yet, still working out kinks for it, I need it to support both blocking and async modes of the driver and seems like rethinkdb doesn't automatically push changes, you must poll for it so need to adjust code to work in that context.

Also questions like these are really helpful, I'm going to use some of this for updating the wiki.

shengc commented 9 years ago

awesome, all work ! For the update method, can its argument type be updated to reflect what is truly allowed by rethink db ? I think Var => Typed is indeed misleading. Maybe Var => Map[String, String], and Var => Map[String, Typed] are good choices? I am only exposed to rethink db for two days, so I probably miss a few other cases.

For the real time change feeds, yes, that is a very important, if not the most important, feature from the perspective of clients using rethink db. Either rxjava or scalaz-stream can be a decent tool for implementation. I personally prefer the latter, since I'd like the whole realtime update process be purely lazy. It brings in scalaz dependency transitively as well, I think import functional. should convert the original Either[, ] to scalaz.\/[, ] instead of Try[], so that client can do leftMap on the result, which sometimes can be useful.

Again, thanks for your very timely response. I am going to turn the tutorial code into an example, and submit a pull request in the next few days. This can be tremendously helpful .

kclay commented 9 years ago

Anytime, so your doing a tutorial for scala and rethinkdb.. NICE!!. As for the scalaz-stream that looks good, I'll do some reading on it