Files
secondo/include/SystemInfoRel.h

321 lines
7.5 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
----
March 2006, M. Spiekermann
1 Overview
This file declares and implements a classes called ~SystemInfoRel~ and
~InfoTuple~. It will be used to store tuples in memory. Hence they can be
regarded as a kind of memory or virtual relations which are recognized by the
system catalog. If they are used inside a query, a list representation of them
will be generated and a relation object will be created on the fly using the
~In-Function~ of type constructor ~rel~. But even without the relation algebra
the contents of the relations is available since it will be dumped into files in
CSV format which can be read in by a spreadsheet program. Hence there will be no
compile time or run time dependency to the relational algebra module.
The system tables should be implemented in file SytemTables.h.
Registration is done
in SecondoInterface.cpp. After a table is registered it can be
used in queries like
a ~normal~ relation, for example
---- let session1 = SEC2COMMANDS feed consume;
----
will show all queries and their command times. However the
contents of the relations must
be created by the ~append~ method during runtime.
*Note:* The contents of these relations will not be persistent,
hence you need to save them
into a file or a persistent relation for later use.
*/
#ifndef CLASS_SYSINFOREL_H
#define CLASS_SYSINFOREL_H
#include <vector>
#include <iostream>
#include <map>
#include "NList.h"
/*
2 Class ~InfoTuple~
This class defines 2 virtual functions which need to be implemented by
its subclasses. An instance of ~InfoTuple~ represents a tuple and can be
appended to an instance of class ~SystemInfoRel~.
*/
class InfoTuple
{
public:
static const std::string sep;
virtual NList valueList() const = 0;
virtual std::ostream& print(std::ostream&) const = 0;
InfoTuple() {}
virtual ~InfoTuple() {}
};
std::ostream& operator<<(std::ostream&, const InfoTuple&);
/*
3 Class ~SystemInfoRel~
Reserved object identifiers for the SECONDO System can be added
in the Constructor of this class. As a convention all system reserverd
identifiers should be prefixed with "SEC\_".
*/
class SystemInfoRel
{
typedef std::vector<InfoTuple*> InfoTupVec;
typedef InfoTupVec::const_iterator iterator;
public:
typedef std::vector< std::pair<std::string, std::string> > RelSchema;
InfoTupVec tuples;
RelSchema* attrList;
const std::string name;
const std::string logFile;
const std::string sep;
const bool isPersistent;
SystemInfoRel( const std::string& inName,
const bool persistent=false ) :
attrList(0),
name(inName),
logFile(name + ".csv"),
sep("|"),
isPersistent(persistent)
{}
virtual ~SystemInfoRel()
{
iterator it = tuples.begin();
while( it != tuples.end() )
{
delete *it;
it++;
}
if ( attrList)
delete attrList;
attrList = 0;
}
void writeFiles()
{
// Write Headline
std::ostream& clog = cmsg.file(logFile);
RelSchema::iterator it = attrList->begin();
while ( it != attrList->end() )
{
clog << it->first;
if (it+1 != attrList->end())
clog << sep;
it++;
}
clog << endl;
// write configuration file
std::ostream& cfg = cmsg.file(name+".cfg");
cfg << "# Generated file: Can be used together with "
<< "commands.csv by CVS2Secondo!" << endl
<< "Separator |" << endl
<< "Object " << name << endl
<< "Scheme ";
it = attrList->begin();
while ( it != attrList->end() )
{
cfg << it->first << " " << it->second;
if (it+1 != attrList->end())
cfg << " \\t ";
it++;
}
cfg << endl;
}
NList relSchema() const
{
RelSchema::iterator it = attrList->begin();
assert(it != attrList->end());
NList types;
NList pair( NList(it->first), NList(it->second) );
types.makeHead( pair );
it++;
while ( it != attrList->end() )
{
pair = NList( NList(it->first), NList(it->second) );
types.append( pair );
it++;
}
NList relSchema = NList( NList("trel"), NList(NList("tuple"), types) );
//cout << "Schema: " << relSchema << endl;
return relSchema;
}
NList relValues() const
{
//SHOW(tuples.size())
iterator it = begin();
NList values;
if (it == end())
return values;
values.makeHead( (*it)->valueList() );
it++;
while( it != end() )
{
values.append( (*it)->valueList() );
it++;
}
//cout << "Values: " << values << endl;
return values;
}
const std::string& getName() const { return name; }
void append(InfoTuple* t, bool dump)
{
if (dump)
cmsg.file(logFile) << *t << endl;
tuples.push_back(t);
}
void addAttribute(const std::string& name, const std::string& type)
{
if ( attrList == 0 )
attrList = new RelSchema();
attrList->push_back( make_pair(name, type) );
}
iterator begin() const { return tuples.begin(); }
iterator end() const { return tuples.end(); }
virtual void initSchema() = 0;
void clear() {
iterator it = begin();
while (it != end())
{
delete *it;
it++;
}
tuples.clear();
}
};
class SystemTables {
public:
typedef std::map<std::string, const SystemInfoRel*> Str2TableMap;
typedef Str2TableMap::const_iterator iterator;
~SystemTables()
{
iterator it = tables.begin();
while (it != tables.end())
{
delete it->second;
it++;
}
}
static SystemTables& getInstance()
{
if (instance) {
return *instance;
} else {
cout << "Creating SystemTable instance!" << endl;
instance = new SystemTables;
return *instance;
}
}
void insert(SystemInfoRel* rel)
{
const std::string& name = rel->getName();
assert( tables.find(name) == tables.end() );
// register new system table
std::string type="virtual";
if (rel->isPersistent)
type="persistent";
cout << " registering " << type << " system table " << name << endl;
tables[name] = rel;
rel->initSchema();
}
const SystemInfoRel* getInfoRel(const std::string& name) const
{
iterator it = tables.find(name);
if ( it == tables.end() ) {
//cout << "table " << name << " not found!" << endl;
return 0;
}
else
return it->second;
}
iterator begin() const { return tables.begin(); }
iterator end() const { return tables.end(); }
private:
Str2TableMap tables;
static SystemTables* instance;
SystemTables() {}
};
#endif