2009-10-21 02:42:38 +02:00
|
|
|
/*
|
|
|
|
* 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 Adriano dos Santos Fernandes
|
|
|
|
* for the Firebird Open Source RDBMS project.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2008 Adriano dos Santos Fernandes <adrianosf@uol.com.br>
|
|
|
|
* and all contributors signed below.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef JRD_EXT_ENGINE_MANAGER_H
|
|
|
|
#define JRD_EXT_ENGINE_MANAGER_H
|
|
|
|
|
2014-09-29 13:03:47 +02:00
|
|
|
#include "firebird/Interface.h"
|
2023-10-18 10:46:57 +02:00
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
2009-10-21 02:42:38 +02:00
|
|
|
#include "../common/classes/array.h"
|
|
|
|
#include "../common/classes/fb_string.h"
|
|
|
|
#include "../common/classes/GenericMap.h"
|
2020-06-16 18:22:15 +02:00
|
|
|
#include "../jrd/MetaName.h"
|
2010-11-21 04:47:29 +01:00
|
|
|
#include "../common/classes/NestConst.h"
|
2009-10-21 02:42:38 +02:00
|
|
|
#include "../common/classes/auto.h"
|
|
|
|
#include "../common/classes/rwlock.h"
|
2011-05-19 18:24:46 +02:00
|
|
|
#include "../common/classes/ImplementHelper.h"
|
2011-06-01 03:44:54 +02:00
|
|
|
#include "../common/StatementMetadata.h"
|
2023-03-22 15:07:02 +01:00
|
|
|
#include "../common/classes/GetPlugins.h"
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
struct dsc;
|
|
|
|
|
|
|
|
namespace Jrd {
|
|
|
|
|
|
|
|
class thread_db;
|
|
|
|
class jrd_prc;
|
2022-02-13 14:51:30 +01:00
|
|
|
class Request;
|
2011-05-07 21:52:44 +02:00
|
|
|
class jrd_tra;
|
2009-10-21 02:42:38 +02:00
|
|
|
class Attachment;
|
2013-04-11 17:44:17 +02:00
|
|
|
class CompilerScratch;
|
2009-10-21 02:42:38 +02:00
|
|
|
class Database;
|
|
|
|
class Format;
|
|
|
|
class Trigger;
|
2009-12-21 18:43:01 +01:00
|
|
|
class Function;
|
2019-01-21 16:06:01 +01:00
|
|
|
class DeclareVariableNode;
|
|
|
|
class StmtNode;
|
2010-11-21 04:47:29 +01:00
|
|
|
class ValueExprNode;
|
2009-10-21 02:42:38 +02:00
|
|
|
struct impure_value;
|
|
|
|
struct record_param;
|
|
|
|
|
|
|
|
|
2022-01-06 14:10:56 +01:00
|
|
|
class ExtEngineManager final : public Firebird::PermanentStorage
|
2009-10-21 02:42:38 +02:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
class AttachmentImpl;
|
|
|
|
template <typename T> class ContextManager;
|
|
|
|
class TransactionImpl;
|
|
|
|
|
2022-01-06 14:10:56 +01:00
|
|
|
class RoutineMetadata final :
|
2015-01-12 01:21:38 +01:00
|
|
|
public Firebird::VersionedIface<Firebird::IRoutineMetadataImpl<RoutineMetadata, Firebird::CheckStatusWrapper> >,
|
2013-01-29 02:21:32 +01:00
|
|
|
public Firebird::PermanentStorage
|
2011-05-15 17:37:11 +02:00
|
|
|
{
|
|
|
|
public:
|
2011-06-24 08:34:16 +02:00
|
|
|
explicit RoutineMetadata(MemoryPool& pool)
|
2011-05-15 17:37:11 +02:00
|
|
|
: PermanentStorage(pool),
|
|
|
|
package(pool),
|
|
|
|
name(pool),
|
|
|
|
entryPoint(pool),
|
|
|
|
body(pool),
|
|
|
|
triggerTable(pool),
|
2014-09-29 13:03:47 +02:00
|
|
|
triggerType(0)
|
2011-05-15 17:37:11 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
const char* getPackage(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-05-15 17:37:11 +02:00
|
|
|
{
|
|
|
|
return package.nullStr();
|
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
const char* getName(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-05-15 17:37:11 +02:00
|
|
|
{
|
|
|
|
return name.c_str();
|
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
const char* getEntryPoint(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-05-15 17:37:11 +02:00
|
|
|
{
|
|
|
|
return entryPoint.c_str();
|
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
const char* getBody(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-05-15 17:37:11 +02:00
|
|
|
{
|
|
|
|
return body.c_str();
|
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
Firebird::IMessageMetadata* getInputMetadata(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-06-01 03:44:54 +02:00
|
|
|
{
|
2013-02-17 13:08:53 +01:00
|
|
|
return getMetadata(inputParameters);
|
2011-06-01 03:44:54 +02:00
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
Firebird::IMessageMetadata* getOutputMetadata(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-06-01 03:44:54 +02:00
|
|
|
{
|
2013-02-17 13:08:53 +01:00
|
|
|
return getMetadata(outputParameters);
|
2011-06-01 03:44:54 +02:00
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
Firebird::IMessageMetadata* getTriggerMetadata(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-06-01 03:44:54 +02:00
|
|
|
{
|
2013-02-17 13:08:53 +01:00
|
|
|
return getMetadata(triggerFields);
|
2011-06-01 03:44:54 +02:00
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
const char* getTriggerTable(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-05-15 17:37:11 +02:00
|
|
|
{
|
|
|
|
return triggerTable.c_str();
|
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
unsigned getTriggerType(Firebird::CheckStatusWrapper* /*status*/) const
|
2011-05-15 17:37:11 +02:00
|
|
|
{
|
|
|
|
return triggerType;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2020-06-16 18:22:15 +02:00
|
|
|
MetaName package;
|
|
|
|
MetaName name;
|
2011-05-15 17:37:11 +02:00
|
|
|
Firebird::string entryPoint;
|
|
|
|
Firebird::string body;
|
2013-03-04 02:42:58 +01:00
|
|
|
Firebird::RefPtr<Firebird::IMessageMetadata> inputParameters;
|
|
|
|
Firebird::RefPtr<Firebird::IMessageMetadata> outputParameters;
|
|
|
|
Firebird::RefPtr<Firebird::IMessageMetadata> triggerFields;
|
2020-06-16 18:22:15 +02:00
|
|
|
MetaName triggerTable;
|
2014-09-29 13:03:47 +02:00
|
|
|
unsigned triggerType;
|
2013-02-17 13:08:53 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
static Firebird::IMessageMetadata* getMetadata(const Firebird::IMessageMetadata* par)
|
|
|
|
{
|
|
|
|
Firebird::IMessageMetadata* rc = const_cast<Firebird::IMessageMetadata*>(par);
|
|
|
|
rc->addRef();
|
|
|
|
return rc;
|
|
|
|
}
|
2011-05-15 17:37:11 +02:00
|
|
|
};
|
|
|
|
|
2015-01-15 02:17:27 +01:00
|
|
|
class ExternalContextImpl :
|
|
|
|
public Firebird::VersionedIface<Firebird::IExternalContextImpl<ExternalContextImpl, Firebird::CheckStatusWrapper> >
|
2009-10-21 02:42:38 +02:00
|
|
|
{
|
|
|
|
friend class AttachmentImpl;
|
|
|
|
|
|
|
|
public:
|
2014-09-29 13:03:47 +02:00
|
|
|
ExternalContextImpl(thread_db* tdbb, Firebird::IExternalEngine* aEngine);
|
2009-10-21 02:42:38 +02:00
|
|
|
virtual ~ExternalContextImpl();
|
|
|
|
|
|
|
|
void releaseTransaction();
|
|
|
|
void setTransaction(thread_db* tdbb);
|
|
|
|
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IMaster* getMaster();
|
2015-01-12 01:21:38 +01:00
|
|
|
Firebird::IExternalEngine* getEngine(Firebird::CheckStatusWrapper* status);
|
|
|
|
Firebird::IAttachment* getAttachment(Firebird::CheckStatusWrapper* status);
|
|
|
|
Firebird::ITransaction* getTransaction(Firebird::CheckStatusWrapper* status);
|
2014-09-29 13:03:47 +02:00
|
|
|
const char* getUserName();
|
|
|
|
const char* getDatabaseName();
|
2014-11-10 15:45:40 +01:00
|
|
|
const char* getClientCharSet();
|
2014-09-29 13:03:47 +02:00
|
|
|
int obtainInfoCode();
|
|
|
|
void* getInfo(int code);
|
|
|
|
void* setInfo(int code, void* value);
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
private:
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalEngine* engine;
|
2009-10-21 02:42:38 +02:00
|
|
|
Attachment* internalAttachment;
|
2017-10-26 17:13:41 +02:00
|
|
|
Firebird::ITransaction* internalTransaction;
|
2011-05-07 21:52:44 +02:00
|
|
|
Firebird::IAttachment* externalAttachment;
|
|
|
|
Firebird::ITransaction* externalTransaction;
|
2009-10-21 02:42:38 +02:00
|
|
|
Firebird::GenericMap<Firebird::NonPooled<int, void*> > miscInfo;
|
2020-06-16 18:22:15 +02:00
|
|
|
MetaName clientCharSet;
|
2009-10-21 02:42:38 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct EngineAttachment
|
|
|
|
{
|
2014-09-29 13:03:47 +02:00
|
|
|
EngineAttachment(Firebird::IExternalEngine* aEngine, Jrd::Attachment* aAttachment)
|
2009-10-21 02:42:38 +02:00
|
|
|
: engine(aEngine),
|
|
|
|
attachment(aAttachment)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool greaterThan(const EngineAttachment& i1, const EngineAttachment& i2)
|
|
|
|
{
|
|
|
|
return (i1.engine > i2.engine) ||
|
|
|
|
(i1.engine == i2.engine && i1.attachment > i2.attachment);
|
|
|
|
}
|
|
|
|
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalEngine* engine;
|
2009-10-21 02:42:38 +02:00
|
|
|
Jrd::Attachment* attachment;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct EngineAttachmentInfo
|
|
|
|
{
|
|
|
|
EngineAttachmentInfo()
|
|
|
|
: engine(NULL),
|
2009-10-30 11:50:59 +01:00
|
|
|
context(NULL),
|
|
|
|
adminCharSet(0)
|
2009-10-21 02:42:38 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalEngine* engine;
|
2009-10-21 02:42:38 +02:00
|
|
|
Firebird::AutoPtr<ExternalContextImpl> context;
|
|
|
|
USHORT adminCharSet;
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
2023-03-22 15:07:02 +01:00
|
|
|
class ExtRoutine
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ExtRoutine(thread_db* tdbb, ExtEngineManager* aExtManager,
|
|
|
|
Firebird::IExternalEngine* aEngine, RoutineMetadata* aMetadata);
|
|
|
|
|
2023-10-18 10:46:57 +02:00
|
|
|
private:
|
|
|
|
class PluginDeleter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void operator()(Firebird::IPluginBase* ptr);
|
|
|
|
};
|
|
|
|
|
2023-03-22 15:07:02 +01:00
|
|
|
protected:
|
|
|
|
ExtEngineManager* extManager;
|
2023-10-18 10:46:57 +02:00
|
|
|
std::unique_ptr<Firebird::IExternalEngine, PluginDeleter> engine;
|
2023-03-22 15:07:02 +01:00
|
|
|
Firebird::AutoPtr<RoutineMetadata> metadata;
|
|
|
|
Database* database;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Function : public ExtRoutine
|
2009-10-21 02:42:38 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
Function(thread_db* tdbb, ExtEngineManager* aExtManager,
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalEngine* aEngine,
|
2011-05-15 17:37:11 +02:00
|
|
|
RoutineMetadata* aMetadata,
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalFunction* aFunction,
|
2009-12-21 18:43:01 +01:00
|
|
|
const Jrd::Function* aUdf);
|
2009-10-21 02:42:38 +02:00
|
|
|
~Function();
|
|
|
|
|
2011-06-01 03:44:54 +02:00
|
|
|
void execute(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg) const;
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
private:
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalFunction* function;
|
2009-12-21 18:43:01 +01:00
|
|
|
const Jrd::Function* udf;
|
2009-10-21 02:42:38 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class ResultSet;
|
|
|
|
|
2023-03-22 15:07:02 +01:00
|
|
|
class Procedure : public ExtRoutine
|
2009-10-21 02:42:38 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
Procedure(thread_db* tdbb, ExtEngineManager* aExtManager,
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalEngine* aEngine,
|
2011-05-15 17:37:11 +02:00
|
|
|
RoutineMetadata* aMetadata,
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalProcedure* aProcedure,
|
2009-10-21 02:42:38 +02:00
|
|
|
const jrd_prc* aPrc);
|
|
|
|
~Procedure();
|
|
|
|
|
2011-06-01 03:44:54 +02:00
|
|
|
ResultSet* open(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg) const;
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
private:
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalProcedure* procedure;
|
2009-10-21 02:42:38 +02:00
|
|
|
const jrd_prc* prc;
|
|
|
|
|
|
|
|
friend class ResultSet;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ResultSet
|
|
|
|
{
|
|
|
|
public:
|
2011-06-01 03:44:54 +02:00
|
|
|
ResultSet(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg, const Procedure* aProcedure);
|
2009-10-21 02:42:38 +02:00
|
|
|
~ResultSet();
|
|
|
|
|
|
|
|
bool fetch(thread_db* tdbb);
|
|
|
|
|
|
|
|
private:
|
2009-12-27 23:05:22 +01:00
|
|
|
const Procedure* procedure;
|
2011-05-09 12:15:19 +02:00
|
|
|
Attachment* attachment;
|
2009-10-21 02:42:38 +02:00
|
|
|
bool firstFetch;
|
|
|
|
EngineAttachmentInfo* attInfo;
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalResultSet* resultSet;
|
2009-10-21 02:42:38 +02:00
|
|
|
USHORT charSet;
|
|
|
|
};
|
|
|
|
|
2023-03-22 15:07:02 +01:00
|
|
|
class Trigger : public ExtRoutine
|
2009-10-21 02:42:38 +02:00
|
|
|
{
|
|
|
|
public:
|
2019-01-21 16:06:01 +01:00
|
|
|
Trigger(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, ExtEngineManager* aExtManager,
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalEngine* aEngine, RoutineMetadata* aMetadata,
|
|
|
|
Firebird::IExternalTrigger* aTrigger, const Jrd::Trigger* aTrg);
|
2009-10-21 02:42:38 +02:00
|
|
|
~Trigger();
|
|
|
|
|
2022-02-13 14:51:30 +01:00
|
|
|
void execute(thread_db* tdbb, Request* request, unsigned action,
|
2010-10-12 13:36:51 +02:00
|
|
|
record_param* oldRpb, record_param* newRpb) const;
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
private:
|
2019-01-21 16:06:01 +01:00
|
|
|
void setupComputedFields(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb);
|
2022-02-13 14:51:30 +01:00
|
|
|
void setValues(thread_db* tdbb, Request* request, Firebird::Array<UCHAR>& msgBuffer, record_param* rpb) const;
|
2009-10-21 02:42:38 +02:00
|
|
|
|
2019-01-21 16:06:01 +01:00
|
|
|
public:
|
|
|
|
Firebird::Array<NestConst<StmtNode>> computedStatements;
|
|
|
|
|
|
|
|
private:
|
2013-01-29 02:21:32 +01:00
|
|
|
Firebird::AutoPtr<Format> format;
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalTrigger* trigger;
|
2009-10-21 02:42:38 +02:00
|
|
|
const Jrd::Trigger* trg;
|
2013-01-29 02:21:32 +01:00
|
|
|
Firebird::Array<USHORT> fieldsPos;
|
2019-01-21 16:06:01 +01:00
|
|
|
Firebird::Array<const DeclareVariableNode*> varDecls;
|
|
|
|
USHORT computedCount;
|
2009-10-21 02:42:38 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
2018-05-25 18:06:30 +02:00
|
|
|
explicit ExtEngineManager(MemoryPool& p);
|
2009-10-21 02:42:38 +02:00
|
|
|
~ExtEngineManager();
|
|
|
|
|
|
|
|
public:
|
|
|
|
static void initialize();
|
|
|
|
|
|
|
|
public:
|
|
|
|
void closeAttachment(thread_db* tdbb, Attachment* attachment);
|
|
|
|
|
2013-04-11 17:44:17 +02:00
|
|
|
void makeFunction(thread_db* tdbb, CompilerScratch* csb, Jrd::Function* udf,
|
2020-06-16 18:22:15 +02:00
|
|
|
const MetaName& engine, const Firebird::string& entryPoint,
|
2013-03-04 02:42:58 +01:00
|
|
|
const Firebird::string& body);
|
2013-04-11 17:44:17 +02:00
|
|
|
void makeProcedure(thread_db* tdbb, CompilerScratch* csb, jrd_prc* prc,
|
2020-06-16 18:22:15 +02:00
|
|
|
const MetaName& engine, const Firebird::string& entryPoint,
|
2013-03-04 02:42:58 +01:00
|
|
|
const Firebird::string& body);
|
2013-04-11 17:44:17 +02:00
|
|
|
void makeTrigger(thread_db* tdbb, CompilerScratch* csb, Jrd::Trigger* trg,
|
2020-06-16 18:22:15 +02:00
|
|
|
const MetaName& engine, const Firebird::string& entryPoint,
|
2014-09-29 13:03:47 +02:00
|
|
|
const Firebird::string& body, unsigned type);
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
private:
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalEngine* getEngine(thread_db* tdbb,
|
2020-06-16 18:22:15 +02:00
|
|
|
const MetaName& name);
|
2009-10-21 02:42:38 +02:00
|
|
|
EngineAttachmentInfo* getEngineAttachment(thread_db* tdbb,
|
2020-06-16 18:22:15 +02:00
|
|
|
const MetaName& name);
|
2009-10-21 02:42:38 +02:00
|
|
|
EngineAttachmentInfo* getEngineAttachment(thread_db* tdbb,
|
2014-09-29 13:03:47 +02:00
|
|
|
Firebird::IExternalEngine* engine, bool closing = false);
|
|
|
|
void setupAdminCharSet(thread_db* tdbb, Firebird::IExternalEngine* engine,
|
2009-11-14 23:21:11 +01:00
|
|
|
EngineAttachmentInfo* attInfo);
|
2009-10-21 02:42:38 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
typedef Firebird::GenericMap<Firebird::Pair<
|
2020-06-16 18:22:15 +02:00
|
|
|
Firebird::Left<MetaName, Firebird::IExternalEngine*> > > EnginesMap;
|
2009-10-21 02:42:38 +02:00
|
|
|
typedef Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<
|
|
|
|
EngineAttachment, EngineAttachmentInfo*> >, EngineAttachment> EnginesAttachmentsMap;
|
|
|
|
|
|
|
|
Firebird::RWLock enginesLock;
|
|
|
|
EnginesMap engines;
|
|
|
|
EnginesAttachmentsMap enginesAttachments;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace Jrd
|
|
|
|
|
|
|
|
#endif // JRD_EXT_ENGINE_MANAGER_H
|