mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 22:03:03 +01:00
108 lines
4.1 KiB
Plaintext
108 lines
4.1 KiB
Plaintext
-----------------
|
|
External Routines
|
|
-----------------
|
|
|
|
Author:
|
|
Adriano dos Santos Fernandes <adrianosf@uol.com.br>
|
|
|
|
Syntax:
|
|
|
|
{ CREATE [ OR ALTER ] | RECREATE | ALTER } PROCEDURE <name>
|
|
[ ( <parameter list> ) ]
|
|
[ RETURNS ( <parameter list> ) ]
|
|
EXTERNAL NAME '<external name>' ENGINE <engine>
|
|
|
|
{ CREATE [ OR ALTER ] | RECREATE | ALTER } FUNCTION <name>
|
|
[ <parameter list> ]
|
|
RETURNS <data type>
|
|
EXTERNAL NAME '<external name>' ENGINE <engine>
|
|
|
|
{ CREATE [ OR ALTER ] | RECREATE | ALTER } TRIGGER <name>
|
|
...
|
|
EXTERNAL NAME '<external name>' ENGINE <engine>
|
|
|
|
Examples:
|
|
|
|
create procedure gen_rows (
|
|
start_n integer not null,
|
|
end_n integer not null
|
|
) returns (
|
|
n integer not null
|
|
) external name 'udrcpp_example!gen_rows'
|
|
engine udr;
|
|
|
|
create function wait_event (
|
|
event_name varchar(31) character set ascii
|
|
) returns integer
|
|
external name 'udrcpp_example!wait_event'
|
|
engine udr;
|
|
|
|
create trigger persons_replicate
|
|
after insert on persons
|
|
external name 'udrcpp_example!replicate!ds1'
|
|
engine udr;
|
|
|
|
How it works:
|
|
|
|
External names are opaque strings to Firebird. They are recognized by specific external engines.
|
|
External engines are declared in config files (possibly in the same file as a plugin, like in the
|
|
config example present below).
|
|
|
|
<external_engine UDR>
|
|
plugin_module UDR_engine
|
|
</external_engine>
|
|
|
|
<plugin_module UDR_engine>
|
|
filename $(this)/udr_engine
|
|
plugin_config UDR_config
|
|
</plugin_module>
|
|
|
|
<plugin_config UDR_config>
|
|
path $(this)/udr
|
|
</plugin_config>
|
|
|
|
When Firebird wants to load an external routine (function, procedure or trigger) into its metadata
|
|
cache, it gets (if not already done for the database*) the external engine through the plugin
|
|
external engine factory and asks it for the routine. The plugin used is the one referenced by the
|
|
attribute plugin_module of the external engine.
|
|
|
|
* This is in Super-Server. In [Super-]Classic, different attachments to one database create
|
|
multiple metadata caches and hence multiple external engine instances.
|
|
|
|
|
|
----------------------------------
|
|
UDR - User Defined Routines engine
|
|
----------------------------------
|
|
|
|
The UDR (User Defined Routines) engine adds a layer on top of the FirebirdExternal interface with
|
|
these objectives:
|
|
- Establish a way to place external modules into server and make them available for usage;
|
|
- Create an API so that external modules can register their available routines;
|
|
- Make routines instances per-attachment, instead of per-database like the FirebirdExternal does
|
|
in SuperServer mode.
|
|
|
|
External names of the UDR engine are defined as following:
|
|
'<module name>!<routine name>!<misc info>'
|
|
|
|
The <module name> is used to locate the library, <routine name> is used to locate the routine
|
|
registered by the given module, and <misc info> is an user defined string passed to the routine
|
|
and can be read by the user. "!<misc info>" may be ommitted.
|
|
|
|
Modules available to the UDR engine should be in a directory listed through the path attribute of
|
|
the correspondent plugin_config tag. By default, UDR modules should be on <fbroot>/plugins/udr,
|
|
accordingly to its path attribute in <fbroot>/plugins/udr_engine.conf.
|
|
|
|
The user library should include FirebirdUdr.h (or FirebirdUdrCpp.h) and link with the udr_engine
|
|
library. Routines are easily defined and registered using some macros, but nothing prevents you from
|
|
doing things manually. An example routine library is implemented in examples/plugins, showing how to
|
|
write functions, selectable procedures and triggers. Also it shows how to interact with the current
|
|
database through the ISC API.
|
|
|
|
The UDR routines state (i.e., member variables) are shared between multiple invocations of the same
|
|
routine until it's unloaded from the metadata cache. But note that it isolates the instances per
|
|
session, different from the raw interface that shares instances by multiple sessions in SuperServer.
|
|
|
|
By default, UDR routines use the same character set specified by the client. They can modify it
|
|
overriding the getCharSet method. The chosen character set is valid for communication with the ISC
|
|
library as well as the communications done through the FirebirdExternal API.
|