Hi,

This is a very weird behaviour I've found of either SQLite, or the Unit.
I'm not sure... I have been discussing this same problem on the SQLite
mailing list but without success there, so perhaps someone here might
know...

I have attached a test database, which contains 1 database entry, null
strings are inserted using NULL... Check the database schema yourself.

The problem therein lies in the fact that test3.pas returns "" for the
query: SELECT channelNotice FROM channels WHERE channel LIKE '#ProLogiTech';
It should return a null string as it does in test2.pas and in the sqlite
shell program.

$ ./test2
Creating class
Fields Names -------------------
0 -> channel
1 -> owner
2 -> regTime
3 -> state
4 -> URL
5 -> email
6 -> channelNotice
7 -> joins
8 -> peak
9 -> games
10 -> modeLocked
11 -> mailLevel
12 -> restrict
13 -> entries
14 -> quota
15 -> channelIdle
16 -> noIdle
17 -> lastSuspension
18 -> hideAccess
19 -> keepTopic
20 -> onChannel
21 -> opRestrict
22 -> funMsg
23 -> mustId
24 -> tellAdd
25 -> tellDel
26 -> tellSet
27 -> msgNotice
28 -> topic
29 -> topicSetter
30 -> lastTopic
31 -> autoCmd
32 -> modes
Fields -------------------
0 -> #ProLogiTech  prologic  1057934559  REGISTERED        1  1      0  0  1  50  0  
OFF    NO  YES  YES  NO  NO  NO  NO  NO  NO  NO          

$ ./test3
Creating class
Fields Names -------------------
0 -> channelNotice
Fields -------------------
0 -> ""  

This should be: 0 ->  

Any ideas anyone  ?
The attached sqlite.pas and sqlitedb.pas were put together by Michael,
myself and Eric Jourde (possibly ported from tsqlite I hear)

cheers
James

-- 
-
- James Mills
Zero Defect Software Engineers Group - ZDSEG
program test2;

uses cmem, sqlite,sqlitedb, strings,classes;

var
  MySQL: TSQLite;
  SQL: String;
  i,j : Integer;
  a : TStringList;
begin
  Writeln('Creating class');
  MySQL := TSQLite.Create('./channels.db');
  MySQL.BusyTimeout := 1000;
  
  SQL := 'SELECT * FROM channels WHERE channel LIKE ''#ProLogiTech'';';
  MySQL.Query(sql, nil);
  writeln('Fields Names -------------------');
  for i:=0 to MySQL.List_FieldName.count-1 do 
    writeln(i,' -> ',MySQL.List_FieldName.Strings[i]);
  writeln('Fields -------------------');
  for i:=0 to MySQL.List_Field.count-1 do 
      begin
 	a:=TStringList(MySQL.List_Field.items[i]); 
 	write(i,' -> ');
        for j:=0 to a.count-1 do  
          write(a.Strings[j],'  ');
        writeln('');
      end;   

// Uncomment to remove table again.
//  SQL := 'DROP TABLE Test;';
//  MySQL.Query(sql, nil);
  MySQL.Free;
end.
program test3;

uses cmem, sqlite,sqlitedb, strings,classes;

var
  MySQL: TSQLite;
  SQL: String;
  i,j : Integer;
  a : TStringList;
begin
  Writeln('Creating class');
  MySQL := TSQLite.Create('./channels.db');
  MySQL.BusyTimeout := 1000;
  
  SQL := 'SELECT channelNotice FROM channels WHERE channel LIKE ''#ProLogiTech'';';
  MySQL.Query(sql, nil);
  writeln('Fields Names -------------------');
  for i:=0 to MySQL.List_FieldName.count-1 do 
    writeln(i,' -> ',MySQL.List_FieldName.Strings[i]);
  writeln('Fields -------------------');
  for i:=0 to MySQL.List_Field.count-1 do 
      begin
 	a:=TStringList(MySQL.List_Field.items[i]); 
 	write(i,' -> ');
        for j:=0 to a.count-1 do  
          write(a.Strings[j],'  ');
        writeln('');
      end;   

// Uncomment to remove table again.
//  SQL := 'DROP TABLE Test;';
//  MySQL.Query(sql, nil);
  MySQL.Free;
end.

Attachment: channels.db
Description: Binary data

{$mode objfpc}
unit sqlite;
interface

