I'm trying to read sqlite database with ZeosLib components and Delphi XE2. Everything works perfectly, except when I try to read three timestamp values that are stored, which are basically 17 digit numbers. Instead getting the proper value, I get zero. Function that reads database data (watch for commented lines):
procedure TCookieImporter.LoadCookies(const AChromeDatabase: String);
var
zconn : TZConnection;
zquery : TZReadOnlyQuery;
creation_utc : Int64;
expires_utc : Int64;
last_access_utc: Int64;
host_key : String;
name : String;
value : String;
path : String;
secure : Integer;
httponly : Integer;
has_expires : Integer;
persistent : Integer;
priority : Integer;
cookie : TChromeCookie;
begin
zconn := TZConnection.Create(nil);
try
zconn.Protocol := 'sqlite-3';
zconn.Database := AChromeDatabase;
zconn.Connect;
if zconn.Connected then
try
zquery := TZReadOnlyQuery.Create(nil);
try
zquery.Connection := zconn;
zquery.SQL.Text := 'SELECT * FROM cookies';
zquery.Active := TRUE;
while not zquery.Eof do
begin
// bug: following three lines - they all return zero
creation_utc := zquery.FieldByName('creation_utc').AsLargeInt;
expires_utc := zquery.FieldByName('expires_utc').AsLargeInt;
last_access_utc := zquery.FieldByName('last_access_utc').AsLargeInt;
// debug info for SO
WriteLn(zquery.FieldDefs[0].Name); // = creation_utc
WriteLn(zquery.FieldDefs[0].Size); // = 0
WriteLn(zquery.FieldByName('creation_utc').AsString); // = 0
WriteLn(VarToStr(zquery.FieldValues['creation_utc'])); // = 0
dt := zquery.FieldDefs[0].DataType; // dt = ftInteger
host_key := zquery.FieldByName('host_key').AsString;
name := zquery.FieldByName('name').AsString;
value := zquery.FieldByName('value').AsString;
path := zquery.FieldByName('path').AsString;
secure := zquery.FieldByName('secure').AsInteger;
httponly := zquery.FieldByName('httponly').AsInteger;
has_expires := zquery.FieldByName('has_expires').AsInteger;
persistent := zquery.FieldByName('persistent').AsInteger;
priority := zquery.FieldByName('priority').AsInteger;
cookie := TChromeCookie.Create(creation_utc, host_key, name, value, path, expires_utc, secure, httponly, last_access_utc, has_expires, persistent, priority);
FChromeCookies.Add(cookie);
zquery.Next;
end;
finally
zquery.Free;
end;
finally
zconn.Disconnect;
end;
finally
zconn.Free;
end;
end;
I've tried everything that came to my mind, from simply getting value with .AsLargeInt()
getter, to getting it as Variant
, then casting to Integer
/Int64
/String
, etc.. In all cases, I got zero as return value. I've also tried with different versions of ZeosLib, specifically 7.0.6-stable
and 7.1.1-rc
ones. Wasn't able to compile with 6.6.6-stable
one due to incompatibility with newer versions of Delphi.
Here is how data looks like when I open it with SQLite Manager (firefox addon):
And table structure:
I've tried another approach, by reading data with DISqlite3
components, and they work, however they are shareware and I'd rather go with freeware ones if possible.
Any ideas what is causing this weird bug?
To answer my own question, I created thread on their official forum and got following response:
Zeos is a common access component. I know we could assume Int64 types for the Integer fields.
Actually we use BIGINT to assume TLongInt-Fields. Which the most RDBM's are using for.
This is an open discussion. Internaly SQLite accepts two Integer-bindings for prepared statments. Not a problem to make this patch..
So others can post here if we should change this or not. On 7.2 if you doubt, not on 7.0 or 7.1. Think about: This is a long-standing code. And it could make loads of trouble if the users do update there components.