Linguaggio C++ per la modellazione e il dimensionamento
Questo esempio utilizza il seguente nome di file: 'shaper.cpp
Codice
#include <nzaefactory.hpp>
using namespace nz::ae;
static int run(nz::ae::NzaeFunction *aeFunc);
static int doShaper(nz::ae::NzaeShaper *aeShaper);
int main(int argc, char * argv[])
{
NzaeApiGenerator helper;
// The following line is only needed if a launcher is not used
helper.setName("testcapi");
int i = 0;
while (i < 1) {
nz::ae::NzaeApi &api = helper.getApi(nz::ae::NzaeApi::ANY);
if (api.apiType == nz::ae::NzaeApi::FUNCTION) {
run(api.aeFunction);
i++;
}
else {
doShaper(api.aeShaper);
}
if (!helper.isRemote())
break;
}
return 0;
}
class MyHandler : public nz::ae::NzaeFunctionMessageHandler
{
public:
void evaluate(NzaeFunction& api, NzaeRecord &input, NzaeRecord &result) {
const NzaeMetadata& m = api.getMetadata();
nz::ae::NzaeField &field = input.get(0);
if (!field.isNull() ) {
nz::ae::NzaeField &f = result.get(0);
if (field.type() == NzaeDataTypes::NZUDSUDX_NUMERIC32 ||
field.type() == NzaeDataTypes::NZUDSUDX_NUMERIC64 ||
field.type() == NzaeDataTypes::NZUDSUDX_NUMERIC128)
{
NzaeNumericField &nf = (NzaeNumericField&)field;
if (m.getInputSize(0) != nf.precision() ||
m.getInputScale(0) != nf.scale()) {
NzaeNumeric128Field* np = nf.toNumeric128(38, 5);
f.assign(*np);
delete np;
}
else
f.assign(field);
}
else {
f.assign(field);
}
}
}
};
class MyHandler2 : public nz::ae::NzaeShaperMessageHandler
{
public:
void shaper(NzaeShaper& api){
const NzaeMetadata& m = api.getMetadata();
char name[2];
if (api.catalogIsUpper())
name[0] = 'I';
else
name[0] = 'i';
name[1] = 0;
if (m.getInputType(0) == NzaeDataTypes::NZUDSUDX_FIXED ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_VARIABLE ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NATIONAL_FIXED ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NATIONAL_VARIABLE) {
api.addOutputColumnString(m.getInputType(0), name,
m.getInputSize(0));
}
else if (m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NUMERIC128 ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NUMERIC64 ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NUMERIC32) {
api.addOutputColumnNumeric(m.getInputType(0), name, \
m.getInputSize(0), m.getInputScale(0));
}
else {
api.addOutputColumn(m.getInputType(0), name);
}
}
};
static int doShaper(nz::ae::NzaeShaper *aeShaper)
{
aeShaper->run(new MyHandler2());
return 0;
}
static int run(nz::ae::NzaeFunction *aeFunc)
{
aeFunc->run(new MyHandler());
return 0;
}
Si noti nel main che un oggetto API deve essere recuperato in modalità locale, che ottiene sia un'API di funzione che un'API di modellazione (anche se non allo stesso tempo). Inoltre, il codice modifica la logica del ciclo per la modalità remota in modo che lo shaper non venga incrementato, consentendo alla stessa istanza del programma di gestire sia uno shaper che una chiamata di funzione in modalità remota prima di uscire. Infine, aggiunge il gestore dei messaggi di shaper.
Compilazione
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language cpp --template compile \
--exe shaperae --compargs "-g -Wall" --linkargs "-g" shaper.cpp \
--version 3Registrazione
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "shaperae(VARARGS)" \
--return "table(ANY)" --language cpp --template udtf --exe shaperae \
--version 3$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "sizerae(VARCHAR(ANY))" \
--return "varchar(ANY)" --language cpp --template udf --exe shaperae \
--version 3In esecuzione
SELECT sizerae('test');
SIZERAE
---------
test
(1 row)
SELECT * FROM TABLE WITH FINAL(shaperae('test'));
I
------
test
(1 row)
SELECT * FROM TABLE WITH FINAL(shaperae(1.1));
I
-----
1.1
(1 row)