Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialize joda time from string in grails?

I had a LocalTime field (using Joda Time) in Grails domain class.

Class WorkDone{
    LocalTime duration
}

Now I have altered this field to String (with Text constraint) so that it can support duration larger than 24 hrs.

String duration

The problem is there is already some data in database. And I want to sanitize that data through database migrations in Grails. I am using Postgres which saves LocalTime as Bytea (binary data).

When I call WorkDone.duration it returns me a String of the form:

\xaced0005737200176f72672e6a6f64612e74696d652e4c6f63616c54696d65fffff44abbf29def0200024a000c694c6f63616c4d696c6c69734c000b694368726f6e6f6c6f677974001a4c6f72672f6a6f64612f74696d652f4368726f6e6f6c6f67793b78700000000000000000737200276f72672e6a6f64612e74696d652e6368726f6e6f2e49534f4368726f6e6f6c6f67792453747562a9c811667137502703000078707372001f6f72672e6a6f64612e74696d652e4461746554696d655a6f6e652453747562a62f019a7c321ae30300007870770500035554437878

How can I extract time from this string?

like image 848
Yash Agarwal Avatar asked Nov 22 '13 21:11

Yash Agarwal


3 Answers

Your data is scaped in bytea Hex format, (starts with \x) take a look at PostgreSQL docs

http://www.postgresql.org/docs/current/static/datatype-binary.html

You have to unescape it before read as ObjectInputStream ang get the LocalTime object, unescape it and then try again as Raphael suggest.

like image 172
vzamanillo Avatar answered Oct 14 '22 23:10

vzamanillo


You should have done a data-migration before changing your Data-type to String.

Here is what you should do. 1. Change the Data-type of the field back to LocalTime. 2. Create a new field with String Date. 3. Write a script that would get all date in LocalTime and convert it to String and save it in new field. 4. Once you have your data migrated, delete the old field and then rename your new field to duration.

like image 36
Ashish Joseph Avatar answered Oct 14 '22 23:10

Ashish Joseph


I ended up doing the following -

grailsChange{
        change{
            sql.eachRow("Select id,duration from work_done"){
                def wdId =  it.id
                def durationObj = (LocalTime)(new ObjectInputStream(new ByteArrayInputStream(it.duration))).readObject()

                durationObj = durationObj.toString().substring(0,8)

                WorkDone.executeUpdate("update WorkDone wd set wd.duration=:newDuration" +
                    "where wd.id=:wdId",
                    [newDuration:durationObj ,wdId:wdId ])
            }
        }
like image 1
Yash Agarwal Avatar answered Oct 14 '22 23:10

Yash Agarwal