//Advanced Delphi Systems Code: ads_DBSqlite
Unit ads_DBSqlite;
{Copyright(c)2016 Advanced Delphi Systems

 Richard Maley
 Advanced Delphi Systems
 12613 Maidens Bower Drive
 Potomac, MD 20854 USA
 phone 301-840-1554
 dickmaley@advdelphisys.com

 The code herein can be used or modified by anyone.  Please retain references
 to Richard Maley at Advanced Delphi Systems.  If you make improvements to the
 code please send your improvements to dickmaley@advdelphisys.com so that the
 entire Delphi community can benefit.  All comments are welcome.
}
(*
UnitIndex Master Index Implementation Section Download Units
Description: ads_DBSqlite.pas
This unit contains the following routines.

Register   TQuerySqlite.ClientDatasetSaveChanges  TQuerySqlite.GetActive   TQuerySqlite.GetDatabase   TQuerySqlite.GetFilter   TQuerySqlite.GetFiltered   TQuerySqlite.GetFilterOptions   TQuerySqlite.GetMasterSource   TQuerySqlite.GetParamCheck   TQuerySqlite.GetReadOnly   TQuerySqlite.GetSqlDelete   TQuerySqlite.GetSqlInsert   TQuerySqlite.GetSqlModify   TQuerySqlite.GetSqlSelect   TQuerySqlite.SetActive   TQuerySqlite.SetDatabase   TQuerySqlite.SetFilter   TQuerySqlite.SetFiltered   TQuerySqlite.SetFilterOptions   TQuerySqlite.SetMasterSource   TQuerySqlite.SetParamCheck   TQuerySqlite.SetReadOnly   TQuerySqlite.SetSqlDelete   TQuerySqlite.SetSqlInsert   TQuerySqlite.SetSqlModify   TQuerySqlite.SetSqlSelect  

*)
Interface
Uses
  Classes,
  DISQLite3DataSet,
  DISQLite3Database,
  Provider,
  DBClient,
  DB,
  DBGrids
  ;