{
  Automatically converted by H2Pas 0.99.15 from sqlite.h
  The following command line parameters were used:
    -S
    -D
    -p
    -l
    sqlite
    sqlite.h
}

  const
    External_library='sqlite'; {Setup as you need}

  { Pointers to basic pascal types, inserted by h2pas conversion program.}
  Type
    PLongint  = ^Longint;
    PSmallInt = ^SmallInt;
    PByte     = ^Byte;
    PWord     = ^Word;
    PDWord    = ^DWord;
    PDouble   = ^Double;
    PPPchar   = ^ppchar;
    
{$PACKRECORDS C}

const
  _SQLITE_VERSION = '2.8.3';
  SQLITE_ISO8859 = 1;

{$ifndef win32}
var
  sqlite_version  : pchar;cvar;external;
  sqlite_encoding : pchar;cvar;external;
{$endif}

const
  SQLITE_OK         = 0;
  SQLITE_ERROR      = 1;
  SQLITE_INTERNAL   = 2;
  SQLITE_PERM       = 3;
  SQLITE_ABORT      = 4;
  SQLITE_BUSY       = 5;
  SQLITE_LOCKED     = 6;
  SQLITE_NOMEM      = 7;
  SQLITE_READONLY   = 8;
  SQLITE_INTERRUPT  = 9;
  SQLITE_IOERR      = 10;
  SQLITE_CORRUPT    = 11;
  SQLITE_NOTFOUND   = 12;
  SQLITE_FULL       = 13;
  SQLITE_CANTOPEN   = 14;
  SQLITE_PROTOCOL   = 15;
  SQLITE_EMPTY      = 16;
  SQLITE_SCHEMA     = 17;
  SQLITE_TOOBIG     = 18;
  SQLITE_CONSTRAINT = 19;
  SQLITE_MISMATCH   = 20;
  SQLITE_MISUSE     = 21;
  SQLITE_NOLFS      = 22;
  SQLITE_AUTH       = 23;
  SQLITE_FORMAT     = 24;
  SQLITE_ROW        = 100;
  SQLITE_DONE       = 101;


  SQLITE_COPY                = 0;
  SQLITE_CREATE_INDEX        = 1;
  SQLITE_CREATE_TABLE        = 2;
  SQLITE_CREATE_TEMP_INDEX   = 3;
  SQLITE_CREATE_TEMP_TABLE   = 4;
  SQLITE_CREATE_TEMP_TRIGGER = 5;
  SQLITE_CREATE_TEMP_VIEW    = 6;
  SQLITE_CREATE_TRIGGER      = 7;
  SQLITE_CREATE_VIEW         = 8;
  SQLITE_DELETE              = 9;
  SQLITE_DROP_INDEX          = 10;
  SQLITE_DROP_TABLE          = 11;
  SQLITE_DROP_TEMP_INDEX     = 12;
  SQLITE_DROP_TEMP_TABLE     = 13;
  SQLITE_DROP_TEMP_TRIGGER   = 14;
  SQLITE_DROP_TEMP_VIEW      = 15;
  SQLITE_DROP_TRIGGER        = 16;
  SQLITE_DROP_VIEW           = 17;
  SQLITE_INSERT              = 18;
  SQLITE_PRAGMA              = 19;
  SQLITE_READ                = 20;
  SQLITE_SELECT              = 21;
  SQLITE_TRANSACTION         = 22;
  SQLITE_UPDATE              =  23;
  SQLITE_DENY                = 1;
  SQLITE_IGNORE              = 2;

  SQLITE_NUMERIC = -1;
  SQLITE_TEXT    = -2;
  SQLITE_ARGS    = -3;

  
