summaryrefslogtreecommitdiffstats
path: root/src/database.cpp
diff options
context:
space:
mode:
authorMorten Sørvig <msorvig@trolltech.com>2008-12-05 13:04:56 +0100
committerMorten Sørvig <msorvig@trolltech.com>2008-12-05 13:04:56 +0100
commit33116778ad21ffc7309d99c739026565482935ae (patch)
treefc43357ef0186c8bd5cb52043e1b3f9e42e6c0e1 /src/database.cpp
Initital commit.
Diffstat (limited to 'src/database.cpp')
-rw-r--r--src/database.cpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/src/database.cpp b/src/database.cpp
new file mode 100644
index 0000000..80a0772
--- /dev/null
+++ b/src/database.cpp
@@ -0,0 +1,281 @@
+
+#include "database.h"
+#include <QtGui>
+#include <QtXml>
+
+// Database schema definition and open/create functions
+
+QString resultsTable = QString("(TestName varchar, TestCaseName varchar, Series varchar, Idx varchar, ") +
+ QString("Result varchar, ChartType varchar, Title varchar, ChartWidth varchar, ") +
+ QString("ChartHeight varchar, TestTitle varchar, QtVersion varchar, Iterations varchar") +
+ QString(")");
+
+void execQuery(QSqlQuery query, bool warnOnFail)
+{
+ bool ok = query.exec();
+ if (!ok && warnOnFail) {
+ qDebug() << "FAIL:" << query.lastQuery() << query.lastError().text();
+ }
+}
+
+void execQuery(const QString &spec, bool warnOnFail)
+{
+ QSqlQuery query;
+ query.prepare(spec);
+ execQuery(query, warnOnFail);
+}
+
+QSqlDatabase openDataBase(const QString &databaseFile)
+{
+// qDebug() << "open data base";
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+ db.setDatabaseName(databaseFile);
+ bool ok = db.open();
+ if (!ok)
+ qDebug() << "FAIL: could not open database";
+ return db;
+}
+
+QSqlDatabase createDataBase(const QString &databaseFile)
+{
+// qDebug() << "create data base";
+ QSqlDatabase db = openDataBase(databaseFile);
+
+ execQuery("DROP TABLE Results", false);
+ execQuery("CREATE TABLE Results " + resultsTable);
+
+ return db;
+}
+
+struct Tag
+{
+ Tag(QString key, QString value)
+ : key(key.trimmed()), value(value.trimmed())
+ {
+
+ }
+
+ QString key;
+ QString value;
+};
+
+QList<Tag> parseTag(const QString &tag)
+{
+ // Format: key1=value ; key2=value
+ // key1=value key2=value
+ // value--value
+
+ QList<Tag> keyValues;
+
+ QString keyValuePairSeparator("");
+ if (tag.contains(";"))
+ keyValuePairSeparator = ';';
+ if (tag.contains("--"))
+ keyValuePairSeparator = "--";
+
+ foreach (QString keyValue, tag.split(keyValuePairSeparator)) {
+ if (keyValue.contains("=")) {
+ QStringList parts = keyValue.split("=");
+ keyValues.append(Tag(parts.at(0), parts.at(1)));
+ } else {
+ keyValues.append(Tag(QString(), keyValue)); // no key, just a value.
+ }
+ }
+
+ return keyValues;
+}
+
+void loadXml(const QStringList &fileNames)
+{
+ foreach(const QString &fileName, fileNames) {
+ QFileInfo fi( fileName );
+ loadXml(fileName, fi.fileName());
+ }
+}
+
+void loadXml(const QString &fileName, const QString &context)
+{
+ QFile f(fileName);
+ f.open(QIODevice::ReadOnly);
+ loadXml(f.readAll(), context);
+}
+
+void loadXml(const QByteArray &xml, const QString& context)
+{
+ QDomDocument doc;
+
+ int line;
+ int col;
+ QString errorMsg;
+ if (doc.setContent(xml, &errorMsg, &line, &col) == false) {
+ qDebug() << "dom setContent failed" << line << col << errorMsg;
+ }
+
+ // Grab "Value" from <Environment><QtVersion>Value</QtVersion></Environment>
+ QString qtVersion = doc.elementsByTagName("Environment").at(0).toElement().elementsByTagName("QtVersion")
+ .at(0).toElement().childNodes().at(0).nodeValue();
+ QString testCase = doc.elementsByTagName("TestCase").at(0).toElement().attributeNode("name").value();
+
+// qDebug() << "qt version" << qtVersion;
+// qDebug() << "test case" << testCase;
+
+ DataBaseWriter writer;
+ writer.testName = testCase; // testCaseName and testName is mixed up in the database writer class
+ writer.qtVersion = qtVersion;
+
+ QDomNodeList testFunctions = doc.elementsByTagName("TestFunction");
+ for (int i = 0; i < testFunctions.count(); ++i) {
+ QDomElement function = testFunctions.at(i).toElement();
+ QString functionName = function.attributeNode("name").value();
+ writer.testCaseName = functionName; // testCaseName and testName is mixed up in the database writer class
+
+// qDebug() << "fn" << functionName;
+
+ QDomNodeList results = function.elementsByTagName("BenchmarkResult");
+ for (int j = 0; j < results.count(); ++j) {
+ QDomElement result = results.at(j).toElement();
+ QString tag = result.attributeNode("tag").value();
+
+// if (!context.isEmpty())
+// tag += QString(" (%1)").arg(context);
+
+ QString series;
+ QString index;
+
+ // By convention, "--" separates series and indexes in tags.
+ if (tag.contains("--")) {
+ QStringList parts = tag.split("--");
+ series = parts.at(0);
+ index = parts.at(1);
+ } else {
+ series = tag;
+ }
+
+ QString resultString = result.attributeNode("value").value();
+ QString iterationCount = result.attributeNode("iterations").value();
+ double resultNumber = resultString.toDouble() / iterationCount.toDouble();
+ writer.addResult(series, index, QString::number(resultNumber), iterationCount);
+// qDebug() << "result" << series << index << tag << resultString << iterationCount;
+ }
+ }
+}
+
+void displayTable(const QString &table)
+{
+ QSqlTableModel *model = new QSqlTableModel();
+ model->setTable(table);
+ model->select();
+ QTableView *view = new QTableView();
+ view->setModel(model);
+ view->show();
+}
+
+void printDataBase()
+{
+ QSqlQuery query;
+ query.prepare("SELECT TestName, TestCaseName, Result FROM Results;");
+ bool ok = query.exec();
+ qDebug() << "printDataBase ok?" << ok;
+
+ query.next();
+ qDebug() << "";
+ qDebug() << "Benchmark" << query.value(0).toString();
+ query.previous();
+
+ while (query.next()) {
+ // QString country = query.value(fieldNo).toString();
+ // doSomething(country);
+ qDebug() << "result for" << query.value(1).toString() << query.value(2).toString();
+ }
+}
+
+// TempTable implementation
+
+static int tempTableIdentifier = 0;
+TempTable::TempTable(const QString &spec)
+{
+ m_name = "TempTable" + QString::number(tempTableIdentifier++);
+ execQuery("CREATE TEMP TABLE " + m_name + " " + spec);
+}
+
+TempTable::~TempTable()
+{
+ // ref count and drop it?
+}
+
+QString TempTable::name()
+{
+ return m_name;
+}
+
+// DataBaseWriter implementation
+
+DataBaseWriter::DataBaseWriter()
+{
+ disable = false;
+ chartSize = QSize(800, 400);
+ databaseFileName = ":memory:";
+ qtVersion = QT_VERSION_STR;
+}
+
+void DataBaseWriter::openDatabase()
+{
+ db = openDataBase(databaseFileName);
+}
+
+void DataBaseWriter::createDatabase()
+{
+ db = createDataBase(databaseFileName);
+}
+
+void DataBaseWriter::beginTransaction()
+{
+ if (db.transaction() == false) {
+ qDebug() << db.lastError();
+ qFatal("no transaction support");
+ }
+}
+
+void DataBaseWriter::commitTransaction()
+{
+ db.commit();
+}
+
+void DataBaseWriter::rollbackTransaction()
+{
+ db.rollback();
+}
+
+void DataBaseWriter::addResult(const QString &result)
+{
+ return addResult(QString(), QString(), result);
+}
+
+void DataBaseWriter::addResult(const QString &series, const QString &index, const QString &result, const QString &iterations)
+{
+ if (disable)
+ return;
+
+ QSqlQuery query;
+
+ query.prepare("INSERT INTO Results (TestName, TestCaseName, Series, Idx, Result, ChartWidth, ChartHeight, Title, TestTitle, ChartType, QtVersion, Iterations) "
+ "VALUES (:TestName, :TestCaseName, :Series, :Idx, :Result, :ChartWidth, :ChartHeight, :Title, :TestTitle, :ChartType, :QtVersion, :Iterations)");
+ query.bindValue(":TestName", testName);
+ query.bindValue(":TestCaseName", testCaseName);
+ query.bindValue(":Series", series);
+ query.bindValue(":Idx", index);
+ query.bindValue(":Result", result);
+ query.bindValue(":ChartWidth", chartSize.width());
+ query.bindValue(":ChartHeight", chartSize.height());
+ query.bindValue(":Title", chartTitle);
+ query.bindValue(":TestTitle", testTitle);
+ query.bindValue(":QtVersion", qtVersion);
+ query.bindValue(":Iterations", iterations);
+
+
+ if (chartType == LineChart)
+ query.bindValue(":ChartType", "LineChart");
+ else
+ query.bindValue(":ChartType", "BarChart");
+ execQuery(query);
+}