>>Karol, I also created an UDR demo for a selectable stored procedure.

>>https://github.com/asfernandes/fbstuff/commit/161e1bb98f6321cff87afe24ca1050a23b8a2e10

>>You should build it and copy the pascaludr.dll file to 
>><fbroot>/plugins/udr

>>Then declare in the database:
>>And use:
>>select * from gen_rows_pascal(2, 5);
>>Result:
>>2
>>3
>>4
>>5
>>Adriano

Hi Adriano,

few problems
didive library file into two files (initialization is not allowed in library 
file itself - only in unit)
change PChar to PAnsiChar
and change 2 declarations of functions and implementation
function open(status: Status; context: ExternalContext; inMsg: Pointer; 
outMsg: Pointer): ExternalResultSet; override;
and
function newItem(status: Status; context: ExternalContext; metadata: 
RoutineMetadata): ExternalProcedure; override;

and what i should do to tell Firebird to use this dll?
when i try to declare it

create procedure gen_rows_pascal (
    start_n integer not null,
    end_n integer not null
) returns (
    result integer not null
)
    external name 'pascaludr!gen_rows'
    engine udr;

i got error
SQL Message : -901
Unsuccessful execution caused by system error that does not preclude 
successful execution of subsequent statements

Engine Code    : 335544382
Engine Message :
Module not found

first why 'pascaludr!gen_rows'? i do not see any word pascal in units

below are changed files

regards,
Karol Bieniaszewski


library Udr;

uses
  FbApi,
  UdrMain in 'UdrMain.pas';

begin

end.

unit UdrMain;

interface
uses FBApi;

type
    GenRowsInMessage = record
        start: Integer;
        startNull: WordBool;
        end_: Integer;
        endNull: WordBool;
    end;

    GenRowsInMessagePtr = ^GenRowsInMessage;

    GenRowsOutMessage = record
        result: Integer;
        resultNull: WordBool;
    end;

    GenRowsOutMessagePtr = ^GenRowsOutMessage;

    GenRowsResultSet = class(ExternalResultSetImpl)
        procedure dispose(); override;
        function fetch(status: Status): Boolean; override;

    public
        inMessage: GenRowsInMessagePtr;
        outMessage: GenRowsOutMessagePtr;
    end;

    GenRowsProcedure = class(ExternalProcedureImpl)
        procedure dispose(); override;

        procedure getCharSet(status: Status; context: ExternalContext; name: 
PAnsiChar;
            nameSize: Cardinal); override;

        function open(status: Status; context: ExternalContext; inMsg: 
Pointer; outMsg: Pointer): ExternalResultSet; override;
    end;

    GenRowsFactory = class(UdrProcedureFactoryImpl)
        procedure dispose(); override;

        procedure setup(status: Status; context: ExternalContext; metadata: 
RoutineMetadata;
            inBuilder: MetadataBuilder; outBuilder: MetadataBuilder); 
override;

        function newItem(status: Status; context: ExternalContext; metadata: 
RoutineMetadata): ExternalProcedure; override;
    end;

implementation
var
    myUnloadFlag: Boolean;
    theirUnloadFlag: BooleanPtr;
{
create procedure gen_rows_pascal (
    start_n integer not null,
    end_n integer not null
) returns (
    result integer not null
)
    external name 'pascaludr!gen_rows'
    engine udr;
}


procedure GenRowsResultSet.dispose();
begin
    destroy;
end;

function GenRowsResultSet.fetch(status: Status): Boolean;
begin
    if (outMessage.result >= inMessage.end_) then
        Result := false
    else
    begin
        outMessage.result := outMessage.result + 1;
        Result := true;
    end;
end;


procedure GenRowsProcedure.dispose();
begin
    destroy;
end;

procedure GenRowsProcedure.getCharSet(status: Status; context: 
ExternalContext; name: PAnsiChar; nameSize: Cardinal);
begin
end;

function GenRowsProcedure.open(status: Status; context: ExternalContext; 
inMsg: Pointer; outMsg: Pointer): ExternalResultSet;
begin
    Result := GenRowsResultSet.create();
    GenRowsResultSet(Result).inMessage := inMsg;
    GenRowsResultSet(Result).outMessage := outMsg;

    GenRowsResultSet(Result).outMessage.resultNull := false;
    GenRowsResultSet(Result).outMessage.result := 
GenRowsResultSet(Result).inMessage.start - 1;
end;


procedure GenRowsFactory.dispose();
begin
    destroy;
end;

procedure GenRowsFactory.setup(status: Status; context: ExternalContext; 
metadata: RoutineMetadata;
    inBuilder: MetadataBuilder; outBuilder: MetadataBuilder);
begin
end;

function GenRowsFactory.newItem(status: Status; context: ExternalContext; 
metadata: RoutineMetadata): ExternalProcedure;
begin
    Result := GenRowsProcedure.create;
end;


function firebird_udr_plugin(status: Status; theirUnloadFlagLocal: 
BooleanPtr; udrPlugin: UdrPlugin): BooleanPtr; cdecl;
begin
    udrPlugin.registerProcedure(status, 'gen_rows', 
GenRowsFactory.create());

    theirUnloadFlag := theirUnloadFlagLocal;
    Result := @myUnloadFlag;
end;


exports firebird_udr_plugin;



initialization
    myUnloadFlag := false;

finalization
    if (not myUnloadFlag) then
        theirUnloadFlag^ := true;

end.




------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to