Zeoslib не может прочитать поля LargeInt из базы данных sqlite

Я пытаюсь прочитать базу данных sqlite с компонентами ZeosLib и Delphi XE2. Все работает отлично, за исключением случаев, когда я пытаюсь прочитать три сохраненных значения метки времени, которые в основном представляют собой 17-значные числа. Вместо того, чтобы получить правильное значение, я получаю ноль. Функция, которая читает данные базы данных (следите за комментариями):

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;

Я перепробовал все, что пришло мне в голову, от простого получения значения с помощью .AsLargeInt() геттера до получения его как Variant, затем приведения к Integer/Int64/String и т. д. Во всех случаях я получал ноль в качестве возвращаемого значения. Я также пробовал разные версии ZeosLib, особенно 7.0.6-stable и 7.1.1-rc. Не удалось скомпилировать с 6.6.6-stable из-за несовместимости с более новыми версиями Delphi.

Вот как выглядят данные, когда я открываю их с помощью SQLite Manager (надстройка Firefox):

данные таблицы файлов cookie

И структура таблицы:

структура таблицы файлов cookie

Я пробовал другой подход, читая данные с помощью DISqlite3 компонентов, и они работают, однако они являются условно-бесплатными, и я бы предпочел использовать бесплатные, если это возможно.

Любые идеи, что вызывает эту странную ошибку?


person Marko Paunovic    schedule 08.10.2013    source источник
comment
Попробуйте trunc(...AsDouble). Не идеально, но может работать. ИЛИ наши классы с открытым исходным кодом для прямого доступа к SQlite3 на полной скорости — см. blog.synopse.info/post/2011/07/22/ - и не проблема с большими числами Int64. :)   -  person Arnaud Bouchez    schedule 08.10.2013
comment
Огромное спасибо. Сейчас я попробую SynDBSQLite3. Trunc() не помог, кстати.   -  person Marko Paunovic    schedule 08.10.2013
comment
попробуйте определить поля как BIGINT; см. пост здесь: zeoslib.sourceforge.net/viewtopic.php?f=5&t =1275   -  person A Lombardo    schedule 08.10.2013
comment
база данных внешняя, поэтому я не могу ее редактировать, но SynDBSQLite работает без нареканий :)   -  person Marko Paunovic    schedule 08.10.2013
comment
@ArnaudBouchez, у вас есть минутка, чтобы просмотреть это и высказать свое мнение, могу ли я как-то его улучшить? Мне трудно найти подходящие примеры sqlite mORMot в Интернете: pastebin.com/8xq0N9cb   -  person Marko Paunovic    schedule 08.10.2013
comment
У вас есть доступные методы транзакций. Остальное звучит нормально. См. также эксклюзивный режим для лучшей скорости. В нашем блоге есть несколько статей, а документ mORMot является исчерпывающим.   -  person Arnaud Bouchez    schedule 08.10.2013


Ответы (1)


Чтобы ответить на свой вопрос, я создал тему на их официальном форуме и получил следующий ответ:

Zeos — это компонент общего доступа. Я знаю, что мы могли бы предположить типы Int64 для полей Integer.

На самом деле мы используем BIGINT для предположения TLongInt-Fields. Для чего используется большинство RDBM.

Это открытая дискуссия. Внутренний SQLite принимает две привязки Integer для подготовленных отчетов. Не проблема сделать этот патч..

Так что другие могут публиковать здесь, если мы должны изменить это или нет. На 7.2, если сомневаетесь, не на 7.0 или 7.1. Подумайте: это давний код. И это может создать массу проблем, если пользователи обновят свои компоненты.

[ссылка на ветку]

person Marko Paunovic    schedule 09.10.2013