Files
secondo/Algebras/ContinuousQueries/foreverQueries.cpp

547 lines
16 KiB
C++
Raw Normal View History

2026-01-23 17:03:45 +08:00
/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of 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
----
//paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}]
//characters [1] Type: [] []
//characters [2] Type: [] []
//[ae] [\"{a}]
//[oe] [\"{o}]
//[ue] [\"{u}]
//[ss] [{\ss}]
//[Ae] [\"{A}]
//[Oe] [\"{O}]
//[Ue] [\"{U}]
//[x] [$\times $]
//[->] [$\rightarrow $]
//[toc] [\tableofcontents]
[1] Implementation of operation foreverQueries.
[toc]
1 Operation foreverQueries implementation
Produces an optionally never ending stream of tuples of the
format...
*/
#include "Algebras/Relation-C++/RelationAlgebra.h"
#include "Stream.h"
#include "QueryProcessor.h"
#include "ListUtils.h"
#include "Algebras/FText/FTextAlgebra.h"
#include "sha1.hpp"
#include "SecParser.h"
#include "Protocols.h"
#include "ForeverHelper.h"
#include "Tcp/TcpClient.h"
#include <thread>
#include <chrono>
#include <boost/algorithm/string.hpp>
extern NestedList* nl;
extern QueryProcessor* qp;
extern AlgebraManager* am;
namespace continuousqueries {
/*
1.1 Operation foreverQueries TypeMapping
*/
ListExpr foreverQueries_TM(ListExpr args) {
std::cout << "foreverQueries: TypeMapping" << endl;
std::cout << "Argument: " << nl->ToString(args) << endl;
// Check for text x int x text x int x int -> text
if (!nl->HasLength(args, 5))
return listutils::typeError(" five arguments are expected");
ListExpr arg1Type = nl->First(args);
ListExpr arg2Type = nl->Second(args);
ListExpr arg3Type = nl->Third(args);
ListExpr arg4Type = nl->Fourth(args);
ListExpr arg5Type = nl->Fifth(args);
// Check first argument (address/text)
if (!nl->HasLength(arg1Type, 2))
return listutils::typeError(" internal error (address) ");
if (!FText::checkType(nl->First(arg1Type)))
return listutils::typeError(" address as text is expected");
// Check second argument (valid portnumber/int)
if (!nl->HasLength(arg2Type, 2))
return listutils::typeError(" internal error (portnumber) ");
if(!CcInt::checkType(nl->First(arg2Type)))
return listutils::typeError(" portnummer not an CcInt ");
if(!listutils::isNumeric(nl->Second(arg2Type)))
return listutils::typeError(
" portnumber can't be converted to numeric "
);
if(listutils::getNumValue(nl->Second(arg2Type)) < 0 ||
listutils::getNumValue(nl->Second(arg2Type)) > 65535 )
return listutils::typeError(
" portnumber between 0 and 65535 expected "
);
// Check third argument (email/text)
if (!nl->HasLength(arg3Type, 2))
return listutils::typeError(" internal error (email) ");
if (!FText::checkType(nl->First(arg3Type)))
return listutils::typeError(" email as text is expected");
// Check fourth argument (volume/int)
if (!nl->HasLength(arg4Type, 2))
return listutils::typeError(" internal error (volume) ");
if(!CcInt::checkType(nl->First(arg4Type)))
return listutils::typeError(" volume not an CcInt ");
if(!listutils::isNumeric(nl->Second(arg4Type)))
return listutils::typeError(
" volume can't be converted to numeric "
);
if(listutils::getNumValue(nl->Second(arg4Type)) < 0)
return listutils::typeError(
" volume greater or equal 0 expected "
);
// Check fifth argument (type/int)
if (!nl->HasLength(arg5Type, 2))
return listutils::typeError(" internal error (type) ");
if(!CcInt::checkType(nl->First(arg5Type)))
return listutils::typeError(" type not an CcInt ");
if(!listutils::isNumeric(nl->Second(arg5Type)))
return listutils::typeError(
" type can't be converted to numeric "
);
if(listutils::getNumValue(nl->Second(arg5Type)) < 0 ||
listutils::getNumValue(nl->Second(arg5Type)) > 3 )
return listutils::typeError(
" type should between 0 and 3 "
);
return arg1Type;
}
class foreverQueries_LI {
public:
foreverQueries_LI(int volume, int type):
_volume(volume), _type(type), _count(1), _currentTuple(1001)
{
}
~foreverQueries_LI()
{}
bool refreshRelation()
{
std::string exestring = "";
Word exeword;
if(_type==0||_type==2) exestring="(consume (foreverStream 1000 2 20))";
if(_type==1||_type==3) exestring="(consume (foreverStream 1000 3 20))";
if (!QueryProcessor::ExecuteQuery(exestring, exeword)) return false;
_result = (Relation*) exeword.addr;
return true;
}
std::string getNext()
{
if (_volume && (_count > _volume)) return "";
if (_currentTuple == 1001)
{
if (!refreshRelation()) return "error";
_currentTuple = 1;
}
Tuple* currentTuple = _result->GetTuple(_currentTuple, true);
std::string query = "";
if (_type == 0)
{
std::string parts[3];
parts[0] = "";
parts[1] = "";
parts[2] = "";
int count = 0;
if (currentTuple->GetAttribute(0)->toText() != "-")
{
parts[count] = "(=(attr t I)" + currentTuple
->GetAttribute(0)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(1)->toText() != "-")
{
parts[count] = "(>(attr t I)" + currentTuple
->GetAttribute(1)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(2)->toText() != "-")
{
parts[count] = "(<(attr t I)" + currentTuple
->GetAttribute(2)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(3)->toText() != "-")
{
parts[count] = "(=(attr t S)\"" + currentTuple
->GetAttribute(3)->toText() + "\")";
count++;
}
if (count == 1)
query = "(fun(t(tuple((I int)(S string))))" + parts[0] + ")";
if (count == 2)
query = "(fun(t(tuple((I int)(S string))))(and"
+ parts[0] + parts[1] + "))";
if (count == 3)
query = "(fun(t(tuple((I int)(S string))))(and"
+ parts[0] + "(and" + parts[1] + parts[2] + ")))";
}
if (_type == 1)
{
std::string parts[3];
parts[0] = "";
parts[1] = "";
parts[2] = "";
int count = 0;
if (currentTuple->GetAttribute(1)->toText() != "-")
{
parts[count] = "(=(attr t City)\"" + currentTuple
->GetAttribute(1)->toText() + "\")";
count++;
}
if (currentTuple->GetAttribute(2)->toText() != "-")
{
parts[count] = "(=(attr t Month)\"" + currentTuple
->GetAttribute(2)->toText() + "\")";
count++;
}
if (currentTuple->GetAttribute(3)->toText() != "-")
{
parts[count] = "(=(attr t Number)" + currentTuple
->GetAttribute(3)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(4)->toText() != "-")
{
parts[count] = "(>(attr t Number)" + currentTuple
->GetAttribute(4)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(5)->toText() != "-")
{
parts[count] = "(<(attr t Number)" + currentTuple
->GetAttribute(5)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(6)->toText() != "-")
{
parts[count] = "(=(attr t Fraction)" + currentTuple
->GetAttribute(6)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(7)->toText() != "-")
{
parts[count] = "(>(attr t Fraction)" + currentTuple
->GetAttribute(7)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(8)->toText() != "-")
{
parts[count] = "(<(attr t Fraction)" + currentTuple
->GetAttribute(8)->toText() + ")";
count++;
}
if (currentTuple->GetAttribute(9)->toText() != "-")
{
parts[count] = "(=(attr t Valid)" + boost::to_upper_copy(
currentTuple->GetAttribute(9)->toText()) + ")";
count++;
}
if (count == 0) {
count = 1;
parts[0] = "(=(attr t City)\""
+ ForeverHelper::getBigString() + "\")";
}
if (count == 1)
query = "(fun(t(tuple((Id string)(City string)(Month string)"
"(Number int)(Fraction real)(Valid bool))))"
+ parts[0] + ")";
if (count == 2)
query = "(fun(t(tuple((Id string)(City string)(Month string)"
"(Number int)(Fraction real)(Valid bool))))(and"
+ parts[0] + parts[1] + "))";
if (count == 3)
query = "(fun(t(tuple((Id string)(City string)(Month string)"
"(Number int)(Fraction real)(Valid bool))))(and"
+ parts[0] + "(and" + parts[1] + parts[2] + ")))";
}
if (_type == 2)
{
query += "(";
if (currentTuple->GetAttribute(0)->toText() != "-")
query += "(I_eq " + currentTuple->GetAttribute(0)
->toText() + ")";
if (currentTuple->GetAttribute(1)->toText() != "-")
query += "(I_gt " + currentTuple->GetAttribute(1)
->toText() + ")";
if (currentTuple->GetAttribute(2)->toText() != "-")
query += "(I_lt " + currentTuple->GetAttribute(2)
->toText() + ")";
if (currentTuple->GetAttribute(3)->toText() != "-")
query += "(S_eq \"" + currentTuple
->GetAttribute(3)->toText() + "\")";
query += ")";
}
if (_type == 3)
{
query += "(";
if (currentTuple->GetAttribute(1)->toText() != "-")
query += "(City_eq \"" + currentTuple
->GetAttribute(1)->toText() + "\")";
if (currentTuple->GetAttribute(2)->toText() != "-")
query += "(Month_eq \"" + currentTuple
->GetAttribute(2)->toText() + "\")";
if (currentTuple->GetAttribute(3)->toText() != "-")
query += "(Number_eq " + currentTuple
->GetAttribute(3)->toText() + ")";
if (currentTuple->GetAttribute(4)->toText() != "-")
query += "(Number_gt " + currentTuple
->GetAttribute(4)->toText() + ")";
if (currentTuple->GetAttribute(5)->toText() != "-")
query += "(Number_lt " + currentTuple
->GetAttribute(5)->toText() + ")";
if (currentTuple->GetAttribute(6)->toText() != "-")
query += "(Fraction_eq " + currentTuple
->GetAttribute(6)->toText() + ")";
if (currentTuple->GetAttribute(7)->toText() != "-")
query += "(Fraction_gt " + currentTuple
->GetAttribute(7)->toText() + ")";
if (currentTuple->GetAttribute(8)->toText() != "-")
query += "(Fraction_lt " + currentTuple
->GetAttribute(8)->toText() + ")";
if (currentTuple->GetAttribute(9)->toText() != "-")
query += "(Valid_eq " + boost::to_upper_copy(
currentTuple->GetAttribute(9)->toText()) + ")";
query += ")";
}
// if the test was only on the QID, test instead on the city.
if (query.length() == 2)
query = "((City_eq \"" + ForeverHelper::getBigString() + "\"))";
if (_volume) _count++;
_currentTuple++;
return query;
}
int _volume;
int _type;
int _count;
int _currentTuple;
Relation* _result;
};
/*
1.2 Operation foreverQueries ValueMappings
*/
int foreverQueries_VM( Word* args, Word& result, int message,
Word& local, Supplier s )
{
std::cout << "foreverQueries: ValueMapping" << endl;
FText* ftaddress = static_cast<FText*>(args[0].addr);
CcInt* ccport = (CcInt*) args[1].addr;
FText* ftemail = static_cast<FText*>(args[2].addr);
CcInt* ccvolume = (CcInt*) args[3].addr;
CcInt* cctype = (CcInt*) args[4].addr;
foreverQueries_LI* li = new foreverQueries_LI(
ccvolume->GetValue(),
cctype->GetValue()
);
SHA1 sha;
sha.update(ftemail->GetValue() + "password");
std::string hash = sha.final();
// create tcp client for coordinator
TcpClient client(ftaddress->GetValue(), ccport->GetValue());
client.Initialize();
// register user
client.Send(CoordinatorGenP::userauth() + "|" + hash + "|"
+ ftemail->GetValue() + "|register");
std::cout << endl << "Log in to the webinterface with username '"
<< ftemail->GetValue() << "' and password 'password'." << endl;
std::string lastQuery = "";
std::string newQuery = "";
newQuery = li->getNext();
while (newQuery != "")
{
lastQuery = newQuery;
client.Send(CoordinatorGenP::addquery(0, "", false) + "|" + hash
+ "|" + newQuery);
std::cout << "Added Query: " << newQuery << endl;
newQuery = li->getNext();
if (newQuery!="")
{
std::cout << "Now waiting for 20 milliseconds..." << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
} // repeat until li yields ""
std::cout << "All done!" << endl;
client.Shutdown();
result = qp->ResultStorage(s);
FText* res = (FText*) result.addr;
res->Set(true, lastQuery);
delete li;
return 0;
}
/*
1.3 Operation foreverQueries operator selection array
*/
ValueMapping foreverQueries[] = {
foreverQueries_VM
};
/*
1.4 Operation foreverQueries operator selection
*/
int foreverQueries_Select(ListExpr args) {
return 0;
}
/*
1.5 Operation foreverQueries operator specification
*/
const std::string foreverQueriesOpSpec =
"( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) "
"( <text>text x int x text x int x int -> text</text--->"
"<text>foreverQueries ( _, _, _, _, _ )</text--->"
"<text>(address, port, email, volume (0->infinite), type)"
" Creates an (optionally) infinite number of user"
" queries for the Secondo Stream Processor. Two tuple "
"variants implemented. To see the queries in the web inter"
"face log in with the specified email and the password 'pa"
"ssword'. Returns the last added query.</text--->"
"<text>query foreverQueries('127.0.0.1', 12300, "
"'test-ssp@mailinator.com', 5, 1);</text--->"
") )";
/*
1.6 Operation foreverQueries
*/
Operator foreverQueries_Op(
"foreverQueries",
foreverQueriesOpSpec,
1,
foreverQueries,
foreverQueries_Select,
foreverQueries_TM
);
} /* end of namespace */