unit uDADBISAMDriver; {----------------------------------------------------------------------------} { Data Abstract Library - Driver Library { { compiler: Delphi 6 and up { platform: Win32 { { (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_DBISAMDriver_Glyphs.res} {$I dbisamvr.inc} {$IFNDEF DBISAM_V4} {$DEFINE DBISAM_V3} {$ENDIF} interface uses DB, Classes, uDAEngine, uDAInterfaces, uROClasses, DBISAMTb, uDAUtils; type { TDADBISAMDriver } TDADBISAMDriver = class(TDADriverReference) end; { IDBISAMConnection } IDBISAMConnection = interface ['{C6222EF8-FBAE-42AE-B034-8FFAE8FF2578}'] end; { IDBISAMConnectionProperties Provides access to common properties of DBISAM connections } IDBISAMConnectionProperties = interface ['{41BAFCD6-D6EA-477E-B489-7EA6E05FFCC0}'] function GetForceBufferFlush: Boolean; procedure SetForceBufferFlush(Value: Boolean); function GetKeepConnections: Boolean; procedure SetKeepConnections(Value: Boolean); function GetLockProtocol: TLockProtocol; procedure SetLockProtocol(Value: TLockProtocol); function GetLockRetryCount: Byte; procedure SetLockRetryCount(Value: Byte); function GetLockWaitTime: Word; procedure SetLockWaitTime(Value: Word); function GetPrivateDir: string; procedure SetPrivateDir(const Value: string); function GetRemotePort: Integer; procedure SetRemotePort(Value: Integer); function GetRemoteService: string; procedure SetRemoteService(const Value: string); function GetRemoteTrace: Boolean; procedure SetRemoteTrace(Value: Boolean); {$IFDEF DBISAM_V3} function GetRemoteType: TRemoteType; procedure SetRemoteType(Value: TRemoteType); {$ENDIF} {$IFDEF DBISAM_V4} function GetRemoteCompression: Byte; procedure SetRemoteCompression(Value: Byte); function GetRemoteEncryption: Boolean; procedure SetRemoteEncryption(Value: Boolean); function GetRemoteEncryptionPassword: string; procedure SetRemoteEncryptionPassword(const Value: string); function GetRemoteTimeout: Integer; procedure SetRemoteTimeout(Value: Integer); {$ENDIF} procedure AddPassword( const aPassword: string); procedure RemovePassword(const aPassword: string); procedure RemoveAllPasswords; property ForceBufferFlush: Boolean read GetForceBufferFlush write SetForceBufferFlush; property KeepConnections: Boolean read GetKeepConnections write SetKeepConnections; property LockProtocol: TLockProtocol read GetLockProtocol write SetLockProtocol; property LockRetryCount: Byte read GetLockRetryCount write SetLockRetryCount; property LockWaitTime: Word read GetLockWaitTime write SetLockWaitTime; property PrivateDir: string read GetPrivateDir write SetPrivateDir; property RemotePort: Integer read GetRemotePort write SetRemotePort; property RemoteService: string read GetRemoteService write SetRemoteService; property RemoteTrace: Boolean read GetRemoteTrace write SetRemoteTrace; {$IFDEF DBISAM_V3} property RemoteType: TRemoteType read GetRemoteType write SetRemoteType; {$ENDIF} {$IFDEF DBISAM_V4} property RemoteCompression: Byte read GetRemoteCompression write SetRemoteCompression; property RemoteEncryption: Boolean read GetRemoteEncryption write SetRemoteEncryption; property RemoteEncryptionPassword: string read GetRemoteEncryptionPassword write SetRemoteEncryptionPassword; property RemoteTimeout: Integer read GetRemoteTimeout write SetRemoteTimeout; {$ENDIF} end; { TDBISAMConnection } TDBISAMConnection = class(TDAConnectionWrapper) private fDatabase: TDBISAMDatabase; fSession: TDBISAMSession; protected function GetConnected: Boolean; override; procedure SetConnected(Value: Boolean); override; public constructor Create(AOwner: TComponent); override; property Database: TDBISAMDatabase read fDatabase; property Session: TDBISAMSession read fSession; end; { TDAEDBISAMDriver } TDAEDBISAMDriver = class(TDAEDriver) private 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; function GetDefaultConnectionType(const AuxDriver: string): string; override; safecall; public end; { TDAEDBISAMConnection } TDAEDBISAMConnection = class(TDAEConnection, IDBISAMConnection, IDBISAMConnectionProperties) private fConnection: TDBISAMConnection; protected // IDBISAMConnectionProperties function GetForceBufferFlush: Boolean; procedure SetForceBufferFlush(Value: Boolean); function GetKeepConnections: Boolean; procedure SetKeepConnections(Value: Boolean); function GetLockProtocol: TLockProtocol; procedure SetLockProtocol(Value: TLockProtocol); function GetLockRetryCount: Byte; procedure SetLockRetryCount(Value: Byte); function GetLockWaitTime: Word; procedure SetLockWaitTime(Value: Word); function GetPrivateDir: string; procedure SetPrivateDir(const Value: string); function GetRemotePort: Integer; procedure SetRemotePort(Value: Integer); function GetRemoteService: string; procedure SetRemoteService(const Value: string); function GetRemoteTrace: Boolean; procedure SetRemoteTrace(Value: Boolean); {$IFDEF DBISAM_V3} function GetRemoteType: TRemoteType; procedure SetRemoteType(Value: TRemoteType); {$ENDIF} {$IFDEF DBISAM_V4} function GetRemoteCompression: Byte; procedure SetRemoteCompression(Value: Byte); function GetRemoteEncryption: Boolean; procedure SetRemoteEncryption(Value: Boolean); function GetRemoteEncryptionPassword: string; procedure SetRemoteEncryptionPassword(const Value: string); function GetRemoteTimeout: Integer; procedure SetRemoteTimeout(Value: Integer); {$ENDIF} procedure AddPassword( const aPassword: string); procedure RemovePassword(const aPassword: string); procedure RemoveAllPasswords; // IDAConnection function CreateCustomConnection: TCustomConnection; override; function CreateMacroProcessor: TDASQLMacroProcessor; 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; procedure DoGetTableNames(out List: IROStrings); override; function DoGetLastAutoInc(const GeneratorName: string): integer; override; procedure DoGetTableFields(const aTableName: string; out Fields: TDAFieldCollection);override; public end; { TDAEDBISAMQuery } TDAEDBISAMQuery = class(TDAEDataset, IDAMustSetParams) private protected function CreateDataset(aConnection: TDAEConnection): TDataset; override; function DoExecute: Integer; override; function DoGetSQL: string; override; procedure DoSetSQL(const Value: string); override; procedure DoPrepare(Value: Boolean); override; // IDAMustSetParams procedure SetParamValues(Params: TDAParamCollection); safecall; {$IFDEF DBISAM_V4} procedure RefreshParams; override; {$ENDIF} procedure GetParamValues(Params: TDAParamCollection); safecall; end; const DBISAM_DriverType = 'DBISAM'; procedure Register; function GetDriverObject: IDADriver; stdcall; implementation uses SysUtils, uDADriverManager, uDARes, uDAMacroProcessors, Variants, uROBinaryHelpers; var _driver: TDAEDriver = nil; procedure Register; begin RegisterComponents(DAPalettePageName, [TDADBISAMDriver]); end; {$IFDEF DataAbstract_SchemaModelerOnly} {$INCLUDE ..\DataAbstract_SchemaModelerOnly.inc} {$ENDIF DataAbstract_SchemaModelerOnly} function GetDriverObject: IDADriver; begin {$IFDEF DataAbstract_SchemaModelerOnly} if not RunningInSchemaModeler then begin result := nil; exit; end; {$ENDIF} if (_driver = nil) then _driver := TDAEDBISAMDriver.Create(nil); result := _driver; end; { TDBISAMConnection } constructor TDBISAMConnection.Create(AOwner: TComponent); begin inherited; fSession := TDBISAMSession.Create(Self); fSession.AutoSessionName := TRUE; fDatabase := TDBISAMDatabase.Create(Self); fDatabase.SessionName := fSession.SessionName; fDatabase.DatabaseName := 'DBISAMDB'; end; function TDBISAMConnection.GetConnected: Boolean; begin result := fDatabase.Connected; end; procedure TDBISAMConnection.SetConnected(Value: Boolean); begin if not(csDestroying in fDatabase.ComponentState) then begin try fSession.Active := Value; fDatabase.Connected := Value; except fSession.Active := FALSE; fDatabase.Connected := FALSE; raise; end; end; end; { TDAEDBISAMConnection } procedure TDAEDBISAMConnection.DoApplyConnectionString( aConnStrParser: TDAConnectionStringParser; aConnectionObject: TCustomConnection); begin inherited; with aConnStrParser do begin if (Self.UserID <> '') then fConnection.Session.RemoteUser := Self.UserID else fConnection.Session.RemoteUser := UserID; if (Self.Password <> '') then fConnection.Session.RemotePassword := Self.Password else fConnection.Session.RemotePassword := Password; if (Server <> '') then begin // Remote connection fConnection.Session.SessionType := stRemote; fConnection.Session.RemoteHost := Server; fConnection.Database.RemoteDatabase := Database; if (AuxParams['RemotePort'] <> '') then fConnection.Session.RemotePort := StrToInt(AuxParams['RemotePort']); if (AuxParams['RemoteService'] <> '') then fConnection.Session.RemoteService := AuxParams['RemoteService']; if (AuxParams['RemoteTrace'] = 'False') then fConnection.Session.RemoteTrace := False else if (AuxParams['RemoteTrace'] = 'True') then fConnection.Session.RemoteTrace := True; {$IFDEF DBISAM_V3} if (AuxParams['RemoteType'] = 'rtLAN') then fConnection.Session.RemoteType := rtLAN else if (AuxParams['RemoteType'] = 'rtInternet') then fConnection.Session.RemoteType := rtInternet; {$ENDIF} {$IFDEF DBISAM_V4} if (AuxParams['RemoteCompression'] <> '') then if (StrToInt(AuxParams['RemoteCompression']) in [0..9]) then fConnection.Session.RemoteCompression := StrToInt(AuxParams['RemoteCompression']); if (AuxParams['RemoteEncryption'] = 'False') then fConnection.Session.RemoteEncryption := False else if (AuxParams['RemoteEncryption'] = 'True') then fConnection.Session.RemoteEncryption := True; if (AuxParams['RemoteEncryptionPassword'] <> '') then fConnection.Session.RemoteEncryptionPassword := AuxParams['RemoteEncryptionPassword']; if (AuxParams['RemoteTimeout'] <> '') then fConnection.Session.RemoteTimeout := StrToInt(AuxParams['RemoteTimeout']); {$ENDIF} end else begin // Local connection fConnection.Session.SessionType := stLocal; fConnection.Database.Directory := Database; end; if (AuxParams['ForceBufferFlush'] = 'False') then fConnection.Session.ForceBufferFlush := False else if (AuxParams['ForceBufferFlush'] = 'True') then fConnection.Session.ForceBufferFlush := True; if (AuxParams['KeepConnections'] = 'False') then begin fConnection.Session.KeepConnections := False; fConnection.Database.KeepConnection := False; end else if (AuxParams['KeepConnections'] = 'True') then begin fConnection.Session.KeepConnections := True; fConnection.Database.KeepConnection := True; end; if (AuxParams['LockProtocol'] = 'lpOptimistic') then fConnection.Session.LockProtocol := lpOptimistic else if (AuxParams['LockProtocol'] = 'lpPessimistic') then fConnection.Session.LockProtocol := lpPessimistic; if (AuxParams['LockRetryCount'] <> '') then fConnection.Session.LockRetryCount := StrToInt(AuxParams['LockRetryCount']); if (AuxParams['LockWaitTime'] <> '') then fConnection.Session.LockWaitTime := StrToInt(AuxParams['LockWaitTime']); if (AuxParams['PrivateDir'] <> '') then fConnection.Session.PrivateDir := AuxParams['PrivateDir']; if (AuxParams['TablePassword'] <> '') then begin fConnection.Session.Active := True; fConnection.Session.AddPassword(AuxParams['TablePassword']); end; end; end; function TDAEDBISAMConnection.DoBeginTransaction: integer; begin result := -1; fConnection.Database.StartTransaction; end; procedure TDAEDBISAMConnection.DoCommitTransaction; begin with fConnection do Database.Commit(Session.ForceBufferFlush); end; function TDAEDBISAMConnection.CreateCustomConnection: TCustomConnection; begin result := TDBISAMConnection.Create(nil); fConnection := TDBISAMConnection(result); end; function TDAEDBISAMConnection.GetDatasetClass: TDAEDatasetClass; begin result := TDAEDBISAMQuery end; procedure TDAEDBISAMConnection.DoGetTableNames(out List: IROStrings); var _database: string; begin List := TROStrings.Create; if (fConnection.Session.SessionType = stLocal) then _database := fConnection.Database.Directory else _database := fConnection.Database.RemoteDatabase; fConnection.Session.GetTableNames(_database, List.Strings); end; procedure TDAEDBISAMConnection.DoRollbackTransaction; begin fConnection.Database.Rollback; end; function TDAEDBISAMConnection.DoGetInTransaction: Boolean; begin result := fConnection.Database.InTransaction; end; function TDAEDBISAMConnection.CreateMacroProcessor: TDASQLMacroProcessor; begin result := TDADBISAMMacroProcessor.Create; end; function TDAEDBISAMConnection.GetForceBufferFlush: Boolean; begin result := fConnection.Session.ForceBufferFlush; end; procedure TDAEDBISAMConnection.SetForceBufferFlush(Value: Boolean); begin fConnection.Session.ForceBufferFlush := Value; end; function TDAEDBISAMConnection.GetKeepConnections: Boolean; begin result := fConnection.Session.KeepConnections; end; procedure TDAEDBISAMConnection.SetKeepConnections(Value: Boolean); begin fConnection.Session.KeepConnections := Value; fConnection.Database.KeepConnection := Value; end; function TDAEDBISAMConnection.GetLockProtocol: TLockProtocol; begin result := fConnection.Session.LockProtocol; end; procedure TDAEDBISAMConnection.SetLockProtocol(Value: TLockProtocol); begin fConnection.Session.LockProtocol := Value; end; function TDAEDBISAMConnection.GetLockRetryCount: Byte; begin result := fConnection.Session.LockRetryCount; end; procedure TDAEDBISAMConnection.SetLockRetryCount(Value: Byte); begin fConnection.Session.LockRetryCount := Value; end; function TDAEDBISAMConnection.GetLockWaitTime: Word; begin result := fConnection.Session.LockWaitTime; end; procedure TDAEDBISAMConnection.SetLockWaitTime(Value: Word); begin fConnection.Session.LockWaitTime := Value; end; function TDAEDBISAMConnection.GetPrivateDir: string; begin result := fConnection.Session.PrivateDir; end; procedure TDAEDBISAMConnection.SetPrivateDir(const Value: string); begin fConnection.Session.PrivateDir := Value; end; function TDAEDBISAMConnection.GetRemotePort: Integer; begin result := fConnection.Session.RemotePort; end; procedure TDAEDBISAMConnection.SetRemotePort(Value: Integer); begin fConnection.Session.RemotePort := Value; end; function TDAEDBISAMConnection.GetRemoteService: string; begin result := fConnection.Session.RemoteService; end; procedure TDAEDBISAMConnection.SetRemoteService(const Value: string); begin fConnection.Session.RemoteService := Value; end; function TDAEDBISAMConnection.GetRemoteTrace: Boolean; begin result := fConnection.Session.RemoteTrace; end; procedure TDAEDBISAMConnection.SetRemoteTrace(Value: Boolean); begin fConnection.Session.RemoteTrace := Value; end; {$IFDEF DBISAM_V3} function TDAEDBISAMConnection.GetRemoteType: TRemoteType; begin result := fConnection.Session.RemoteType; end; procedure TDAEDBISAMConnection.SetRemoteType(Value: TRemoteType); begin fConnection.Session.RemoteType := Value; end; {$ENDIF} {$IFDEF DBISAM_V4} function TDAEDBISAMConnection.GetRemoteCompression: Byte; begin result := fConnection.Session.RemoteCompression; end; procedure TDAEDBISAMConnection.SetRemoteCompression(Value: Byte); begin fConnection.Session.RemoteCompression := Value; end; function TDAEDBISAMConnection.GetRemoteEncryption: Boolean; begin result := fConnection.Session.RemoteEncryption; end; procedure TDAEDBISAMConnection.SetRemoteEncryption(Value: Boolean); begin fConnection.Session.RemoteEncryption := Value; end; function TDAEDBISAMConnection.GetRemoteEncryptionPassword: string; begin result := fConnection.Session.RemoteEncryptionPassword; end; procedure TDAEDBISAMConnection.SetRemoteEncryptionPassword(const Value: string); begin fConnection.Session.RemoteEncryptionPassword := Value; end; function TDAEDBISAMConnection.GetRemoteTimeout: Integer; begin result := fConnection.Session.RemoteTimeout; end; procedure TDAEDBISAMConnection.SetRemoteTimeout(Value: Integer); begin fConnection.Session.RemoteTimeout := Value; end; {$ENDIF} procedure TDAEDBISAMConnection.AddPassword( const aPassword: string); begin fConnection.Session.AddPassword(aPassword); end; procedure TDAEDBISAMConnection.RemovePassword( const aPassword: string); begin fConnection.Session.RemovePassword(aPassword); end; procedure TDAEDBISAMConnection.RemoveAllPasswords; begin fConnection.Session.RemoveAllPasswords; end; function TDAEDBISAMConnection.DoGetLastAutoInc( const GeneratorName: string): integer; var lQuery: IDADataset; begin lQuery:=GetDatasetClass.Create(Self); try lQuery.SQL := 'SELECT LASTAUTOINC('''+GeneratorName+''') from '+QuoteIdentifierIfNeeded(GeneratorName); lQuery.Open; Result := lQuery.Fields[0].AsInteger; finally lQuery:=nil; end; end; procedure TDAEDBISAMConnection.DoGetTableFields(const aTableName: string; out Fields: TDAFieldCollection); var i: integer; begin inherited DoGetTableFields(aTableName,Fields); For i:=0 to Fields.Count -1 do if Fields[i].DataType = datAutoInc then Fields[i].GeneratorName:= aTableName; end; { TDAEDBISAMDriver } procedure TDAEDBISAMDriver.GetAuxParams(const AuxDriver: string; out List: IROStrings); begin inherited; List.Add('ForceBufferFlush=False,True'); List.Add('KeepConnections=False,True'); List.Add('LockProtocol=lpOptimistic,lpPessimistic'); List.Add('LockRetryCount='); List.Add('LockWaitTime='); List.Add('PrivateDir='); List.Add('RemotePort='); List.Add('RemoteService='); List.Add('RemoteTrace=False,True'); List.Add('TablePassword='); {$IFDEF DBISAM_V3} List.Add('RemoteType=rtLAN,rtInternet'); {$ENDIF} {$IFDEF DBISAM_V4} List.Add('RemoteCompression='); List.Add('RemoteEncryption=False,True'); List.Add('RemoteEncryptionPassword='); List.Add('RemoteTimeout='); {$ENDIF} List.Sorted := True; end; function TDAEDBISAMDriver.GetAvailableDriverOptions: TDAAvailableDriverOptions; begin result := [doServerName, doDatabaseName, doLogin, doCustom]; end; function TDAEDBISAMDriver.GetConnectionClass: TDAEConnectionClass; begin result := TDAEDBISAMConnection end; function TDAEDBISAMDriver.GetDefaultConnectionType( const AuxDriver: string): string; begin Result:=DBISAM_DriverType; end; function TDAEDBISAMDriver.GetDescription: string; begin {$IFDEF DBISAM_V3} result := 'DBISAM3 Driver'{$IFDEF DataAbstract_SchemaModelerOnly} + SchemaModelerOnly{$ENDIF}; {$ENDIF} {$IFDEF DBISAM_V4} result := 'DBISAM4 Driver'{$IFDEF DataAbstract_SchemaModelerOnly} + SchemaModelerOnly{$ENDIF}; {$ENDIF} end; function TDAEDBISAMDriver.GetDriverID: string; begin {$IFDEF DBISAM_V3} result := 'DBISAM3'; {$ENDIF} {$IFDEF DBISAM_V4} result := 'DBISAM4'; {$ENDIF} end; { TDAEDBISAMQuery } function TDAEDBISAMQuery.CreateDataset(aConnection: TDAEConnection): TDataset; begin result := TDBISAMQuery.Create(nil); with TDBISAMQuery(result) do begin DatabaseName := TDAEDBISAMConnection(aConnection).fConnection.Database.DatabaseName; SessionName := TDAEDBISAMConnection(aConnection).fConnection.Session.SessionName; ReadOnly := True; RequestLive := True; end; end; function TDAEDBISAMQuery.DoExecute: integer; begin with TDBISAMQuery(Dataset) do begin ExecSQL; result := RowsAffected; end; end; function TDAEDBISAMQuery.DoGetSQL: string; begin result := TDBISAMQuery(Dataset).SQL.Text end; procedure TDAEDBISAMQuery.DoPrepare(Value: Boolean); begin TDBISAMQuery(Dataset).Prepared := Value; end; procedure TDAEDBISAMQuery.SetParamValues(Params: TDAParamCollection); var i: integer; par: uDAInterfaces.TDAParam; {$IFDEF DBISAM_V4} outpar: TDBISAMParam; {$ELSE} outpar: TParam; {$ENDIF} s : string; begin s := ''; for i := 0 to (Params.Count - 1) do begin par := Params[i]; outpar := TDBISAMQuery(Dataset).Params.ParamByName(par.Name); if par.DataType = datBlob then begin outpar.DataType := ftBlob; outpar.Value := VariantBinaryToString(par.Value); end else begin {$IFDEF DBISAM_V4} outpar.DataType := DATypeToVCLType(par.DataType); {$ENDIF} outpar.Value := par.Value; end; s := s+outpar.Name+'='+VarToStr(outpar.Value)+#13#10; end; end; procedure TDAEDBISAMQuery.GetParamValues(Params: TDAParamCollection); var i: integer; par: uDAInterfaces.TDAParam; {$IFDEF DBISAM_V4} inpar: TDBISAMParam; {$ELSE} inpar: TParam; {$ENDIF} begin for i := 0 to (Params.Count - 1) do begin par := Params[i]; inpar := TDBISAMQuery(Dataset).Params.ParamByName(par.Name); par.Value := inpar.Value; end; end; procedure TDAEDBISAMQuery.DoSetSQL(const Value: string); begin TDBISAMQuery(Dataset).SQL.Text := Value; end; {$IFDEF DBISAM_V4} procedure TDAEDBISAMQuery.RefreshParams; var i: Integer; par: TDAParam; outpar: TDBISAMParam; ds: TDBISAMQuery; begin inherited; ds := TDBISAMQuery(Dataset); if not Assigned(ds.Params) then Exit; for i := 0 to ds.Params.Count -1 do begin outpar := ds.Params[i]; par := self.ParamByName(outpar.Name); if outpar.DataType <> ftUnknown then begin par.DataType := VCLTypeToDAType(outpar.DataType); end; end; end; {$ENDIF} exports GetDriverObject name func_GetDriverObject; initialization _driver := nil; RegisterDriverProc(GetDriverObject); finalization UnregisterDriverProc(GetDriverObject); FreeAndNIL(_driver); end.