Funzione di tabella semplice in linguaggio C++
Questo esempio utilizza il seguente nome di file: 'split.cpp
Codice
Il codice di questo esempio crea una funzione che divide una stringa in più stringhe in base al delimitatore. Questo esempio può restituire più righe di output che di input. Per questo motivo, non può utilizzare il modello dei gestori e richiede una logica di gestione degli errori aggiuntiva. Si noti il blocco try catch nel main e la logica del ciclo in run. Si noti inoltre che è necessario fornire il codice per recuperare gli oggetti record, produrre l'oggetto e cancellare gli oggetti record.
#include <nzaefactory.hpp>
using namespace nz::ae;
using namespace std;
static int run(nz::ae::NzaeFunction *aeFunc);
int main(int argc, char * argv[])
{
NzaeApiGenerator helper;
// The following line is only needed if a launcher is not used
helper.setName("testcapi");
for (int i=0; i < 2; i++) {
nz::ae::NzaeApi &api = helper.getApi(nz::ae::NzaeApi::FUNCTION);
try {
run(api.aeFunction);
}
catch (nz::ae::NzaeException &ex) {
if (api.aeFunction) {
api.aeFunction->userError(ex.what());
}
break;
}
if (!helper.isRemote())
break;
}
return 0;
}
static void split_string(string text,char delim, vector<string>& words)
{
int i=0;
char ch;
string word;
while((ch=text[i++]))
{
if (ch == delim)
{
if (!word.empty())
{
words.push_back(word);
}
word = "";
}
else
{
word += ch;
}
}
if (!word.empty())
{
words.push_back(word);
}
}
static int run(NzaeFunction *aeFunc)
{
const NzaeMetadata& meta = aeFunc->getMetadata();
if (meta.getOutputColumnCount() != 1 ||
meta.getOutputType(0) != NzaeDataTypes::NZUDSUDX_VARIABLE) {
throw NzaeException("expecting one output column of type string");
}
if (meta.getInputColumnCount() != 1) {
throw NzaeException("expecting one input column");
}
if (meta.getInputType(0) != NzaeDataTypes::NZUDSUDX_FIXED &&
meta.getInputType(0) != NzaeDataTypes::NZUDSUDX_VARIABLE) {
throw NzaeException("first input column expected to be a string type");
}
for (;;)
{
nz::ae::NzaeRecord *input = aeFunc->next();
if (!input)
break;
nz::ae::NzaeRecord *output = aeFunc->createOutputRecord();
NzaeField &field = input->get(0);
if (field.isNull())
throw NzaeException("first input column may not be null");
NzaeStringField &sf = (NzaeStringField&) input->get(0);
std::string str = (std::string)sf;
vector<string> words;
split_string(str,',', words);
for (int i=0; i < (int)words.size(); i++) {
string tip = words[i];
NzaeStringField &sf = (NzaeStringField&) output->get(0);
sf = tip;
aeFunc->outputResult(*output);
}
delete input;
delete output;
}
aeFunc->done();
return 0;
}
Compilazione
Utilizzare la compilazione standard:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language cpp --template compile \
--exe splitae --compargs "-g -Wall" --linkargs "-g" split.cpp --version 3Registrazione
Registrare l'eseguibile '
"splitae" appena creato:$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "splitae(VARCHAR(ANY))" \
--return "table(val varchar(2000))" --language cpp --template udtf \
--exe splitae --version 3In esecuzione
Eseguire la query in nzsql:
SELECT * FROM TABLE WITH FINAL(splitae('12:30:15'));
VAL
----------
12:30:15
(1 row)
SELECT * FROM TABLE WITH FINAL(splitae('12:30:15,two,three'));
VAL
----------
12:30:15
two
three
(3 rows)
SELECT * FROM TABLE WITH FINAL(splitae(NULL));
ERROR: first input COLUMN may NOT be NULL