Files
secondo/Algebras/NestedRelation2/Nr2aHelper.cpp

212 lines
5.4 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
----
*/
#include "Include.h"
using namespace std;
namespace nr2a {
/*
The following functions build some less more complex types from the given
list expression containing the resulting type's attributes' types.
*/
/*static*/ ListExpr Nr2aHelper::TupleStreamOf(ListExpr attributesTypes)
{
return nl->TwoElemList(nl->SymbolAtom(Symbol::STREAM()),
TupleOf(attributesTypes));
}
/*static*/ ListExpr Nr2aHelper::TupleOf(ListExpr attributesTypes)
{
return nl->TwoElemList(nl->SymbolAtom("tuple"), attributesTypes);
}
/*static*/ ListExpr Nr2aHelper::RecordOf(ListExpr attributesTypes)
{
return nl->Cons(nl->SymbolAtom("record"), attributesTypes);
}
/*
To check whether a given type is either a nested relation or an attribute
relation this function can be used.
*/
/*static*/ bool Nr2aHelper::IsNestedRelation(const ListExpr definition)
{
bool result = false;
AutoWrite(definition);
if (!nl->IsEmpty(definition) && nl->HasLength(definition, 2))
{
const ListExpr nestedRelationType = nl->First(definition);
if (listutils::isSymbol(nestedRelationType))
{
result = (nl->SymbolValue(nestedRelationType) == ARel::BasicType())
|| (nl->SymbolValue(nestedRelationType) == NRel::BasicType());
}
else if (IsNumericRepresentationOf(nestedRelationType, ARel::BasicType())
|| IsNumericRepresentationOf(nestedRelationType, NRel::BasicType()))
{
result = true;
}
}
return result;
}
/*
Checks if the first argument is a numeric representation (in nested list
format) of the type given as a string in the second argument.
*/
/*static*/ bool Nr2aHelper::IsNumericRepresentationOf(
const ListExpr list, const string typeName)
{
int algId = 0;
int typeId = 0;
bool result = false;
if (nl->HasLength(list, 2) && (nl->AtomType(nl->First(list))==IntType)
&& (nl->AtomType(nl->Second(list))==IntType))
{
SecondoSystem::GetCatalog()->GetTypeId(typeName, algId, typeId);
result = (algId == nl->IntValue(nl->First(list))) &&
(typeId == nl->IntValue(nl->Second(list)));
}
return result;
}
/*
A few operators in the algebra can process both, "ARel"[2] and "NRel"[2]
values. They can reference this method instead of defining their implementation
of the same logic.
*/
/*static*/ int Nr2aHelper::DefaultSelect(const ListExpr type)
{
// When using this function it is assumed, that only arel2 and nrel2 are
// accepted by the type mapping function
AutoWrite(type);
assert(
listutils::isSymbol(nl->First(type), ARel::BasicType())
|| listutils::isSymbol(nl->First(type), NRel::BasicType()));
return (nl->SymbolValue(nl->First(type)) == ARel::BasicType()) ? 0 : 1;
}
/*static*/ string Nr2aHelper::IntToString(const int num)
{
const int cBufferLen = 10;
char buffer[cBufferLen];
memset(buffer, '\0', cBufferLen);
sprintf(buffer, "%d", num);
return string(buffer);
}
/*static*/ double Nr2aHelper::MillisecondsElapsedSince
(clock_t previousClock)
{
clock_t now = clock();
assert(previousClock <= now);
return ((double)(now - previousClock) * 1000) / CLOCKS_PER_SEC;
}
/*
A list builder is constructed with an empty list in its storage...
*/
ListBuilder::ListBuilder()
: m_list(nl->TheEmptyList()), m_end(nl->TheEmptyList())
{
}
/*
...which can then be filled via appending nested list expression or attribute
definitions, which are then transformed to nested list format internally.
*/
void ListBuilder::Append(const ListExpr newElement)
{
if (nl->IsEmpty(m_list))
{
m_list = nl->OneElemList(newElement);
m_end = m_list;
}
else
{
m_end = nl->Append(m_end, newElement);
}
}
void ListBuilder::AppendAttribute(const string attributeName,
const ListExpr type)
{
Append(nl->TwoElemList(nl->SymbolAtom(attributeName), type));
}
void ListBuilder::AppendAttribute(const string attributeName,
const string typeName)
{
AppendAttribute(attributeName, nl->SymbolAtom(typeName));
}
/*
If the content is defined properly one can request a type definition of the
desired type by calling one of the provided getters.
*/
ListExpr ListBuilder::GetList() const
{
return m_list;
}
ListExpr ListBuilder::GetTuple() const
{
return Nr2aHelper::TupleOf(m_list);
}
ListExpr ListBuilder::GetRecord() const
{
return Nr2aHelper::RecordOf(m_list);
}
ListExpr ListBuilder::GetARel() const
{
return nl->TwoElemList(nl->SymbolAtom(ARel::BasicType()),
Nr2aHelper::TupleOf(m_list));
}
ListExpr ListBuilder::GetNRel() const
{
return nl->TwoElemList(nl->SymbolAtom(NRel::BasicType()),
Nr2aHelper::TupleOf(m_list));
}
ListExpr ListBuilder::GetTupleStream() const
{
return Nr2aHelper::TupleStreamOf(m_list);
}
} // namespace nr2a