Type
  TSqliteStringArray = Array Of String;
  TSqliteCreateTableFieldLines = TSqliteStringArray;

  TQuerySqlite = Class(TDataSource)
  Private
    {Private Section}

  Protected
    FClientDataSet: TClientDataSet;
    FDatabase: TDISQLite3Database;
    FDataSet: TDataSet;
    FDataSetProvider: TDataSetProvider;
    FDISQLite3UniDirQuery: TDISQLite3UniDirQuery;
    Function GetActive: Boolean;
    Function GetDatabase: TDISQLite3Database;
    Function GetFilter: String;
    Function GetFiltered: Boolean;
    Function GetFilterOptions: TFilterOptions;
    Function GetMasterSource: TDataSource;
    Function GetParamCheck: Boolean;
    Function GetReadOnly: Boolean;
    Function GetSqlDelete: WideString;
    Function GetSqlInsert: WideString;
    Function GetSqlModify: WideString;
    Function GetSqlSelect: WideString;
    Procedure ClientDatasetSaveChanges(DataSet: TDataSet);
    Procedure SetActive(Const Value: Boolean);
    Procedure SetDatabase(Const Value: TDISQLite3Database);
    Procedure SetFilter(Const Value: String);
    Procedure SetFiltered(Const Value: Boolean);
    Procedure SetFilterOptions(Const Value: TFilterOptions);
    Procedure SetMasterSource(Const Value: TDataSource);
    Procedure SetParamCheck(Const Value: Boolean);
    Procedure SetReadOnly(Const Value: Boolean);
    Procedure SetSqlDelete(Const Value: WideString);
    Procedure SetSqlInsert(Const Value: WideString);
    Procedure SetSqlModify(Const Value: WideString);
    Procedure SetSqlSelect(Const Value: WideString);
  Public
    Constructor Create(AOwner: TComponent); Override;
    Destructor Destroy; Override;
    Class Function DBDropTable(DB: TDISQLite3Database; TableName: String): Boolean;
    Class Function DBEmptyTable(DB: TDISQLite3Database; TableName: String): Boolean;
    Class Function DBNextInteger(DB: TDISQLite3Database; TableName, FieldName: String): Integer;
    Class Function GetCreateTableFieldDefLines(DB: TDISQLite3Database; TableName: String): TSqliteCreateTableFieldLines;
    Class Function GetCreateTableSQL(DB: TDISQLite3Database; TableName: String): String;
    Class Function GetDatabaseCreateScript(DB: TDISQLite3Database): String;
    Class Function GetDatabaseCreateScriptArray(DB: TDISQLite3Database): TSqliteStringArray;
    Class Function GetMaxFieldWidth(Database: TDISQLite3Database; FieldName, TableName: String): Integer;
    Class Function GetStringFieldSize(Const AColumn: TDISQLite3Column; Const AFieldDef: TFieldDef): Integer; Overload;
    Class Function GetStringFieldSize(DB: TDISQLite3Database; TableName, FieldName: String): Integer; Overload;
    Class Function GetTableNames(DB: TDISQLite3Database): TSqliteStringArray;
    Class Function PosLast(SubString, Source: String): Integer;
    Class Function PosLastCaseInsensitive(SubString, Source: String): Integer;
    Class Procedure AdjustColumnWidths(qry: TQuerySqlite; TableName: String; DBGrid: TDBGrid);
    Class Procedure InitFieldDef(Const AColumn: TDISQLite3Column; Const AFieldDef: TFieldDef);
  Public
    Property CDS: TClientDataset Read FClientDataSet Write FClientDataSet;
    Property Provider: TDataSetProvider Read FDataSetProvider Write FDataSetProvider;
    Property Query: TDISQLite3UniDirQuery Read FDISQLite3UniDirQuery Write FDISQLite3UniDirQuery;
  Published
    Property Active: Boolean Read GetActive Write SetActive;
    Property Database: TDISQLite3Database Read GetDatabase Write SetDatabase;
    Property Filter: String Read GetFilter Write SetFilter;
    Property Filtered: Boolean Read GetFiltered Write SetFiltered;
    Property FilterOptions: TFilterOptions Read GetFilterOptions Write SetFilterOptions;
    Property MasterSource: TDataSource Read GetMasterSource Write SetMasterSource;
    Property ParamCheck: Boolean Read GetParamCheck Write SetParamCheck;
    Property Read_Only: Boolean Read GetReadOnly Write SetReadOnly;
    Property SqlDelete: WideString Read GetSqlDelete Write SetSqlDelete;
    Property SqlInsert: WideString Read GetSqlInsert Write SetSqlInsert;
    Property SqlModify: WideString Read GetSqlModify Write SetSqlModify;
    Property SqlSelect: WideString Read GetSqlSelect Write SetSqlSelect;
  End;
Procedure Register;

implementation

Uses
  DBConsts,
  Dialogs,
  SysUtils;

//
Unit Description UnitIndex Master Index
Procedure Register;
Begin
  RegisterComponents('ads_Sqlite', [TQuerySqlite]);
End;

{ TCustomQuerySqlite }

Constructor TQuerySqlite.Create(AOwner: TComponent);
Begin
  Inherited;
  FDISQLite3UniDirQuery := TDISQLite3UniDirQuery.Create(self);
  FDISQLite3UniDirQuery.OnInitFieldDef := InitFieldDef;
  FDataSetProvider := TDataSetProvider.Create(Self);
  FDataSetProvider.DataSet := FDISQLite3UniDirQuery;
  FDataSetProvider.Name := 'DataSetProvider';
  FClientDataSet := TClientDataSet.Create(Self);
  FClientDataSet.Name := 'InternalClientDataSet';
  FClientDataSet.ProviderName := FDataSetProvider.Name;
  FClientDataSet.SetProvider(FDataSetProvider);
  FClientDataSet.AfterPost := ClientDatasetSaveChanges;
  FClientDataSet.AfterDelete := ClientDatasetSaveChanges;
  DataSet := FClientDataSet;
End;

Destructor TQuerySqlite.Destroy;
Begin
  FreeAndNil(FDISQLite3UniDirQuery);
  FreeAndNil(FDataSetProvider);
  FreeAndNil(FClientDataSet);
  Inherited;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetActive: Boolean;
