views:

176

answers:

1

Hi all,

I have a table called Basic , start_time is one field with type :VARCHAR(5), which actually stores a 5 bytes time data: byte 0 and 1 map to the year , month and day, and byte 2 to 4 map to the hour, min and second. So, it could possible bytes 2 ,3 ,4 are all 0. And I want to do following query :

Basic.find (:all , :conditions => "start_time > ? AND end_time < ?" , start_time , end_time)

Here are the questions:

Suppose in VARCHAR(5) format ,the start time is [214, 222,0 ,0, 0] (Jun, 24th, 2009) and the end time is [214, 223, 0, 0, 0] (Jun , 25, 2009).

As activerecord maps VARCHAR(5) to String , so in above query the start_time and end_time should also be String. What is the correct way to convert above VARCHAR(5) format time to the String?

I did it this way, but fails to get correct result:

tmp = [214, 222,0 ,0 ,0].map {|t| t.to_s(16)} ; start_time = tmp.to_s

And i was using sqlite3 adapter for activerecord.

Thanks for your help.


I have found where the problem is: "\000" is not allowed to be contained in the start_time when do follwing query:

Basic.find (:all , :conditions => "start_time > ? AND end_time < ?" , start_time , end_time)

So, I need to do two steps:

  1. [214, 222,0 ,0, 0] - > [214,222]

  2. [214,222] -> "\326\336"

The 1st steps can be done using:

a = [214,222,0,0,0] 
while a.last ==0 do a.pop end

The 2nd steps can be done using:

a = [214,222]
a.pack("c" * a.size)

However, I still can not do query when start_time = [214, 222,0 ,23, 0] , because the corresponding string contains "\000" in the middle. fortunately, It would not be a big problem in our appication , as we never query in hours level, that means last two number will always be 0.

A: 

Is this what you're after?

[214, 222, 0, 0, 0].inject(""){|s,c| s << c.chr; s} # => "\326\336\000\000\000"

As to why I know this...I wanted to say MLM on twitter once, without actually saying it. Because if you actually say it, you get auto-followed by all these MLM spammers. So instead I said

[77, 76, 77].inject(""){|s,c| s << c.chr; s}

In your case, though, it seems like a lot of work just to avoid using a timestamp.

Sarah Mei