357 lines
9.6 KiB
ObjectPascal
357 lines
9.6 KiB
ObjectPascal
unit uDASQLiteDriver;
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ Data Abstract Library - Driver Library
|
|
{
|
|
{ compiler: Delphi 6 and up, Kylix 3 and up
|
|
{ platform: Win32, Linux
|
|
{
|
|
{ (c)opyright RemObjects Software. all rights reserved.
|
|
{
|
|
{ Using this code requires a valid license of the Data Abstract
|
|
{ which can be obtained at http://www.remobjects.com.
|
|
{----------------------------------------------------------------------------}
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
{$I ..\DataAbstract.inc}
|
|
{$ENDIF MSWINDOWS}
|
|
{$IFDEF LINUX}
|
|
{$I ../DataAbstract.inc}
|
|
{$ENDIF LINUX}
|
|
|
|
{$R DataAbstract_SQLiteDriver_Glyphs.res}
|
|
|
|
interface
|
|
|
|
uses Windows, Classes, DB, uDAEngine, uDAInterfaces, uROClasses, uDAUtils, ASGSQLite3, uDASQLiteInterfaces;
|
|
|
|
type
|
|
{ TDASQLiteDriver }
|
|
TDASQLiteDriver = class(TDADriverReference)
|
|
end;
|
|
|
|
{ TDAESQLiteDriver }
|
|
TDAESQLiteDriver = class(uDASQLiteInterfaces.TDASQLiteDriver, IDADriver40)
|
|
protected
|
|
function GetConnectionClass: TDAEConnectionClass; override;
|
|
|
|
// IDADriver
|
|
function GetDriverID: string; override;
|
|
function GetDescription: string; override;
|
|
|
|
procedure GetAuxParams(const AuxDriver: string; out List: IROStrings); override;
|
|
|
|
function GetAvailableDriverOptions: TDAAvailableDriverOptions; override;
|
|
// IDADriver40
|
|
function GetProviderDefaultCustomParameters(Provider: string): string; safecall;
|
|
public
|
|
end;
|
|
|
|
// for access to protected methods
|
|
TDAASQLite3DB = class(TASQLite3DB)
|
|
private
|
|
public
|
|
function GetLastInsertRow: integer;
|
|
end;
|
|
|
|
{ TSQLiteConnection }
|
|
TSQLiteConnection = class(TDAConnectionWrapper)
|
|
private
|
|
fConnection: TDAASQLite3DB;
|
|
protected
|
|
function GetConnected: Boolean; override;
|
|
procedure SetConnected(Value: Boolean); override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
property Connection: TDAASQLite3DB read fConnection;
|
|
end;
|
|
|
|
{ TDAESQLiteConnection }
|
|
TDAESQLiteConnection = class(TDASQLiteConnection)
|
|
private
|
|
FtransactionFlag: Boolean;
|
|
fConnection: TSQLiteConnection;
|
|
protected
|
|
// TDAEConnection
|
|
function CreateCustomConnection: TCustomConnection; override;
|
|
function GetDatasetClass: TDAEDatasetClass; override;
|
|
procedure DoApplyConnectionString(aConnStrParser: TDAConnectionStringParser; aConnectionObject: TCustomConnection); override;
|
|
function DoBeginTransaction: integer; override;
|
|
procedure DoCommitTransaction; override;
|
|
procedure DoRollbackTransaction; override;
|
|
function DoGetInTransaction: boolean; override;
|
|
function DoGetLastAutoInc(const GeneratorName: string): integer; override;
|
|
procedure DoGetForeignKeys(out ForeignKeys: TDADriverForeignKeyCollection); override;
|
|
procedure DoGetTableFields(const aTableName: string; out Fields: TDAFieldCollection); override;
|
|
|
|
function IdentifierNeedsQuoting(const iIdentifier: string): boolean; override; safecall;
|
|
public
|
|
constructor Create(aDriver: TDAEDriver; aName: string = ''); override;
|
|
end;
|
|
|
|
{ TDAESQLiteQuery }
|
|
TDAESQLiteQuery = class(TDAEDataset)
|
|
private
|
|
protected
|
|
function CreateDataset(aConnection: TDAEConnection): TDataset; override;
|
|
procedure DoPrepare(Value: boolean); override; safecall;
|
|
function DoExecute: integer; override;
|
|
function DoGetSQL: string; override;
|
|
procedure DoSetSQL(const Value: string); override;
|
|
end;
|
|
|
|
procedure Register;
|
|
|
|
function GetDriverObject: IDADriver; stdcall;
|
|
|
|
implementation
|
|
|
|
uses SysUtils, uDADriverManager, uDARes, Variants,
|
|
uROBinaryHelpers, uDASQL92Interfaces;
|
|
|
|
var
|
|
_driver: TDAEDriver = nil;
|
|
|
|
procedure Register;
|
|
begin
|
|
RegisterComponents(DAPalettePageName, [TDASQLiteDriver]);
|
|
end;
|
|
|
|
{$IFDEF DataAbstract_SchemaModelerOnly}
|
|
{$INCLUDE ..\DataAbstract_SchemaModelerOnly.inc}
|
|
{$ENDIF DataAbstract_SchemaModelerOnly}
|
|
|
|
function GetDriverObject: IDADriver;
|
|
begin
|
|
if (_driver = nil) then _driver := TDAESQLiteDriver.Create(nil);
|
|
result := _driver;
|
|
end;
|
|
|
|
{ TSQLiteConnection }
|
|
|
|
constructor TSQLiteConnection.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
fConnection := TDAASQLite3DB.Create(nil);
|
|
end;
|
|
|
|
destructor TSQLiteConnection.Destroy;
|
|
begin
|
|
inherited;
|
|
fConnection.Free;
|
|
end;
|
|
|
|
function TSQLiteConnection.GetConnected: Boolean;
|
|
begin
|
|
result := fConnection.Connected;
|
|
end;
|
|
|
|
procedure TSQLiteConnection.SetConnected(Value: Boolean);
|
|
begin
|
|
fConnection.Connected := Value;
|
|
end;
|
|
|
|
{ TDAESQLiteConnection }
|
|
|
|
procedure TDAESQLiteConnection.DoApplyConnectionString(
|
|
aConnStrParser: TDAConnectionStringParser; aConnectionObject: TCustomConnection);
|
|
var
|
|
sName, sValue: string;
|
|
i: integer;
|
|
begin
|
|
inherited;
|
|
with aConnStrParser do begin
|
|
TSQLiteConnection(aConnectionObject).Connection.Database := Database;
|
|
for i := 0 to (AuxParamsCount - 1) do begin
|
|
sName := AuxParamNames[i];
|
|
sValue := AuxParams[sName];
|
|
if AnsiSameText(sName, 'TransactionType') then begin
|
|
if AnsiSameText(sValue, 'DEFAULT') or
|
|
AnsiSameText(sValue, 'DEFERRED') or
|
|
AnsiSameText(sValue, 'IMMEDIATE') or
|
|
AnsiSameText(sValue, 'EXCLUSIVE') then
|
|
fConnection.fConnection.TransactionType := AnsiUpperCase(sValue);
|
|
end
|
|
else if AnsiSameText(sName, 'DriverDll') then begin
|
|
fConnection.fConnection.DriverDll := sValue
|
|
end
|
|
else if AnsiSameText(sName, 'CharacterEncoding') then begin
|
|
if AnsiSameText(sValue, 'STANDARD') or
|
|
AnsiSameText(sValue, 'UTF8') then
|
|
fConnection.fConnection.CharacterEncoding := AnsiUpperCase(sValue);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TDAESQLiteConnection.DoBeginTransaction: integer;
|
|
begin
|
|
result := -1;
|
|
fConnection.Connection.StartTransaction;
|
|
FtransactionFlag := True;
|
|
end;
|
|
|
|
procedure TDAESQLiteConnection.DoCommitTransaction;
|
|
begin
|
|
fConnection.Connection.Commit;
|
|
FtransactionFlag := False;
|
|
end;
|
|
|
|
function TDAESQLiteConnection.CreateCustomConnection: TCustomConnection;
|
|
begin
|
|
fConnection := TSQLiteConnection.Create(nil);
|
|
result := fConnection;
|
|
end;
|
|
|
|
function TDAESQLiteConnection.GetDatasetClass: TDAEDatasetClass;
|
|
begin
|
|
result := TDAESQLiteQuery;
|
|
end;
|
|
|
|
procedure TDAESQLiteConnection.DoRollbackTransaction;
|
|
begin
|
|
FtransactionFlag := False;
|
|
fConnection.Connection.RollBack;
|
|
end;
|
|
|
|
function TDAESQLiteConnection.DoGetInTransaction: boolean;
|
|
begin
|
|
Result := FtransactionFlag;
|
|
end;
|
|
|
|
procedure TDAESQLiteConnection.DoGetTableFields(const aTableName: string;
|
|
out Fields: TDAFieldCollection);
|
|
var
|
|
List: TList;
|
|
i: integer;
|
|
fld: TDAField;
|
|
begin
|
|
inherited DoGetTableFields(QuoteIdentifierIfNeeded(aTableName), Fields);
|
|
List := TList.Create;
|
|
try
|
|
fConnection.Connection.GetTableInfo(aTableName, List);
|
|
for i := 0 to List.Count - 1 do
|
|
with TASQLite3Field(List[i]) do begin
|
|
fld := Fields.FieldByName(FieldName);
|
|
fld.Required := FieldNN <> 0;
|
|
fld.InPrimaryKey := FieldPK <> 0;
|
|
if fld.InPrimaryKey then fld.Required := True;
|
|
fld.DefaultValue := FieldDefault;
|
|
end;
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
function TDAESQLiteConnection.IdentifierNeedsQuoting(
|
|
const iIdentifier: string): boolean;
|
|
begin
|
|
Result := inherited IdentifierNeedsQuoting(iIdentifier) or
|
|
SQL92_IdentifierNeedsQuoting(iIdentifier);
|
|
end;
|
|
|
|
constructor TDAESQLiteConnection.Create(aDriver: TDAEDriver;
|
|
aName: string);
|
|
begin
|
|
inherited;
|
|
FtransactionFlag := False;
|
|
end;
|
|
|
|
function TDAESQLiteConnection.DoGetLastAutoInc(
|
|
const GeneratorName: string): integer;
|
|
begin
|
|
Result := fConnection.Connection.GetLastInsertRow;
|
|
end;
|
|
|
|
procedure TDAESQLiteConnection.DoGetForeignKeys(
|
|
out ForeignKeys: TDADriverForeignKeyCollection);
|
|
begin
|
|
inherited;
|
|
// SQL Features That SQLite Does Not Implement
|
|
end;
|
|
|
|
{ TDAESQLiteDriver }
|
|
|
|
function TDAESQLiteDriver.GetAvailableDriverOptions: TDAAvailableDriverOptions;
|
|
begin
|
|
result := [doDatabaseName, doCustom];
|
|
end;
|
|
|
|
function TDAESQLiteDriver.GetConnectionClass: TDAEConnectionClass;
|
|
begin
|
|
result := TDAESQLiteConnection;
|
|
end;
|
|
|
|
function TDAESQLiteDriver.GetDescription: string;
|
|
begin
|
|
result := 'SQLite Driver';
|
|
end;
|
|
|
|
function TDAESQLiteDriver.GetDriverID: string;
|
|
begin
|
|
result := 'SQLite';
|
|
end;
|
|
|
|
procedure TDAESQLiteDriver.GetAuxParams(const AuxDriver: string;
|
|
out List: IROStrings);
|
|
begin
|
|
inherited;
|
|
List.Add('TransactionType=(DEFAULT,DEFERRED,IMMEDIATE,EXCLUSIVE)');
|
|
List.Add('DriverDll=SQLite3.dll');
|
|
List.Add('CharacterEncoding=(STANDARD,UTF8)');
|
|
end;
|
|
|
|
function TDAESQLiteDriver.GetProviderDefaultCustomParameters(
|
|
Provider: string): string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
{ TDAESQLiteQuery }
|
|
|
|
function TDAESQLiteQuery.CreateDataset(aConnection: TDAEConnection): TDataset;
|
|
begin
|
|
result := TASQLite3Query.Create(nil);
|
|
TASQLite3Query(result).Connection := TDAESQLiteConnection(aConnection).fConnection.Connection;
|
|
end;
|
|
|
|
function TDAESQLiteQuery.DoExecute: integer;
|
|
begin
|
|
Result := -1;
|
|
inherited DoExecute;
|
|
end;
|
|
|
|
function TDAESQLiteQuery.DoGetSQL: string;
|
|
begin
|
|
result := TASQLite3Query(Dataset).SQL.Text;
|
|
end;
|
|
|
|
procedure TDAESQLiteQuery.DoPrepare(Value: boolean);
|
|
begin
|
|
// nothing
|
|
end;
|
|
|
|
procedure TDAESQLiteQuery.DoSetSQL(const Value: string);
|
|
begin
|
|
TASQLite3Query(Dataset).SQL.Text := Value;
|
|
end;
|
|
|
|
exports GetDriverObject name func_GetDriverObject;
|
|
|
|
{ TDAASQLite3DB }
|
|
|
|
function TDAASQLite3DB.GetLastInsertRow: integer;
|
|
begin
|
|
result := SQLite3_LastInsertRow(DBHandle)
|
|
end;
|
|
|
|
initialization
|
|
_driver := nil;
|
|
RegisterDriverProc(GetDriverObject);
|
|
finalization
|
|
UnregisterDriverProc(GetDriverObject);
|
|
FreeAndNIL(_driver);
|
|
end.
|
|
|