Пример #1
0
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;
	}
}
Пример #2
0
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;
	}
}