Files
secondo/Algebras/DBService/DerivationClient.cpp

168 lines
5.2 KiB
C++
Raw Permalink Normal View History

2026-01-23 17:03:45 +08:00
/*
----
This file is part of SECONDO.
Copyright (C) 2017,
Faculty of Mathematics and Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
1 Implementation of class DerivationClient
*/
#include "Algebras/DBService/DerivationClient.hpp"
#include "Algebras/DBService/MetadataObject.hpp"
#include "Algebras/DBService/SecondoUtilsLocal.hpp"
#include "Algebras/DBService/CommunicationClient.hpp"
#include "Algebras/DBService/DebugOutput.hpp"
#include "Algebras/DBService/ReplicationUtils.hpp"
#include "SecondoSystem.h"
#include "NestedList.h"
#include "ListUtils.h"
#include "QueryProcessor.h"
namespace DBService{
DerivationClient::DerivationClient(
const std::string& _DBName,
const std::string& _targetName,
const std::string& _relName,
const std::string& _fundef): DBName(_DBName), targetName(_targetName),
relName(_relName), fundef(_fundef){
printFunction(__PRETTY_FUNCTION__, std::cout);
relIdOnWorker = ReplicationUtils::getRelNameOnDBServiceWorker(DBName,
relName);
rid = RelationInfo::getIdentifier(DBName, relName);
targetId = DerivateInfo::getIdentifier(rid, targetName);
}
void DerivationClient::start() {
printFunction(__PRETTY_FUNCTION__, std::cout);
try{
SecondoCatalog* ctlg = SecondoSystem::GetCatalog();
// some basic checks
if(ctlg->IsObjectName(targetId)){
derivationFailed("target " + targetName + " already exists");
return;
}
if(!ctlg->IsObjectName(relIdOnWorker)){
derivationFailed("argument relation " + relName + " does not exist");
return;
}
// convert function string into nested list
// and check for valid format
ListExpr funlist;
if(!nl->ReadFromString(fundef, funlist)){
derivationFailed("cannot parse function definition");
return;
}
if(!nl->HasLength(funlist,3)){
derivationFailed("invalid function description");
return;
}
ListExpr funarg = nl->Second(funlist);
if(!nl->HasLength(funarg,2)){
derivationFailed("invalid function description");
return;
}
ListExpr argNameL = nl->First(funarg);
if(nl->AtomType(argNameL)!=SymbolType){
derivationFailed("invalid argument name");
}
// replace the argument's name in the function
// definition by the relation's id
std::string argName = nl->SymbolValue(argNameL);
ListExpr fundeflist = nl->Third(funlist);
ListExpr relSymb = nl->SymbolAtom(relIdOnWorker);
fundeflist = listutils::replaceSymbol(fundeflist,argName, relSymb,nl);
// try to evaluate the function
Word QueryResult;
std::string typeString, errorString;
bool correct, evaluable, defined, isFunction;
SecondoSystem::BeginTransaction();
try{
QueryProcessor::ExecuteQuery(fundeflist, QueryResult, typeString,
errorString, correct,
evaluable,defined, isFunction);
} catch(...){
correct = false;
errorString = "exception during executeQuery";
}
if(!correct){
derivationFailed(errorString);
return;
}
// insert result into the database
ListExpr typeExpr;
nl->ReadFromString(typeString, typeExpr);
if(!ctlg->InsertObject(targetId, "",typeExpr, QueryResult, true)) {
derivationFailed("could not insert target object");
return;
}
ctlg->CleanUp(false,true);
SecondoSystem::CommitTransaction(true);
// report success of operation
derivationSuccessful();
} catch(...){
derivationFailed("Exception during start function");
}
}
void DerivationClient::derivationFailed(const std::string& error){
print("derivation failed: " + error, std::cout);
}
void DerivationClient::derivationSuccessful(){
printFunction(__PRETTY_FUNCTION__, std::cout);
std::string dbServiceHost;
std::string dbServicePort;
if(!SecondoUtilsLocal::lookupDBServiceLocation(
dbServiceHost,
dbServicePort))
{
print("Error during lookupDBServiceLocation", std::cout);
throw new SecondoException("Unable to connect to DBService");
}
CommunicationClient clientToDBServiceMaster(
dbServiceHost,
atoi(dbServicePort.c_str()),
0);
clientToDBServiceMaster.reportSuccessfulDerivation(
targetId);
print("derivationSuccessful reported", std::cout);
}
}