1378 lines
32 KiB
C++
1378 lines
32 KiB
C++
|
|
/*
|
||
|
|
----
|
||
|
|
This file is part of SECONDO.
|
||
|
|
|
||
|
|
Copyright (C) 2018,
|
||
|
|
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
|
||
|
|
----
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "Tools/DFS/dfs/remotedfs.h"
|
||
|
|
#include "Tools/DFS/dfs/dfs.h"
|
||
|
|
#include "QueryProcessor.h"
|
||
|
|
#include "NestedList.h"
|
||
|
|
#include "StandardTypes.h"
|
||
|
|
#include "ListUtils.h"
|
||
|
|
|
||
|
|
#include "Algebras/FText/FTextAlgebra.h"
|
||
|
|
#include "Algebras/Standard-C++/LongInt.h"
|
||
|
|
|
||
|
|
|
||
|
|
#include <string>
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
using namespace std;
|
||
|
|
|
||
|
|
|
||
|
|
extern QueryProcessor* qp;
|
||
|
|
extern NestedList* nl;
|
||
|
|
|
||
|
|
namespace dfsalg{
|
||
|
|
|
||
|
|
|
||
|
|
#define REMOTE_FILESYSTEM
|
||
|
|
|
||
|
|
// pointer to the currently used file system
|
||
|
|
// may be this will be changed later to an uri
|
||
|
|
#ifdef REMOTE_FILESYSTEM
|
||
|
|
static dfs::remote::RemoteFilesystem* filesystem = 0;
|
||
|
|
#else
|
||
|
|
static dfs::Filesystem* filesystem = 0;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
static dfs::log::Logger* logger = new dfs::log::DefaultOutLogger();
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
2 Operators
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.1 ~connectDFS~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr connectDFSTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,2)){
|
||
|
|
return listutils::typeError("two arguments expected");
|
||
|
|
}
|
||
|
|
ListExpr host = nl->First(args);
|
||
|
|
if(!CcString::checkType(host) && !FText::checkType(host)){
|
||
|
|
return listutils::typeError("first argument must be of type "
|
||
|
|
"string or text");
|
||
|
|
}
|
||
|
|
if(!CcInt::checkType(nl->Second(args))){
|
||
|
|
return listutils::typeError("second argument must be of type int");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
template<class T>
|
||
|
|
int connectDFSVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
|
||
|
|
// prepare result
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
|
||
|
|
// delete existing remote filesystem
|
||
|
|
if(filesystem) {
|
||
|
|
delete filesystem;
|
||
|
|
filesystem = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// check arguments
|
||
|
|
T* host = (T*) args[0].addr;
|
||
|
|
CcInt* port = (CcInt*) args[1].addr;
|
||
|
|
|
||
|
|
if(!host->IsDefined() || !port->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
stringstream ss;
|
||
|
|
ss << "dfs-index://"<<host->GetValue()<<":"<<port->GetValue();
|
||
|
|
URI uri = URI::fromString(ss.str().c_str());
|
||
|
|
filesystem = new dfs::remote::RemoteFilesystem(uri,logger);
|
||
|
|
// check whether connection is successful
|
||
|
|
bool success = false;
|
||
|
|
try{
|
||
|
|
// if there is no connection, some exception will
|
||
|
|
// be thrown by the next command
|
||
|
|
filesystem->countFiles();
|
||
|
|
success = true;
|
||
|
|
} catch(...){
|
||
|
|
success = false;
|
||
|
|
}
|
||
|
|
res->Set(true,success);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping connectDFSVM[] = {
|
||
|
|
connectDFSVMT<CcString>,
|
||
|
|
connectDFSVMT<FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int connectDFSSelect(ListExpr args){
|
||
|
|
return CcString::checkType(nl->First(args))?0:1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec connectDFSSpec(
|
||
|
|
"string x int -> bool",
|
||
|
|
"connectDFS(_)",
|
||
|
|
"Connects tto a distributed file system. Arguments are "
|
||
|
|
" hostname and port of the index node.",
|
||
|
|
" query connectDFS('localhost', 4444)"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator connectDFSOp(
|
||
|
|
"connectDFS",
|
||
|
|
connectDFSSpec.getStr(),
|
||
|
|
2,
|
||
|
|
connectDFSVM,
|
||
|
|
connectDFSSelect,
|
||
|
|
connectDFSTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.1 disconnectDFS
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr disconnectDFSTM(ListExpr args){
|
||
|
|
if(!nl->IsEmpty(args)){
|
||
|
|
return listutils::typeError("no arguments expected");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int disconnectDFSVM( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
((CcBool*) result.addr)->Set(true, filesystem!=0);
|
||
|
|
if(filesystem){
|
||
|
|
delete filesystem;
|
||
|
|
filesystem = 0;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec disconnectDFSSpec(
|
||
|
|
"-> bool",
|
||
|
|
"disconnectDFS()",
|
||
|
|
"Disconnects a distributed filesystem. Returns true "
|
||
|
|
" if there was a distributed filesystem before",
|
||
|
|
"query disconnectDFS() "
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator disconnectDFSOp(
|
||
|
|
"disconnectDFS",
|
||
|
|
disconnectDFSSpec.getStr(),
|
||
|
|
disconnectDFSVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
disconnectDFSTM
|
||
|
|
);
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.2 ~deleteDFSFile~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr deleteDFSFileTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,1)){
|
||
|
|
return listutils::typeError("one argument expected");
|
||
|
|
}
|
||
|
|
ListExpr arg1 = nl->First(args);
|
||
|
|
if(!CcString::checkType(arg1)&&!FText::checkType(arg1)){
|
||
|
|
return listutils::typeError("string or text required");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
template<class T>
|
||
|
|
int deleteDFSFileVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
T* id = (T*) args[0].addr;
|
||
|
|
if(!id->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
if(!filesystem){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
string name = id->GetValue();
|
||
|
|
if(!filesystem->hasFile(name.c_str())){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
filesystem->deleteFile(name.c_str());
|
||
|
|
res->Set(true,true);
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping deleteDFSFileVM[] = {
|
||
|
|
deleteDFSFileVMT<CcString>,
|
||
|
|
deleteDFSFileVMT<FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int deleteDFSFileSelect(ListExpr args){
|
||
|
|
return CcString::checkType(nl->First(args))?0:1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec deleteDFSFileSpec(
|
||
|
|
"{string,text} -> bool",
|
||
|
|
"deleteDFSFile(_)",
|
||
|
|
"removes a file from connected dfs and returns success.",
|
||
|
|
"query deleteDFSFile('myfile')"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator deleteDFSFileOp(
|
||
|
|
"deleteDFSFile",
|
||
|
|
deleteDFSFileSpec.getStr(),
|
||
|
|
2,
|
||
|
|
deleteDFSFileVM,
|
||
|
|
deleteDFSFileSelect,
|
||
|
|
deleteDFSFileTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.3 Operator ~storeTextAsDFSFile~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr storeTextAsDFSFileTM(ListExpr args){
|
||
|
|
// text x {string,text} [ x string ] -> bool
|
||
|
|
if(!nl->HasLength(args,2) && !nl->HasLength(args,3)){
|
||
|
|
return listutils::typeError("2 or 3 arguments required");
|
||
|
|
}
|
||
|
|
if(!FText::checkType(nl->First(args))){
|
||
|
|
return listutils::typeError("fisrt arg is not a text");
|
||
|
|
}
|
||
|
|
ListExpr arg2 = nl->Second(args);
|
||
|
|
if(!CcString::checkType(arg2) && !FText::checkType(arg2)){
|
||
|
|
return listutils::typeError("second arg must be a string or a text");
|
||
|
|
}
|
||
|
|
if(nl->HasLength(args,3)){
|
||
|
|
if(!CcString::checkType(nl->Third(args))){
|
||
|
|
return listutils::typeError("third arg must be a string");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
template<class T>
|
||
|
|
int storeTextAsDFSFileVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
FText* content = (FText*) args[0].addr;
|
||
|
|
T* name = (T*) args[1].addr;
|
||
|
|
if(!content->IsDefined() || !name->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string contentstr = content->GetValue();
|
||
|
|
string namestr = name->GetValue();
|
||
|
|
string catstr;
|
||
|
|
if(qp->GetNoSons(s)==3){
|
||
|
|
CcString* cat = (CcString*) args[2].addr;
|
||
|
|
if(!cat->IsDefined()) {
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
catstr = cat->GetValue();
|
||
|
|
}
|
||
|
|
if(!filesystem){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
if(catstr.length()>0){
|
||
|
|
filesystem->storeFile(namestr.c_str(),contentstr.c_str(),
|
||
|
|
contentstr.length(), catstr.c_str());
|
||
|
|
} else {
|
||
|
|
filesystem->storeFile(namestr.c_str(),contentstr.c_str(),
|
||
|
|
contentstr.length());
|
||
|
|
}
|
||
|
|
res->Set(true,true);
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping storeTextAsDFSFileVM[] = {
|
||
|
|
storeTextAsDFSFileVMT<CcString>,
|
||
|
|
storeTextAsDFSFileVMT<FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int storeTextAsDFSFileSelect(ListExpr args){
|
||
|
|
return CcString::checkType(nl->Second(args))?0:1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec storeTextAsDFSFileSpec(
|
||
|
|
"text x {string,text} [x string] -> bool",
|
||
|
|
" storeTextAsDFSFile(content, filename [,category]) ",
|
||
|
|
"Stores the content of a text into the currently "
|
||
|
|
" connected dfs. ",
|
||
|
|
"query storeTextAsDFSFile('My content', 'myfirstfile')"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator storeTextAsDFSFileOp(
|
||
|
|
"storeTextAsDFSFile",
|
||
|
|
storeTextAsDFSFileSpec.getStr(),
|
||
|
|
2,
|
||
|
|
storeTextAsDFSFileVM,
|
||
|
|
storeTextAsDFSFileSelect,
|
||
|
|
storeTextAsDFSFileTM
|
||
|
|
);
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.4 Operator ~storeLocalFileToDFS~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr storeLocalFileToDFSTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,2) && !nl->HasLength(args,3)){
|
||
|
|
return listutils::typeError("2 or 3 arguments expected");
|
||
|
|
}
|
||
|
|
ListExpr arg = nl->First(args);
|
||
|
|
if(!CcString::checkType(arg) && !FText::checkType(arg)){
|
||
|
|
return listutils::typeError("string or text as 1st arg expected");
|
||
|
|
}
|
||
|
|
arg = nl->Second(args);
|
||
|
|
if(!CcString::checkType(arg) && !FText::checkType(arg)){
|
||
|
|
return listutils::typeError("string or text as 2nd arg expected");
|
||
|
|
}
|
||
|
|
if(nl->HasLength(args,3)){
|
||
|
|
if(!CcString::checkType(nl->Third(args))){
|
||
|
|
return listutils::typeError("3rd arg not of type string");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template<class L, class R>
|
||
|
|
int storeLocalFileToDFSVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
L* localName = (L*) args[0].addr;
|
||
|
|
R* remoteName = (R*) args[1].addr;
|
||
|
|
if(!localName->IsDefined() || !remoteName->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string cat;
|
||
|
|
if(qp->GetNoSons(s)==3){
|
||
|
|
CcString* Cat = (CcString*) args[2].addr;
|
||
|
|
if(!Cat->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
cat = Cat->GetValue();
|
||
|
|
}
|
||
|
|
string localN = localName->GetValue();
|
||
|
|
string remoteN = remoteName->GetValue();
|
||
|
|
if(!filesystem){ // no dfs connected
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// arguments are checked
|
||
|
|
// the file file be transmitted in several parts
|
||
|
|
ifstream in(localN.c_str(), ios::binary);
|
||
|
|
if(!in){ // local file could ot be opened
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
in.close();
|
||
|
|
try{
|
||
|
|
if(cat.length()>0){
|
||
|
|
filesystem->storeFileFromLocal(remoteN.c_str(),
|
||
|
|
localN.c_str(),
|
||
|
|
cat.c_str());
|
||
|
|
} else {
|
||
|
|
filesystem->storeFileFromLocal(remoteN.c_str(), localN.c_str());
|
||
|
|
}
|
||
|
|
res->Set(true,true);
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping storeLocalFileToDFSVM[] = {
|
||
|
|
storeLocalFileToDFSVMT<CcString, CcString>,
|
||
|
|
storeLocalFileToDFSVMT<CcString, FText>,
|
||
|
|
storeLocalFileToDFSVMT<FText, CcString>,
|
||
|
|
storeLocalFileToDFSVMT<FText, FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int storeLocalFileToDFSSelect(ListExpr args){
|
||
|
|
int n1 = CcString::checkType(nl->First(args))?0:2;
|
||
|
|
int n2 = CcString::checkType(nl->Second(args))?0:1;
|
||
|
|
return n1+n2;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec storeLocalFileToDFSSpec(
|
||
|
|
"{string,text} x {string, text} [ x string] -> bool",
|
||
|
|
"storeLocalFileToDFS( localName, remoteName [,category]",
|
||
|
|
"Brings a local file into the dfs. ",
|
||
|
|
" query storeLocalFileToDFS('berlintest', 'berlintest')"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator storeLocalFileToDFSOp(
|
||
|
|
"storeLocalFileToDFS",
|
||
|
|
storeLocalFileToDFSSpec.getStr(),
|
||
|
|
4,
|
||
|
|
storeLocalFileToDFSVM,
|
||
|
|
storeLocalFileToDFSSelect,
|
||
|
|
storeLocalFileToDFSTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.5 Operator ~storeDFSFile~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr storeDFSFileTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,2)){
|
||
|
|
return listutils::typeError("2 args expected");
|
||
|
|
}
|
||
|
|
ListExpr arg = nl->First(args);
|
||
|
|
if(!CcString::checkType(arg) && !FText::checkType(arg)){
|
||
|
|
return listutils::typeError("1st arg not of type string or text");
|
||
|
|
}
|
||
|
|
arg = nl->Second(args);
|
||
|
|
if(!CcString::checkType(arg) && !FText::checkType(arg)){
|
||
|
|
return listutils::typeError("2nd arg not of type string or text");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template<class R, class L, bool partially>
|
||
|
|
int storeDFSFileVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
R* remoteName = (R*) args[0].addr;
|
||
|
|
L* localName = (L*) args[1].addr;
|
||
|
|
if(!remoteName->IsDefined() || !localName->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
if(!filesystem){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string remoteN = remoteName->GetValue();
|
||
|
|
string localN = localName->GetValue();
|
||
|
|
|
||
|
|
char* buffer = 0;
|
||
|
|
try{
|
||
|
|
if(!filesystem->hasFile(remoteN.c_str())){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
if(!partially){
|
||
|
|
filesystem->receiveFileToLocal(remoteN.c_str(), localN.c_str());
|
||
|
|
res->Set(true,true);
|
||
|
|
} else {
|
||
|
|
size_t buffersize = 1024*1024;
|
||
|
|
buffer = new char[buffersize];
|
||
|
|
size_t toRead = filesystem->fileSize(remoteN.c_str());
|
||
|
|
ofstream out(localN.c_str(), ios::binary| ios::trunc);
|
||
|
|
if(!out){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
size_t pos = 0;
|
||
|
|
while(toRead>0){
|
||
|
|
size_t r = buffersize<toRead?buffersize:toRead;
|
||
|
|
filesystem->receiveFilePartially(remoteN.c_str(),pos, r, buffer);
|
||
|
|
out.write(buffer,r);
|
||
|
|
toRead -= r;
|
||
|
|
pos += r;
|
||
|
|
}
|
||
|
|
out.close();
|
||
|
|
res->Set(true,true);
|
||
|
|
}
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
if(buffer){
|
||
|
|
delete[] buffer;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping storeDFSFileVM[] = {
|
||
|
|
storeDFSFileVMT<CcString,CcString,false>,
|
||
|
|
storeDFSFileVMT<CcString,FText,false>,
|
||
|
|
storeDFSFileVMT<FText,CcString,false>,
|
||
|
|
storeDFSFileVMT<FText,FText,false>
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
ValueMapping storeDFSFile2VM[] = {
|
||
|
|
storeDFSFileVMT<CcString,CcString,true>,
|
||
|
|
storeDFSFileVMT<CcString,FText,true>,
|
||
|
|
storeDFSFileVMT<FText,CcString,true>,
|
||
|
|
storeDFSFileVMT<FText,FText,true>
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int storeDFSFileSelect(ListExpr args){
|
||
|
|
int n1 = CcString::checkType(nl->First(args))?0:2;
|
||
|
|
int n2 = CcString::checkType(nl->Second(args))?0:1;
|
||
|
|
return n1+n2;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec storeDFSFileSpec(
|
||
|
|
"{string,text} x {string,text} -> bool",
|
||
|
|
"storeDFSFile(remoteName, localName)",
|
||
|
|
"Copies a file from a connected dfs to the local file system.",
|
||
|
|
"query storeDFSFile('myRemoteFile', 'myLocalFile')"
|
||
|
|
);
|
||
|
|
|
||
|
|
OperatorSpec storeDFSFile2Spec(
|
||
|
|
"{string,text} x {string,text} -> bool",
|
||
|
|
"storeDFSFile2(remoteName, localName)",
|
||
|
|
"Copies a file from a connected dfs to the local file system.",
|
||
|
|
"query storeDFSFile2('myRemoteFile', 'myLocalFile')"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator storeDFSFileOp(
|
||
|
|
"storeDFSFile",
|
||
|
|
storeDFSFileSpec.getStr(),
|
||
|
|
4,
|
||
|
|
storeDFSFileVM,
|
||
|
|
storeDFSFileSelect,
|
||
|
|
storeDFSFileTM
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator storeDFSFile2Op(
|
||
|
|
"storeDFSFile2",
|
||
|
|
storeDFSFile2Spec.getStr(),
|
||
|
|
4,
|
||
|
|
storeDFSFile2VM,
|
||
|
|
storeDFSFileSelect,
|
||
|
|
storeDFSFileTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.6 Operator ~isDFSFile~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr isDFSFileTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,1)){
|
||
|
|
return listutils::typeError("one argument expected");
|
||
|
|
}
|
||
|
|
ListExpr arg = nl->First(args);
|
||
|
|
if(!CcString::checkType(arg) && !FText::checkType(arg)){
|
||
|
|
return listutils::typeError("string or text expected");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template<class R>
|
||
|
|
int isDFSFileVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
R* Id = (R*) args[0].addr;
|
||
|
|
if(!Id->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string id = Id->GetValue();
|
||
|
|
if(!filesystem){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
res->Set(true,filesystem->hasFile(id.c_str()));
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping isDFSFileVM[] = {
|
||
|
|
isDFSFileVMT<CcString>,
|
||
|
|
isDFSFileVMT<FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int isDFSFileSelect(ListExpr args){
|
||
|
|
return CcString::checkType(nl->First(args))?0:1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec isDFSFileSpec(
|
||
|
|
"{string,text} -> bool",
|
||
|
|
"isDFSFile(name)",
|
||
|
|
"Check whether the file is part of the connected dfs",
|
||
|
|
"query isDFSFile('myRemoteFile')"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator isDFSFileOp(
|
||
|
|
"isDFSFile",
|
||
|
|
isDFSFileSpec.getStr(),
|
||
|
|
2,
|
||
|
|
isDFSFileVM,
|
||
|
|
isDFSFileSelect,
|
||
|
|
isDFSFileTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.7 Operator ~nextDFSWritePosition~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr nextDFSWritePositionTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,1)){
|
||
|
|
return listutils::typeError("one argument expected");
|
||
|
|
}
|
||
|
|
ListExpr arg = nl->First(args);
|
||
|
|
if(!CcString::checkType(arg) && !FText::checkType(arg)){
|
||
|
|
return listutils::typeError("string or text expected");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<LongInt>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template<class R>
|
||
|
|
int nextDFSWritePositionVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
LongInt* res = (LongInt*) result.addr;
|
||
|
|
R* Id = (R*) args[0].addr;
|
||
|
|
if(!Id->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string id = Id->GetValue();
|
||
|
|
if(!filesystem){
|
||
|
|
res->Set(true,-1);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
res->Set(true,filesystem->nextWritePosition(id.c_str()));
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,-1);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping nextDFSWritePositionVM[] = {
|
||
|
|
nextDFSWritePositionVMT<CcString>,
|
||
|
|
nextDFSWritePositionVMT<FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int nextDFSWritePositionSelect(ListExpr args){
|
||
|
|
return CcString::checkType(nl->First(args))?0:1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec nextDFSWritePositionSpec(
|
||
|
|
"{string,text} -> bool",
|
||
|
|
"nextDFSWritePosition(name)",
|
||
|
|
"Returns the append position of a dfs file (its length).",
|
||
|
|
"query nextDFSWritePosition('myRemoteFile')"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator nextDFSWritePositionOp(
|
||
|
|
"nextDFSWritePosition",
|
||
|
|
nextDFSWritePositionSpec.getStr(),
|
||
|
|
2,
|
||
|
|
nextDFSWritePositionVM,
|
||
|
|
nextDFSWritePositionSelect,
|
||
|
|
nextDFSWritePositionTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.8 Operator ~getDFSFileAsText~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr getDFSFileAsTextTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,1) && !nl->HasLength(args,3)){
|
||
|
|
return listutils::typeError("one or three args expected");
|
||
|
|
}
|
||
|
|
ListExpr arg1 = nl->First(args);
|
||
|
|
if(!CcString::checkType(arg1) && !FText::checkType(arg1)){
|
||
|
|
return listutils::typeError("first arg must be of type string or text");
|
||
|
|
}
|
||
|
|
if(nl->HasLength(args,3)){
|
||
|
|
if(!CcInt::checkType(nl->Second(args)) ||
|
||
|
|
!CcInt::checkType(nl->Third(args))){
|
||
|
|
return listutils::typeError("2nd and 3rd arg must be of type int");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<FText>();
|
||
|
|
}
|
||
|
|
|
||
|
|
template<class R>
|
||
|
|
int getDFSFileAsTextVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result=qp->ResultStorage(s);
|
||
|
|
FText* res = (FText*) result.addr;
|
||
|
|
R* Fname = (R*) args[0].addr;
|
||
|
|
if(!Fname->IsDefined() || filesystem==0){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string fname = Fname->GetValue();
|
||
|
|
if(!filesystem->hasFile(fname.c_str())){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
int min=0;
|
||
|
|
int max=filesystem->fileSize(fname.c_str());
|
||
|
|
if(qp->GetNoSons(s)==3){
|
||
|
|
CcInt* Min = (CcInt*) args[1].addr;
|
||
|
|
CcInt* Max = (CcInt*) args[2].addr;
|
||
|
|
if(!Min->IsDefined() || !Max->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
min = Min->GetValue();
|
||
|
|
int m = Max->GetValue();
|
||
|
|
if(m<max){
|
||
|
|
max = m;
|
||
|
|
}
|
||
|
|
if(min<0 || min > max){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
size_t bufferlength = max-min;
|
||
|
|
char* buffer = new char[bufferlength];
|
||
|
|
try{
|
||
|
|
filesystem->receiveFilePartially(fname.c_str(),
|
||
|
|
min, bufferlength,buffer);
|
||
|
|
string bufferstr(buffer, bufferlength);
|
||
|
|
res->Set(true,bufferstr);
|
||
|
|
} catch(...){
|
||
|
|
res->SetDefined(false);
|
||
|
|
}
|
||
|
|
delete[] buffer;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping getDFSFileAsTextVM[] = {
|
||
|
|
getDFSFileAsTextVMT<CcString>,
|
||
|
|
getDFSFileAsTextVMT<FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int getDFSFileAsTextSelect(ListExpr args){
|
||
|
|
return CcString::checkType(nl->First(args))?0:1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec getDFSFileAsTextSpec(
|
||
|
|
"{string,text} [x int x int] -> text",
|
||
|
|
"getDFSFileAsText(filename, min, max) ",
|
||
|
|
"Receives a portion of a file from connected remote "
|
||
|
|
"file system. If the min and max is missing, the whole "
|
||
|
|
" file is taken.",
|
||
|
|
"query getDFSFileAsText('myRemoteFile')"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator getDFSFileAsTextOp(
|
||
|
|
"getDFSFileAsText",
|
||
|
|
getDFSFileAsTextSpec.getStr(),
|
||
|
|
2,
|
||
|
|
getDFSFileAsTextVM,
|
||
|
|
getDFSFileAsTextSelect,
|
||
|
|
getDFSFileAsTextTM
|
||
|
|
);
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.9 Operator ~deleteAllDFSFiles~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr deleteAllDFSFilesTM(ListExpr args){
|
||
|
|
if(!nl->IsEmpty(args)){
|
||
|
|
return listutils::typeError("don't bother me with arguments");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
int deleteAllDFSFilesVM( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result=qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
if(!filesystem){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
filesystem->deleteAllFiles();
|
||
|
|
res->Set(true,true);
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec deleteAllDFSFilesSpec(
|
||
|
|
"-> bool",
|
||
|
|
"deleteAllDFSFiles()",
|
||
|
|
"Removes all files from a connected dfs",
|
||
|
|
"query deleteAllDFSFiles() "
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator deleteAllDFSFilesOp(
|
||
|
|
"deleteAllDFSFiles",
|
||
|
|
deleteAllDFSFilesSpec.getStr(),
|
||
|
|
deleteAllDFSFilesVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
deleteAllDFSFilesTM
|
||
|
|
);
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.10 Operator ~deleteAllDFSFilesWithCat~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr deleteAllDFSFilesWithCatTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,1)){
|
||
|
|
return listutils::typeError("one arg expected");
|
||
|
|
}
|
||
|
|
if(!CcString::checkType(nl->First(args))){
|
||
|
|
return listutils::typeError("string expected");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int deleteAllDFSFilesWithCatVM( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
CcString* Cat = (CcString*) args[0].addr;
|
||
|
|
if(!Cat->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string cat = Cat->GetValue();
|
||
|
|
if(!filesystem){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
filesystem->deleteAllFilesOfCategory(cat.c_str());
|
||
|
|
res->Set(true,true);
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec deleteAllDFSFilesWithCatSpec(
|
||
|
|
"string -> bool",
|
||
|
|
"deleteAllDFSFilesWithCat(category)",
|
||
|
|
"Removes all files belonging to a certain category "
|
||
|
|
" from the connected dfs",
|
||
|
|
" query deleteAllDFSFilesWithCat(\"deprecated\")"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator deleteAllDFSFilesWithCatOp(
|
||
|
|
"deleteAllDFSFilesWithCat",
|
||
|
|
deleteAllDFSFilesWithCatSpec.getStr(),
|
||
|
|
deleteAllDFSFilesWithCatVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
deleteAllDFSFilesWithCatTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.11 Operator ~countDFSFiles~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr countDFSFilesTM(ListExpr args){
|
||
|
|
if(!nl->IsEmpty(args)){
|
||
|
|
return listutils::typeError("what should i do with an argument?");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcInt>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int countDFSFilesVM( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcInt* res = (CcInt*) result.addr;
|
||
|
|
if(!filesystem){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
res->Set(true, filesystem->countFiles());
|
||
|
|
} catch(...){
|
||
|
|
res->SetDefined(false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec countDFSFilesSpec(
|
||
|
|
"-> int",
|
||
|
|
"countDFSFiles()",
|
||
|
|
"Returns the number of files in the connected dfs.",
|
||
|
|
" query countDFSFiles()"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator countDFSFilesOp(
|
||
|
|
"countDFSFiles",
|
||
|
|
countDFSFilesSpec.getStr(),
|
||
|
|
countDFSFilesVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
countDFSFilesTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.12 Operator ~totalDFSSize~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr totalDFSSizeTM(ListExpr args){
|
||
|
|
if(!nl->IsEmpty(args)){
|
||
|
|
return listutils::typeError("pfui, an argument. put it away!");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<LongInt>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int totalDFSSizeVM( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
LongInt* res = (LongInt*) result.addr;
|
||
|
|
if(!filesystem){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
res->Set(true, filesystem->totalSize());
|
||
|
|
} catch(...){
|
||
|
|
res->SetDefined(false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec totalDFSSizeSpec(
|
||
|
|
"-> int",
|
||
|
|
"totalDFSSize()",
|
||
|
|
"Returns the amount of hdd space aquired by the dfs.",
|
||
|
|
"query totalDFSSize()"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator totalDFSSizeOp(
|
||
|
|
"totalDFSSize",
|
||
|
|
totalDFSSizeSpec.getStr(),
|
||
|
|
totalDFSSizeVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
totalDFSSizeTM
|
||
|
|
);
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.13 Operator ~dfsFileSize~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr dfsFileSizeTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,1)){
|
||
|
|
return listutils::typeError("one argument expected");
|
||
|
|
}
|
||
|
|
ListExpr arg = nl->First(args);
|
||
|
|
if(!CcString::checkType(arg) && !FText::checkType(arg)){
|
||
|
|
return listutils::typeError("string or text expected");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<LongInt>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template<class R>
|
||
|
|
int dfsFileSizeVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
LongInt* res = (LongInt*) result.addr;
|
||
|
|
R* Id = (R*) args[0].addr;
|
||
|
|
if(!Id->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string id = Id->GetValue();
|
||
|
|
if(!filesystem){
|
||
|
|
res->Set(true,-1);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
try{
|
||
|
|
res->Set(true,filesystem->fileSize(id.c_str()));
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,-1);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
ValueMapping dfsFileSizeVM[] = {
|
||
|
|
dfsFileSizeVMT<CcString>,
|
||
|
|
dfsFileSizeVMT<FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int dfsFileSizeSelect(ListExpr args){
|
||
|
|
return CcString::checkType(nl->First(args))?0:1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec dfsFileSizeSpec(
|
||
|
|
"{string,text} -> bool",
|
||
|
|
"dfsFileSize(name)",
|
||
|
|
"Returns the size of a file stored in a connected dfs.",
|
||
|
|
"query dfsFileSize('myRemoteFile')"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator dfsFileSizeOp(
|
||
|
|
"dfsFileSize",
|
||
|
|
dfsFileSizeSpec.getStr(),
|
||
|
|
2,
|
||
|
|
dfsFileSizeVM,
|
||
|
|
dfsFileSizeSelect,
|
||
|
|
dfsFileSizeTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.14 Operator ~dfsFileNames~
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
ListExpr dfsFileNamesTM(ListExpr args){
|
||
|
|
|
||
|
|
if(!nl->IsEmpty(args)){
|
||
|
|
return listutils::typeError("you are crazy to give me an argument?");
|
||
|
|
}
|
||
|
|
return nl->TwoElemList(nl->SymbolAtom(Symbols::STREAM()),
|
||
|
|
listutils::basicSymbol<FText>());
|
||
|
|
}
|
||
|
|
|
||
|
|
class dfsFileNamesInfo{
|
||
|
|
|
||
|
|
public:
|
||
|
|
dfsFileNamesInfo(dfs::Filesystem* fs): pos(0){
|
||
|
|
if(fs){
|
||
|
|
try{
|
||
|
|
names = fs->listFileNames();
|
||
|
|
} catch(...){
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
FText* next(){
|
||
|
|
FText* res = pos>=names.size()?0:new FText(true,names[pos]);
|
||
|
|
pos++;
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
private:
|
||
|
|
size_t pos;
|
||
|
|
vector<string> names;
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
int dfsFileNamesVM( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
|
||
|
|
dfsFileNamesInfo* li = (dfsFileNamesInfo*) local.addr;
|
||
|
|
switch(message){
|
||
|
|
case OPEN: if(li) delete li;
|
||
|
|
local.addr = new dfsFileNamesInfo(filesystem);
|
||
|
|
return 0;
|
||
|
|
case REQUEST: result.addr = li?li->next():0;
|
||
|
|
return result.addr?YIELD:CANCEL;
|
||
|
|
case CLOSE : if(li){
|
||
|
|
delete li;
|
||
|
|
local.addr = 0;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
}
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec dfsFileNamesSpec(
|
||
|
|
" -> stream(text)",
|
||
|
|
" dfsFileNames() ",
|
||
|
|
" Feeds the names of all stored files into a stream of text.",
|
||
|
|
" query dfsFileNames() count"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator dfsFileNamesOp(
|
||
|
|
"dfsFileNames",
|
||
|
|
dfsFileNamesSpec.getStr(),
|
||
|
|
dfsFileNamesVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
dfsFileNamesTM
|
||
|
|
);
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.15 Operator ~changeDFSChunkSize~
|
||
|
|
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr changeDFSChunkSizeTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,1)){
|
||
|
|
return listutils::typeError("one argument expected");
|
||
|
|
}
|
||
|
|
if(!CcInt::checkType(nl->First(args))){
|
||
|
|
return listutils::typeError("int expected");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int changeDFSChunkSizeVM( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
CcInt* newSize = (CcInt*) args[0].addr;
|
||
|
|
if(!newSize->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
int ns = newSize->GetValue();
|
||
|
|
if(ns < 1){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
if(!filesystem){
|
||
|
|
res->Set(true,false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
try{
|
||
|
|
filesystem->changeChunkSize(ns);
|
||
|
|
res->Set(true,true);
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec changeDFSChunkSizeSpec(
|
||
|
|
"int -> bool",
|
||
|
|
"changeDFSChunkSize(newSize)",
|
||
|
|
"Changes the chunk size in a connected dfs.",
|
||
|
|
" query changeDFSChunkSize(4096)"
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator changeDFSChunkSizeOp(
|
||
|
|
"changeDFSChunkSize",
|
||
|
|
changeDFSChunkSizeSpec.getStr(),
|
||
|
|
changeDFSChunkSizeVM,
|
||
|
|
Operator::SimpleSelect,
|
||
|
|
changeDFSChunkSizeTM
|
||
|
|
);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
#ifdef REMOTE_FILESYSTEM
|
||
|
|
|
||
|
|
/*
|
||
|
|
2.16 Operator ~registerDFSDataNode~
|
||
|
|
|
||
|
|
*/
|
||
|
|
ListExpr registerDFSDataNodeTM(ListExpr args){
|
||
|
|
if(!nl->HasLength(args,2)){
|
||
|
|
return listutils::typeError("2 args required");
|
||
|
|
}
|
||
|
|
ListExpr arg1 = nl->First(args);
|
||
|
|
if(!CcString::checkType(arg1) && !FText::checkType(arg1)){
|
||
|
|
return listutils::typeError("string or text expected as the first arg");
|
||
|
|
}
|
||
|
|
if(!CcInt::checkType(nl->Second(args))){
|
||
|
|
return listutils::typeError("second arguemnt must be an int");
|
||
|
|
}
|
||
|
|
return listutils::basicSymbol<CcBool>();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template<class T>
|
||
|
|
int registerDFSDataNodeVMT( Word* args,
|
||
|
|
Word& result, int message,
|
||
|
|
Word& local,
|
||
|
|
Supplier s ){
|
||
|
|
result = qp->ResultStorage(s);
|
||
|
|
CcBool* res = (CcBool*) result.addr;
|
||
|
|
T* Host = (T*) args[0].addr;
|
||
|
|
CcInt* Port = (CcInt*) args[1].addr;
|
||
|
|
if(!Host->IsDefined() || !Port->IsDefined()){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
string host = Host->GetValue();
|
||
|
|
int port = Port->GetValue();
|
||
|
|
if(port < 1){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
if(!filesystem){
|
||
|
|
res->SetDefined(false);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
stringstream ss;
|
||
|
|
ss << "dfs-data://"<<host<<":"<<port;
|
||
|
|
try{
|
||
|
|
URI uri = URI::fromString(ss.str().c_str());
|
||
|
|
filesystem->registerDataNode(uri);
|
||
|
|
res->Set(true,true);
|
||
|
|
} catch(...){
|
||
|
|
res->Set(true,false);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
ValueMapping registerDFSDataNodeVM[] = {
|
||
|
|
registerDFSDataNodeVMT<CcString>,
|
||
|
|
registerDFSDataNodeVMT<FText>
|
||
|
|
};
|
||
|
|
|
||
|
|
int registerDFSDataNodeSelect(ListExpr args){
|
||
|
|
return CcString::checkType(nl->First(args))?0:1;
|
||
|
|
}
|
||
|
|
|
||
|
|
OperatorSpec registerDFSDataNodeSpec(
|
||
|
|
"{string,text} x int -> bool ",
|
||
|
|
"registerDFSDataNode(host, port)",
|
||
|
|
"Registers a new data node to the currently connected dfs.",
|
||
|
|
" query registerDFSDataNode('remotehost', 4445) "
|
||
|
|
);
|
||
|
|
|
||
|
|
Operator registerDFSDataNodeOp(
|
||
|
|
"registerDFSDataNode",
|
||
|
|
registerDFSDataNodeSpec.getStr(),
|
||
|
|
2,
|
||
|
|
registerDFSDataNodeVM,
|
||
|
|
registerDFSDataNodeSelect,
|
||
|
|
registerDFSDataNodeTM
|
||
|
|
);
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/*
|
||
|
|
3 Algebra definition
|
||
|
|
|
||
|
|
3.1 Algebra class
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
class DFSAlgebra: public Algebra{
|
||
|
|
public:
|
||
|
|
|
||
|
|
DFSAlgebra(){
|
||
|
|
AddOperator(&connectDFSOp);
|
||
|
|
AddOperator(&deleteDFSFileOp);
|
||
|
|
AddOperator(&storeTextAsDFSFileOp);
|
||
|
|
AddOperator(&storeLocalFileToDFSOp);
|
||
|
|
AddOperator(&storeDFSFileOp);
|
||
|
|
AddOperator(&storeDFSFile2Op);
|
||
|
|
AddOperator(&isDFSFileOp);
|
||
|
|
AddOperator(&nextDFSWritePositionOp);
|
||
|
|
AddOperator(&getDFSFileAsTextOp);
|
||
|
|
AddOperator(&deleteAllDFSFilesOp);
|
||
|
|
AddOperator(&deleteAllDFSFilesWithCatOp);
|
||
|
|
AddOperator(&countDFSFilesOp);
|
||
|
|
AddOperator(&totalDFSSizeOp);
|
||
|
|
AddOperator(&dfsFileSizeOp);
|
||
|
|
AddOperator(&dfsFileNamesOp);
|
||
|
|
AddOperator(&changeDFSChunkSizeOp);
|
||
|
|
#ifdef REMOTE_FILESYSTEM
|
||
|
|
AddOperator(®isterDFSDataNodeOp);
|
||
|
|
#endif
|
||
|
|
AddOperator(&disconnectDFSOp);
|
||
|
|
}
|
||
|
|
|
||
|
|
~DFSAlgebra(){
|
||
|
|
if(filesystem){
|
||
|
|
delete filesystem;
|
||
|
|
filesystem = 0;
|
||
|
|
}
|
||
|
|
if(logger){
|
||
|
|
delete logger;
|
||
|
|
logger = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
} // end of namespace dfsalg
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.2 Algebra registration
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
extern "C"
|
||
|
|
Algebra*
|
||
|
|
InitializeDFSAlgebra( NestedList* nlRef,
|
||
|
|
QueryProcessor* qpRef,
|
||
|
|
AlgebraManager* amRef ) {
|
||
|
|
|
||
|
|
|
||
|
|
return new dfsalg::DFSAlgebra();
|
||
|
|
}
|
||
|
|
|