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

ISODate type #15

Open
PovilasID opened this issue Mar 9, 2014 · 6 comments
Open

ISODate type #15

PovilasID opened this issue Mar 9, 2014 · 6 comments

Comments

@PovilasID
Copy link

I have ISODate type dates in mongo database and I tried using DateTime for case class type variables but then I try to load the data in browser it is empty not even an empty array. I tried using Long, Int or String types to no result.

@markschaake
Copy link
Owner

Sorry, but I don't know how I'd help you here without some code example. Could you provide a gist or something?

@markschaake
Copy link
Owner

Also, which DateTime are you using? Is it org.joda.time.DateTime? Or something else?

Sprest uses the ReactiveMongo library behind the scenes. For DateTime support, this means serialization to/from Long using the http://reactivemongo.org/releases/0.10/api/index.html#reactivemongo.bson.BSONDateTime case class, which handles dates as Long values. There is no BSON class provided by ReactiveMongo for ISODate type as you mention. You should do some testing and see if the ISODate values from your database are handled as strings. If so, then you should be able to work around your issue by providing a custom Spray JSON JsonFormat type class. For example:

package foo

import spray.json._
import org.joda.time.DateTime

object Formats extends DefaultJsonProtocol {
  implicit object DateTimeFormat extends JsonFormat[DateTime] {
    override def read(json: JsValue): DateTime = json match {
      case JsString(dateString) => new DateTime(dateString)
      case invalid => throw new SerializationException(s"Invalid JsValue for DateTime: $invalid")
    }
    override def write(dateTime: DateTime): JsValue => JsString(dateTime.toString("<some format string>"))
  }
}

And then you'll need to import your custom formats in your models so they will use it for serialazation:

package foo.models

import foo.Formats._

import spray.json._
import org.joda.time.DateTime

case class MyModel(var id: Option[String] = None, date: DateTime)
object MyModel {
  implicit val jsFormat = jsonFormat2(MyModel.apply)
}

@mikebevz
Copy link

hi @markschaake ,

I've got similar issue.
There is BSONDateTime type in ReactiveMongo, which accepts timestamp.
Is it possible to map DateTime to BSONDateTime, so the date is stored as ISODate in Mongo? For now it stores it as LongNumber.

@mikebevz
Copy link

I mean, when I wass using vanilla ReactiveMongo mapping it was storing BSONDateTime as ISODate and not Long.

@PovilasID
Copy link
Author

I am using Joda DateTime

case class CustomClass(
    var id:     Option[String] = None,
    title:      Option[String],
    desc:       Option[String],
    cover:      Option[String],
    start_time: Option[DateTime], 
    end_time:   Option[DateTime]) extends Model[String]

object CustomClass extends ModelCompanion[CustomClass, String] {
  import sprest.Formats._
  implicit val CustomClassJsonFormat = jsonFormat6(SEvent.apply _)
}

I just need date field to be used for filtering in database and to be readable outside other than that if it is ISO or a long I don't care I will adapt to that as long as I am give the tools to do so.
So how I should format my database fields so that I could perform queries in database and what is the format I should try and use that data in code, so that I could manipulate it latter?

BTW I am having the same issue if id is not string but ObjectID type in the database it also breaks the formating :/

@markschaake
Copy link
Owner

Oh I think I see what's going on. You are using the sprest.reactivemongo.typemappers.SprayJsonTypeMapper, which does not handle BSONDateTime (see https://github.com/markschaake/sprest/blob/master/sprest-reactivemongo/src/main/scala/sprest/reactivemongo/typemappers/TypeMappers.scala#L53). I originally did this on purpose as to allow the user to choose his/her own DateTime implementation. It is a glaring omission though to not support the BSONDateTime, so I'll add a mixin trait that you can use for mapping BSONDateTime to joda.time.DateTime. It would work something like this:

implicit object MyJsonTypeMapper extends DefaultJsonTypeMapper with JodaTimeMapping

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

No branches or pull requests

3 participants