home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 October
/
Chip_2001-10_cd1.bin
/
zkuste
/
delphi
/
kompon
/
d45
/
ARDOCI.ZIP
/
OraDB.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2001-03-01
|
14KB
|
407 lines
unit OraDB;
{
TOraDB - connect to oracle
All other components (such as TOraSQL, TAOraSQL) use this component to get access to oracle server
You can get more information about TOraDB in documentation.
procedure Open;
procedure Close;
procedure StartTransaction;
procedure CommitTransaction;
procedure RollbackTransaction;
procedure Break; // Γ√∩εδφ σ≥ OCIBreak
property InTransaction:boolean read FTransaction;
}
interface
uses
Db, Classes, Windows, OraDefines, ADataSet;
const OraLibName='oci.dll';
type
TOraDB=class;
TOraTransIsolationLevel = (tiDefault, tiReadCommited, tiRepeatableRead, tiReadOnly);
TOraSessionIsolationLevel = (siDefault, siReadCommited, siRepeatableRead);
TBeforeLoginEvent = procedure(Sender: TOraDB;var ConnectString, Username, Password: string;Accept:boolean) of object;
TAfterLoginEvent = procedure(Sender: TOraDB) of object;
TBeforeInitOCI = procedure(Sender: TOraDB;LibName:string;Accept:boolean) of object;
TAfterInitOCI = procedure(Sender: TOraDB) of object;
TOraDB = class(TADataBase)
private
hDll:THandle;
FStreamedActive:boolean;
FActive:boolean;
FStarted:boolean;
FName,FPassword,FServer:string;
FTransaction:boolean;
FOraTransIsolationLevel:TOraTransIsolationLevel;
FOraSessionIsolationLevel:TOraSessionIsolationLevel;
FBeforeInitOCI:TBeforeInitOCI;
FAfterInitOCI:TAfterInitOCI;
FBeforeLoginEvent:TBeforeLoginEvent;
FAfterLoginEvent:TAfterLoginEvent;
FBeforeCommit:TNotifyEvent;
FAfterCommit:TNotifyEvent;
FOnStartTransaction:TNotifyEvent;
FOnRollback:TNotifyEvent;
procedure DoActive(Value:boolean);
procedure InitOCI;
protected
procedure Loaded; override;
procedure SetSessionIsolationLevel;
procedure SetTransIsolationLevel;
public
myenvhp:pOCIEnv;
mysrvhp:pOCIServer;
dberrhp:pOCIError;
myusrhp:pOCISession;
mysvchp:pOCISvcCtx;
OCIInitialize:TOCIInitialize;
OCIEnvInit:TOCIEnvInit;
OCIHandleAlloc:TOCIHandleAlloc;
OCIServerAttach:TOCIServerAttach;
OCIAttrSet:TOCIAttrSet;
OCISessionBegin:TOCISessionBegin;
OCISessionEnd:TOCISessionEnd;
OCIServerDetach:TOCIServerDetach;
OCIHandleFree:TOCIHandleFree;
OCIErrorGet:TOCIErrorGet;
OCIStmtPrepare:TOCIStmtPrepare;
OCIStmtExecute:TOCIStmtExecute;
OCIParamGet:TOCIParamGet;
OCIAttrGet:TOCIAttrGet;
OCIStmtFetch:TOCIStmtFetch;
OCIDefineByPos:TOCIDefineByPos;
OCIDefineArrayOfStruct:TOCIDefineArrayOfStruct;
OCIBindByPos:TOCIBindByPos;
OCIBindByName:TOCIBindByName;
OCITransStart:TOCITransStart;
OCITransCommit:TOCITransCommit;
OCITransRollback:TOCITransRollback;
OCIDescribeAny:TOCIDescribeAny;
OCIBreak:TOCIBreak;
OCIDescriptorAlloc:TOCIDescriptorAlloc;
OCIDescriptorFree:TOCIDescriptorFree;
OCILobRead:TOCILobRead;
OCILobWrite:TOCILobWrite;
OCIStmtGetPieceInfo:TOCIStmtGetPieceInfo;
OCIStmtSetPieceInfo:TOCIStmtSetPieceInfo;
OCILobGetLength:TOCILobGetLength;
OCILobErase:TOCILobErase;
OCILobTrim:TOCILobTrim;
function TestError(where:string;ex:sword):sword;
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
procedure Open;
procedure Close;
procedure StartTransaction;
procedure CommitTransaction;
procedure RollbackTransaction;
procedure Break; // Γ√∩εδφ σ≥ OCIBreak
property InTransaction:boolean read FTransaction;
published
property Active:boolean read FActive write DoActive default False;
property DBLogin:string read FName write FName;
property DBPassword:string read FPassword write FPassword;
property DBServer:string read FServer write FServer;
property OraTransIsolationLevel:TOraTransIsolationLevel read FOraTransIsolationLevel write FOraTransIsolationLevel;
property OraSessionIsolationLevel:TOraSessionIsolationLevel read FOraSessionIsolationLevel write FOraSessionIsolationLevel;
property BeforeInitOCI:TBeforeInitOCI read FBeforeInitOCI write FBeforeInitOCI;
property AfterInitOCI :TAfterInitOCI read FAfterInitOCI write FAfterInitOCI;
property BeforeLogin:TBeforeLoginEvent read FBeforeLoginEvent write FBeforeLoginEvent;
property AfterLogin:TAfterLoginEvent read FAfterLoginEvent write FAfterLoginEvent;
property OnStartTransaction:TNotifyEvent read FOnStartTransaction write FOnStartTransaction;
property BeforeCommit:TNotifyEvent read FBeforeCommit write FBeforeCommit;
property AfterCommit:TNotifyEvent read FAfterCommit write FAfterCommit;
end;
procedure Register;
implementation
uses SysUtils;
procedure Register;
begin
RegisterComponents('Data Access', [TOraDB]);
end;
constructor TOraDB.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FTransaction:=False;
end;
procedure TOraDB.Loaded;
begin
inherited Loaded;
Active:=FStreamedActive;
end;
function TOraDB.TestError(where:string;ex:sword):sword;
var errcode:sb4;
errbuf:array[0..511] of char;
{ f:TFileStream;
len:integer;
str:string;}
begin
{ f:=TFileStream.Create('log.txt',fmOpenReadWrite or fmCreate);
f.Seek(0,soFromEnd);
str:='TOraDB '+where;
len:=length(str);
f.Write(PChar(str)^,len);
f.Write(PChar(#13#10)^,2);
f.free;
}
Result:=ex;
case ex of
OCI_SUCCESS: exit;
OCI_SUCCESS_WITH_INFO: raise EDatabaseError.Create('Oracle error: OCI success with info');
OCI_NEED_DATA: raise EDatabaseError.Create('Oracle error: OCI need data');
OCI_NO_DATA: raise EDatabaseError.Create('Oracle error: OCI no data');
OCI_ERROR: begin
OCIErrorGet(dberrhp,1,nil,errcode,errbuf,sizeof(errbuf),OCI_HTYPE_ERROR);
raise EDatabaseError.Create('Oracle error #'+inttostr(errcode)+': '+strpas(errbuf));
end;
OCI_INVALID_HANDLE: raise EDatabaseError.Create('Oracle error: OCI invalid handle');
OCI_STILL_EXECUTING: raise EDatabaseError.Create('Oracle error: OCI still execute');
else raise EDatabaseError.Create('UNKNOWN ORACLE ERROR!');
end;
end;
procedure TOraDB.InitOCI;
var Accept:boolean;
LibName:string;
begin
LibName:=OraLibName;
Accept:=True;
if Assigned(FBeforeInitOCI) then FBeforeInitOCI(self,LibName,Accept);
if not Accept then exit;
if not FStarted then begin
// hDll:=LoadLibrary('ora803.dll');
{ if FileOpen('C:\NoGrab.al',fmOpenRead)>0
then hDll:=LoadLibrary('oci.dll')
else hDll:=LoadLibrary('ora803.dll');}
hDll:=LoadLibrary(PChar(LibName));
if hDll=0 then raise Exception.Create('Error load library "'+LibName+'"!');
@OCIInitialize:=GetProcAddress(hDll,'OCIInitialize');
@OCIEnvInit:=GetProcAddress(hDll,'OCIEnvInit');
@OCIHandleAlloc:=GetProcAddress(hDll,'OCIHandleAlloc');
@OCIServerAttach:=GetProcAddress(hDll,'OCIServerAttach');
@OCIAttrSet:=GetProcAddress(hDll,'OCIAttrSet');
@OCISessionBegin:=GetProcAddress(hDll,'OCISessionBegin');
@OCISessionEnd:=GetProcAddress(hDll,'OCISessionEnd');
@OCIServerDetach:=GetProcAddress(hDll,'OCIServerDetach');
@OCIHandleFree:=GetProcAddress(hDll,'OCIHandleFree');
@OCIErrorGet:=GetProcAddress(hDll,'OCIErrorGet');
@OCIStmtPrepare:=GetProcAddress(hDll,'OCIStmtPrepare');
@OCIStmtExecute:=GetProcAddress(hDll,'OCIStmtExecute');
@OCIParamGet:=GetProcAddress(hDll,'OCIParamGet');
@OCIAttrGet:=GetProcAddress(hDll,'OCIAttrGet');
@OCIStmtFetch:=GetProcAddress(hDll,'OCIStmtFetch');
@OCIDefineByPos:=GetProcAddress(hDll,'OCIDefineByPos');
@OCIDefineArrayOfStruct:=GetProcAddress(hDll,'OCIDefineArrayOfStruct');
@OCIBindByPos:=GetProcAddress(hDll,'OCIBindByPos');
@OCIBindByName:=GetProcAddress(hDll,'OCIBindByName');
@OCITransStart:=GetProcAddress(hDll,'OCITransStart');
@OCITransCommit:=GetProcAddress(hDll,'OCITransCommit');
@OCITransRollback:=GetProcAddress(hDll,'OCITransRollback');
@OCIDescribeAny:=GetProcAddress(hDll,'OCIDescribeAny');
@OCIBreak:=GetProcAddress(hDll,'OCIBreak');
@OCIDescriptorAlloc:=GetProcAddress(hDll,'OCIDescriptorAlloc');
@OCIDescriptorFree:=GetProcAddress(hDll,'OCIDescriptorFree');
@OCILobRead:=GetProcAddress(hDll,'OCILobRead');
@OCILobWrite:=GetProcAddress(hDll,'OCILobWrite');
@OCIStmtGetPieceInfo:=GetProcAddress(hDll,'OCIStmtGetPieceInfo');
@OCIStmtSetPieceInfo:=GetProcAddress(hDll,'OCIStmtSetPieceInfo');
@OCILobGetLength:=GetProcAddress(hDll,'OCILobGetLength');
@OCILobErase:=GetProcAddress(hDll,'OCILobErase');
@OCILobTrim:=GetProcAddress(hDll,'OCILobTrim');
FStarted:=True;
end;
if Assigned(FAfterInitOCI) then FAfterInitOCI(self);
end;
procedure TOraDB.SetSessionIsolationLevel;
var str:array[0..1023] of char;
mystmthp:pOCIStmt;
begin
if not factive then exit;
case FOraSessionIsolationLevel of
siReadCommited : str:='ALTER SESSION SET ISOLATION_LEVEL=READ COMMITTED';
siRepeatableRead : str:='ALTER SESSION SET ISOLATION_LEVEL=SERIALIZABLE';
siDefault : exit;
end;
// setting Isolation Level for current session
TestError('OCIHandleAlloc - ',OCIHandleAlloc(myenvhp,mystmthp,OCI_HTYPE_STMT,0,nil));
TestError('OCIStmtPrepare - ',OCIStmtPrepare(mystmthp,dberrhp,str,strlen(str),OCI_NTV_SYNTAX,OCI_DEFAULT));
TestError('OCIStmtExecute ',OCIStmtExecute(mysvchp,mystmthp,dberrhp,1,0,nil,nil,OCI_DEFAULT));
TestError('OCIHandleFree - ',OCIHandleFree(mystmthp,OCI_HTYPE_STMT));
end;
procedure TOraDB.SetTransIsolationLevel;
var str:array[0..1023] of char;
mystmthp:pOCIStmt;
begin
if not factive then exit;
case FOraTransIsolationLevel of
tiReadCommited : str:='SET TRANSACTION ISOLATION LEVEL READ COMMITTED';
tiRepeatableRead : str:='SET TRANSACTION ISOLATION LEVEL SERIALIZABLE';
tiReadOnly : str:='SET TRANSACTION READ ONLY';
tiDefault : exit;
end;
// setting Isolation Level for current beginning transaction
TestError('OCIHandleAlloc - ',OCIHandleAlloc(myenvhp,mystmthp,OCI_HTYPE_STMT,0,nil));
TestError('OCIStmtPrepare - ',OCIStmtPrepare(mystmthp,dberrhp,str,strlen(str),OCI_NTV_SYNTAX,OCI_DEFAULT));
TestError('OCIStmtExecute ',OCIStmtExecute(mysvchp,mystmthp,dberrhp,1,0,nil,nil,OCI_DEFAULT));
TestError('OCIHandleFree - ',OCIHandleFree(mystmthp,OCI_HTYPE_STMT));
end;
procedure TOraDB.Open;
var str:array[0..1023] of char;
Accept:boolean;
begin
InitOCI;
Accept:=True;
if Assigned(FBeforeLoginEvent) then FBeforeLoginEvent(self,FServer,FName,FPassword,Accept);
if not Accept then exit;
TestError('OCIInitialize ',OCIInitialize(OCI_DEFAULT {OCI_THREADED},nil,nil,nil,nil));
TestError('OCIEnvInit ',OCIEnvInit(myenvhp, OCI_DEFAULT, 0, nil));
TestError('OCIHandleAlloc ',OCIHandleAlloc(myenvhp,mysrvhp,OCI_HTYPE_SERVER,0,nil));
TestError('OCIHandleAlloc ',OCIHandleAlloc(myenvhp,dberrhp,OCI_HTYPE_ERROR,0,nil));
TestError('OCIHandleAlloc ',OCIHandleAlloc(myenvhp,mysvchp,OCI_HTYPE_SVCCTX,0,nil));
strpcopy(str,FServer);
TestError('OCIServerAttach ',OCIServerAttach(mysrvhp,dberrhp,@str,strlen(str),OCI_DEFAULT));
TestError('OCIAttrSet ',OCIAttrSet(mysvchp,OCI_HTYPE_SVCCTX,mysrvhp,0,OCI_ATTR_SERVER,dberrhp));
TestError('OCIHandleAlloc ',OCIHandleAlloc(myenvhp,myusrhp,OCI_HTYPE_SESSION,0,nil));
strpcopy(str,FName);
TestError('OCIAttrSet ',OCIAttrSet(myusrhp,OCI_HTYPE_SESSION,@str,strlen(str),OCI_ATTR_USERNAME,dberrhp));
strpcopy(str,FPassword);
TestError('OCIAttrSet ',OCIAttrSet(myusrhp,OCI_HTYPE_SESSION,@str,strlen(str),OCI_ATTR_PASSWORD,dberrhp));
TestError('OCISessionBegin ',OCISessionBegin(mysvchp,dberrhp,myusrhp,OCI_CRED_RDBMS,OCI_DEFAULT));
TestError('OCIAttrSet ',OCIAttrSet(mysvchp,OCI_HTYPE_SVCCTX,myusrhp,0,OCI_ATTR_SESSION,dberrhp));
FActive:=True;
SetSessionIsolationLevel;
if Assigned(FAfterLoginEvent) then FAfterLoginEvent(self);
end;
procedure TOraDB.Close;
begin
if not FActive then exit;
CloseLinkedDataSets; // ταΩ≡√Γασ∞ Γ±σ DataSet√ Ω Ωε≥ε≡√∞ ∩≡Φ±εσΣΦφσφ ²≥ε≥ OraDB
// ∩ε ταΩ≡√≥ΦΦ ΩεφσΩ≥α Γ±σπΣα Σσδασ∞ RollBack (±≥≡α⌡εΓΩα ε≥ ≥επε ≈≥ε ■τσ≡ ταß√δ ±Σσδα≥ⁿ Commit)
TestError('OCITransRollback ',OCITransRollback(mysvchp,dberrhp,OCI_DEFAULT));
FTransaction:=False;
TestError('OCISessionEnd ',OCISessionEnd(mysvchp,dberrhp,myusrhp,OCI_DEFAULT));
TestError('OCIServerDetach ',OCIServerDetach(mysrvhp,dberrhp,OCI_DEFAULT));
TestError('OCIHandleFree ',OCIHandleFree(mysrvhp,OCI_HTYPE_SERVER));
TestError('OCIHandleFree ',OCIHandleFree(mysvchp,OCI_HTYPE_SVCCTX));
TestError('OCIHandleFree ',OCIHandleFree(myusrhp,OCI_HTYPE_SESSION));
TestError('OCIHandleFree ',OCIHandleFree(dberrhp,OCI_HTYPE_ERROR));
TestError('OCIHandleFree ',OCIHandleFree(myenvhp,OCI_HTYPE_ENV));
FActive:=False;
FreeLibrary(hDll);
FStarted:=False;
end;
procedure TOraDB.Break;
begin
TestError('OCIBreak ',OCIBreak(mysvchp,dberrhp));
end;
procedure TOraDB.DoActive(Value:boolean);
begin
if (csReading in ComponentState) then begin
if Value then FStreamedActive := True;
exit;
end;
if (csDestroying in ComponentState) then exit;
if Value and not Active then Open;
if not Value and Active then Close;
end;
procedure TOraDB.StartTransaction;
begin
if not Active then begin
raise Exception.Create('Database not active !');
end;
SetTransIsolationLevel;
// TestError('OCIHandleFree ',OCITransStart(mysvchp,dberrhp,30,OCI_TRANS_NEW+OCI_TRANS_SERIALIZABLE));
FTransaction:=True;
if Assigned(FOnStartTransaction) then FOnStartTransaction(self);
end;
procedure TOraDB.CommitTransaction;
begin
if not Active then begin
raise Exception.Create('Database not active !');
end;
if Assigned(FBeforeCommit) then FBeforeCommit(self);
TestError('OCITransCommit ',OCITransCommit(mysvchp,dberrhp,OCI_DEFAULT));
FTransaction:=False;
if Assigned(FAfterCommit) then FAfterCommit(self);
end;
procedure TOraDB.RollbackTransaction;
begin
if not Active then begin
raise Exception.Create('Database not active');
end;
if Assigned(FOnRollback) then FOnRollback(self);
TestError('OCITransRollback ',OCITransRollback(mysvchp,dberrhp,OCI_DEFAULT));
FTransaction:=False;
end;
destructor TOraDB.Destroy;
begin
if Active then Close;
inherited Destroy;
end;
end.