Begin
  Result := FClientDataSet.Active;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetDatabase: TDISQLite3Database;
Begin
  Result := FDatabase;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetFilter: String;
Begin
  Result := FClientDataSet.Filter;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetFiltered: Boolean;
Begin
  Result := FClientDataSet.Filtered;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetFilterOptions: TFilterOptions;
Begin
  Result := FClientDataSet.FilterOptions;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetMasterSource: TDataSource;
Begin
  Result := FClientDataSet.MasterSource;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetParamCheck: Boolean;
Begin
  Result := FDISQLite3UniDirQuery.ParamCheck;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetReadOnly: Boolean;
Begin
  Result := FClientDataSet.ReadOnly;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetSqlDelete: WideString;
Begin
  Result := FDISQLite3UniDirQuery.DeleteSQL;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetSqlInsert: WideString;
Begin
  Result := FDISQLite3UniDirQuery.InsertSQL;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetSqlModify: WideString;
Begin
  Result := FDISQLite3UniDirQuery.ModifySQL;
End;

//
Unit Description UnitIndex Master Index
Function TQuerySqlite.GetSqlSelect: WideString;
Begin
  Result := FDISQLite3UniDirQuery.SelectSQL;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.ClientDatasetSaveChanges(DataSet: TDataSet);
Begin
  FClientDataSet.ApplyUpdates(0);
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetActive(Const Value: Boolean);
Begin
  FClientDataSet.Active := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetDatabase(Const Value: TDISQLite3Database);
Begin
  FDatabase := Value;
  FDISQLite3UniDirQuery.Database := FDatabase;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetFilter(Const Value: String);
Begin
  FClientDataSet.Filter := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetFiltered(Const Value: Boolean);
Begin
  FClientDataSet.Filtered := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetFilterOptions(Const Value: TFilterOptions);
Begin
  FClientDataSet.FilterOptions := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetMasterSource(Const Value: TDataSource);
Begin
  FClientDataSet.MasterSource := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetParamCheck(Const Value: Boolean);
Begin
  FDISQLite3UniDirQuery.ParamCheck := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetReadOnly(Const Value: Boolean);
Begin
  FClientDataSet.ReadOnly := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetSqlDelete(Const Value: WideString);
Begin
  FDISQLite3UniDirQuery.DeleteSQL := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetSqlInsert(Const Value: WideString);
Begin
  FDISQLite3UniDirQuery.InsertSQL := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetSqlModify(Const Value: WideString);
Begin
  FDISQLite3UniDirQuery.ModifySQL := Value;
End;

//
Unit Description UnitIndex Master Index
Procedure TQuerySqlite.SetSqlSelect(Const Value: WideString);
Begin
  FDISQLite3UniDirQuery.SelectSQL := Value;
End;

Class Procedure TQuerySqlite.InitFieldDef(Const AColumn: TDISQLite3Column;
  Const AFieldDef: TFieldDef);
Begin
  If AFieldDef.DataType In [ftString, ftMemo, ftFmtMemo, ftFixedChar, ftWideString,
    ftOraClob, ftFixedWideChar, ftWideMemo] Then
  Begin
    AFieldDef.Size := GetStringFieldSize(AColumn, AFieldDef);
  End;
End;

Class Function TQuerySqlite.PosLast(SubString, Source: String): Integer;
Var
  sgRevSource: String;
  sgRevSubStr: String;
  inLenSource: Integer;
  inLenSubStr: Integer;
  inCounter: Integer;
  inPos: Integer;
Begin
  Result := 0;
  sgRevSource := '';
  sgRevSubStr := '';
  inLenSource := Length(Source);
  inLenSubStr := Length(SubString);
  For inCounter := inLenSource Downto 1 Do
    sgRevSource := sgRevSource + Copy(Source, inCounter, 1);
  For inCounter := inLenSubStr Downto 1 Do
    sgRevSubStr := sgRevSubStr + Copy(SubString, inCounter, 1);
  inPos := Pos(sgRevSubStr, sgRevSource);
  If inPos = 0 Then Exit;
  Result := inLenSource - inPos - inLenSubStr + 2;
