Devart ODAC driver
This unit, directly inspired by Aurelius.Drivers.UniDac.pas seems to work:
unit Aurelius.Drivers.Odac;
{$I Aurelius.inc}
interface
uses
Classes, DB, Variants, Generics.Collections,
DBAccess,
Aurelius.Drivers.Base,
Aurelius.Drivers.Interfaces;
type
TOdacResultSetAdapter = class(TDriverResultSetAdapter<TCustomDADataset>)
end;
TOdacStatementAdapter = class(TInterfacedObject, IDBStatement)
private
FQuery: TCustomDADataset;
public
constructor Create(AQuery: TCustomDADataset);
destructor Destroy; override;
procedure SetSQLCommand(SQLCommand: string);
procedure SetParams(Params: TEnumerable<TDBParam>);
procedure Execute;
function ExecuteQuery: IDBResultSet;
end;
TOdacConnectionAdapter = class(TDriverConnectionAdapter<TCustomDAConnection>, IDBConnection)
public
procedure Connect;
procedure Disconnect;
function IsConnected: Boolean;
function CreateStatement: IDBStatement;
function BeginTransaction: IDBTransaction;
function RetrieveSqlDialect: string; override;
end;
TOdacTransactionAdapter = class(TInterfacedObject, IDBTransaction)
private
FConnection: TCustomDAConnection;
public
constructor Create(AConnection: TCustomDAConnection);
procedure Commit;
procedure Rollback;
end;
implementation
{ TOdacStatementAdapter }
uses
SysUtils,
Ora,
Aurelius.Drivers.Exceptions,
Aurelius.Global.Utils;
constructor TOdacStatementAdapter.Create(AQuery: TCustomDADataset);
begin
FQuery := AQuery;
end;
destructor TOdacStatementAdapter.Destroy;
begin
FQuery.Free;
inherited;
end;
procedure TOdacStatementAdapter.Execute;
begin
FQuery.ExecSQL;
end;
function TOdacStatementAdapter.ExecuteQuery: IDBResultSet;
var
ResultSet: TCustomDADataset;
I: Integer;
begin
ResultSet := FQuery.Connection.CreateDataSet;
try
ResultSet.Connection := FQuery.Connection;
ResultSet.SQL := FQuery.SQL;
for I := 0 to FQuery.Params.Count - 1 do
ResultSet.Params.Assign(FQuery.Params);
ResultSet.Open;
except
ResultSet.Free;
raise;
end;
Result := TOdacResultSetAdapter.Create(ResultSet);
end;
procedure TOdacStatementAdapter.SetParams(Params: TEnumerable<TDBParam>);
var
P: TDBParam;
Parameter: TDAParam;
Bytes: TBytes;
begin
for P in Params do
begin
Parameter := FQuery.ParamByName(P.ParamName);
Parameter.DataType := P.ParamType;
Parameter.ParamType := ptInput;
if P.ParamType in [ftOraBlob, ftOraClob, ftBlob] then
begin
Bytes := TUtils.VariantToBytes(P.ParamValue);
if VarIsNull(P.ParamValue) or (Length(Bytes) = 0) then
Parameter.Clear
else
begin
Parameter.DataType := P.ParamType;
Parameter.AsBlob := Bytes;
end;
end
else
if P.ParamType in [ftMemo, ftWideMemo] then
begin
if VarIsNull(P.ParamValue) or (Length(VarToStr(P.ParamValue)) = 0) then
Parameter.AsMemo := ''
else
begin
Parameter.AsMemo := P.ParamValue;
end;
end
else
Parameter.Value := P.ParamValue;
end;
end;
procedure TOdacStatementAdapter.SetSQLCommand(SQLCommand: string);
begin
FQuery.SQL.Text := SQLCommand;
end;
{ TOdacConnectionAdapter }
procedure TOdacConnectionAdapter.Disconnect;
begin
if Connection <> nil then
Connection.Connected := False;
end;
function TOdacConnectionAdapter.RetrieveSqlDialect: string;
begin
if Connection = nil then
Exit('');
Result := 'Oracle';
end;
function TOdacConnectionAdapter.IsConnected: Boolean;
begin
if Connection <> nil then
Result := Connection.Connected
else
Result := false;
end;
function TOdacConnectionAdapter.CreateStatement: IDBStatement;
var
Statement: TCustomDADataset;
begin
if Connection = nil then
Exit(nil);
Statement := Connection.CreateDataSet;
try
Statement.Connection := Connection;
except
Statement.Free;
raise;
end;
Result := TOdacStatementAdapter.Create(Statement);
end;
procedure TOdacConnectionAdapter.Connect;
begin
if Connection <> nil then
Connection.Connected := True;
end;
function TOdacConnectionAdapter.BeginTransaction: IDBTransaction;
begin
if Connection = nil then
Exit(nil);
Connection.Connected := true;
if not Connection.InTransaction then
begin
Connection.StartTransaction;
Result := TOdacTransactionAdapter.Create(Connection);
end else
Result := TOdacTransactionAdapter.Create(nil);
end;
{ TOdacTransactionAdapter }
procedure TOdacTransactionAdapter.Commit;
begin
if (FConnection = nil) then
Exit;
FConnection.Commit;
end;
constructor TOdacTransactionAdapter.Create(AConnection: TCustomDAConnection);
begin
FConnection := AConnection;
end;
procedure TOdacTransactionAdapter.Rollback;
begin
if (FConnection = nil) then
Exit;
FConnection.Rollback;
end;
end.