/* * PROGRAM: Firebird interface. * MODULE: firebird/Interface.idl * DESCRIPTION: Collection of interfaces used by FB to talk with outer world. * * The contents of this file are subject to the Initial * Developer's Public License Version 1.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. * * Software distributed under the License is distributed AS IS, * WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights * and limitations under the License. * * The Original Code was created by Alex Peshkov * for the Firebird Open Source RDBMS project. * * Copyright (c) 2010 Alex Peshkov * and all contributors signed below. * * All Rights Reserved. * Contributor(s): ______________________________________. * * */ typedef ISC_DATE; typedef ISC_QUAD; typedef ISC_TIME; typedef ISC_TIMESTAMP; typedef ISC_TIME_TZ; typedef ISC_TIMESTAMP_TZ; typedef ISC_TIME_TZ_EX; typedef ISC_TIMESTAMP_TZ_EX; typedef FB_DEC16; typedef FB_DEC34; typedef FB_I128; // Versioned interface - base for all FB interfaces interface Versioned { } // Reference counted interface - base for refCounted FB interfaces interface ReferenceCounted : Versioned { void addRef(); int release(); } // Disposable interface - base for disposable FB interfaces interface Disposable : Versioned { void dispose(); } // Interface to work with status vector [exception] interface Status : Disposable { // flags in value returned by getState() const uint STATE_WARNINGS = 0x01; const uint STATE_ERRORS = 0x02; // completion codes - not used in Status, but I must have them somewhere const int RESULT_ERROR = -1; const int RESULT_OK = 0; const int RESULT_NO_DATA = 1; const int RESULT_SEGMENT = 2; void init(); uint getState() const; void setErrors2(uint length, const intptr* value); void setWarnings2(uint length, const intptr* value); void setErrors(const intptr* value); void setWarnings(const intptr* value); [onError stubError] const intptr* getErrors() const; [onError stubError] const intptr* getWarnings() const; Status clone() const; } // Master interface is used to access almost all other interfaces. interface Master : Versioned { Status getStatus(); Provider getDispatcher(); PluginManager getPluginManager(); TimerControl getTimerControl(); Dtc getDtc(); Attachment registerAttachment(Provider provider, Attachment attachment); Transaction registerTransaction(Attachment attachment, Transaction transaction); MetadataBuilder getMetadataBuilder(Status status, uint fieldCount); int serverMode(int mode); Util getUtilInterface(); ConfigManager getConfigManager(); boolean getProcessExiting(); } /* * Firebird plugins are accessed using methods of PluginLoader interface. * For each plugin_module tag found, it constructs a Plugin object, reads the corresponding * plugin_config tag and inserts all config information in the object. * * When requested, the engine gets the attribute value of plugin_module/filename, load it as a * dynamic (shared) library and calls the exported function firebirdPlugin (FB_PLUGIN_ENTRY_POINT * definition, PluginEntrypoint prototype) passing the Plugin object as parameter. * * The plugin library may save the plugin object and call they methods later. The object and all * pointers returned by it are valid until the plugin is unloaded (done through OS unload of the * dynamic library) when Firebird is shutting down. * * Inside the plugin entry point (firebirdPlugin), the plugin may register extra functionality that * may be obtained by Firebird when required. Currently only External Engines may be registered * through Plugin::setExternalEngineFactory. * * Example plugin configuration file: * * * plugin_module UDR_engine * * * * filename $(this)/udr_engine * plugin_config UDR_config * * * * path $(this)/udr * * * Note that the external_engine tag is ignored at this stage. Only plugin_module and plugin_config * are read. The dynamic library extension may be ommitted, and $(this) expands to the directory of * the .conf file. * * Plugins may access Firebird API through the fbclient library. */ // IPluginBase interface - base for master plugin interfaces (factories are registered for them) interface PluginBase : ReferenceCounted { // Additional (compared with Interface) functions getOwner() and setOwner() // are needed to release() owner of the plugin. This is done in releasePlugin() // function in PluginManager. Such method is needed to make sure that owner is released // after plugin itself, and therefore module is unloaded after release of last plugin from it. // Releasing owner from release() of plugin will unload module and after returning control // to missing code segfault is unavoidable. void setOwner(ReferenceCounted r); ReferenceCounted getOwner(); } // PluginSet - low level tool to access plugins according to parameter from firebird.conf interface PluginSet : ReferenceCounted { const string getName() const; const string getModuleName() const; PluginBase getPlugin(Status status); void next(Status status); void set(Status status, const string s); } // Entry in configuration file interface ConfigEntry : ReferenceCounted { const string getName(); const string getValue(); int64 getIntValue(); boolean getBoolValue(); Config getSubConfig(Status status); } // Generic form of access to configuration file - find specific entry in it interface Config : ReferenceCounted { ConfigEntry find(Status status, const string name); ConfigEntry findValue(Status status, const string name, const string value); ConfigEntry findPos(Status status, const string name, uint pos); } // Used to access config values from firebird.conf (may be DB specific) interface FirebirdConf : ReferenceCounted { // Get integer key by it's name // Value ~0 means name is invalid // Keys are stable: one can use once obtained key in other instances of this interface // provided they have same minor version (upper 16 bits match with getVersion()) uint getKey(const string name); // Use to access integer values int64 asInteger(uint key); // Use to access string values const string asString(uint key); // Use to access boolean values boolean asBoolean(uint key); version: // 3.0 => 4.0 // Use to access version of configuration manager serving this interface // Format: major byte, minor byte, buildno 2-byte uint getVersion(Status status); } // This interface is passed to plugin's factory as it's single parameter // and contains methods to access specific plugin's configuration data interface PluginConfig : ReferenceCounted { const string getConfigFileName(); Config getDefaultConfig(Status status); FirebirdConf getFirebirdConf(Status status); void setReleaseDelay(Status status, uint64 microSeconds); } // Required to creat instances of given plugin interface PluginFactory : Versioned { PluginBase createPlugin(Status status, PluginConfig factoryParameter); } // Required to let plugins manager invoke module's cleanup routine before unloading it. // For some OS/compiler this may be done in dtor of global variable in module itself. // Others (Windows/VC) fail to create some very useful resources (threads) when module is unloading. interface PluginModule : Versioned { void doClean(); version: // 3.0.3 => 3.0.4 // Used to release resources allocated per-thread void threadDetach(); } // Interface to deal with plugins here and there, returned by master interface interface PluginManager : Versioned { // Plugin types const uint TYPE_PROVIDER = 1; const uint TYPE_FIRST_NON_LIB = 2; const uint TYPE_AUTH_SERVER = 3; const uint TYPE_AUTH_CLIENT = 4; const uint TYPE_AUTH_USER_MANAGEMENT = 5; const uint TYPE_EXTERNAL_ENGINE = 6; const uint TYPE_TRACE = 7; const uint TYPE_WIRE_CRYPT = 8; const uint TYPE_DB_CRYPT = 9; const uint TYPE_KEY_HOLDER = 10; const uint TYPE_REPLICATOR = 11; const uint TYPE_COUNT = 12; // keep in sync //// TODO: TYPE_COUNT is not count. And these constants starts from 1, different than DIR_* ones. // Main function called by plugin modules in firebird_plugin() void registerPluginFactory(uint pluginType, const string defaultName, PluginFactory factory); // Sets cleanup for plugin module // Pay attention - this should be called at plugin-register time! // Only at this moment manager knows, which module sets his cleanup void registerModule(PluginModule cleanup); // Remove registered module before cleanup routine. // This method must be called by module which detects that it's unloaded, // but not notified prior to it by PluginManager via PluginModule. void unregisterModule(PluginModule cleanup); // Main function called to access plugins registered in plugins manager // Has front-end in GetPlugins.h - template GetPlugins // In namesList parameter comma or space separated list of names of configured plugins is passed // in case when plugin's version is less than desired // If caller already has an interface for firebird.conf, it may be passed here // If parameter is missing, plugins will get access to default (non database specific) config PluginSet getPlugins(Status status, uint pluginType, const string namesList, FirebirdConf firebirdConf); // Get generic config interface for given file Config getConfig(Status status, const string filename); // Plugins must be released using this function - use of plugin's release() // will cause resources leak void releasePlugin(PluginBase plugin); } // Helper interface to pass wire crypt key from authentication to crypt plugin interface CryptKey : Versioned { // In 2 following methods NULL type means auth plugin's name is used as key type void setSymmetric(Status status, const string type, uint keyLength, const void* key); void setAsymmetric(Status status, const string type, uint encryptKeyLength, const void* encryptKey, uint decryptKeyLength, const void* decryptKey); const void* getEncryptKey(uint* length); const void* getDecryptKey(uint* length); } // Generic access to all config interfaces interface ConfigManager : Versioned { // Codes for ConfigManager::getDirectory() const uint DIR_BIN = 0; const uint DIR_SBIN = 1; const uint DIR_CONF = 2; const uint DIR_LIB = 3; const uint DIR_INC = 4; const uint DIR_DOC = 5; const uint DIR_UDF = 6; const uint DIR_SAMPLE = 7; const uint DIR_SAMPLEDB = 8; const uint DIR_HELP = 9; const uint DIR_INTL = 10; const uint DIR_MISC = 11; const uint DIR_SECDB = 12; const uint DIR_MSG = 13; const uint DIR_LOG = 14; const uint DIR_GUARD = 15; const uint DIR_PLUGINS = 16; const uint DIR_TZDATA = 17; const uint DIR_COUNT = 18; // keep in sync const string getDirectory(uint code); FirebirdConf getFirebirdConf(); FirebirdConf getDatabaseConf(const string dbName); Config getPluginConfig(const string configuredPlugin); const string getInstallDirectory(); const string getRootDirectory(); version: // 3.0 => 4.0 const string getDefaultSecurityDb(); } // Provider interface - how we talk to databases // This interfaces are implemented by yvalve code and by each of providers. interface EventCallback : ReferenceCounted { // eventCallbackFunction is missing error status cause it's always called from places // where an ability to report an error to the user is missing void eventCallbackFunction(uint length, const uchar* events); } interface Blob : ReferenceCounted { void getInfo(Status status, uint itemsLength, const uchar* items, uint bufferLength, uchar* buffer); [notImplemented(Status::RESULT_ERROR)] int getSegment(Status status, uint bufferLength, void* buffer, uint* segmentLength); void putSegment(Status status, uint length, const void* buffer); void cancel(Status status); void close(Status status); int seek(Status status, int mode, int offset); // returns position } interface Transaction : ReferenceCounted { void getInfo(Status status, uint itemsLength, const uchar* items, uint bufferLength, uchar* buffer); void prepare(Status status, uint msgLength, const uchar* message); void commit(Status status); void commitRetaining(Status status); void rollback(Status status); void rollbackRetaining(Status status); void disconnect(Status status); Transaction join(Status status, Transaction transaction); Transaction validate(Status status, Attachment attachment); Transaction enterDtc(Status status); } interface MessageMetadata : ReferenceCounted { uint getCount(Status status); const string getField(Status status, uint index); const string getRelation(Status status, uint index); const string getOwner(Status status, uint index); const string getAlias(Status status, uint index); uint getType(Status status, uint index); boolean isNullable(Status status, uint index); int getSubType(Status status, uint index); uint getLength(Status status, uint index); int getScale(Status status, uint index); uint getCharSet(Status status, uint index); uint getOffset(Status status, uint index); uint getNullOffset(Status status, uint index); MetadataBuilder getBuilder(Status status); uint getMessageLength(Status status); version: // 3.0 => 4.0 uint getAlignment(Status status); uint getAlignedLength(Status status); } interface MetadataBuilder : ReferenceCounted { void setType(Status status, uint index, uint type); void setSubType(Status status, uint index, int subType); void setLength(Status status, uint index, uint length); void setCharSet(Status status, uint index, uint charSet); void setScale(Status status, uint index, int scale); void truncate(Status status, uint count); void moveNameToIndex(Status status, const string name, uint index); void remove(Status status, uint index); uint addField(Status status); MessageMetadata getMetadata(Status status); version: // 3.0 => 4.0 void setField(Status status, uint index, const string field); void setRelation(Status status, uint index, const string relation); void setOwner(Status status, uint index, const string owner); void setAlias(Status status, uint index, const string alias); } interface ResultSet : ReferenceCounted { [notImplemented(Status::RESULT_ERROR)] int fetchNext(Status status, void* message); [notImplemented(Status::RESULT_ERROR)] int fetchPrior(Status status, void* message); [notImplemented(Status::RESULT_ERROR)] int fetchFirst(Status status, void* message); [notImplemented(Status::RESULT_ERROR)] int fetchLast(Status status, void* message); [notImplemented(Status::RESULT_ERROR)] int fetchAbsolute(Status status, int position, void* message); [notImplemented(Status::RESULT_ERROR)] int fetchRelative(Status status, int offset, void* message); boolean isEof(Status status); boolean isBof(Status status); MessageMetadata getMetadata(Status status); void close(Status status); // This item is for ISC API emulation only // It may be gone in future versions // Please do not use it! void setDelayedOutputFormat(Status status, MessageMetadata format); } interface Statement : ReferenceCounted { // Prepare flags. const uint PREPARE_PREFETCH_NONE = 0x00; const uint PREPARE_PREFETCH_TYPE = 0x01; const uint PREPARE_PREFETCH_INPUT_PARAMETERS = 0x02; const uint PREPARE_PREFETCH_OUTPUT_PARAMETERS = 0x04; const uint PREPARE_PREFETCH_LEGACY_PLAN = 0x08; const uint PREPARE_PREFETCH_DETAILED_PLAN = 0x10; const uint PREPARE_PREFETCH_AFFECTED_RECORDS = 0x20; // not used yet const uint PREPARE_PREFETCH_FLAGS = 0x40; const uint PREPARE_PREFETCH_METADATA = PREPARE_PREFETCH_TYPE | PREPARE_PREFETCH_FLAGS | PREPARE_PREFETCH_INPUT_PARAMETERS | PREPARE_PREFETCH_OUTPUT_PARAMETERS; const uint PREPARE_PREFETCH_ALL = PREPARE_PREFETCH_METADATA | PREPARE_PREFETCH_LEGACY_PLAN | PREPARE_PREFETCH_DETAILED_PLAN | PREPARE_PREFETCH_AFFECTED_RECORDS; // Statement flags. const uint FLAG_HAS_CURSOR = 0x01; const uint FLAG_REPEAT_EXECUTE = 0x02; // Cursor flags. const uint CURSOR_TYPE_SCROLLABLE = 0x01; void getInfo(Status status, uint itemsLength, const uchar* items, uint bufferLength, uchar* buffer); uint getType(Status status); const string getPlan(Status status, boolean detailed); uint64 getAffectedRecords(Status status); MessageMetadata getInputMetadata(Status status); MessageMetadata getOutputMetadata(Status status); Transaction execute(Status status, Transaction transaction, MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, void* outBuffer); ResultSet openCursor(Status status, Transaction transaction, MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, uint flags); void setCursorName(Status status, const string name); void free(Status status); uint getFlags(Status status); version: // 3.0 => 4.0 // Statement execution timeout, milliseconds uint getTimeout(Status status); void setTimeout(Status status, uint timeOut); // Batch API Batch createBatch(Status status, MessageMetadata inMetadata, uint parLength, const uchar* par); /* Pipe createPipe(Status status, Transaction transaction, MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, uint parLength, const uchar* par); */ } interface Batch : ReferenceCounted { const uchar VERSION1 = 1; // Tag for parameters block const uchar TAG_MULTIERROR = 1; // Can have >1 buffers with errors const uchar TAG_RECORD_COUNTS = 2; // Per-record modified records accountung const uchar TAG_BUFFER_BYTES_SIZE = 3; // Maximum possible buffer size const uchar TAG_BLOB_POLICY = 4; // What policy is used to store blobs const uchar TAG_DETAILED_ERRORS = 5; // How many vectors with detailed error info are stored const uchar BLOB_NONE = 0; // Blobs can't be used const uchar BLOB_ID_ENGINE = 1; // Blobs are added one by one, IDs are generated by firebird const uchar BLOB_ID_USER = 2; // Blobs are added one by one, IDs are generated by user const uchar BLOB_STREAM = 3; // Blobs are added in a stream, IDs are generated by user const uint BLOB_SEGHDR_ALIGN = 2; // Alignment of segment header in the stream void add(Status status, uint count, const void* inBuffer); void addBlob(Status status, uint length, const void* inBuffer, ISC_QUAD* blobId, uint parLength, const uchar* par); void appendBlobData(Status status, uint length, const void* inBuffer); void addBlobStream(Status status, uint length, const void* inBuffer); void registerBlob(Status status, const ISC_QUAD* existingBlob, ISC_QUAD* blobId); BatchCompletionState execute(Status status, Transaction transaction); void cancel(Status status); uint getBlobAlignment(Status status); MessageMetadata getMetadata(Status status); void setDefaultBpb(Status status, uint parLength, const uchar* par); void close(Status status); } interface BatchCompletionState : Disposable { const int EXECUTE_FAILED = -1; // Error happened when processing record const int SUCCESS_NO_INFO = -2; // Record update info was not collected const uint NO_MORE_ERRORS = 0xFFFFFFFF; // Special value returned by findError() uint getSize(Status status); int getState(Status status, uint pos); uint findError(Status status, uint pos); void getStatus(Status status, Status to, uint pos); } /* interface Pipe : ReferenceCounted { uint add(Status status, uint count, void* inBuffer); uint fetch(Status status, uint count, void* outBuffer); void close(Status status); } */ /* interface ReplicationBatch : Versioned { void process(Status status, ReplicationSession replicator); const string getDatabaseID(); uint64 getTransactionID(); ISC_TIMESTAMP getTimestamp(); } */ interface Replicator : ReferenceCounted { /* void process(Status status, ReplicationBatch batch); */ void process(Status status, uint length, const uchar* data); void close(Status status); } interface Request : ReferenceCounted { void receive(Status status, int level, uint msgType, uint length, void* message); void send(Status status, int level, uint msgType, uint length, const void* message); void getInfo(Status status, int level, uint itemsLength, const uchar* items, uint bufferLength, uchar* buffer); void start(Status status, Transaction tra, int level); void startAndSend(Status status, Transaction tra, int level, uint msgType, uint length, const void* message); void unwind(Status status, int level); void free(Status status); } interface Events : ReferenceCounted { void cancel(Status status); } interface Attachment : ReferenceCounted { void getInfo(Status status, uint itemsLength, const uchar* items, uint bufferLength, uchar* buffer); Transaction startTransaction(Status status, uint tpbLength, const uchar* tpb); Transaction reconnectTransaction(Status status, uint length, const uchar* id); Request compileRequest(Status status, uint blrLength, const uchar* blr); void transactRequest(Status status, Transaction transaction, uint blrLength, const uchar* blr, uint inMsgLength, const uchar* inMsg, uint outMsgLength, uchar* outMsg); Blob createBlob(Status status, Transaction transaction, ISC_QUAD* id, uint bpbLength, const uchar* bpb); Blob openBlob(Status status, Transaction transaction, ISC_QUAD* id, uint bpbLength, const uchar* bpb); int getSlice(Status status, Transaction transaction, ISC_QUAD* id, uint sdlLength, const uchar* sdl, uint paramLength, const uchar* param, int sliceLength, uchar* slice); void putSlice(Status status, Transaction transaction, ISC_QUAD* id, uint sdlLength, const uchar* sdl, uint paramLength, const uchar* param, int sliceLength, uchar* slice); void executeDyn(Status status, Transaction transaction, uint length, const uchar* dyn); Statement prepare(Status status, Transaction tra, uint stmtLength, const string sqlStmt, uint dialect, uint flags); Transaction execute(Status status, Transaction transaction, uint stmtLength, const string sqlStmt, uint dialect, MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, void* outBuffer); ResultSet openCursor(Status status, Transaction transaction, uint stmtLength, const string sqlStmt, uint dialect, MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, const string cursorName, uint cursorFlags); Events queEvents(Status status, EventCallback callback, uint length, const uchar* events); void cancelOperation(Status status, int option); void ping(Status status); void detach(Status status); void dropDatabase(Status status); version: // 3.0 => 4.0 // Idle attachment timeout, seconds uint getIdleTimeout(Status status); void setIdleTimeout(Status status, uint timeOut); // Statement execution timeout, milliseconds uint getStatementTimeout(Status status); void setStatementTimeout(Status status, uint timeOut); // Batch API Batch createBatch(Status status, Transaction transaction, uint stmtLength, const string sqlStmt, uint dialect, MessageMetadata inMetadata, uint parLength, const uchar* par); /* Pipe createPipe(Status status, uint stmtLength, const string sqlStmt, uint dialect, Transaction transaction, MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, uint parLength, const uchar* par); */ Replicator createReplicator(Status status); } interface Service : ReferenceCounted { void detach(Status status); void query(Status status, uint sendLength, const uchar* sendItems, uint receiveLength, const uchar* receiveItems, uint bufferLength, uchar* buffer); void start(Status status, uint spbLength, const uchar* spb); } interface Provider : PluginBase { Attachment attachDatabase(Status status, const string fileName, uint dpbLength, const uchar* dpb); Attachment createDatabase(Status status, const string fileName, uint dpbLength, const uchar* dpb); Service attachServiceManager(Status status, const string service, uint spbLength, const uchar* spb); void shutdown(Status status, uint timeout, const int reason); void setDbCryptCallback(Status status, CryptKeyCallback cryptCallback); } // Helper to start transaction over >1 attachments (former TEB) interface DtcStart : Disposable { void addAttachment(Status status, Attachment att); void addWithTpb(Status status, Attachment att, uint length, const uchar* tpb); Transaction start(Status status); // successfull call disposes interfaces } // Distributed transactions coordinator interface Dtc : Versioned { Transaction join(Status status, Transaction one, Transaction two); DtcStart startBuilder(Status status); } // Interfaces, used by authentication plugins interface Auth : PluginBase { const int AUTH_FAILED = -1; const int AUTH_SUCCESS = 0; const int AUTH_MORE_DATA = 1; const int AUTH_CONTINUE = 2; } interface Writer : Versioned { void reset(); void add(Status status, const string name); void setType(Status status, const string value); void setDb(Status status, const string value); } // Representation of auth-related data, passed to/from server auth plugin interface ServerBlock : Versioned { const string getLogin(); const uchar* getData(uint* length); void putData(Status status, uint length, const void* data); CryptKey newKey(Status status); } // Representation of auth-related data, passed to/from client auth plugin interface ClientBlock : ReferenceCounted { const string getLogin(); const string getPassword(); const uchar* getData(uint* length); void putData(Status status, uint length, const void* data); CryptKey newKey(Status status); version: // 3.0 => 4.0 AuthBlock getAuthBlock(Status status); } // server part of authentication plugin interface Server : Auth { [notImplemented(Auth::AUTH_FAILED)] int authenticate(Status status, ServerBlock sBlock, Writer writerInterface); version: // 3.0.1 => 4.0 void setDbCryptCallback(Status status, CryptKeyCallback cryptCallback); } // .. and corresponding client interface Client : Auth { [notImplemented(Auth::AUTH_FAILED)] int authenticate(Status status, ClientBlock cBlock); } interface UserField : Versioned { int entered(); int specified(); void setEntered(Status status, int newValue); } interface CharUserField : UserField { const string get(); void set(Status status, const string newValue); } interface IntUserField : UserField { int get(); void set(Status status, int newValue); } interface User : Versioned { uint operation(); CharUserField userName(); CharUserField password(); CharUserField firstName(); CharUserField lastName(); CharUserField middleName(); CharUserField comment(); CharUserField attributes(); IntUserField active(); IntUserField admin(); void clear(Status status); // code of operation() const uint OP_USER_ADD = 1; const uint OP_USER_MODIFY = 2; const uint OP_USER_DELETE = 3; const uint OP_USER_DISPLAY = 4; const uint OP_USER_SET_MAP = 5; const uint OP_USER_DROP_MAP = 6; } interface ListUsers : Versioned { void list(Status status, User user); } interface LogonInfo : Versioned { const string name(); const string role(); const string networkProtocol(); const string remoteAddress(); const uchar* authBlock(uint* length); version: Attachment attachment(Status status); Transaction transaction(Status status); } interface Management : PluginBase { void start(Status status, LogonInfo logonInfo); int execute(Status status, User user, ListUsers callback); void commit(Status status); void rollback(Status status); } interface AuthBlock : Versioned { const string getType(); const string getName(); const string getPlugin(); const string getSecurityDb(); const string getOriginalPlugin(); boolean next(Status status); boolean first(Status status); } // Encryption // Part 1. Network crypt. // Plugins of this type are used to crypt data, sent over the wire // Plugin must support encrypt and decrypt operations. // Interface of plugin is the same for both client and server, // and it may have different or same implementations for client and server. interface WireCryptPlugin : PluginBase { // getKnownTypes() function must return list of acceptable keys' types // special type 'builtin' means that crypt plugin knows itself where to get the key from const string getKnownTypes(Status status); void setKey(Status status, CryptKey key); void encrypt(Status status, uint length, const void* from, void* to); void decrypt(Status status, uint length, const void* from, void* to); version: const uchar* getSpecificData(Status status, const string keyType, uint* length); void setSpecificData(Status status, const string keyType, uint length, const uchar* data); } // Part 2. Database crypt. // This interface is used to transfer some data (related to crypt keys) // between different components of firebird. interface CryptKeyCallback : Versioned { // First two parameters can be used by calling side to identify // itself for callback object. // Buffer must be big enough to hold a key. // It may be NULL, in this case just a key size will be returned // (not recommended because callback may cause network roundtrip). // Returning value is a real size of the key. // Returning of zero means error, but there is no way to provide // any further details. uint callback(uint dataLength, const void* data, uint bufferLength, void* buffer); } // Key holder accepts key(s) from attachment at database attach time // (or gets them it some other arbitrary way) // and sends it to database crypt plugin on request. interface KeyHolderPlugin : PluginBase { // keyCallback() signals that a new attachment will need a key. // Key holder can call callback to send upstairs a request for // some additional information (if needed). For example, RSA key // holder can send request to end user application for passphrase. // Return value is 1 if key is ready. int keyCallback(Status status, CryptKeyCallback callback); // Crypt plugin calls keyHandle() when it needs a key with a given name, stored in key holder. // Key is not returned directly - instead of it callback interface is returned. // Missing key with given name is not an error condition for keyHandle(). // It should just return NULL in this case CryptKeyCallback keyHandle(Status status, const string keyName); version: // 3.0.1 => 4.0 // With returning true here KeyHolder attachment can use only keys, provided by this KeyHolder. // Use of keys, got by database crypt plugin from other attachments, is prohibited. boolean useOnlyOwnKeys(Status status); // Communication in a chain of key holders - get callback interface for chaining holders CryptKeyCallback chainHandle(Status status); } // Information calls available for crypt plugin interface DbCryptInfo : ReferenceCounted { const string getDatabaseFullPath(Status status); } interface DbCryptPlugin : PluginBase { // When database crypt plugin is loaded, setKey() is called to provide information // about key holders, available for a given database and key name for database. // It's supposed that crypt plugin will invoke keyHandle() function from them // to access callback interface for getting actual crypt key. // If crypt plugin fails to find appropriate key in sources, it should raise error. void setKey(Status status, uint length, KeyHolderPlugin* sources, const string keyName); void encrypt(Status status, uint length, const void* from, void* to); void decrypt(Status status, uint length, const void* from, void* to); version: // 3.0.1 => 4.0 // Crypto manager may pass some additional info to plugin void setInfo(Status status, DbCryptInfo info); } // External procedures, functions & triggers // Connection to current database in external engine. // Context passed to ExternalEngine has SYSDBA privileges. // Context passed to ExternalFunction, ExternalProcedure and ExternalTrigger // has user privileges. // There is one IExternalContext per attachment. The privileges and character // set properties are changed during the calls. interface ExternalContext : Versioned { // Gets the Master associated with this context. Master getMaster(); // Gets the ExternalEngine associated with this context. ExternalEngine getEngine(Status status); // Gets the Attachment associated with this context. Attachment getAttachment(Status status); // Obtained transaction is valid only before control is returned to the engine // or in ExternalResultSet::fetch calls of correspondent ExternalProcedure::open. Transaction getTransaction(Status status); const string getUserName(); const string getDatabaseName(); // Get user attachment character set. const string getClientCharSet(); // Misc info associated with a context. The pointers are never accessed or freed by Firebird. // Obtains an unique (across all contexts) code to associate plugin and/or user information. int obtainInfoCode(); // Gets a value associated with this code or FB_NULL if no value was set. void* getInfo(int code); // Sets a value associated with this code and returns the last value. void* setInfo(int code, void* value); } // To return set of rows in selectable procedures. interface ExternalResultSet : Disposable { boolean fetch(Status status); } interface ExternalFunction : Disposable { // This method is called just before execute and informs the engine our requested character // set for data exchange inside that method. // During this call, the context uses the character set obtained from ExternalEngine::getCharSet. void getCharSet(Status status, ExternalContext context, string name, uint nameSize); void execute(Status status, ExternalContext context, void* inMsg, void* outMsg); } interface ExternalProcedure : Disposable { // This method is called just before open and informs the engine our requested character // set for data exchange inside that method and ExternalResultSet::fetch. // During this call, the context uses the character set obtained from ExternalEngine::getCharSet. void getCharSet(Status status, ExternalContext context, string name, uint nameSize); // Returns a ExternalResultSet for selectable procedures. // Returning NULL results in a result set of one record. // Procedures without output parameters should return NULL. ExternalResultSet open(Status status, ExternalContext context, void* inMsg, void* outMsg); } interface ExternalTrigger : Disposable { // types const uint TYPE_BEFORE = 1; const uint TYPE_AFTER = 2; const uint TYPE_DATABASE = 3; // actions const uint ACTION_INSERT = 1; const uint ACTION_UPDATE = 2; const uint ACTION_DELETE = 3; const uint ACTION_CONNECT = 4; const uint ACTION_DISCONNECT = 5; const uint ACTION_TRANS_START = 6; const uint ACTION_TRANS_COMMIT = 7; const uint ACTION_TRANS_ROLLBACK = 8; const uint ACTION_DDL = 9; // This method is called just before execute and informs the engine our requested character // set for data exchange inside that method. // During this call, the context uses the character set obtained from ExternalEngine::getCharSet. void getCharSet(Status status, ExternalContext context, string name, uint nameSize); void execute(Status status, ExternalContext context, uint action, void* oldMsg, void* newMsg); } interface RoutineMetadata : Versioned { const string getPackage(Status status) const; const string getName(Status status) const; const string getEntryPoint(Status status) const; const string getBody(Status status) const; MessageMetadata getInputMetadata(Status status) const; MessageMetadata getOutputMetadata(Status status) const; MessageMetadata getTriggerMetadata(Status status) const; const string getTriggerTable(Status status) const; uint getTriggerType(Status status) const; } // In SuperServer, shared by all attachments to one database and disposed when last (non-external) // user attachment to the database is closed. interface ExternalEngine : PluginBase { // This method is called once (per ExternalEngine instance) before any following methods. // The requested character set for data exchange inside methods of this interface should // be copied to charSet parameter. // During this call, the context uses the UTF-8 character set. void open(Status status, ExternalContext context, string charSet, uint charSetSize); // Attachment is being opened. void openAttachment(Status status, ExternalContext context); // Attachment is being closed. void closeAttachment(Status status, ExternalContext context); // Called when engine wants to load object in the cache. Objects are disposed when // going out of the cache. ExternalFunction makeFunction(Status status, ExternalContext context, RoutineMetadata metadata, MetadataBuilder inBuilder, MetadataBuilder outBuilder); ExternalProcedure makeProcedure(Status status, ExternalContext context, RoutineMetadata metadata, MetadataBuilder inBuilder, MetadataBuilder outBuilder); ExternalTrigger makeTrigger(Status status, ExternalContext context, RoutineMetadata metadata, MetadataBuilder fieldsBuilder); } // Identifies particular timer. // Callback handler is invoked when timer fires. interface Timer : ReferenceCounted { void handler(); } // Interface to set timer for particular time interface TimerControl : Versioned { // Set timer void start(Status status, Timer timer, uint64 microSeconds); // Stop timer void stop(Status status, Timer timer); } // Misc calls interface VersionCallback : Versioned { void callback(Status status, const string text); } interface Util : Versioned { void getFbVersion(Status status, Attachment att, VersionCallback callback); void loadBlob(Status status, ISC_QUAD* blobId, Attachment att, Transaction tra, const string file, boolean txt); void dumpBlob(Status status, ISC_QUAD* blobId, Attachment att, Transaction tra, const string file, boolean txt); void getPerfCounters(Status status, Attachment att, const string countersSet, int64* counters); Attachment executeCreateDatabase(Status status, uint stmtLength, const string creatDBstatement, uint dialect, boolean* stmtIsCreateDb); void decodeDate(ISC_DATE date, uint* year, uint* month, uint* day); void decodeTime(ISC_TIME time, uint* hours, uint* minutes, uint* seconds, uint* fractions); ISC_DATE encodeDate(uint year, uint month, uint day); ISC_TIME encodeTime(uint hours, uint minutes, uint seconds, uint fractions); uint formatStatus(string buffer, uint bufferSize, Status status); uint getClientVersion(); // Returns major * 256 + minor XpbBuilder getXpbBuilder(Status status, uint kind, const uchar* buf, uint len); uint setOffsets(Status status, MessageMetadata metadata, OffsetsCallback callback); version: // 3.0 => 4.0 Alpha1 DecFloat16 getDecFloat16(Status status); DecFloat34 getDecFloat34(Status status); void decodeTimeTz(Status status, const ISC_TIME_TZ* timeTz, uint* hours, uint* minutes, uint* seconds, uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer); void decodeTimeStampTz(Status status, const ISC_TIMESTAMP_TZ* timeStampTz, uint* year, uint* month, uint* day, uint* hours, uint* minutes, uint* seconds, uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer); void encodeTimeTz(Status status, ISC_TIME_TZ* timeTz, uint hours, uint minutes, uint seconds, uint fractions, const string timeZone); void encodeTimeStampTz(Status status, ISC_TIMESTAMP_TZ* timeStampTz, uint year, uint month, uint day, uint hours, uint minutes, uint seconds, uint fractions, const string timeZone); version: // 4.0 Beta1 => 4.0 Beta2 Int128 getInt128(Status status); void decodeTimeTzEx(Status status, const ISC_TIME_TZ_EX* timeTz, uint* hours, uint* minutes, uint* seconds, uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer); void decodeTimeStampTzEx(Status status, const ISC_TIMESTAMP_TZ_EX* timeStampTz, uint* year, uint* month, uint* day, uint* hours, uint* minutes, uint* seconds, uint* fractions, uint timeZoneBufferLength, string timeZoneBuffer); } interface OffsetsCallback : Versioned { void setOffset(Status status, uint index, uint offset, uint nullOffset); } interface XpbBuilder : Disposable { const uint DPB = 1; const uint SPB_ATTACH = 2; const uint SPB_START = 3; const uint TPB = 4; const uint BATCH = 5; const uint BPB = 6; const uint SPB_SEND = 7; const uint SPB_RECEIVE = 8; const uint SPB_RESPONSE = 9; // removing data void clear(Status status); void removeCurrent(Status status); // adding data void insertInt(Status status, uchar tag, int value); void insertBigInt(Status status, uchar tag, int64 value); void insertBytes(Status status, uchar tag, const void* bytes, uint length); void insertString(Status status, uchar tag, const string str); void insertTag(Status status, uchar tag); // navigation boolean isEof(Status status); void moveNext(Status status); void rewind(Status status); boolean findFirst(Status status, uchar tag); boolean findNext(Status status); // Methods which work with current selection uchar getTag(Status status); uint getLength(Status status); int getInt(Status status); int64 getBigInt(Status status); const string getString(Status status); const uchar* getBytes(Status status); // Methods which work with resulting buffer uint getBufferLength(Status status); const uchar* getBuffer(Status status); } // Database trace objects struct PerformanceInfo; struct dsc; interface TraceConnection : Versioned { const uint KIND_DATABASE = 1; const uint KIND_SERVICE = 2; uint getKind(); int getProcessID(); const string getUserName(); const string getRoleName(); const string getCharSet(); const string getRemoteProtocol(); const string getRemoteAddress(); int getRemoteProcessID(); const string getRemoteProcessName(); } interface TraceDatabaseConnection : TraceConnection { int64 getConnectionID(); const string getDatabaseName(); } interface TraceTransaction : Versioned { const uint ISOLATION_CONSISTENCY = 1; const uint ISOLATION_CONCURRENCY = 2; const uint ISOLATION_READ_COMMITTED_RECVER = 3; const uint ISOLATION_READ_COMMITTED_NORECVER = 4; const uint ISOLATION_READ_COMMITTED_READ_CONSISTENCY = 5; int64 getTransactionID(); boolean getReadOnly(); int getWait(); uint getIsolation(); PerformanceInfo* getPerf(); version: // 3.0.4 -> 3.0.5 int64 getInitialID(); int64 getPreviousID(); } interface TraceParams : Versioned { uint getCount(); const dsc* getParam(uint idx); version: const string getTextUTF8(Status status, uint idx); } interface TraceStatement : Versioned { int64 getStmtID(); PerformanceInfo* getPerf(); } interface TraceSQLStatement : TraceStatement { const string getText(); const string getPlan(); TraceParams getInputs(); const string getTextUTF8(); const string getExplainedPlan(); } interface TraceBLRStatement : TraceStatement { const uchar* getData(); uint getDataLength(); const string getText(); } interface TraceDYNRequest : Versioned { const uchar* getData(); uint getDataLength(); const string getText(); } interface TraceContextVariable : Versioned { const string getNameSpace(); const string getVarName(); const string getVarValue(); } interface TraceProcedure : Versioned { const string getProcName(); TraceParams getInputs(); PerformanceInfo* getPerf(); } interface TraceFunction : Versioned { const string getFuncName(); TraceParams getInputs(); TraceParams getResult(); PerformanceInfo* getPerf(); } interface TraceTrigger : Versioned { //// TODO: TYPE or WHICH? ExternalTrigger has similar constants. const uint TYPE_ALL = 0; const uint TYPE_BEFORE = 1; const uint TYPE_AFTER = 2; //// TODO: What about database triggers? //// TODO: Action constants? const string getTriggerName(); const string getRelationName(); int getAction(); int getWhich(); PerformanceInfo* getPerf(); } interface TraceServiceConnection : TraceConnection { void* getServiceID(); const string getServiceMgr(); const string getServiceName(); } interface TraceStatusVector : Versioned { boolean hasError(); boolean hasWarning(); Status getStatus(); const string getText(); } interface TraceSweepInfo : Versioned { int64 getOIT(); int64 getOST(); int64 getOAT(); int64 getNext(); PerformanceInfo* getPerf(); } interface TraceLogWriter : ReferenceCounted { uint write(const void* buf, uint size); version: // 3.0.4 -> 3.0.5 uint write_s(Status status, const void* buf, uint size); } interface TraceInitInfo : Versioned { const string getConfigText(); int getTraceSessionID(); const string getTraceSessionName(); const string getFirebirdRootDirectory(); const string getDatabaseName(); TraceDatabaseConnection getConnection(); TraceLogWriter getLogWriter(); } // API of trace plugin. Used to deliver notifications for each database interface TracePlugin : ReferenceCounted { const uint RESULT_SUCCESS = 0; const uint RESULT_FAILED = 1; const uint RESULT_UNAUTHORIZED = 2; // Function to return error string for hook failure const string trace_get_error(); // Events supported: // Create/close attachment [notImplemented(true)] boolean trace_attach(TraceDatabaseConnection connection, boolean create_db, uint att_result); [notImplemented(true)] boolean trace_detach(TraceDatabaseConnection connection, boolean drop_db); // Start/end transaction [notImplemented(true)] boolean trace_transaction_start(TraceDatabaseConnection connection, TraceTransaction transaction, uint tpb_length, const uchar* tpb, uint tra_result); [notImplemented(true)] boolean trace_transaction_end(TraceDatabaseConnection connection, TraceTransaction transaction, boolean commit, boolean retain_context, uint tra_result); // Stored procedures and triggers execution [notImplemented(true)] boolean trace_proc_execute (TraceDatabaseConnection connection, TraceTransaction transaction, TraceProcedure procedure, boolean started, uint proc_result); [notImplemented(true)] boolean trace_trigger_execute(TraceDatabaseConnection connection, TraceTransaction transaction, TraceTrigger trigger, boolean started, uint trig_result); // Assignment to context variables [notImplemented(true)] boolean trace_set_context(TraceDatabaseConnection connection, TraceTransaction transaction, TraceContextVariable variable); // DSQL statement lifecycle [notImplemented(true)] boolean trace_dsql_prepare(TraceDatabaseConnection connection, TraceTransaction transaction, TraceSQLStatement statement, int64 time_millis, uint req_result); [notImplemented(true)] boolean trace_dsql_free(TraceDatabaseConnection connection, TraceSQLStatement statement, uint option); [notImplemented(true)] boolean trace_dsql_execute(TraceDatabaseConnection connection, TraceTransaction transaction, TraceSQLStatement statement, boolean started, uint req_result); // BLR requests [notImplemented(true)] boolean trace_blr_compile(TraceDatabaseConnection connection, TraceTransaction transaction, TraceBLRStatement statement, int64 time_millis, uint req_result); [notImplemented(true)] boolean trace_blr_execute(TraceDatabaseConnection connection, TraceTransaction transaction, TraceBLRStatement statement, uint req_result); // DYN requests [notImplemented(true)] boolean trace_dyn_execute(TraceDatabaseConnection connection, TraceTransaction transaction, TraceDYNRequest request, int64 time_millis, uint req_result); // Using the services [notImplemented(true)] boolean trace_service_attach(TraceServiceConnection service, uint att_result); [notImplemented(true)] boolean trace_service_start(TraceServiceConnection service, uint switches_length, const string switches, uint start_result); [notImplemented(true)] boolean trace_service_query(TraceServiceConnection service, uint send_item_length, const uchar* send_items, uint recv_item_length, const uchar* recv_items, uint query_result); [notImplemented(true)] boolean trace_service_detach(TraceServiceConnection service, uint detach_result); // Errors happened [notImplemented(true)] boolean trace_event_error(TraceConnection connection, TraceStatusVector status, const string function); // Sweep activity const uint SWEEP_STATE_STARTED = 1; const uint SWEEP_STATE_FINISHED = 2; const uint SWEEP_STATE_FAILED = 3; const uint SWEEP_STATE_PROGRESS = 4; [notImplemented(true)] boolean trace_event_sweep(TraceDatabaseConnection connection, TraceSweepInfo sweep, uint sweep_state); // Stored functions execution [notImplemented(true)] boolean trace_func_execute (TraceDatabaseConnection connection, TraceTransaction transaction, TraceFunction function, boolean started, uint func_result); } // Trace plugin second level factory (this is what is known to PluginManager as "trace plugin") interface TraceFactory : PluginBase { // Known notifications const uint TRACE_EVENT_ATTACH = 0; const uint TRACE_EVENT_DETACH = 1; const uint TRACE_EVENT_TRANSACTION_START = 2; const uint TRACE_EVENT_TRANSACTION_END = 3; const uint TRACE_EVENT_SET_CONTEXT = 4; const uint TRACE_EVENT_PROC_EXECUTE = 5; const uint TRACE_EVENT_TRIGGER_EXECUTE = 6; const uint TRACE_EVENT_DSQL_PREPARE = 7; const uint TRACE_EVENT_DSQL_FREE = 8; const uint TRACE_EVENT_DSQL_EXECUTE = 9; const uint TRACE_EVENT_BLR_COMPILE = 10; const uint TRACE_EVENT_BLR_EXECUTE = 11; const uint TRACE_EVENT_DYN_EXECUTE = 12; const uint TRACE_EVENT_SERVICE_ATTACH = 13; const uint TRACE_EVENT_SERVICE_START = 14; const uint TRACE_EVENT_SERVICE_QUERY = 15; const uint TRACE_EVENT_SERVICE_DETACH = 16; const uint TRACE_EVENT_ERROR = 17; const uint TRACE_EVENT_SWEEP = 18; const uint TRACE_EVENT_FUNC_EXECUTE = 19; const uint TRACE_EVENT_MAX = 20; // keep it last // What notifications does plugin need uint64 trace_needs(); // Create plugin TracePlugin trace_create(Status status, TraceInitInfo init_info); } // UDR Factory interfaces. They should be singletons instances created by user's modules and // registered. When UDR engine is going to load a routine, it calls newItem. interface UdrFunctionFactory : Disposable { void setup(Status status, ExternalContext context, RoutineMetadata metadata, MetadataBuilder inBuilder, MetadataBuilder outBuilder); ExternalFunction newItem(Status status, ExternalContext context, RoutineMetadata metadata); } interface UdrProcedureFactory : Disposable { void setup(Status status, ExternalContext context, RoutineMetadata metadata, MetadataBuilder inBuilder, MetadataBuilder outBuilder); ExternalProcedure newItem(Status status, ExternalContext context, RoutineMetadata metadata); } interface UdrTriggerFactory : Disposable { void setup(Status status, ExternalContext context, RoutineMetadata metadata, MetadataBuilder fieldsBuilder); ExternalTrigger newItem(Status status, ExternalContext context, RoutineMetadata metadata); } interface UdrPlugin : Versioned { Master getMaster(); void registerFunction(Status status, const string name, UdrFunctionFactory factory); void registerProcedure(Status status, const string name, UdrProcedureFactory factory); void registerTrigger(Status status, const string name, UdrTriggerFactory factory); } interface DecFloat16 : Versioned { const uint BCD_SIZE = 16; const uint STRING_SIZE = 24; // includes terminating \0 void toBcd(const FB_DEC16* from, int* sign, uchar* bcd, int* exp); void toString(Status status, const FB_DEC16* from, uint bufferLength, string buffer); void fromBcd(int sign, const uchar* bcd, int exp, FB_DEC16* to); void fromString(Status status, const string from, FB_DEC16* to); } interface DecFloat34 : Versioned { const uint BCD_SIZE = 34; const uint STRING_SIZE = 43; // includes terminating \0 void toBcd(const FB_DEC34* from, int* sign, uchar* bcd, int* exp); void toString(Status status, const FB_DEC34* from, uint bufferLength, string buffer); void fromBcd(int sign, const uchar* bcd, int exp, FB_DEC34* to); void fromString(Status status, const string from, FB_DEC34* to); } interface Int128 : Versioned { // - 170141183460469231731687303715884105728 e - 128 \0 // 1 + 39 + 1 + 1 + 3 + 1 = 46 const uint STRING_SIZE = 46; // includes terminating \0 void toString(Status status, const FB_I128* from, int scale, uint bufferLength, string buffer); void fromString(Status status, int scale, const string from, FB_I128* to); } // Replication interfaces interface ReplicatedField : Versioned { // Return field name (or nullptr on error) const string getName(); // Return field type (or zero if the field does not exist) uint getType(); // Return field subtype, if applicable int getSubType(); // Return field scale (behavior is undefined for non-numeric fields) int getScale(); // Return maximum length of the field data in bytes uint getLength(); // Return character set without collation part for text or CLOB fields uint getCharSet(); // Return pointer to data (or nullptr for NULL values) const void* getData(); } interface ReplicatedRecord : Versioned { // Return count of fields uint getCount(); // Return ReplicatedField with given index (or nullptr if index is invalid). // Returned reference is valid until next call of getField() or end of the record life. ReplicatedField getField(uint index); // Return size of raw data uint getRawLength(); // Dirty method to return record buffer in internal format const uchar* getRawData(); } interface ReplicatedTransaction : Disposable { // Last chance to return an error and make commit to be aborted. // The transaction still can be rolled back on error happened after this call. void prepare(Status status); // An error returned from these methods may be logged but do not abort process. void commit(Status status); void rollback(Status status); void startSavepoint(Status status); void releaseSavepoint(Status status); void rollbackSavepoint(Status status); // ReplicatedRecords parameters point to local objects, do not ever store the pointer. void insertRecord(Status status, const string name, ReplicatedRecord record); void updateRecord(Status status, const string name, ReplicatedRecord orgRecord, ReplicatedRecord newRecord); void deleteRecord(Status status, const string name, ReplicatedRecord record); void executeSql(Status status, const string sql); void executeSqlIntl(Status status, uint charset, const string sql); } interface ReplicatedSession : PluginBase { // Parameter don't need to be released if not used. boolean init(Status status, Attachment attachment); ReplicatedTransaction startTransaction(Status status, Transaction transaction, int64 number); void cleanupTransaction(Status status, int64 number); void setSequence(Status status, const string name, int64 value); }