From a9fb4f869271f47c3a4507d2bc6b8b3d756ec873 Mon Sep 17 00:00:00 2001 From: Aaron Seigo Date: Tue, 9 Dec 2014 22:02:35 +0100 Subject: DataSet, and create a small lib to be used by tests --- tests/hawd/CMakeLists.txt | 14 ++- tests/hawd/dataset.cpp | 193 +++++++++++++++++++++++++++++++++++++++ tests/hawd/dataset.h | 80 ++++++++++++++++ tests/hawd/datasetdefinition.cpp | 46 +--------- tests/hawd/datasetdefinition.h | 14 --- tests/hawd/state.cpp | 24 ++--- tests/hawd/state.h | 2 +- 7 files changed, 301 insertions(+), 72 deletions(-) create mode 100644 tests/hawd/dataset.cpp create mode 100644 tests/hawd/dataset.h (limited to 'tests/hawd') diff --git a/tests/hawd/CMakeLists.txt b/tests/hawd/CMakeLists.txt index 8c677c0..ebc5ac2 100644 --- a/tests/hawd/CMakeLists.txt +++ b/tests/hawd/CMakeLists.txt @@ -2,15 +2,25 @@ project(hawd) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) -set(SRCS +set(lib_SRCS + dataset.cpp datasetdefinition.cpp + state.cpp +) + +set(SRCS main.cpp module.cpp - state.cpp modules/list.cpp ) +add_library(libhawd ${lib_SRCS}) +qt5_use_modules(libhawd Core) +target_link_libraries(libhawd akonadi2common) +install(TARGETS libhawd DESTINATION lib) + add_executable(${PROJECT_NAME} ${SRCS}) qt5_use_modules(${PROJECT_NAME} Core) +target_link_libraries(${PROJECT_NAME} libhawd) install(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/tests/hawd/dataset.cpp b/tests/hawd/dataset.cpp new file mode 100644 index 0000000..9211430 --- /dev/null +++ b/tests/hawd/dataset.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2014 Aaron Seigo + * + * This program 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. + * + * This program 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 this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "dataset.h" + +#include +#include + +#include + +namespace HAWD +{ + +Dataset::Row::Row(const Row &other) + : m_key(other.m_key), + m_columns(other.m_columns), + m_data(other.m_data), + m_dataset(other.m_dataset) +{ +} + +Dataset::Row::Row(const Dataset &dataset, qint64 key) + : m_key(key), + m_columns(dataset.definition().columns()), + m_dataset(&dataset) +{ + // TODO: pre-populate m_data, or do that on buffer creation? + QHashIterator it(dataset.definition().columns()); + while (it.hasNext()) { + it.next(); + m_data.insert(it.key(), QVariant()); + } +} + +Dataset::Row &Dataset::Row::operator=(const Row &rhs) +{ + m_key = rhs.m_key; + m_columns = rhs.m_columns; + m_data = rhs.m_data; + m_dataset = rhs.m_dataset; + return *this; +} + +void Dataset::Row::setValue(const QString &column, const QVariant &value) +{ + if (!m_columns.contains(column) || !value.canConvert(m_columns[column].type())) { + return; + } + + m_data[column] = value; +} + +void Dataset::Row::annotate(const QString ¬e) +{ + m_annotation = note; +} + +qint64 Dataset::Row::key() const +{ + if (m_key < 1) { + const_cast(this)->m_key = QDateTime::currentMSecsSinceEpoch(); + } + + return m_key; +} + +void Dataset::Row::fromBinary(QByteArray &data) +{ + QVariant value; + QString key; + QDataStream stream(&data, QIODevice::ReadOnly); + + while (!stream.atEnd()) { + stream >> key >> value; + setValue(key, value); + } +} + +QByteArray Dataset::Row::toBinary() const +{ + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + QHashIterator it(m_data); + while (it.hasNext()) { + it.next(); + stream << it.key() << it.value(); + } + + return data; +} + +QString Dataset::Row::toString() const +{ + if (m_data.isEmpty()) { + return QString(); + } + + QString string; + QHashIterator it(m_data); + while (it.hasNext()) { + it.next(); + string.append('\t').append(it.value().toString()); + } + + if (!m_annotation.isEmpty()) { + string.append('\t').append(m_annotation); + } + + return string; +} + +Dataset::Dataset(const QString &name, const State &state) + : m_definition(state.datasetDefinition(name)), + m_storage(state.resultsPath(), m_definition.name(), Storage::ReadWrite) +{ + //TODO: it should use a different file name if the data columns have changed + m_storage.startTransaction(); +} + +Dataset::~Dataset() +{ + m_storage.commitTransaction(); +} + +bool Dataset::isValid() +{ + return m_definition.isValid(); +} + +const DatasetDefinition &Dataset::definition() const +{ + return m_definition; +} + +qint64 Dataset::insertRow(const Row &row) +{ + if (row.m_dataset != this) { + return 0; + } + + qint64 key = row.key(); + QByteArray data = row.toBinary(); + m_storage.write((const char *)&key, sizeof(qint64), data.constData(), data.size()); + return key; +} + +void Dataset::removeRow(const Row &row) +{ + //TODO +} + +Dataset::Row Dataset::row(qint64 key) +{ + if (key < 1) { + return Row(*this); + } + + Row row(*this, key); + m_storage.read((const char *)&key, sizeof(qint64), + [&row](void *ptr, int size) -> bool { + QByteArray array((const char*)ptr, size); + row.fromBinary(array); + return true; + }, + Storage::basicErrorHandler() + ); + return row; +} + +Dataset::Row Dataset::lastRow() +{ + //TODO + return Row(*this); +} + +} // namespace HAWD + diff --git a/tests/hawd/dataset.h b/tests/hawd/dataset.h new file mode 100644 index 0000000..eb18b70 --- /dev/null +++ b/tests/hawd/dataset.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2014 Aaron Seigo + * + * This program 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. + * + * This program 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 this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include "datasetdefinition.h" + +#include "state.h" +#include "common/storage.h" + +#include +#include + +namespace HAWD +{ + +class Dataset +{ +public: + class Row + { + public: + Row(const Row &other); + Row &operator=(const Row &rhs); + void setValue(const QString &column, const QVariant &value); + QVariant value(const QString &column); + void annotate(const QString ¬e); + qint64 key() const; + QByteArray toBinary() const; + QString toString() const; + + private: + Row(); + Row(const Dataset &dataset, qint64 key = 0); + void fromBinary(QByteArray &binary); + + qint64 m_key; + QHash m_columns; + QHash m_data; + QString m_annotation; + const Dataset *m_dataset; + friend class Dataset; + }; + + Dataset(const DatasetDefinition &definition); + Dataset(const QString &name, const State &state); + ~Dataset(); + + bool isValid(); + const DatasetDefinition &definition() const; + + qint64 insertRow(const Row &row); + void removeRow(const Row &row); + Row row(qint64 key = 0); + Row lastRow(); + //TODO: row cursor + +private: + DatasetDefinition m_definition; + Storage m_storage; +}; + +} // namespace HAWD + diff --git a/tests/hawd/datasetdefinition.cpp b/tests/hawd/datasetdefinition.cpp index d67c136..2fa96cf 100644 --- a/tests/hawd/datasetdefinition.cpp +++ b/tests/hawd/datasetdefinition.cpp @@ -54,6 +54,8 @@ DataDefinition::DataDefinition(const QJsonObject &json) s_types.insert("int", QMetaType::Int); s_types.insert("uint", QMetaType::UInt); s_types.insert("bool", QMetaType::Bool); + s_types.insert("float", QMetaType::Float); + s_types.insert("double", QMetaType::Double); s_types.insert("char", QMetaType::QChar); s_types.insert("string", QMetaType::QString); s_types.insert("datetime", QMetaType::QDateTime); @@ -95,50 +97,6 @@ int DataDefinition::max() const return m_max; } -DatasetRow::DatasetRow(const QHash &columns) - : m_columns(columns) -{ - QHashIterator it(columns); - while (it.hasNext()) { - it.next(); - m_data.insert(it.key(), QVariant()); - } -} - -void DatasetRow::setValue(const QString &column, const QVariant &value) -{ - if (!m_columns.contains(column) || !value.canConvert(m_columns[column].type())) { - return; - } - - m_data[column] = value; -} - -void DatasetRow::annotate(const QString ¬e) -{ - m_annotation = note; -} - -QString DatasetRow::toString() const -{ - if (m_data.isEmpty()) { - return QString(); - } - - QString string = QString::number(QDateTime::currentMSecsSinceEpoch()); - QHashIterator it(m_data); - while (it.hasNext()) { - it.next(); - string.append('\t').append(it.value().toString()); - } - - if (!m_annotation.isEmpty()) { - string.append('\t').append(m_annotation); - } - - return string; -} - DatasetDefinition::DatasetDefinition(const QString &path) : m_valid(false) { diff --git a/tests/hawd/datasetdefinition.h b/tests/hawd/datasetdefinition.h index 0593f39..eb4b780 100644 --- a/tests/hawd/datasetdefinition.h +++ b/tests/hawd/datasetdefinition.h @@ -47,20 +47,6 @@ private: int m_max; }; -class DatasetRow -{ -public: - DatasetRow(const QHash &columns); - void setValue(const QString &column, const QVariant &value); - void annotate(const QString ¬e); - QString toString() const; - -private: - QHash m_columns; - QHash m_data; - QString m_annotation; -}; - class DatasetDefinition { public: diff --git a/tests/hawd/state.cpp b/tests/hawd/state.cpp index cfc4326..3ee7775 100644 --- a/tests/hawd/state.cpp +++ b/tests/hawd/state.cpp @@ -31,22 +31,24 @@ static const QString configFileName("hawd.conf"); namespace HAWD { -State::State() +State::State(const QString &_configPath) : m_valid(true) { - QDir dir; - QString configPath; + QString configPath = _configPath; + if (configPath.isEmpty()) { + QDir dir; - while (!dir.exists(configFileName) && dir.cdUp()) { } + while (!dir.exists(configFileName) && dir.cdUp()) { } - if (dir.exists(configFileName)) { - configPath = dir.absoluteFilePath(configFileName); - } + if (dir.exists(configFileName)) { + configPath = dir.absoluteFilePath(configFileName); + } - if (configPath.isEmpty()) { - std::cerr << QObject::tr("Could not find hawd configuration. A hawd.conf file must be in the current directory or in a directory above it.").toStdString() << std::endl; - m_valid = false; - return; + if (configPath.isEmpty()) { + std::cerr << QObject::tr("Could not find hawd configuration. A hawd.conf file must be in the current directory or in a directory above it.").toStdString() << std::endl; + m_valid = false; + return; + } } QFile configFile(configPath); diff --git a/tests/hawd/state.h b/tests/hawd/state.h index 5e4d3c2..72ac528 100644 --- a/tests/hawd/state.h +++ b/tests/hawd/state.h @@ -30,7 +30,7 @@ namespace HAWD class State { public: - State(); + State(const QString &configPath = QString()); bool isValid() const; QVariant configValue(const QString &key) const; -- cgit v1.2.3