Fonction de tableau simple en langage C++
Cet exemple utilise le nom de fichier suivant : " split.cpp
Coder
Le code de cet exemple crée une fonction qui divise une chaîne en plusieurs chaînes en fonction du délimiteur. Cet exemple peut renvoyer plus de lignes de sortie que de lignes d'entrée. Pour cette raison, il ne peut pas utiliser le modèle de gestionnaire et nécessite une logique supplémentaire de gestion des erreurs. Notez le bloc try catch dans le main et la logique de boucle dans le run. Notez également que du code doit être fourni pour récupérer les objets d'enregistrement, éditer l'objet et supprimer les objets d'enregistrement.
#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;
}
Compilation
Utiliser la compilation standard :
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language cpp --template compile \
--exe splitae --compargs "-g -Wall" --linkargs "-g" split.cpp --version 3
Enregistrement
Enregistrer l'exécutable "
"splitae"
nouvellement créé :$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "splitae(VARCHAR(ANY))" \
--return "table(val varchar(2000))" --language cpp --template udtf \
--exe splitae --version 3
En cours d'exécution
Exécutez la requête dans 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