- key-value storage enabled cell (BS) completed.
- test content file is provided in sample/Sample2_SimpleStorageCells
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head><title>Dennco - test1</title>
+<link rel="stylesheet" type="text/css" href="dstyle.css" />
+</head>
+
+<body>
+<h1>Sample2 - persistent storage test</h1>
+
+<a define="cell" name="ConsoleOut">
+<a parameter="cellcode" type="B"> </a>
+<pre parameter="script">
+<![CDATA[
+function doTick(time)
+{
+ print("\nTickTime: " + time.toFixed(3));
+ print(" AutoCounter :" + this.cell.receptors.CounterValue);
+ print(" PersistentAutoCounter :" + this.cell.receptors.PersistentCounterValue);
+}
+]]>
+</pre>
+</a>
+
+<a define="cell" name="AutoCounter">
+<a parameter="cellcode" type="B"> </a>
+<pre parameter="script">
+<![CDATA[
+var counter = 0;
+function doTick(time)
+{
+ this.counter ++;
+ this.cell.axonValue = counter;
+}
+]]>
+</pre>
+<a parameter="connection" href="#ConsoleOut" receptor="CounterValue"></a>
+<a parameter="connection" href="#output1" receptor="autoCounter"></a>
+</a>
+
+<a define="cell" name="PersistentAutoCounter">
+<a parameter="cellcode" type="BS"> </a>
+<pre parameter="script">
+<![CDATA[
+var counter;
+function doInit()
+{
+ counter = this.cell.storage.getValue("counter");
+ if (counter == undefined)
+ {
+ counter = 0;
+ this.cell.storage.setValue("counter", counter);
+ }
+}
+
+function doTick(time)
+{
+ this.counter ++;
+ this.cell.axonValue = counter;
+}
+
+function doDestroy()
+{
+ this.cell.storage.setValue("counter", counter);
+}
+]]>
+</pre>
+<a parameter="connection" href="#ConsoleOut" receptor="PersistentCounterValue"></a>
+<a parameter="connection" href="#output2" receptor="persistentAutoCounter"></a>
+</a>
+
+<a define="cell" name="output1"><a parameter="cellcode" type="O"></a></a>
+<a define="cell" name="output2"><a parameter="cellcode" type="O"></a></a>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+
+a[define] {
+ border-top: 1px solid gray;
+ text-indent: 1em;
+ display: block;
+ margin-top: 32px;
+ margin-bottom: 8px;
+}
+
+a[define="cellcode"]:before {
+ content: "Definition of CellCode : " attr(name) " (type:" attr(type) ")" ;
+ font-size: large;
+ font-weight: bold;
+ display: inline;
+ white-space: pre;
+}
+
+
+a[define="cell"]:before {
+ content: "Definition of Cell : " attr(name) ;
+ font-size: large;
+ font-weight: bold;
+ display: inline;
+ white-space: pre;
+}
+
+a[parameter="cellcode"]:before {
+ content: "CellCode : " attr(href) attr(type);
+ display: inline;
+}
+
+a[parameter="cellcode"] {
+ text-indent: 1em;
+ display: block;
+}
+
+a[parameter="connection"]:before {
+ content: "-> " attr(href) "(" attr(name) ")";
+ display: inline;
+}
+
+a[parameter="connection"] {
+ text-indent: 2em;
+ display: block;
+}
+
+[parameter="script"] {
+ border: 1px solid gray;
+ background-color: #f0f0cc;
+ margin-left: 2em;
+}
--- /dev/null
+<dennco>
+
+<TickIntervalSec>1.0</TickIntervalSec>
+<UIPath>/ui/index.html</UIPath>
+<EnableHTTPServer>no</EnableHTTPServer> <!-- not implemented yet -->
+<EnableSerialServer>no</EnableSerialServer> <!-- not implemented yet -->
+
+</dennco>
\ No newline at end of file
--- /dev/null
+<html>
+<head>
+<title>Dennco Sample2 - Persistent storage test</title>
+<script type="text/javascript">
+var timerId = setInterval("updateOutput()", 500);
+
+function updateOutput()
+{
+ document.getElementById("output1Value").value = engine.getValue('/cells.xhtml#output1');
+ document.getElementById("output2Value").value = engine.getValue('/cells.xhtml#output2');
+}
+
+
+function stopTimer()
+{
+ clearInterval(timerId);
+}
+</script>
+</head>
+<body onunload="stopTimer()">
+<h3>Sample2 - Persistent storage test</h3>
+<table border=1 cellspacing=0 cellpadding=2>
+<tr>
+<td>Output from AutoCounter cell</td>
+<td><input type="text" disabled size="6" style="text-align:right" id="output1Value"/></td>
+</tr>
+<tr>
+<td>Output from PersistentAutoCounter cell</td>
+<td><input type="text" disabled size="6" style="text-align:right" id="output2Value"/></td>
+</tr>
+</table>
+
+</body>
+</html>
dnGlobal()->updateRunningStatus(DNGlobal::STOPPED);
std::string basePath(contentPath);
- std::string containerRoot = basePath.append("/Container");
+ std::string containerRoot = basePath;
+ containerRoot.append("/Container");
bool succeeded = false;
succeeded = parseSettingFile(contentPath);
}
return;
}
- succeeded = parseContainerFile(containerRoot.c_str());
+
+ std::string dataStorePath = containerRoot;
+ dataStorePath.append("/data.db");
+
+ succeeded = mContainer->setDataStore(dataStorePath.c_str());
if (!succeeded)
{
if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
{
dnGlobal()->setMessage1("Initialization failed");
- dnGlobal()->setMessage2("Failed to parse container file");
+ dnGlobal()->setMessage2("Failed to the setup data store");
}
else
{
return;
}
- std::string dataStorePath = containerRoot.append("/data.db");
-
- succeeded = mContainer->setDataStore(dataStorePath.c_str());
+ succeeded = parseContainerFile(containerRoot.c_str());
if (!succeeded)
{
if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
{
dnGlobal()->setMessage1("Initialization failed");
- dnGlobal()->setMessage2("Failed to the setup data store");
+ dnGlobal()->setMessage2("Failed to parse container file");
}
else
{
delete mDoTickThread;
mDoTickThread = NULL;
}
+ if (mContainer)
+ {
+ mContainer->doDestroy();
+ mContainer->releaseDataStore();
+ }
+
return r;
}
return r;
}
+int DNStorage::getCount(const char *path, const char *key)
+{
+ int r = 0;
+ if (impl)
+ {
+ r = impl->getCount(path,key);
+ }
+ return r;
+}
+
float DNStorage::getValue(const char *path, const char *key)
{
float r = 0;
//methods for simple key-value storage
bool setValue(const char *path, const char *key, float value);
float getValue(const char *path, const char *key);
+ int getCount(const char *path, const char *key);
//methods for dataset storage
int insertToDataSet(const char *path, const char *key, float v, float x, float y, float z);
virtual ~DNStorageImpl() {}
virtual bool setValue(const char *path, const char *key, float value) = 0;
virtual float getValue(const char *path, const char *key) = 0;
+ virtual int getCount(const char *path, const char *key) = 0;
virtual int insertToDataSet(const char *path, const char *key, float v, float x, float y, float z) = 0;
virtual const DNStorageDataSet *queryDataSet(const char *path, const char *key, const DNStorageDataSetQuery *query) const = 0;
//
#include "dnqsbasiccell.h"
+#include "TKContainer.h"
#include "dnqscontainer.h"
#include "TKLog.h"
#include "TKReceptor.h"
#include <QtScript/QScriptValue>
#include <QObject>
-class DNQSBasicCell : public DNQSCellBase, QObject
+class DNQSBasicCell : public DNQSCellBase
{
public:
- DNQSBasicCell(DNQSContainer *container, std::string location, std::string name, bool canIntarface = false);
+ DNQSBasicCell(DNQSContainer *container, std::string location, std::string name, bool canInterface = false);
virtual ~DNQSBasicCell();
virtual bool doTick(float time);
void reflectValueFromScript();
void handleScriptException(const char *funcName);
+protected:
QScriptEngine *mEngine;
QScriptValue mQSReceptors;
QScriptString mAxonValueHandle;
--- /dev/null
+// Copyright (c) 2012 Dennco Project
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+//
+// Created by tkawata on 3/28/2012.
+//
+#include "dnqsbasicstoragecell.h"
+
+#include "TKContainer.h"
+#include "dnqscontainer.h"
+#include "dnqsbasiccell.h"
+#include "TKLog.h"
+#include "TKDebug.h"
+#include "DNUtils.h"
+#include "DNStorage.h"
+
+static QScriptValue scriptStorageSetValue(QScriptContext *context, QScriptEngine *engine)
+{
+ QScriptValue data = context->thisObject().data();
+ TKASSERT(data.isQObject());
+ DNQSBasicStorageCell::QObjectSelfWrapper *wrapper = (DNQSBasicStorageCell::QObjectSelfWrapper*) data.toQObject();
+ TKASSERT(wrapper);
+ if (wrapper && context->argumentCount() >= 2)
+ {
+ wrapper->setValue(context->argument(0).toString().toUtf8().constData(),context->argument(1).toNumber());
+ }
+ return engine->nullValue();
+}
+
+static QScriptValue scriptStorageGetValue(QScriptContext *context, QScriptEngine *engine)
+{
+ QScriptValue data = context->thisObject().data();
+ TKASSERT(data.isQObject());
+ DNQSBasicStorageCell::QObjectSelfWrapper *wrapper = (DNQSBasicStorageCell::QObjectSelfWrapper*) data.toQObject();
+ TKASSERT(wrapper);
+ if (wrapper && context->argumentCount() >= 1)
+ {
+ QByteArray qkey = context->argument(0).toString().toUtf8();
+ const char *key = qkey.constData();
+ if (wrapper->getCount(key) == 0)
+ {
+ return engine->undefinedValue();
+ }
+ else
+ {
+ return QScriptValue(wrapper->getValue(key));
+ }
+ }
+ return engine->nullValue();
+}
+
+
+DNQSBasicStorageCell::DNQSBasicStorageCell(DNQSContainer *container, std::string location, std::string name, bool canInterface) :
+ DNQSBasicCell(container, location, name, canInterface)
+{
+
+ mQSStorage = mEngine->newObject();
+ mQSStorage.setProperty("setValue",mEngine->newFunction(scriptStorageSetValue, 2));
+ mQSStorage.setProperty("getValue",mEngine->newFunction(scriptStorageGetValue, 1));
+ mQSAPIInstance.setProperty("storage", mQSStorage,QScriptValue::ReadOnly|QScriptValue::Undeletable);
+ mQSelf = new QObjectSelfWrapper(this);
+ mQSStorage.setData(mEngine->newQObject(mQSelf));
+}
+
+DNQSBasicStorageCell::~DNQSBasicStorageCell()
+{
+ if (mQSelf)
+ {
+ delete mQSelf;
+ mQSelf = NULL;
+ }
+}
+
+DNQSBasicStorageCell::QObjectSelfWrapper::QObjectSelfWrapper(DNQSBasicStorageCell *self) : mSelf(self)
+{
+ mPath = getFQNString(self->mLocation.c_str(), self->mName.c_str());
+}
+
+int DNQSBasicStorageCell::QObjectSelfWrapper::getCount(const char* key)
+{
+ DNStorage *storage = mSelf->mContainer->getDataStore();
+ if (storage)
+ return storage->getCount(mPath.c_str(),key);
+ else
+ return 0;
+}
+
+float DNQSBasicStorageCell::QObjectSelfWrapper::getValue(const char *key)
+{
+ DNStorage *storage = mSelf->mContainer->getDataStore();
+ if (storage)
+ return storage->getValue(mPath.c_str(), key);
+ else
+ return 0.0;
+}
+
+bool DNQSBasicStorageCell::QObjectSelfWrapper::setValue(const char *key, float value)
+{
+ DNStorage *storage = mSelf->mContainer->getDataStore();
+ if (storage)
+ return storage->setValue(mPath.c_str(), key, value);
+ else
+ return false;
+}
--- /dev/null
+// Copyright (c) 2012 Dennco Project
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+//
+// Created by tkawata on 3/28/2012.
+//
+#ifndef DNQSBASICSTORAGECELL_H
+#define DNQSBASICSTORAGECELL_H
+
+#include "dnqsbasiccell.h"
+
+#include <QtScript/QScriptEngine>
+#include <QtScript/QScriptValue>
+#include <QObject>
+
+#include <string>
+
+class DNQSBasicStorageCell : public DNQSBasicCell
+{
+public:
+ DNQSBasicStorageCell(DNQSContainer *container, std::string location, std::string name, bool canInterface = false);
+ virtual ~DNQSBasicStorageCell();
+
+ class QObjectSelfWrapper : public QObject
+ {
+ public:
+ QObjectSelfWrapper(DNQSBasicStorageCell *self);
+
+ int getCount(const char* key);
+ float getValue(const char *key);
+ bool setValue(const char *key, float value);
+
+ private:
+ DNQSBasicStorageCell *mSelf;
+ std::string mPath;
+ };
+
+private:
+ QScriptValue mQSStorage;
+ QObjectSelfWrapper *mQSelf;
+};
+
+#endif // DNQSBASICSTORAGECELL_H
#include "DNUtils.h"
#include "TKLog.h"
+#include "TKContainer.h"
#include "dnqscontainer.h"
#include "dnqscellbase.h"
#include "dnqscellcodeinstance.h"
//
#include "dnqscellcodeinstance.h"
+#include "TKContainer.h"
#include "dnqscontainer.h"
#include "TKCell.h"
#include "TKLog.h"
#include "TKCell.h"
#include "TKCellCode.h"
+#include "TKContainer.h"
#include "TKLog.h"
#include "DNUtils.h"
#include "versioninfo.h"
#include "dnqsbasiccell.h"
#include "dnqsinputcell.h"
#include "dnqsoutputcell.h"
+#include "dnqsbasicstoragecell.h"
#include "TKUICell.h"
#include "dnqscellcode.h"
#include "DNGlobal.h"
const std::string DNQSContainer::CELLTYPE_JSBASIC = "B";
const std::string DNQSContainer::CELLTYPE_OUT = "O";
const std::string DNQSContainer::CELLTYPE_IN = "I";
+const std::string DNQSContainer::CELLTYPE_BASICSTORAGE = "BS";
static QScriptValue scriptPrint(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() >= 2)
{
const char *location = context->argument(0).toString().toUtf8().constData();
- const char *name = context->argument(0).toString().toUtf8().constData();
+ const char *name = context->argument(1).toString().toUtf8().constData();
std::string fqnString = getFQNString(location, name);
return QScriptValue(fqnString.c_str());
cell = new DNQSOutputCell(this, theLocation, theName, true);
noScript = true;
}
+ else if (type == CELLTYPE_BASICSTORAGE)
+ {
+ cell = new DNQSBasicStorageCell(this, theLocation, theName, false);
+ }
else
{
std::string message = std::string("Failed to construct cell '").append(theLocation).append("#").append(theName);
return cellCode;
}
-bool DNQSContainer::doTick(float time)
-{
- for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it ) {
- it->second->doTick(time);
- }
-
- return true;
-}
-
void DNQSContainer::setValue(std::string key, float value)
{
mQSGlobalObject.setProperty(QString::fromStdString(key), QScriptValue(value));
virtual TKCell* createCellWithCellCodeClass(std::string theLocation, std::string theName, TKCellCode *cellCode, std::string customScript);
virtual TKCellCode* createCellCode(std::string theName, std::string theAPIType, std::string code);
- virtual bool doTick(float time);
-
virtual void setValue(std::string key, float value);
virtual float getValue(std::string key);
static const std::string CELLTYPE_JSBASIC;
static const std::string CELLTYPE_OUT;
static const std::string CELLTYPE_IN;
+ static const std::string CELLTYPE_BASICSTORAGE;
private:
QScriptEngine *mQSEngine;
TKContainer::~TKContainer()
{
+ doDestroy();
+ releaseDataStore();
+}
+
+bool TKContainer::doTick(float time)
+{
+ mLock.lock();
+ for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it ) {
+ it->second->doTick(time);
+ }
+ mLock.unlock();
+ return true;
+}
+
+bool TKContainer::doDestroy()
+{
+ mLock.lock();
+
for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it ) {
(it->second)->doDestroy();
}
mCells.clear();
mInterfaceCells.clear();
- if (mStorage)
- {
- delete mStorage;
- }
+ mLock.unlock();
+ return true;
}
bool TKContainer::setDataStore(std::string storagePath)
return mStorage->isValid();
}
+bool TKContainer::releaseDataStore()
+{
+ mLock.lock();
+ if (mStorage)
+ {
+ delete mStorage;
+ mStorage = NULL;
+ }
+ mLock.unlock();
+ return true;
+}
+
TKCell* TKContainer::getCell(std::string theFQNName)
{
TKCellMap::iterator it = mCells.find(theFQNName);
#ifndef __INCLUDE_TKCONTAINER__
#define __INCLUDE_TKCONTAINER__
+#include "TKLock.h"
+
#include <string>
#include <map>
const TKCellMap* getCells() { return &mCells; }
const TKCellCodeMap* getCellCodes() { return &mCellCodes; }
- void setContentPath(std::string contentPath) { mContentPath = contentPath; }
+
+ void setContentPath(std::string contentPath) { mContentPath = contentPath; }
std::string getContentPath() { return mContentPath; }
- bool setDataStore(std::string storagePath);
- TKCell* getCell(std::string theFQNName);
- TKCell* getInterfaceCell(std::string theFQNName);
+ bool setDataStore(std::string storagePath);
+ DNStorage* getDataStore() { return mStorage; }
+ bool releaseDataStore();
+ TKCell* getCell(std::string theFQNName);
+ TKCell* getInterfaceCell(std::string theFQNName);
TKCellCode* getCellCode(std::string theCellCodeName);
+ bool doTick(float time);
+ bool doDestroy();
+
virtual TKCell* createCellWithoutCellCodeClass(std::string theLocation, std::string theName, std::string type, std::string customScript) = 0;
virtual TKCell* createCellWithCellCodeClass(std::string theLocation, std::string theName, TKCellCode *cellCode, std::string customScript) = 0;
virtual TKCellCode* createCellCode(std::string theName, std::string theAPIType, std::string code) = 0;
- virtual bool doTick(float time) = 0;
-
virtual void setValue(std::string key, float value) = 0;
inline virtual float getValue(std::string key) = 0;
TKCellCodeMap mCellCodes;
std::string mContentPath;
DNStorage *mStorage;
+
+private:
+ TKLock mLock;
};
#endif
#include "qtdnstorageimpl.h"
#include "DNStorageImpl.h"
+#include "TKLog.h"
#include <QtSql>
-
#include <DNGlobal.h>
//static
QtDNStorageImpl::~QtDNStorageImpl()
{
- if (mDB.isValid() && mDB.isOpen())
+ if (mQueries)
{
- mDB.close();
- mDB.removeDatabase(mDB.connectionName());
+ delete mQueries;
+ mQueries = NULL;
+ }
+
+ if (mDatabase)
+ {
+ QString connectionName = mDatabase->database.connectionName();
+ if (mDatabase->database.isValid() && mDatabase->database.isOpen())
+ {
+ mDatabase->database.close();
+ }
+
+ delete mDatabase;
+ QSqlDatabase::removeDatabase(connectionName);
+ mDatabase = NULL;
}
}
-QtDNStorageImpl::QtDNStorageImpl(const char *storagePath)
+QtDNStorageImpl::QtDNStorageImpl(const char *storagePath) : mDatabase(NULL),mQueries(NULL)
{
mStoragePath = QString::fromLocal8Bit(storagePath);
mIsValid = initDB();
QString qPath(path);
QString qKey(key);
- mPropertiesCountQuery.addBindValue(qPath);
- mPropertiesCountQuery.addBindValue(qKey);
- if (!mPropertiesCountQuery.exec())
+ mQueries->propertiesCountQuery.addBindValue(qPath);
+ mQueries->propertiesCountQuery.addBindValue(qKey);
+ if (!mQueries->propertiesCountQuery.exec())
{
std::string message = "SQL error while processing cell ";
message.append(path);
message.append("\n");
- message.append(mPropertiesCountQuery.lastError().text().toStdString());
+ message.append(mQueries->propertiesCountQuery.lastError().text().toStdString());
+ TKLog::printf("%s", message.c_str());
return false;
}
- int cnt = mPropertiesCountQuery.boundValue(1).toInt();
+ mQueries->propertiesCountQuery.next();
+ int cnt = mQueries->propertiesCountQuery.value(0).toInt();
if (cnt == 0)
{
- mPropertiesInsertQuery.addBindValue(qPath);
- mPropertiesInsertQuery.addBindValue(qKey);
- mPropertiesInsertQuery.addBindValue(value);
- if (!mPropertiesInsertQuery.exec())
+ mQueries->propertiesInsertQuery.addBindValue(qPath);
+ mQueries->propertiesInsertQuery.addBindValue(qKey);
+ mQueries->propertiesInsertQuery.addBindValue(value);
+ if (!mQueries->propertiesInsertQuery.exec())
{
std::string message = "SQL error while processing cell ";
message.append(path);
message.append("\n");
- message.append(mPropertiesCountQuery.lastError().text().toStdString());
+ message.append(mQueries->propertiesCountQuery.lastError().text().toStdString());
+ TKLog::printf("%s", message.c_str());
return false;
}
}
else
{
- mPropertiesUpdateQuery.addBindValue(value);
- mPropertiesUpdateQuery.addBindValue(qPath);
- mPropertiesUpdateQuery.addBindValue(qKey);
- if (!mPropertiesUpdateQuery.exec())
+ mQueries->propertiesUpdateQuery.addBindValue(value);
+ mQueries->propertiesUpdateQuery.addBindValue(qPath);
+ mQueries->propertiesUpdateQuery.addBindValue(qKey);
+ if (!mQueries->propertiesUpdateQuery.exec())
{
std::string message = "SQL error while processing cell ";
message.append(path);
message.append("\n");
- message.append(mPropertiesCountQuery.lastError().text().toStdString());
+ message.append(mQueries->propertiesCountQuery.lastError().text().toStdString());
+ TKLog::printf("%s", message.c_str());
return false;
}
}
float QtDNStorageImpl::getValue(const char *path, const char *key)
{
- if (!mIsValid)
+ if (mQueries == NULL || !mIsValid)
return 0;
- mPropertiesGetQuery.prepare("SELECT value FROM properties WHERE cell=? and key=?");
-
QString qPath(path);
QString qKey(key);
- mPropertiesGetQuery.addBindValue(qPath);
- mPropertiesGetQuery.addBindValue(qKey);
- if (!mPropertiesGetQuery.exec())
+ mQueries->propertiesGetQuery.addBindValue(qPath);
+ mQueries->propertiesGetQuery.addBindValue(qKey);
+ if (!mQueries->propertiesGetQuery.exec())
{
std::string message = "SQL error while processing cell ";
message.append(path);
message.append("\n");
- message.append(mPropertiesCountQuery.lastError().text().toStdString());
+ message.append(mQueries->propertiesCountQuery.lastError().text().toStdString());
+ TKLog::printf("%s", message.c_str());
return false;
}
- if (mPropertiesGetQuery.size() > 0)
+ mQueries->propertiesGetQuery.next();
+ return mQueries->propertiesGetQuery.value(0).toFloat();
+}
+
+int QtDNStorageImpl::getCount(const char *path, const char *key)
+{
+ if (!mIsValid)
+ return false;
+
+ QString qPath(path);
+ QString qKey(key);
+ mQueries->propertiesCountQuery.addBindValue(qPath);
+ mQueries->propertiesCountQuery.addBindValue(qKey);
+ if (!mQueries->propertiesCountQuery.exec())
{
- return mPropertiesGetQuery.boundValue(1).toFloat();
+ std::string message = "SQL error while processing cell ";
+ message.append(path);
+ message.append("\n");
+ message.append(mQueries->propertiesCountQuery.lastError().text().toStdString());
+ TKLog::printf("%s", message.c_str());
+ return false;
}
- else
- return 0.0;
+
+ mQueries->propertiesCountQuery.next();
+ return mQueries->propertiesCountQuery.value(0).toInt();
}
+
int QtDNStorageImpl::insertToDataSet(const char *path, const char *key, float v, float x, float y, float z)
{
- if (!mIsValid)
+ if (mQueries == NULL || !mIsValid)
return 0;
//TODO
return 0;
const DNStorageDataSet* QtDNStorageImpl::queryDataSet(const char *path, const char *key, const DNStorageDataSetQuery *query) const
{
- if (!mIsValid)
+ if (mQueries == NULL || !mIsValid)
return 0;
//TODO
return 0;
bool QtDNStorageImpl::updateDataSet(const char *path, const char *key, int index, float v, float x, float y, float z)
{
- if (!mIsValid)
+ if (mQueries == NULL || !mIsValid)
return false;
//TODO
return false;
bool QtDNStorageImpl::deleteFromDataSet(const char *path, const char *key, int index)
{
- if (!mIsValid)
+ if (mQueries == NULL || !mIsValid)
return false;
//TODO
return false;
bool QtDNStorageImpl::flush()
{
- if (!mIsValid || !mDB.isValid())
+ if (mDatabase == NULL || !mIsValid)
return false;
- mDB.commit();
+ mDatabase->database.commit();
return true;
}
bool QtDNStorageImpl::initDB()
{
+ mDatabase = new QtDNDatabase;
- mDB = QSqlDatabase::addDatabase("QSQLITE");
- mDB.setDatabaseName(mStoragePath);
+ mDatabase->database = QSqlDatabase::addDatabase("QSQLITE");
+ mDatabase->database.setDatabaseName(mStoragePath);
- if (!mDB.open())
+ if (!mDatabase->database.open())
{
std::string message = "Failied to open storage file ";
message.append(mStoragePath.toStdString());
message.append("\n");
- message.append(mDB.lastError().text().toStdString());
+ message.append(mDatabase->database.lastError().text().toStdString());
if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
{
dnGlobal()->setMessage1("Persistent storage initialization error.");
return false;
}
- QStringList tables = mDB.tables();
+ QStringList tables = mDatabase->database.tables();
if (!tables.contains("properties"))
{
QSqlQuery q;
if (!q.exec("CREATE TABLE properties(cell TEXT, prokey TEXT, value REAL, PRIMARY KEY (cell, prokey))"));
{
- if (mDB.lastError().type() != QSqlError::NoError)
+ if (mDatabase->database.lastError().type() != QSqlError::NoError)
{
std::string message = "Failied to create data table (properties) in ";
message.append(mStoragePath.toStdString());
message.append("\n");
- message.append(mDB.lastError().text().toStdString());
+ message.append(mDatabase->database.lastError().text().toStdString());
if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
{
dnGlobal()->setMessage1("Persistent storage initialization error.");
if (!q.exec("CREATE TABLE dataset(cell TEXT, dskey TEXT, dsindex INTEGER, v REAL, x REAL, y REAL, z REAL, PRIMARY KEY (cell, dskey, dsindex))"));
{
- if (mDB.lastError().type() != QSqlError::NoError)
+ if (mDatabase->database.lastError().type() != QSqlError::NoError)
{
std::string message = "Failied to create data table (dataset) in ";
message.append(mStoragePath.toStdString());
message.append("\n");
- message.append(mDB.lastError().text().toStdString());
+ message.append(mDatabase->database.lastError().text().toStdString());
if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
{
dnGlobal()->setMessage1("Persistent storage initialization error.");
}
}
- mPropertiesCountQuery.prepare("SELECT count(*) FROM properties WHERE cell=? and prokey=?");
- mPropertiesInsertQuery.prepare("INSERT INTO properties (?,?,?)");
- mPropertiesUpdateQuery.prepare("UPDATE SET value=? WHERE cell=? and prokey=?");
- mPropertiesGetQuery.prepare("SELECT value FROM properties WHERE cell=? and prokey=?");
+ mQueries = new QtDNDBQueries;
+
+ mQueries->propertiesCountQuery.prepare("SELECT count(*) FROM properties WHERE cell=? and prokey=?");
+ mQueries->propertiesInsertQuery.prepare("INSERT INTO properties VALUES(?,?,?)");
+ mQueries->propertiesUpdateQuery.prepare("UPDATE properties SET value=? WHERE cell=? and prokey=?");
+ mQueries->propertiesGetQuery.prepare("SELECT value FROM properties WHERE cell=? and prokey=?");
+
+ mQueries->dataSetInsetToDataSetQuery.prepare("INSERT INTO dataset (?,?,?, ?,?,?,?)");
+ mQueries->dataSetUpdateDataSetQuery.prepare("UPDATE SET v=?, x=?, y=? z=? WHERE cell=? and dskey=? and dsindex=?");
+ mQueries->dataSetDeleteFromDataSetQuery.prepare("DELETE FROM dataset WHERE cell=? and key=? and index=?");
- mDataSetInsetToDataSetQuery.prepare("INSERT INTO dataset (?,?,?, ?,?,?,?)");
- mDataSetUpdateDataSetQuery.prepare("UPDATE SET v=?, x=?, y=? z=? WHERE cell=? and dskey=? and dsindex=?");
- mDataSetDeleteFromDataSetQuery.prepare("DELETE FROM dataset WHERE cell=? and key=? and index=?");
+ if (mDatabase->database.lastError().type() != QSqlError::NoError)
+ {
+ std::string message = "Failied to prepare database ";
+ message.append(mStoragePath.toStdString());
+ message.append("\n");
+ message.append(mDatabase->database.lastError().text().toStdString());
+ if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
+ {
+ dnGlobal()->setMessage1("Persistent storage initialization error.");
+ dnGlobal()->setMessage2(message);
+ }
+ return false;
+ }
return true;
}
#include <QString>
#include <QtSql>
+class QtDNDatabase
+{
+public:
+ QSqlDatabase database;
+};
+
+class QtDNDBQueries
+{
+public:
+ QSqlQuery propertiesCountQuery;
+ QSqlQuery propertiesInsertQuery;
+ QSqlQuery propertiesUpdateQuery;
+ QSqlQuery propertiesGetQuery;
+
+ QSqlQuery dataSetInsetToDataSetQuery;
+ QSqlQuery dataSetUpdateDataSetQuery;
+ QSqlQuery dataSetDeleteFromDataSetQuery;
+};
+
class QtDNStorageImpl : public DNStorageImpl
{
public:
virtual bool setValue(const char *path, const char *key, float value);
virtual float getValue(const char *path, const char *key);
+ virtual int getCount(const char *path, const char *key);
virtual int insertToDataSet(const char *path, const char *key, float v, float x, float y, float z);
virtual const DNStorageDataSet *queryDataSet(const char *path, const char *key, const DNStorageDataSetQuery *query) const;
virtual bool isValid() { return mIsValid; }
private:
- bool initDB();
- bool mIsValid;
- QString mStoragePath;
-
- QSqlQuery mPropertiesCountQuery;
- QSqlQuery mPropertiesInsertQuery;
- QSqlQuery mPropertiesUpdateQuery;
- QSqlQuery mPropertiesGetQuery;
-
- QSqlQuery mDataSetInsetToDataSetQuery;
- QSqlQuery mDataSetUpdateDataSetQuery;
- QSqlQuery mDataSetDeleteFromDataSetQuery;
-
- QSqlDatabase mDB;
+ bool initDB();
+ bool mIsValid;
+ QString mStoragePath;
+ QtDNDatabase *mDatabase;
+ QtDNDBQueries *mQueries;
};
#endif // QTDNSTORAGEIMPL_H
Source/QtScript/dnqsinputcell.cpp \
Source/QtScript/dnqsoutputcell.cpp \
Source/platform/qt/qtdnstorageimpl.cpp \
- Source/DNStorage.cpp
+ Source/DNStorage.cpp \
+ Source/QtScript/dnqsbasicstoragecell.cpp
HEADERS += Source/QtDennco/mainwindow.h \
Source/TKUICell.h \
Source/QtScript/dnqsoutputcell.h \
Source/DNStorageImpl.h \
Source/DNStorage.h \
- Source/platform/qt/qtdnstorageimpl.h
+ Source/platform/qt/qtdnstorageimpl.h \
+ Source/QtScript/dnqsbasicstoragecell.h
FORMS += Source/QtDennco/mainwindow.ui
Debug:DEFINES+=DEBUG