mirror of
https://gitea.invidious.io/iv-org/shard-crystal-sqlite3.git
synced 2024-08-15 00:53:26 +00:00
Fix timestamp reading issue (#68)
This commit is contained in:
parent
367c11031d
commit
985bfa2d7c
6 changed files with 76 additions and 5 deletions
|
@ -46,5 +46,5 @@ end
|
||||||
|
|
||||||
### DB::Any
|
### DB::Any
|
||||||
|
|
||||||
* `Time` is implemented as `TEXT` column using `SQLite3::DATE_FORMAT` format.
|
* `Time` is implemented as `TEXT` column using `SQLite3::DATE_FORMAT_SUBSECOND` format (or `SQLite3::DATE_FORMAT_SECOND` if the text does not contain a dot).
|
||||||
* `Bool` is implemented as `INT` column mapping `0`/`1` values.
|
* `Bool` is implemented as `INT` column mapping `0`/`1` values.
|
||||||
|
|
|
@ -34,7 +34,9 @@ DB::DriverSpecs(DB::Any).run do
|
||||||
sample_value 1.5_f32, "float", "1.5", type_safe_value: false
|
sample_value 1.5_f32, "float", "1.5", type_safe_value: false
|
||||||
sample_value 1.5, "float", "1.5"
|
sample_value 1.5, "float", "1.5"
|
||||||
sample_value Time.utc(2016, 2, 15), "text", "'2016-02-15 00:00:00.000'", type_safe_value: false
|
sample_value Time.utc(2016, 2, 15), "text", "'2016-02-15 00:00:00.000'", type_safe_value: false
|
||||||
|
sample_value Time.utc(2016, 2, 15, 10, 15, 30), "text", "'2016-02-15 10:15:30'", type_safe_value: false
|
||||||
sample_value Time.utc(2016, 2, 15, 10, 15, 30), "text", "'2016-02-15 10:15:30.000'", type_safe_value: false
|
sample_value Time.utc(2016, 2, 15, 10, 15, 30), "text", "'2016-02-15 10:15:30.000'", type_safe_value: false
|
||||||
|
sample_value Time.utc(2016, 2, 15, 10, 15, 30, nanosecond: 123000000), "text", "'2016-02-15 10:15:30.123'", type_safe_value: false
|
||||||
sample_value Time.local(2016, 2, 15, 7, 15, 30, location: Time::Location.fixed("fixed", -3*3600)), "text", "'2016-02-15 10:15:30.000'", type_safe_value: false
|
sample_value Time.local(2016, 2, 15, 7, 15, 30, location: Time::Location.fixed("fixed", -3*3600)), "text", "'2016-02-15 10:15:30.000'", type_safe_value: false
|
||||||
|
|
||||||
ary = UInt8[0x53, 0x51, 0x4C, 0x69, 0x74, 0x65]
|
ary = UInt8[0x53, 0x51, 0x4C, 0x69, 0x74, 0x65]
|
||||||
|
|
57
spec/result_set_spec.cr
Normal file
57
spec/result_set_spec.cr
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
require "./spec_helper"
|
||||||
|
|
||||||
|
describe SQLite3::ResultSet do
|
||||||
|
it "reads integer data types" do
|
||||||
|
with_db do |db|
|
||||||
|
db.exec "CREATE TABLE test_table (test_int integer)"
|
||||||
|
db.exec "INSERT INTO test_table (test_int) values (?)", 42
|
||||||
|
db.query("SELECT test_int FROM test_table") do |rs|
|
||||||
|
rs.each do
|
||||||
|
rs.read.should eq(42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reads string data types" do
|
||||||
|
with_db do |db|
|
||||||
|
db.exec "CREATE TABLE test_table (test_text text)"
|
||||||
|
db.exec "INSERT INTO test_table (test_text) values (?), (?)", "abc", "123"
|
||||||
|
db.query("SELECT test_text FROM test_table") do |rs|
|
||||||
|
rs.each do
|
||||||
|
rs.read.should match(/abc|123/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reads time data types" do
|
||||||
|
with_db do |db|
|
||||||
|
db.exec "CREATE TABLE test_table (test_date datetime)"
|
||||||
|
timestamp = Time.utc
|
||||||
|
db.exec "INSERT INTO test_table (test_date) values (current_timestamp)"
|
||||||
|
db.query("SELECT test_date FROM test_table") do |rs|
|
||||||
|
rs.each do
|
||||||
|
rs.read(Time).should be_close(timestamp, 1.second)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reads time stored in text fields, too" do
|
||||||
|
with_db do |db|
|
||||||
|
db.exec "CREATE TABLE test_table (test_date text)"
|
||||||
|
timestamp = Time.utc
|
||||||
|
# Try 3 different ways: our own two formats and using SQLite's current_timestamp.
|
||||||
|
# They should all work.
|
||||||
|
db.exec "INSERT INTO test_table (test_date) values (?)", timestamp.to_s SQLite3::DATE_FORMAT_SUBSECOND
|
||||||
|
db.exec "INSERT INTO test_table (test_date) values (?)", timestamp.to_s SQLite3::DATE_FORMAT_SECOND
|
||||||
|
db.exec "INSERT INTO test_table (test_date) values (current_timestamp)"
|
||||||
|
db.query("SELECT test_date FROM test_table") do |rs|
|
||||||
|
rs.each do
|
||||||
|
rs.read(Time).should be_close(timestamp, 1.second)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,7 +2,8 @@ require "db"
|
||||||
require "./sqlite3/**"
|
require "./sqlite3/**"
|
||||||
|
|
||||||
module SQLite3
|
module SQLite3
|
||||||
DATE_FORMAT = "%F %H:%M:%S.%L"
|
DATE_FORMAT_SUBSECOND = "%F %H:%M:%S.%L"
|
||||||
|
DATE_FORMAT_SECOND = "%F %H:%M:%S"
|
||||||
|
|
||||||
# :nodoc:
|
# :nodoc:
|
||||||
TIME_ZONE = Time::Location::UTC
|
TIME_ZONE = Time::Location::UTC
|
||||||
|
|
|
@ -64,11 +64,22 @@ class SQLite3::ResultSet < DB::ResultSet
|
||||||
end
|
end
|
||||||
|
|
||||||
def read(t : Time.class) : Time
|
def read(t : Time.class) : Time
|
||||||
Time.parse read(String), SQLite3::DATE_FORMAT, location: SQLite3::TIME_ZONE
|
text = read(String)
|
||||||
|
if text.includes? "."
|
||||||
|
Time.parse text, SQLite3::DATE_FORMAT_SUBSECOND, location: SQLite3::TIME_ZONE
|
||||||
|
else
|
||||||
|
Time.parse text, SQLite3::DATE_FORMAT_SECOND, location: SQLite3::TIME_ZONE
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def read(t : Time?.class) : Time?
|
def read(t : Time?.class) : Time?
|
||||||
read(String?).try { |v| Time.parse(v, SQLite3::DATE_FORMAT, location: SQLite3::TIME_ZONE) }
|
read(String?).try { |v|
|
||||||
|
if v.includes? "."
|
||||||
|
Time.parse v, SQLite3::DATE_FORMAT_SUBSECOND, location: SQLite3::TIME_ZONE
|
||||||
|
else
|
||||||
|
Time.parse v, SQLite3::DATE_FORMAT_SECOND, location: SQLite3::TIME_ZONE
|
||||||
|
end
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def read(t : Bool.class) : Bool
|
def read(t : Bool.class) : Bool
|
||||||
|
|
|
@ -70,7 +70,7 @@ class SQLite3::Statement < DB::Statement
|
||||||
end
|
end
|
||||||
|
|
||||||
private def bind_arg(index, value : Time)
|
private def bind_arg(index, value : Time)
|
||||||
bind_arg(index, value.in(SQLite3::TIME_ZONE).to_s(SQLite3::DATE_FORMAT))
|
bind_arg(index, value.in(SQLite3::TIME_ZONE).to_s(SQLite3::DATE_FORMAT_SUBSECOND))
|
||||||
end
|
end
|
||||||
|
|
||||||
private def bind_arg(index, value)
|
private def bind_arg(index, value)
|
||||||
|
|
Loading…
Reference in a new issue