class Test
::DB.mapping({
first_time: {type: Int32?},
})
::JSON.mapping({
first_time: {type: Int32?},
})
end
get "/" do |env|
tested = ::DB.db.query_all("SELECT first_time FROM test_table", as: Test)
tested.to_json
#tested.map(&.inspect).join("\n")
end
First_time from test_table is an integer which contains an epoch. Is there anyway I can convert the value into a date/time format within the JSON.mapping? If not which other options do I have to convert before the to_json action?
Tried this
require "json"
require "kemal"
require "./db"
class Device
::DB.mapping({
first_time: {type: Time, converter: Time::EpochConverter},
})
::JSON.mapping({
first_time: {type: Time, converter: Time::EpochConverter},
})
end
get "/" do |env|
devices = Devices::DB.db.query_all("SELECT first_time FROM devices", as: Device)
devices.to_json
#devices.map(&.inspect).join("\n")
end
Kemal.run
Got this in return on compiling
Error in src/devices.cr:22: instantiating 'DB::Database#query_all(String)'
devices = Devices::DB.db.query_all("SELECT first_time FROM devices", as: Device)
^~~~~~~~~
in lib/db/src/db/query_methods.cr:241: instantiating 'DB::ResultSet+#read(Device.class)'
rs.read(type)
^~~~
in lib/db/src/db/result_set.cr:74: instantiating 'Device.class#new(DB::ResultSet+)'
type.new(self)
^~~
in src/devices.cr:7: expanding macro
::DB.mapping({
^
in macro 'mapping' /root/crystal/hello-world/lib/db/src/db/mapping.cr:60, line 41:
1. include ::DB::Mappable
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14. @first_time : Time
15.
16. def first_time=(_first_time : Time )
17. @first_time = _first_time
18. end
19.
20. def first_time
21. @first_time
22. end
23.
24.
25. def self.from_rs(__temp_52 : ::DB::ResultSet)
26. __temp_53 = Array(self).new
27. __temp_52.each do
28. __temp_53 << self.new(__temp_52)
29. end
30. __temp_53
31. ensure
32. __temp_52.close
33. end
34.
35. def initialize(__temp_52 : ::DB::ResultSet)
36.
37. __temp_54 = nil
38. __temp_55 = false
39.
40.
> 41. __temp_52.each_column do |col_name|
42. case col_name
43.
44. when "first_time"
45. __temp_55 = true
46. __temp_54 =
47.
48. Time::EpochConverter.from_rs(__temp_52)
49.
50.
51. else
52.
53. raise ::DB::MappingException.new("unknown result set attribute: #{col_name}")
54.
55. end
56. end
57.
58.
59.
60. if __temp_54.is_a?(Nil) && !__temp_55
61. raise ::DB::MappingException.new("missing result set attribute: first_time")
62. end
63.
64.
65.
66.
67.
68. @first_time = __temp_54.as(Time)
69.
70.
71. end
72.
instantiating 'DB::ResultSet+#each_column()'
in src/devices.cr:7: expanding macro
::DB.mapping({
^
in macro 'mapping' /root/crystal/hello-world/lib/db/src/db/mapping.cr:60, line 41:
1. include ::DB::Mappable
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14. @first_time : Time
15.
16. def first_time=(_first_time : Time )
17. @first_time = _first_time
18. end
19.
20. def first_time
21. @first_time
22. end
23.
24.
25. def self.from_rs(__temp_52 : ::DB::ResultSet)
26. __temp_53 = Array(self).new
27. __temp_52.each do
28. __temp_53 << self.new(__temp_52)
29. end
30. __temp_53
31. ensure
32. __temp_52.close
33. end
34.
35. def initialize(__temp_52 : ::DB::ResultSet)
36.
37. __temp_54 = nil
38. __temp_55 = false
39.
40.
> 41. __temp_52.each_column do |col_name|
42. case col_name
43.
44. when "first_time"
45. __temp_55 = true
46. __temp_54 =
47.
48. Time::EpochConverter.from_rs(__temp_52)
49.
50.
51. else
52.
53. raise ::DB::MappingException.new("unknown result set attribute: #{col_name}")
54.
55. end
56. end
57.
58.
59.
60. if __temp_54.is_a?(Nil) && !__temp_55
61. raise ::DB::MappingException.new("missing result set attribute: first_time")
62. end
63.
64.
65.
66.
67.
68. @first_time = __temp_54.as(Time)
69.
70.
71. end
72.
instantiating 'DB::ResultSet+#each_column()'
in src/devices.cr:7: expanding macro
::DB.mapping({
^
in macro 'mapping' /root/crystal/hello-world/lib/db/src/db/mapping.cr:60, line 48:
1. include ::DB::Mappable
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14. @first_time : Time
15.
16. def first_time=(_first_time : Time )
17. @first_time = _first_time
18. end
19.
20. def first_time
21. @first_time
22. end
23.
24.
25. def self.from_rs(__temp_52 : ::DB::ResultSet)
26. __temp_53 = Array(self).new
27. __temp_52.each do
28. __temp_53 << self.new(__temp_52)
29. end
30. __temp_53
31. ensure
32. __temp_52.close
33. end
34.
35. def initialize(__temp_52 : ::DB::ResultSet)
36.
37. __temp_54 = nil
38. __temp_55 = false
39.
40.
41. __temp_52.each_column do |col_name|
42. case col_name
43.
44. when "first_time"
45. __temp_55 = true
46. __temp_54 =
47.
> 48. Time::EpochConverter.from_rs(__temp_52)
49.
50.
51. else
52.
53. raise ::DB::MappingException.new("unknown result set attribute: #{col_name}")
54.
55. end
56. end
57.
58.
59.
60. if __temp_54.is_a?(Nil) && !__temp_55
61. raise ::DB::MappingException.new("missing result set attribute: first_time")
62. end
63.
64.
65.
66.
67.
68. @first_time = __temp_54.as(Time)
69.
70.
71. end
72.
undefined method 'from_rs' for Time::EpochConverter:Module
Where do I go wrong?
It’s only for JSON/YAML.mapping
.
I’d maybe look into using an ORM that would handle this stuff for you.
EDIT: It looks like DB.mapping
also supports converters. Should be able to add a from_rs
method to the Time::EpochConverter
module so it would also work for DB.mapping
. Probably something like
module Time::EpochConverter
def self.from_rs(result_set : DB::ResultSet) : Time
Time.unix result_set.read(Int32)
end
end
Something like that maybe? @miessos
Will do, thank you for your assistance.
Which database driver are you using? Maybe such a converter should be added to the driver. Or maybe it’s already there?