1

ZeosLib コンポーネントと Delphi XE2 を使用して sqlite データベースを読み込もうとしています。保存されている 3 つのタイムスタンプ値 (基本的には 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()getter で単に値を取得することから、 として取得してから/ /にVariantキャストすることまで、頭に浮かんだすべてを試しました。すべての場合で、戻り値としてゼロを取得しました。また、さまざまなバージョンの ZeosLib、具体的には と を試しました。新しいバージョンの Delphi との互換性がないため、コンパイルできませんでした。IntegerInt64String7.0.6-stable7.1.1-rc6.6.6-stable

SQLite Manager (firefox アドオン) で開くと、データは次のようになります。

クッキー テーブル データ

そしてテーブル構造:

Cookie テーブル構造

コンポーネントを使用してデータを読み取るという別のアプローチを試してみましたが、機能しDISqlite3ますが、それらはシェアウェアであり、可能であればフリーウェアを使用したいと考えています。

この奇妙なバグの原因は何ですか?

4

1 に答える 1

0

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.

[link to the thread]

于 2013-10-09T00:58:39.230 に答える