void ExtEngineManager::makeProcedure(thread_db* tdbb, CompilerScratch* csb, jrd_prc* prc, const MetaName& engine, const string& entryPoint, const string& body) { string entryPointTrimmed = entryPoint; entryPointTrimmed.trim(); EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine); ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, attInfo->adminCharSet, (prc->getName().package.isEmpty() ? CallerName(obj_procedure, prc->getName().identifier) : CallerName(obj_package_header, prc->getName().package))); ///MemoryPool& pool = *tdbb->getDefaultPool(); MemoryPool& pool = *getDefaultMemoryPool(); AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool)); metadata->package = prc->getName().package; metadata->name = prc->getName().identifier; metadata->entryPoint = entryPointTrimmed; metadata->body = body; metadata->inputParameters = Routine::createMetadata(prc->getInputFields()); metadata->outputParameters = Routine::createMetadata(prc->getOutputFields()); LocalStatus status; RefPtr<IMetadataBuilder> inBuilder(REF_NO_INCR, metadata->inputParameters->getBuilder(&status)); status.check(); RefPtr<IMetadataBuilder> outBuilder(REF_NO_INCR, metadata->outputParameters->getBuilder(&status)); status.check(); ExternalProcedure* externalProcedure; { // scope Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalProcedure = attInfo->engine->makeProcedure(&status, attInfo->context, metadata, inBuilder, outBuilder); status.check(); if (!externalProcedure) { status_exception::raise( Arg::Gds(isc_eem_proc_not_returned) << prc->getName().toString() << engine); } metadata->inputParameters = inBuilder->getMetadata(&status); status.check(); metadata->outputParameters = outBuilder->getMetadata(&status); status.check(); } prc->setInputFormat(Routine::createFormat(pool, metadata->inputParameters, false)); prc->setOutputFormat(Routine::createFormat(pool, metadata->outputParameters, true)); try { prc->setExternal(FB_NEW(getPool()) Procedure(tdbb, this, attInfo->engine, metadata.release(), externalProcedure, prc)); CompoundStmtNode* mainNode = FB_NEW(getPool()) CompoundStmtNode(getPool()); ExtMessageNode* inMessageNode = prc->getInputFields().hasData() ? FB_NEW(getPool()) ExtMessageNode(tdbb, getPool(), csb, 0, prc->getInputFields(), prc->getInputFormat()) : NULL; if (inMessageNode) mainNode->statements.add(inMessageNode); ExtMessageNode* outMessageNode = FB_NEW(getPool()) ExtMessageNode(tdbb, getPool(), csb, 1, prc->getOutputFields(), prc->getOutputFormat()); mainNode->statements.add(outMessageNode); ExtInitOutputNode* initOutputNode = FB_NEW(getPool()) ExtInitOutputNode( tdbb, getPool(), csb, outMessageNode); mainNode->statements.add(initOutputNode); ReceiveNode* receiveNode = inMessageNode ? FB_NEW(getPool()) ReceiveNode(getPool()) : NULL; if (inMessageNode) { receiveNode->message = inMessageNode; receiveNode->statement = FB_NEW(getPool()) ExtValidationNode( getPool(), inMessageNode, true, true); mainNode->statements.add(receiveNode); } ExtProcedureNode* extProcedureNode = FB_NEW(getPool()) ExtProcedureNode(getPool(), receiveNode, prc->getExternal()); mainNode->statements.add(extProcedureNode); extProcedureNode->message = outMessageNode; extProcedureNode->statement = FB_NEW(getPool()) ExtValidationNode( getPool(), outMessageNode, true, false); JrdStatement* statement = prc->getStatement(); PAR_preparsed_node(tdbb, NULL, mainNode, NULL, &csb, &statement, false, 0); prc->setStatement(statement); } catch (...) { Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalProcedure->dispose(); throw; } }
void ExtEngineManager::makeProcedure(thread_db* tdbb, jrd_prc* prc, const MetaName& engine, const string& entryPoint, const string& body) { string entryPointTrimmed = entryPoint; entryPointTrimmed.trim(); EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine); ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, attInfo->adminCharSet, (prc->getName().package.isEmpty() ? CallerName(obj_procedure, prc->getName().identifier) : CallerName(obj_package_header, prc->getName().package))); ///MemoryPool& pool = *tdbb->getDefaultPool(); MemoryPool& pool = *getDefaultMemoryPool(); AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool)); metadata->package = prc->getName().package; metadata->name = prc->getName().identifier; metadata->entryPoint = entryPointTrimmed; metadata->body = body; metadata->inputParameters = Routine::createMetadata(prc->getInputFields()); metadata->outputParameters = Routine::createMetadata(prc->getOutputFields()); LocalStatus status; RefPtr<IMetadataBuilder> inBuilder(metadata->inputParameters->getBuilder(&status)); status.check(); inBuilder->release(); RefPtr<IMetadataBuilder> outBuilder(metadata->outputParameters->getBuilder(&status)); status.check(); outBuilder->release(); ExternalProcedure* externalProcedure; { // scope Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalProcedure = attInfo->engine->makeProcedure(&status, attInfo->context, metadata, inBuilder, outBuilder); status.check(); if (!externalProcedure) { status_exception::raise( Arg::Gds(isc_eem_proc_not_returned) << prc->getName().toString() << engine); } metadata->inputParameters = inBuilder->getMetadata(&status); status.check(); metadata->outputParameters = outBuilder->getMetadata(&status); status.check(); } try { prc->setInputFormat(Routine::createFormat(pool, metadata->inputParameters, false)); prc->setOutputFormat(Routine::createFormat(pool, metadata->outputParameters, false)); prc->setExternal(FB_NEW(getPool()) Procedure(tdbb, this, attInfo->engine, metadata.release(), externalProcedure, prc)); } catch (...) { Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalProcedure->dispose(); throw; } }