gStore/Query/ResultSet.cpp

352 lines
7.5 KiB
C++
Raw Normal View History

2016-09-18 20:01:57 +08:00
/*=============================================================================
# Filename: ResultSet.cpp
# Author: Bookug Lobert
# Mail: 1181955272@qq.com
# Last Modified: 2015-10-24 22:01
# Description: implement functions in ResultSet.h
=============================================================================*/
#include "ResultSet.h"
using namespace std;
ResultSet::ResultSet()
{
this->select_var_num = 0;
this->var_name = NULL;
this->ansNum = 0;
this->answer = NULL;
this->stream = NULL;
this->useStream = false;
2017-02-28 20:32:01 +08:00
this->output_offset = 0;
this->output_limit = -1;
2016-09-18 20:01:57 +08:00
}
ResultSet::~ResultSet()
{
delete[] this->var_name;
if (!this->useStream)
{
2017-03-24 20:10:43 +08:00
for(unsigned i = 0; i < this->ansNum; i++)
{
delete[] this->answer[i];
}
delete[] this->answer;
}
else
2016-09-18 20:01:57 +08:00
{
delete this->stream; //maybe NULL
2016-09-18 20:01:57 +08:00
}
}
ResultSet::ResultSet(int _v_num, const string* _v_names)
{
this->select_var_num = _v_num;
this->var_name = new string[this->select_var_num];
2017-02-28 20:32:01 +08:00
for(int i = 0; i < this->select_var_num; i++)
2016-09-18 20:01:57 +08:00
{
this->var_name[i] = _v_names[i];
}
this->ansNum = 0;
this->answer = NULL;
2016-09-18 20:01:57 +08:00
this->stream = NULL;
this->useStream = false;
2017-02-28 20:32:01 +08:00
this->output_offset = 0;
this->output_limit = -1;
}
void
ResultSet::setUseStream()
{
this->useStream = true;
2016-09-18 20:01:57 +08:00
}
2017-02-28 20:32:01 +08:00
bool
ResultSet::checkUseStream()
{
return this->useStream;
}
2016-09-18 20:01:57 +08:00
void
2017-03-24 20:10:43 +08:00
ResultSet::setOutputOffsetLimit(unsigned _output_offset, unsigned _output_limit)
2017-02-28 20:32:01 +08:00
{
this->output_offset = _output_offset;
this->output_limit = _output_limit;
}
void
2016-09-18 20:01:57 +08:00
ResultSet::setVar(const vector<string> & _var_names)
{
this->select_var_num = _var_names.size();
this->var_name = new string[this->select_var_num];
for(int i = 0; i < this->select_var_num; i++)
{
this->var_name[i] = _var_names[i];
}
}
2017-02-28 20:32:01 +08:00
//convert to TSV string
2016-09-18 20:01:57 +08:00
string
ResultSet::to_str()
{
2017-03-24 20:10:43 +08:00
unsigned ans_num = max((long long)this->ansNum - this->output_offset, (long long)0);
2017-02-28 20:32:01 +08:00
if (this->output_limit != -1)
ans_num = min(ans_num, this->output_limit);
if(ans_num == 0)
2016-09-18 20:01:57 +08:00
{
return "[empty result]\n";
}
stringstream _buf;
2017-02-28 20:32:01 +08:00
for(int i = 0; i < this->select_var_num; i++)
2016-09-18 20:01:57 +08:00
{
2017-02-28 20:32:01 +08:00
if (i != 0)
_buf << "\t";
_buf << this->var_name[i];
2016-09-18 20:01:57 +08:00
}
2017-02-28 20:32:01 +08:00
_buf << "\n";
if (this->useStream)
this->resetStream();
const Bstr* bp;
2017-03-24 20:10:43 +08:00
for(unsigned i = (!this->useStream ? this->output_offset : 0); i < this->ansNum; i++)
2016-09-18 20:01:57 +08:00
{
2017-02-28 20:32:01 +08:00
if (this->output_limit != -1 && i == this->output_offset + this->output_limit)
break;
if (this->useStream)
bp = this->stream->read();
if (i >= this->output_offset)
{
2017-02-28 20:32:01 +08:00
for(int j = 0; j < this->select_var_num; j++)
2016-09-18 20:01:57 +08:00
{
2017-02-28 20:32:01 +08:00
if (j != 0)
_buf << "\t";
if (!this->useStream)
_buf << Util::node2string(this->answer[i][j].c_str());
else
_buf << Util::node2string(bp[j].getStr());
2016-09-18 20:01:57 +08:00
}
2017-02-28 20:32:01 +08:00
_buf << "\n";
2016-09-18 20:01:57 +08:00
}
}
2017-02-28 20:32:01 +08:00
return _buf.str();
}
//convert to JSON string
string
ResultSet::to_JSON()
{
stringstream _buf;
_buf << "{ \"head\": { \"link\": [], \"vars\": [";
for (int i = 0; i < this->select_var_num; i++)
{
if (i != 0)
_buf << ", ";
_buf << "\"" + this->var_name[i].substr(1) + "\"";
}
_buf << "] }, \n";
_buf << "\t\"results\": \n";
_buf << "\t{\n";
_buf << "\t\t\"bindings\": \n";
_buf << "\t\t[\n";
if (this->useStream)
this->resetStream();
const Bstr* bp;
2017-03-24 20:10:43 +08:00
for(unsigned i = (!this->useStream ? this->output_offset : 0); i < this->ansNum; i++)
{
2017-02-28 20:32:01 +08:00
if (this->output_limit != -1 && i == this->output_offset + this->output_limit)
break;
if (this->useStream)
bp = this->stream->read();
if (i >= this->output_offset)
{
if (i != this->output_offset)
_buf << ",\n";
_buf << "\t\t\t{ ";
bool list_empty = true;
for(int j = 0; j < this->select_var_num; j++)
{
string ans_type, ans_str;
if (!this->useStream)
ans_str = this->answer[i][j];
else
ans_str = string(bp[j].getStr());
if (ans_str.length() == 0)
continue;
if (!list_empty)
_buf << ",\t";
if (ans_str[0] == '<')
{
ans_type = "uri";
ans_str = ans_str.substr(1, ans_str.length() - 2);
_buf << "\"" + this->var_name[j].substr(1) + "\": { ";
_buf << "\"type\": \"" + ans_type + "\", \"value\": \"" + Util::node2string(ans_str.c_str()) + "\" }";
}
else if (ans_str[0] == '"' && ans_str.find("\"^^<") == -1 && ans_str[ans_str.length() - 1] != '>' )
{
ans_type = "literal";
ans_str = ans_str.substr(1, ans_str.rfind('"') - 1);
_buf << "\"" + this->var_name[j].substr(1) + "\": { ";
_buf << "\"type\": \"" + ans_type + "\", \"value\": \"" + Util::node2string(ans_str.c_str()) + "\" }";
}
else if (ans_str[0] == '"' && ans_str.find("\"^^<") != -1 && ans_str[ans_str.length() - 1] == '>' )
{
ans_type = "typed-literal";
int pos = ans_str.find("\"^^<");
string data_type = ans_str.substr(pos + 4, ans_str.length() - pos - 5);
ans_str = ans_str.substr(1, pos - 1);
_buf << "\"" + this->var_name[j].substr(1) + "\": { ";
_buf << "\"type\": \"" + ans_type + "\", \"datatype\": \"" + data_type + "\", \"value\": \"" + Util::node2string(ans_str.c_str()) + "\" }";
}
list_empty = false;
}
_buf << "}";
}
}
2017-02-28 20:32:01 +08:00
_buf << "\n\t\t]\n";
_buf << "\t}\n";
_buf << "}\n";
2016-09-18 20:01:57 +08:00
return _buf.str();
}
void
ResultSet::output(FILE* _fp)
{
if (this->useStream)
2016-09-18 20:01:57 +08:00
{
2017-03-24 20:10:43 +08:00
unsigned ans_num = max((long long)this->ansNum - this->output_offset, (long long)0);
2017-02-28 20:32:01 +08:00
if (this->output_limit != -1)
ans_num = min(ans_num, this->output_limit);
if(ans_num == 0)
{
fprintf(_fp, "[empty result]\n");
return;
}
fprintf(_fp, "%s", this->var_name[0].c_str());
for(int i = 1; i < this->select_var_num; i++)
{
fprintf(_fp, "\t%s", this->var_name[i].c_str());
}
fprintf(_fp, "\n");
2016-09-18 20:01:57 +08:00
const Bstr* bp;
2017-03-24 20:10:43 +08:00
for(unsigned i = 0; i < this->ansNum; i++)
{
if (this->output_limit != -1 && i == this->output_offset + this->output_limit)
break;
2017-02-28 20:32:01 +08:00
bp = this->stream->read();
if (i >= this->output_offset)
2016-09-18 20:01:57 +08:00
{
2017-01-16 14:12:57 +08:00
fprintf(_fp, "%s", Util::node2string(bp[0].getStr()).c_str());
for(int j = 1; j < this->select_var_num; j++)
{
2017-01-16 14:12:57 +08:00
fprintf(_fp, "\t%s", Util::node2string(bp[j].getStr()).c_str());
}
fprintf(_fp, "\n");
2016-09-18 20:01:57 +08:00
}
}
}
2017-02-28 20:32:01 +08:00
else
{
2017-01-16 14:12:57 +08:00
fprintf(_fp, "%s", this->to_str().c_str());
}
2016-09-18 20:01:57 +08:00
}
void
2017-03-24 20:10:43 +08:00
ResultSet::openStream(vector<unsigned> &_keys, vector<bool> &_desc)
2016-09-18 20:01:57 +08:00
{
if (this->useStream)
2016-09-18 20:01:57 +08:00
{
#ifdef DEBUG_STREAM
vector<int> debug_keys;
vector<bool> debug_desc;
for(int i = 0; i < this->select_var_num; ++i)
{
debug_keys.push_back(i);
debug_desc.push_back(false);
}
2016-09-18 20:01:57 +08:00
#endif
if(this->stream != NULL)
{
delete this->stream;
this->stream = NULL;
}
2016-09-18 20:01:57 +08:00
#ifdef DEBUG_STREAM
if(this->ansNum > 0)
this->stream = new Stream(debug_keys, debug_desc, this->ansNum, this->select_var_num, true);
2016-09-18 20:01:57 +08:00
#else
if(this->ansNum > 0)
this->stream = new Stream(_keys, _desc, this->ansNum, this->select_var_num, _keys.size() > 0);
2016-09-18 20:01:57 +08:00
#endif //DEBUG_STREAM
}
2016-09-18 20:01:57 +08:00
}
void
ResultSet::resetStream()
{
if (this->useStream)
{
//this->stream.reset();
if(this->stream != NULL)
this->stream->setEnd();
}
2016-09-18 20:01:57 +08:00
}
void
ResultSet::writeToStream(string& _s)
{
if (this->useStream)
{
if(this->stream != NULL)
this->stream->write(_s.c_str(), _s.length());
}
2016-09-18 20:01:57 +08:00
}
const Bstr*
ResultSet::getOneRecord()
{
if (this->useStream)
2016-09-18 20:01:57 +08:00
{
if(this->stream == NULL)
{
fprintf(stderr, "ResultSet::getOneRecord(): no results now!\n");
return NULL;
}
if(this->stream->isEnd())
{
fprintf(stderr, "ResultSet::getOneRecord(): read till end now!\n");
return NULL;
}
//NOTICE:this is one record, and donot free the memory!
//NOTICE:Bstr[] but only one element, used as Bstr*
return this->stream->read();
2016-09-18 20:01:57 +08:00
}
else
2016-09-18 20:01:57 +08:00
{
return NULL;
}
}