procedure TSqliteDataset.RetrieveFieldDefs;
var
ColumnCount, i, DataSize:Integer;
AType: TFieldType;
vm: Pointer;
ColumnNames, ColumnValues:PPAnsiChar;
ColumnStr: String;
begin
FieldDefs.Clear;
FAutoIncFieldNo := -1;
FReturnCode := sqlite_compile(FSqliteHandle, PAnsiChar(FEffectiveSQL), nil, @vm, nil);
if FReturnCode <> SQLITE_OK then
DatabaseError(ReturnString, Self);
sqlite_step(vm, @ColumnCount, @ColumnValues, @ColumnNames);
//Prepare the array of pchar2sql functions
SetLength(FGetSqlStr, ColumnCount);
// Sqlite is typeless (allows any type in any field)
// regardless of what is in Create Table, but returns
// exactly what is in Create Table statement
// here is a trick to get the datatype.
// If the field contains another type, may have problems
for i := 0 to ColumnCount - 1 do
begin
DataSize := 0;
ColumnStr := UpperCase(String(ColumnNames[i + ColumnCount]));
if (ColumnStr = 'INTEGER') or (ColumnStr = 'INT') then
begin
if AutoIncrementKey and
(UpperCase(String(ColumnNames[i])) = UpperCase(PrimaryKey)) then
begin
AType := ftAutoInc;
FAutoIncFieldNo := i;
end
else
AType := ftInteger;
end else if Pos('VARCHAR', ColumnStr) = 1 then
begin
AType := ftString;
DataSize := StrToIntDef(Trim(ExtractDelimited(2, ColumnStr, ['(', ')'])), DefaultStringSize);
end else if Pos('BOOL', ColumnStr) = 1 then
begin
AType := ftBoolean;
end else if Pos('AUTOINC', ColumnStr) = 1 then
begin
AType := ftAutoInc;
if FAutoIncFieldNo = -1 then
FAutoIncFieldNo := i;
end else if (Pos('FLOAT', ColumnStr)=1) or (Pos('NUMERIC', ColumnStr) = 1) then
begin
AType := ftFloat;
end else if (ColumnStr = 'DATETIME') then
begin
AType := ftDateTime;
end else if (ColumnStr = 'DATE') then
begin
AType := ftDate;
end else if (ColumnStr = 'TIME') then
begin
AType := ftTime;
end else if (ColumnStr = 'LARGEINT') or (ColumnStr = 'BIGINT') then
begin
AType := ftLargeInt;
end else if (ColumnStr = 'TEXT') then
begin
AType := ftMemo;
end else if (ColumnStr = 'CURRENCY') then
begin
AType := ftCurrency;
end else if (ColumnStr = 'WORD') then
begin
AType := ftWord;
end else
begin
AType := ftString;
end;
FieldDefs.Add(FieldDefs.MakeNameUnique(String(ColumnNames[i])), AType, DataSize);
//Set the pchar2sql function
case AType of
ftString:
FGetSqlStr[i] := @Char2SQLStr;
ftMemo:
FGetSqlStr[i] := @Memo2SQLStr;
else
FGetSqlStr[i] := @Num2SQLStr;
end;
end;
sqlite_finalize(vm, nil);
{
if FReturnCode <> SQLITE_ABORT then
DatabaseError(ReturnString,Self);
}
end;