Type
  Psqlite = Pointer;
  Psqlite_vm = Pointer;
  PPsqlite_vm = ^Psqlite_vm;
  Psqlite_func = Pointer;
  
  // Procedural types used in functions.
  
  sqlite_callback = function (_para1:pointer; _para2:longint; _para3:PPchar; _para4:PPchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};
  sqlite_trace_func = procedure (_para1:pointer; _para2:Pchar);{$ifdef win32}cdecl{$else}cdecl{$endif};
  sqlite_create_func = procedure (_para1:Psqlite_func; _para2:longint; _para3:PPchar);{$ifdef win32}cdecl{$else}cdecl{$endif};
  sqlite_handler = function (_para1:pointer; _para2:Pchar; _para3:longint):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};
  sqlite_step_func = procedure (_para1:Psqlite_func; _para2:longint; _para3:PPchar)  ;{$ifdef win32}cdecl{$else}cdecl{$endif};
  sqlite_finalize_func = procedure (_para1:Psqlite_func);{$ifdef win32}cdecl{$else}cdecl{$endif};
  sqlite_authorize_func = function (_para1:pointer; _para2:longint; _para3, _para4,_para5,_para6:Pchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};
  
  function sqlite_create_function(_para1:Psqlite; zName:Pchar; nArg:longint; xFunc:sqlite_create_func; pUserData:pointer):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_create_function';
  function sqlite_open(filename:Pchar; mode:longint; errmsg:PPchar):Psqlite;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_open';
  procedure sqlite_close(_para1:Psqlite);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_close';
  function sqlite_exec(_para1:Psqlite; sql:Pchar; _para3:sqlite_callback; _para4:pointer; errmsg:PPchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_exec';
  function sqlite_last_insert_rowid(_para1:Psqlite):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_last_insert_rowid';
  function sqlite_changes(_para1:Psqlite):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_changes';
  function sqlite_error_string(_para1:longint):Pchar;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_error_string';
  procedure do_sqlite_interrupt(_para1:Psqlite);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_interrupt';
  function sqlite_complete(sql:Pchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_complete';
  procedure sqlite_busy_handler(_para1:Psqlite; _para2:sqlite_handler; _para3:pointer);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_busy_handler';
  procedure sqlite_busy_timeout(_para1:Psqlite; ms:longint);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_busy_timeout';
  function sqlite_get_table(_para1:Psqlite; sql:Pchar; resultp:PPPchar; nrow:Plongint; ncolumn:Plongint; 
             errmsg:PPchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_get_table';
  procedure sqlite_free_table(result:PPchar);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_free_table';
  function sqlite_exec_printf(_para1:Psqlite; sqlFormat:Pchar; _para3:sqlite_callback; _para4:pointer; errmsg:PPchar; 
             args:array of const):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_exec_printf';
  function sqlite_exec_printf(_para1:Psqlite; sqlFormat:Pchar; _para3:sqlite_callback; _para4:pointer; errmsg:PPchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_exec_printf';
  function sqlite_exec_vprintf(_para1:Psqlite; sqlFormat:Pchar; _para3:sqlite_callback; _para4:pointer; errmsg:PPchar; 
             ap:array of const):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_exec_vprintf';
  function sqlite_get_table_printf(_para1:Psqlite; sqlFormat:Pchar; resultp:PPPchar; nrow:Plongint; ncolumn:Plongint; 
             errmsg:PPchar; args:array of const):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_get_table_printf';
  function sqlite_get_table_printf(_para1:Psqlite; sqlFormat:Pchar; resultp:PPPchar; nrow:Plongint; ncolumn:Plongint; 
             errmsg:PPchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_get_table_printf';
  function sqlite_get_table_vprintf(_para1:Psqlite; sqlFormat:Pchar; resultp:PPPchar; nrow:Plongint; ncolumn:Plongint; 
             errmsg:PPchar; ap:array of const):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_get_table_vprintf';
  function sqlite_mprintf(_para1:Pchar; args:array of const):Pchar;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_mprintf';
  function sqlite_mprintf(_para1:Pchar):Pchar;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_mprintf';
  procedure sqlite_freemem(p:pointer);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_freemem';
  function sqlite_libversion:Pchar;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_libversion';
  function sqlite_libencoding:Pchar;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_libencoding';
  function sqlite_create_aggregate(_para1:Psqlite; zName:Pchar; nArg:longint; xStep:sqlite_step_func ; xFinalize:sqlite_finalize_func; 
             pUserData:pointer):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_create_aggregate';
  function sqlite_function_type(db:Psqlite; zName:Pchar; datatype:longint):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_function_type';
  function sqlite_set_result_string(_para1:Psqlite_func; _para2:Pchar; _para3:longint):Pchar;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_set_result_string';
  procedure sqlite_set_result_int(_para1:Psqlite_func; _para2:longint);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_set_result_int';
  procedure sqlite_set_result_double(_para1:Psqlite_func; _para2:double);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_set_result_double';
  procedure sqlite_set_result_error(_para1:Psqlite_func; _para2:Pchar; _para3:longint);{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_set_result_error';
  function sqlite_user_data(_para1:Psqlite_func):pointer;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_user_data';
  function sqlite_aggregate_context(_para1:Psqlite_func; nBytes:longint):pointer;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_aggregate_context';
  function sqlite_aggregate_count(_para1:Psqlite_func):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_aggregate_count';
  function sqlite_set_authorizer(_para1:Psqlite; xAuth:sqlite_authorize_func ; pUserData:pointer):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_set_authorizer';
  function sqlite_trace(_para1:Psqlite; xTrace:sqlite_trace_func; _para3:pointer):pointer;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_trace';
  function sqlite_compile(db:Psqlite; zSql:Pchar; pzTail:PPchar; ppVm:PPsqlite_vm; pzErrmsg:PPchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_compile';
  function sqlite_step(pVm:Psqlite_vm; pN:Plongint; pazValue:PPPchar; pazColName:PPPchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_step';
  function sqlite_finalize(_para1:Psqlite_vm; pzErrMsg:PPchar):longint;{$ifdef win32}cdecl{$else}cdecl{$endif};external External_library name 'sqlite_finalize';

implementation


end.
{$mode objfpc}
{$h+}

unit SQLitedb;

interface

uses  Classes,strings,sqlite;

type
  TSQLiteExecCallback = function(Sender: TObject; Columns: Integer; ColumnValues: Pointer; ColumnNames: Pointer): integer of object; cdecl;
  TSQLiteBusyCallback = function(Sender: TObject; ObjectName: PChar; BusyCount: integer): integer of object; cdecl;
  TOnData = Procedure(Sender: TObject; Columns: Integer; ColumnNames, ColumnValues: String)  of object;
  TOnBusy = Procedure(Sender: TObject; ObjectName: String; BusyCount: integer; var Cancel: Boolean) of object;
  TOnQueryComplete = Procedure(Sender: TObject) of object;

  TSQLite = class(TObject)
  private
    fSQLite: Pointer;
    fMsg: String;
    fIsOpen: Boolean;
    fBusy: Boolean;
    fError: Integer;
    fVersion: String;
    fEncoding: String;
    fTable: TStrings;
    fLstName: TStringList;
    fLstVal: TStringList;
    fOnData: TOnData;
    fOnBusy: TOnBusy;
    fOnQueryComplete: TOnQueryComplete;
    fBusyTimeout: integer;
    fPMsg: PChar;
    fChangeCount: integer;
 	fNb_Champ :  Integer; 
  	fList_FieldName : TStringList;
  	fList_Field : TList;
    procedure SetBusyTimeout(Timeout: integer);
  public
    constructor Create(DBFileName: String);
    destructor Destroy; override;
    function Query(Sql: String; Table: TStrings ): boolean;
    function ErrorMessage(ErrNo: Integer): string;
    function IsComplete(Sql: String): boolean;
    function LastInsertRow: integer;
    function Cancel: boolean;
    function DatabaseDetails(Table: TStrings): boolean;
    property LastErrorMessage: string read fMsg;
    property LastError: Integer read fError;
    property Version: String read fVersion;
    property Encoding: String read fEncoding;
    property OnData: TOnData read fOnData write fOnData;
    property OnBusy: TOnBusy read fOnBusy write fOnBusy;
    property OnQueryComplete: TOnQueryComplete read fOnQueryComplete write fOnQueryComplete;
    property BusyTimeout: Integer read fBusyTimeout write SetBusyTimeout;
    property ChangeCount: Integer read fChangeCount;
    property List_FieldName: TStringList read fList_FieldName write fList_FieldName;
    property List_Field: TList read fList_Field write fList_Field;
    property Nb_Champ: integer read fNb_Champ write fNb_Champ;
    
  procedure SQLOnData(Sender: TObject; Columns: Integer; ColumnNames, ColumnValues: String);
    
  end;
  function Pas2SQLStr(const PasString: string): string;
  function SQL2PasStr(const SQLString: string): string;
  function QuoteStr(const s: string; QuoteChar: Char ): string;
  function UnQuoteStr(const s: string; QuoteChar: Char ): string;
  procedure ValueList(const ColumnNames, ColumnValues: String; NameValuePairs: TStrings);

implementation

Const
  DblQuote: Char    = '"';
  SngQuote: Char    = #39;
  Crlf: String      = #13#10;
  Tab: Char         = #9;

var
  MsgNoError: String;

function QuoteStr(const s: string; QuoteChar: Char ): string;
begin
  Result := Concat(QuoteChar, s, QuoteChar);
end;

function UnQuoteStr(const s: string; QuoteChar: Char ): string;
begin
  Result := s;
  if length(Result) > 1 then
  begin
    if Result[1] = QuoteChar then
      Delete(Result, 1, 1);
    if Result[Length(Result)] = QuoteChar then
      Delete(Result, Length(Result), 1);
  end;
end;

function Pas2SQLStr(const PasString: string): string;
var
  n: integer;
begin
  Result := SQL2PasStr(PasString);
  n := Length(Result);
  while n > 0 do
  begin
    if Result[n] = SngQuote then
      Insert(SngQuote, Result, n);
    dec(n);
  end;
  Result := QuoteStr(Result,#39);
end;

function SQL2PasStr(const SQLString: string): string;
const
  DblSngQuote: String = #39#39;
var
  p: integer;
begin
  Result := SQLString;
  p := pos(DblSngQuote, Result);
  while p > 0 do
  begin
    Delete(Result, p, 1);
    p := pos(DblSngQuote, Result);
  end;
  Result := UnQuoteStr(Result,#39);
end;

procedure ValueList(const ColumnNames, ColumnValues: String; NameValuePairs: TStrings);
var
  n: integer;
  lstName, lstValue: TStringList;
begin
  if NameValuePairs <> nil then
  begin
    lstName := TStringList.Create;
    lstValue := TStringList.Create;
    lstName.CommaText := ColumnNames;
    lstValue.CommaText := ColumnValues;
    NameValuePairs.Clear;
    if lstName.Count = LstValue.Count then
      if lstName.Count > 0 then
        for n := 0 to lstName.Count - 1 do
          NameValuePairs.Append(Concat(lstName.Strings[n], '=', lstValue.Strings[n]));
    lstValue.Free;
    lstName.Free;
  end;
end;



function SystemErrorMsg(ErrNo: Integer ): String;
var
  buf: PChar;
  size: Integer;
  MsgLen: Integer;
begin
{  size := 256;
  GetMem(buf, size);
  If ErrNo = - 1 then
    ErrNo := GetLastError;
  MsgLen := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, ErrNo, 0, buf, size, nil);
  if MsgLen = 0 then
    Result := 'ERROR'
  else
    Result := buf;}
end;

function BusyCallback(Sender: pointer; ObjectName: PChar; BusyCount: integer): integer; cdecl;
var
  sObjName: String;
  bCancel: Boolean;
begin
  Result := -1;
  with TObject(Sender) as TSQLite do
  begin
    if Assigned(fOnBusy) then
    begin
      bCancel := False;
      sObjName := ObjectName;
      fOnBusy(Tobject(Sender), sObjName, BusyCount, bCancel);
      if bCancel then
        Result := 0;
    end;
  end;
end;

function ExecCallback(Sender: TObject; Columns: Integer; ColumnValues: Pointer; ColumnNames: Pointer): integer; cdecl;
var
  PVal, PName: ^PChar;
  n: integer;
  sVal, sName: String;
begin
  Result := 0;
  with Sender as TSQLite do
  begin
    if (Assigned(fOnData) or Assigned(fTable)) then
    begin
      fLstName.Clear;
      fLstVal.Clear;
      if Columns > 0 then
      begin
        PName := ColumnNames;
        PVal := ColumnValues;
        for n := 0 to Columns - 1 do
        begin
          fLstName.Append(PName^);
          fLstVal.Append(PVal^);
          inc(PName);
          inc(PVal);
        end;
      end;
      sVal := fLstVal.CommaText;
      sName := fLstName.CommaText;
      if Assigned(fOnData) then
        fOnData(Sender, Columns, sName, sVal);
      if Assigned(fTable) then
      begin
        if fTable.Count = 0 then
          fTable.Append(sName);
        fTable.Append(sVal);
      end;
    end;
  end;
end;


procedure TSQLite.SQLOnData(Sender: TObject; Columns: Integer; ColumnNames, ColumnValues: String);
Var i : Integer;
	  InterS,val : String;
	  Field : TStringList;	
		  
	  function Pos1(a: String ; s : char) : integer;
	  var i,j : Integer;
	  
	  begin
	  j:=-1;
	  	for i:=1 to length(a) Do
	  	begin
	  		if a[i] = s then
	  		begin
	  			j:=i;
	  			break;
	  		end;
	  	end;
	  	result:=j;
	  end;
begin
	If Nb_Champ = -1 Then
  	Begin // Put the fields name in List_FieldName
  		Nb_Champ:=Columns;
		InterS:=ColumnNames;
		While (Pos1(InterS,',') > 0)  do
		begin
			val:=copy(InterS,1,Pos1(InterS,',')-1);
			InterS:=copy(InterS,Pos1(InterS,',')+1,length(InterS)); 
			List_FieldName.add(val);
		end;
		if length(InterS) > 0 then List_FieldName.add(InterS);
	end;
	// Put the list of TStringList of value
	Field :=TStringList.Create;
	InterS:=ColumnValues;
	While (Pos1(InterS,',') > 0)  do
	begin
		val:=copy(InterS,1,Pos1(InterS,',')-1);
		InterS:=copy(InterS,Pos1(InterS,',')+1,length(InterS)); 
		Field.add(val);
	end;
	if length(InterS) > 0 then Field.add(InterS);
	List_Field.add(Field);
end;

constructor TSQLite.Create(DBFileName: String);
var
  fPMsg1: PChar;
  name : pchar;
begin
  inherited Create;
  List_FieldName := TStringList.Create;
  List_Field := TList.Create;
  fError := SQLITE_ERROR;
  fIsOpen := False;
  fLstName := TStringList.Create;
  fLstVal := TStringList.Create;
  fOnData := nil;
  fOnBusy := nil;
  fOnQueryComplete := nil;
  fChangeCount := 0;
   name:=StrAlloc (length(DBFileName)+1);  
   strpcopy(name,DBFileName);
   OnData:[EMAIL PROTECTED];
    fSQLite := SQLite_Open(name, 1, @fPMsg);
    SQLite_FreeMem(fPMsg);
    if fSQLite <> nil then
    begin
      //fVersion := String(SQLite_Version);
      //fEncoding := SQLite_Encoding;
      fIsOpen := True;
      fError := SQLITE_OK;
    end;
  fMsg := ErrorMessage(fError);
end;

destructor TSQLite.Destroy;
begin
  if fIsOpen then
    SQLite_Close(fSQLite);
  fIsOpen := False;
  fLstName.Free;
  fLstVal.Free;
  fSQLite := nil;
  fOnData := nil;
  fOnBusy := nil;
  fOnQueryComplete := nil;
  fLstName := nil;
  fLstVal := nil;
  List_FieldName.destroy; 
  List_Field.destroy; 
  inherited Destroy;
end;

function TSQLite.Query(Sql: String; Table: TStrings ): boolean;
//var
//  fPMsg: PChar;
var Psql : pchar;
begin
  fError := SQLITE_ERROR;
  if fIsOpen then
  begin
    fPMsg := nil;
    fBusy := True;
    fTable := Table;
    if fTable <> nil then
      fTable.Clear;
   Psql:=StrAlloc (length(Sql)+1);  
   strpcopy(Psql,Sql);
   List_FieldName.clear;
   List_Field.clear;
   Nb_Champ:=-1;
    fError := SQLite_Exec(fSQLite, Psql, @ExecCallback, Self, @fPMsg);
    strdispose(Psql);
    SQLite_FreeMem(fPMsg);
    fChangeCount := SQLite_Changes(fSQLite);
    fTable := nil;
    fBusy := False;
    if Assigned(fOnQueryComplete) then
      fOnQueryComplete(Self);
  end;
  fMsg := ErrorMessage(fError);
  Result := (fError <> SQLITE_OK);
end;

function TSQLite.Cancel: boolean;
begin
  Result := False;
  if fBusy and fIsOpen then
  begin
    do_SQLite_interrupt(fSQLite);
    fBusy := false;
    Result := True;
  end;
end;

procedure TSQLite.SetBusyTimeout(Timeout: Integer);
begin
  fBusyTimeout := Timeout;
  if fIsOpen then
  begin
    SQLite_Busy_Timeout(fSQLite, fBusyTimeout);
    if fBusyTimeout > 0 then
      SQLite_Busy_Handler(fSQLite, @BusyCallback, Self)
    else
      SQLite_Busy_Handler(fSQLite, nil, nil);
  end;
end;

function TSQLite.LastInsertRow: integer;
begin
  if fIsOpen then
    Result := SQLite_Last_Insert_RowID(fSQLite)
  else
    Result := -1;
end;

function TSQLite.ErrorMessage(ErrNo: Integer): string;
begin
  exit;
  if ErrNo = 0 then
    Result := MsgNoError
  else
    Result := SQLite_Error_String(ErrNo);
end;

function TSQLite.IsComplete(Sql: String): boolean;
var Psql : pchar;
begin
  Psql:=StrAlloc (length(Sql)+1);  
  strpcopy(Psql,Sql);
  Writeln('Testing: ',psql);
  Result := SQLite_Complete(Psql)<>0;
  strdispose(Psql);
end;

function TSQLite.DatabaseDetails(Table: TStrings): boolean;
begin
  Result := Query('SELECT * FROM SQLITE_MASTER;', Table);
end;

initialization

finalization

end.

Reply via email to