mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-06 00:10:19 +02:00
fcl-db: oracle:
- add basic support for BLOB, CLOB data types (needs more testing) git-svn-id: trunk@28010 -
This commit is contained in:
parent
0dc39b5d63
commit
a6205b83ef
@ -7,7 +7,7 @@ unit oracleconnection;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, sqldb,db,dbconst,
|
||||
Classes, SysUtils, db,dbconst, sqldb, bufdataset,
|
||||
{$IfDef LinkDynamically}
|
||||
ocidyn,
|
||||
{$ELSE}
|
||||
@ -34,10 +34,11 @@ type
|
||||
end;
|
||||
|
||||
TOraFieldBuf = record
|
||||
Buffer : pointer;
|
||||
Ind : sb2;
|
||||
Len : ub4;
|
||||
Size : ub4;
|
||||
DataType : ub2;
|
||||
Buffer : pointer;
|
||||
Ind : sb2; // indicator
|
||||
Len : ub4;
|
||||
Size : ub4;
|
||||
end;
|
||||
|
||||
TOracleCursor = Class(TSQLCursor)
|
||||
@ -85,7 +86,7 @@ type
|
||||
procedure AddFieldDefs(cursor:TSQLCursor; FieldDefs:TFieldDefs); override;
|
||||
function Fetch(cursor:TSQLCursor):boolean; override;
|
||||
function LoadField(cursor:TSQLCursor; FieldDef:TFieldDef; buffer:pointer; out CreateBlob : boolean):boolean; override;
|
||||
// procedure LoadBlobIntoBuffer(FieldDef: TFieldDef; ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction: TSQLTransaction); override;
|
||||
procedure LoadBlobIntoBuffer(FieldDef: TFieldDef; ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction: TSQLTransaction); override;
|
||||
procedure FreeFldBuffers(cursor:TSQLCursor); override;
|
||||
procedure UpdateIndexDefs(IndexDefs : TIndexDefs;TableName : string); override;
|
||||
function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
|
||||
@ -472,15 +473,19 @@ end;
|
||||
|
||||
procedure TOracleConnection.DeAllocateCursorHandle(var cursor: TSQLCursor);
|
||||
|
||||
var counter : word;
|
||||
var i : word;
|
||||
|
||||
begin
|
||||
with cursor as TOracleCursor do
|
||||
begin
|
||||
if Length(FieldBuffers) > 0 then
|
||||
for counter := 0 to high(FieldBuffers) do freemem(FieldBuffers[counter].buffer);
|
||||
for i := 0 to high(FieldBuffers) do
|
||||
if FieldBuffers[i].DataType in [SQLT_BLOB, SQLT_CLOB] then
|
||||
OciDescriptorFree(FieldBuffers[i].buffer, OCI_DTYPE_LOB)
|
||||
else
|
||||
freemem(FieldBuffers[i].buffer);
|
||||
if Length(ParamBuffers) > 0 then
|
||||
for counter := 0 to high(ParamBuffers) do freemem(ParamBuffers[counter].buffer);
|
||||
for i := 0 to high(ParamBuffers) do freemem(ParamBuffers[i].buffer);
|
||||
end;
|
||||
FreeAndNil(cursor);
|
||||
end;
|
||||
@ -766,6 +771,7 @@ var Param : POCIParam;
|
||||
FOciDefine : POCIDefine;
|
||||
OPrecision : sb2;
|
||||
OScale : sb1;
|
||||
OBuffer : pointer;
|
||||
|
||||
begin
|
||||
Param := nil;
|
||||
@ -872,17 +878,35 @@ begin
|
||||
FieldType := ftFloat;
|
||||
OFieldType := SQLT_BDOUBLE;
|
||||
OFieldSize := sizeof(double);
|
||||
end;
|
||||
SQLT_BLOB : begin
|
||||
FieldType := ftBlob;
|
||||
OFieldSize := 0;
|
||||
end;
|
||||
SQLT_CLOB : begin
|
||||
FieldType := ftMemo;
|
||||
OFieldSize := 0;
|
||||
end
|
||||
else
|
||||
FieldType := ftUnknown;
|
||||
end;
|
||||
|
||||
FieldBuffers[counter-1].buffer := getmem(OFieldSize);
|
||||
FieldBuffers[counter-1].DataType := OFieldType;
|
||||
if OFieldType in [SQLT_BLOB, SQLT_CLOB] then
|
||||
begin
|
||||
OBuffer := @FieldBuffers[counter-1].buffer;
|
||||
OCIDescriptorAlloc(FOciEnvironment, OBuffer, OCI_DTYPE_LOB, 0, nil);
|
||||
end
|
||||
else
|
||||
begin
|
||||
OBuffer := getmem(OFieldSize);
|
||||
FieldBuffers[counter-1].buffer := OBuffer;
|
||||
end;
|
||||
|
||||
if FieldType <> ftUnknown then
|
||||
begin
|
||||
FOciDefine := nil;
|
||||
if OciDefineByPos(FOciStmt,FOciDefine,FOciError,counter,fieldbuffers[counter-1].buffer,OFieldSize,OFieldType,@(fieldbuffers[counter-1].ind),nil,nil,OCI_DEFAULT) = OCI_ERROR then
|
||||
if OciDefineByPos(FOciStmt,FOciDefine,FOciError,counter,OBuffer,OFieldSize,OFieldType,@FieldBuffers[counter-1].ind,nil,nil,OCI_DEFAULT) = OCI_ERROR then
|
||||
HandleError;
|
||||
end;
|
||||
|
||||
@ -966,15 +990,29 @@ begin
|
||||
dt := ComposeDateTime(EncodeDate(odt^.year,odt^.month,odt^.day), EncodeTime(odt^.hour,odt^.min,odt^.sec,0));
|
||||
move(dt,buffer^,sizeof(dt));
|
||||
end;
|
||||
ftBlob,
|
||||
ftMemo : CreateBlob := true;
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{procedure TOracleConnection.LoadBlobIntoBuffer(FieldDef: TFieldDef; ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction: TSQLTransaction);
|
||||
procedure TOracleConnection.LoadBlobIntoBuffer(FieldDef: TFieldDef; ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction: TSQLTransaction);
|
||||
var LobLocator: pointer;
|
||||
len: ub4;
|
||||
begin
|
||||
end;}
|
||||
LobLocator := (cursor as TOracleCursor).FieldBuffers[FieldDef.FieldNo-1].Buffer;
|
||||
//if OCILobLocatorIsInit(TOracleTrans(ATransaction.Handle).FOciSvcCtx, FOciError, LobLocator, @is_init) = OCI_ERROR then
|
||||
// HandleError;
|
||||
if OciLobGetLength(TOracleTrans(ATransaction.Handle).FOciSvcCtx, FOciError, LobLocator, @len) = OCI_ERROR then
|
||||
HandleError;
|
||||
// Len - For character LOBs, it is the number of characters, for binary LOBs and BFILEs it is the number of bytes
|
||||
ReAllocMem(ABlobBuf^.BlobBuffer^.Buffer, len);
|
||||
ABlobBuf^.BlobBuffer^.Size := len;
|
||||
if OciLobRead(TOracleTrans(ATransaction.Handle).FOciSvcCtx, FOciError, LobLocator, @len, 1, ABlobBuf^.BlobBuffer^.Buffer, len, nil, nil, 0, SQLCS_IMPLICIT) = OCI_ERROR then
|
||||
HandleError;
|
||||
end;
|
||||
|
||||
procedure TOracleConnection.FreeFldBuffers(cursor: TSQLCursor);
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user