d2sqlite3
d2sqlite3 copied to clipboard
Add support for DateTime and Duration to Statement.d
Line 195 to statement.d of 0.13.1 I've been using this block of code for a little while and it's been helpful. I know dates are complicated and don't know enough about the overall architecture to prepare a proper pull request.
import core.time : Duration;
import std.datetime.date : DateTime;
void bind(int index, DateTime value)
in
{
assert(index > 0 && index <= p.paramCount, "parameter index out of range");
}
body
{
assert(p.handle);
string str = value.toISOString();
auto ptr = anchorMem(cast(void*) str.ptr);
checkResult(sqlite3_bind_text64(p.handle, index, cast(const(char)*) ptr, str.length, &releaseMem, SQLITE_UTF8));
}
void bind(int index, Duration value)
in
{
assert(index > 0 && index <= p.paramCount, "parameter index out of range");
}
body
{
assert(p.handle);
string str = value.to!string();
auto ptr = anchorMem(cast(void*) str.ptr);
checkResult(sqlite3_bind_text64(p.handle, index, cast(const(char)*) ptr, str.length, &releaseMem, SQLITE_UTF8));
}
IsBindable needs to be extended...the const part seems pretty not correct, but makes it work for me. enum bool isBindable(T) = ... || is(T == Duration) || is(T == DateTime) || is(T == const(Duration)) || is(T == const(DateTime))
Edit: add peek function for DateTime
T peek(T)(int index)
if (is(T == DateTime))
{
assert(statement.handle, "operation on an empty statement");
auto s = (cast(const(char)*) sqlite3_column_text(statement.handle, internalIndex(index)));
string value = fromStringz( s ).to!string;
return DateTime.fromISOString( value );
}
Still thinking about the deserialization for a Duration...
I'm not convinced yet :
- I don't want to add specialized functions for any type that the SQLite API doesn't handle natively. Moreover, if there's a
bind
function, there should be an equivalentpeek
function IMO. - Storing dates and times as strings or integers is easy; conversions/constructions as well.