End;

Class Function TQuerySqlite.PosLastCaseInsensitive(SubString,
  Source: String): Integer;
Begin
  Result := PosLast(UpperCase(SubString), UpperCase(Source));
End;

Class Function TQuerySqlite.GetCreateTableSQL(DB: TDISQLite3Database; TableName: String): String;
Var
  ds: TQuerySqlite;
  sgSQL: String;
Begin
  Result := '';
  Try
    ds := TQuerySqlite.Create(Nil);
    ds.SqlSelect := 'Select SQL From sqlite_master Where type="table" And Upper("' + TableName + '")=Upper(tbl_name)';
    ds.Database := DB;
    ds.Active := True;
    sgSQL := '';
    If ds.FClientDataSet.Bof And ds.FClientDataSet.Eof Then Exit;
    sgSQL := ds.FClientDataSet.FieldByName('sql').AsString;
    sgSQL := StringReplace(sgSQL, #13 + #10, ' ', [rfReplaceAll]);
    Result := sgSQL;
  Finally
    FreeAndNil(ds);
  End;
End;

Class Function TQuerySqlite.GetCreateTableFieldDefLines(DB: TDISQLite3Database;
  TableName: String): TSqliteCreateTableFieldLines;
Var
  inPos: Integer;
  sgSQL: String;
  sgTemp: String;
Begin
  SetLength(Result, 0);
  Try
    sgSQL := GetCreateTableSQL(DB, TableName);
    If Trim(sgSQL) = '' Then Exit;
    inPos := Pos('(', sgSQL);
    If inPos = 0 Then Exit;
    sgTemp := Copy(sgSQL, inPos + 1, Length(sgSQL) - (inPos + 1) + 1);
    inPos := PosLast(')', sgTemp);
    If inPos = 0 Then Exit;
    sgTemp := Copy(sgTemp, 1, inPos - 1);
    sgTemp := Trim(sgTemp);
    While True Do
    Begin
      inPos := Pos(',', sgTemp);
      If inPos = 0 Then
      Begin
        SetLength(Result, Length(Result) + 1);
        Result[High(Result)] := sgTemp;
        Break;
      End
      Else
      Begin
        SetLength(Result, Length(Result) + 1);
        Result[High(Result)] := Copy(sgTemp, 1, inPos - 1);
        sgTemp := Copy(sgTemp, inPos + 1, Length(sgTemp) - (inPos + 1) + 1);
      End;
    End;
  Except
  End;
End;

Class Function TQuerySqlite.GetStringFieldSize(DB: TDISQLite3Database; TableName,
  FieldName: String): Integer;
Var
  boFound: Boolean;
  FieldLine: String;
  Fields: TSqliteCreateTableFieldLines;
  i: Integer;
  inPos: Integer;
  inPosSpace: Integer;
  sgAfterName: String;
  sgAfterType: String;
  sgFieldType: String;
  sgFieldTypePrefix: String;
  sgFieldTypeSize: String;
  sgStringTypes: String;
  sgTemp: String;
Begin
  Result := -1;
  sgStringTypes := '|CHAR|CHARACTER|VARCHAR|VARYING CHARACTER|NCHAR|NATIVE CHARACTER|NVARCHAR|TEXT|CLOB|';
  Fields := GetCreateTableFieldDefLines(DB, TableName);
  boFound := False;
  FieldLine := '';
  inPosSpace := -1;
  For i := 0 To High(Fields) Do
  Begin
    Fields[i] := Trim(Fields[i]);
    inPos := Pos(UpperCase(FieldName), UpperCase(Fields[i]));
    If inPos = 0 Then Continue;
    inPosSpace := Pos(' ', Fields[i]);
    If inPosSpace = 0 Then Continue;
    sgTemp := Copy(Fields[i], 1, inPosSpace - 1);
    inPos := Pos(UpperCase(FieldName), UpperCase(sgTemp));
    If inPos = 0 Then Continue;
    FieldLine := UpperCase(Fields[i]);
    boFound := True;
  End;
  If Not boFound Then Exit;
  sgAfterName := Trim(Copy(FieldLine, inPosSpace + 1, Length(FieldLine) - (inPosSpace + 1) + 1));
  sgAfterType := '';
  inPosSpace := Pos(' ', sgAfterName);
  If inPosSpace = 0 Then
  Begin
    sgFieldType := sgAfterName;
    sgAfterType := '';
  End
  Else
  Begin
    sgFieldType := Copy(sgAfterName, 1, inPosSpace - 1);
    sgAfterType := Copy(sgAfterName, inPosSpace + 1, Length(sgAfterName) - (inPosSpace + 1) + 1);
  End;
  inPos := Pos('(', sgFieldType);
  If inPos = 0 Then
  Begin
    sgFieldTypePrefix := sgFieldType;
    sgFieldTypeSize := '';
  End
  Else
  Begin
    sgFieldTypePrefix := Copy(sgFieldType, 1, inPos - 1);
    sgFieldTypeSize := Copy(sgFieldType, inPos + 1, Length(sgFieldType) - (inPos + 1) + 1);
    sgFieldTypeSize := StringReplace(sgFieldTypeSize, ')', '', [rfReplaceAll]);
  End;
  inPos := Pos('|' + sgFieldTypePrefix + '|', sgStringTypes);
  If inPos <> 0 Then
  Begin
    If sgFieldTypeSize = '' Then
    Begin
      If sgFieldTypePrefix = 'CLOB' Then
      Begin
        Result := 10000;
      End
      Else
      Begin
        Result := 2000;
      End;
    End
    Else
    Begin
      Try
        Result := StrToInt(sgFieldTypeSize);
      Except
        Result := 2000;
      End;
    End;
  End;
End;

Class Function TQuerySqlite.GetStringFieldSize(Const AColumn: TDISQLite3Column; Const AFieldDef: TFieldDef): Integer;
Var
  inPos: Integer;
  sgFieldType: String;
  sgFieldTypePrefix: String;
  sgFieldTypeSize: String;
  sgStringTypes: String;
Begin
  Result := -1;
  sgStringTypes := '|CHAR|CHARACTER|VARCHAR|VARYING CHARACTER|NCHAR|NATIVE CHARACTER|NVARCHAR|TEXT|CLOB|';
  sgFieldType := UpperCase(Acolumn.ColumnDeclaration);
  inPos := Pos('(', sgFieldType);
  If inPos = 0 Then
  Begin
    sgFieldTypePrefix := sgFieldType;
    sgFieldTypeSize := '';
  End
  Else
  Begin
    sgFieldTypePrefix := Copy(sgFieldType, 1, inPos - 1);
    sgFieldTypeSize := Copy(sgFieldType, inPos + 1, Length(sgFieldType) - (inPos + 1) + 1);
    sgFieldTypeSize := StringReplace(sgFieldTypeSize, ')', '', [rfReplaceAll]);
  End;
  inPos := Pos('|' + sgFieldTypePrefix + '|', sgStringTypes);
  If inPos <> 0 Then
  Begin
    If sgFieldTypeSize = '' Then
    Begin
      If sgFieldTypePrefix = 'CLOB' Then
      Begin
        Result := 10000;
      End
      Else
      Begin
        Result := 2000;
      End;
    End
    Else
    Begin
      Try
        Result := StrToInt(sgFieldTypeSize);
      Except
        Result := 2000;
      End;
    End;
  End;
End;

Class Function TQuerySqlite.GetMaxFieldWidth(Database: TDISQLite3Database;
  FieldName, TableName: String): Integer;
Var
  qry: TQuerySqlite;
Begin
  Result := -1;
  qry := TQuerySqlite.Create(Nil);
  Try
    qry.SqlSelect :=
      'Select length(' + FieldName + ') As MaxLen from ' + TableName +
      ' where length(' + FieldName + ')=(select max(length(' + FieldName + '))' +
      ' from ' + TableName + ')';
    qry.Database := Database;
    qry.Active := True;
    If qry.DataSet.bof And qry.DataSet.eof Then Exit;
    qry.DataSet.First();
    Result := qry.DataSet.FieldByName('MaxLen').AsInteger;
  Finally
    FreeAndNil(qry);
  End;
End;

Class Procedure TQuerySqlite.AdjustColumnWidths(qry: TQuerySqlite; TableName: String; DBGrid: TDBGrid);
Var
  i: Integer;
Begin
  If Not qry.Active Then Exit;
  If qry.DataSet.Bof And qry.DataSet.EOF Then Exit;
  For i := 0 To qry.DataSet.FieldCount - 1 Do
  Begin
    qry.DataSet.Fields[i].DisplayWidth := TQuerySqlite.GetMaxFieldWidth(qry.Database, qry.DataSet.Fields[i].FieldName, TableName);
    DBGrid.Columns.RestoreDefaults;
  End;
End;

Class Function TQuerySqlite.GetTableNames(
  DB: TDISQLite3Database): TSqliteStringArray;
Var
  qry: TQuerySqlite;
Begin
  SetLength(Result, 0);
  qry := TQuerySqlite.Create(Nil);
  Try
    qry.SqlSelect :=
      'Select tbl_name As TableName From sqlite_master where type="table" Order By tbl_name';
    qry.Database := DB;
    qry.Active := True;
    If qry.DataSet.bof And qry.DataSet.eof Then Exit;
    qry.DataSet.First();
    While Not qry.DataSet.eof Do
    Begin
      SetLength(Result, Length(Result) + 1);
      Result[High(Result)] := qry.DataSet.FieldByName('TableName').AsString;
      qry.DataSet.Next();
    End;
  Finally
    FreeAndNil(qry);
  End;
End;

Class Function TQuerySqlite.GetDatabaseCreateScript(
  DB: TDISQLite3Database): String;
Var
  i: Integer;
  a: TSqliteStringArray;
Begin
  Result := '';
  a := GetDatabaseCreateScriptArray(DB);
  For i := 0 To High(a) Do
  Begin
    Result := Result + a[i] + ';' + #13 + #10 + #13 + #10;
  End;
End;

Class Function TQuerySqlite.GetDatabaseCreateScriptArray(
  DB: TDISQLite3Database): TSqliteStringArray;
Var
  a: TSqliteStringArray;
  i: Integer;
  s: String;
Begin
  a := TQuerySqlite.GetTableNames(DB);
  SetLength(Result, 0);
  For i := 0 To High(a) Do
  Begin
    SetLength(Result, Length(Result) + 1);
    s := GetCreateTableSQL(DB, a[i]);
    Result[High(Result)] := s;
  End;
End;

Class Function TQuerySqlite.DBNextInteger(DB: TDISQLite3Database; TableName,
  FieldName: String): Integer;
Var
  qry: TQuerySqlite;
Begin
  Result := 0;
  qry := TQuerySqlite.Create(Nil);
  Try
    If Trim(TableName) = '' Then Exit;
    If Trim(FieldName) = '' Then Exit;
    Try
      qry.SqlSelect :=
        'Select Max(' + FieldName + ') As MaxValue From ' + TableName;
      qry.Database := DB;
      qry.Active := True;
      If qry.DataSet.bof And qry.DataSet.eof Then Exit;
      qry.DataSet.First();
      Result := qry.DataSet.FieldByName('MaxValue').AsInteger + 1;
    Except
    End;
  Finally
    FreeAndNil(qry);
  End;
End;

Class Function TQuerySqlite.DBDropTable(DB: TDISQLite3Database;
  TableName: String): Boolean;
Begin
  Result := False;
  If Trim(TableName) = '' Then Exit;
  Try
    DB.Execute('Drop Table ' + TableName);
    DB.Commit;
    Result := True;
  Except
  End;
End;

Class Function TQuerySqlite.DBEmptyTable(DB: TDISQLite3Database;
  TableName: String): Boolean;
Var
  sql: String;
Begin
  Result := False;
  If Trim(TableName) = '' Then Exit;
  Try
    sql := GetCreateTableSQL(DB, TableName);
    DB.Execute('Drop Table ' + TableName);
    DB.Commit;
    DB.Execute(sql);
    DB.Commit;
    Result := True;
  Except
  End;
End;

End.
//