add classes for a new sqlite field and table objects

plus a unittest build mode
This commit is contained in:
Peinthor Rene
2013-02-28 17:15:03 +01:00
parent 05a5db3e28
commit 9394caffa9
4 changed files with 275 additions and 5 deletions

127
src/sqlitetypes.cpp Normal file
View File

@@ -0,0 +1,127 @@
#include "sqlitetypes.h"
namespace sqlb {
QString Field::toString(const QString& indent, const QString& sep) const
{
QString str = indent + m_name + sep + m_type;
if(m_notnull)
str += " NOT NULL";
if(!m_check.isEmpty())
str += " CHECK(" + m_check + ")";
if(m_autoincrement)
str += " PRIMARY KEY AUTOINCREMENT";
return str;
}
bool Field::isText() const
{
QString norm = m_type.trimmed().toLower();
return norm.startsWith("character")
|| norm.startsWith("varchar")
|| norm.startsWith("varying character")
|| norm.startsWith("nchar")
|| norm.startsWith("native charactar")
|| norm.startsWith("nvarchar")
|| norm == "text"
|| norm == "clob";
}
bool Field::isInteger() const
{
QString norm = m_type.trimmed().toLower();
return norm == "int"
|| norm == "integer"
|| norm == "tinyint"
|| norm == "smallint"
|| norm == "mediumint"
|| norm == "bigint"
|| norm == "unsigned big int"
|| norm == "int2"
|| norm == "int8";
}
Table::~Table()
{
foreach(Field* f, m_fields) {
delete f;
}
m_fields.clear();
}
void Table::addField(Field *f)
{
m_fields.append(f);
}
bool Table::setPrimaryKey(const FieldList& pk)
{
foreach(Field* f, pk) {
if(!m_fields.contains(f))
return false;
}
m_primarykey = pk;
return true;
}
bool Table::setPrimaryKey(Field* pk, bool autoincrement)
{
if(m_fields.contains(pk))
{
if(pk->isInteger() && autoincrement)
pk->setAutoIncrement(true);
m_primarykey.clear();
m_primarykey.append(pk);
return true;
}
return false;
}
QStringList Table::fieldList() const
{
QStringList sl;
foreach(Field* f, m_fields) {
sl << f->toString();
}
return sl;
}
bool Table::hasAutoIncrement() const
{
foreach(Field* f, m_fields) {
if(f->autoIncrement())
return true;
}
return false;
}
QString Table::sql() const
{
QString sql = QString("CREATE TABLE `%1` (\n").arg(m_name);
sql += fieldList().join(",\n");
// primary key
if( m_primarykey.size() > 0 && !hasAutoIncrement())
{
sql += ",\n\tPRIMARY KEY(";
for(QList<Field*>::ConstIterator it = m_primarykey.constBegin();
it != m_primarykey.constEnd();
++it)
{
sql += (*it)->name();
if(it != --m_primarykey.constEnd())
sql += ",";
}
sql += ")";
}
return sql + "\n)";
}
} //namespace sqlb

63
src/sqlitetypes.h Normal file
View File

@@ -0,0 +1,63 @@
#pragma once
#ifndef SQLITETYPES_H
#define SQLITETYPES_H
#include <QString>
#include <QList>
#include <QStringList>
namespace sqlb {
class Field
{
public:
Field(const QString& name, const QString& type, bool notnull = false, const QString& check = "")
: m_name(name), m_type(type), m_notnull(notnull), m_check(check), m_autoincrement(false) {}
QString toString(const QString& indent = "\t", const QString& sep = "\t") const;
void setAutoIncrement(bool autoinc) { m_autoincrement = autoinc; }
bool isText() const;
bool isInteger() const;
const QString& name() const { return m_name; }
const QString& type() const { return m_type; }
bool notnull() const { return m_notnull; }
const QString& check() const { return m_check; }
bool autoIncrement() const { return m_autoincrement; }
private:
QString m_name;
QString m_type;
bool m_notnull;
QString m_check;
bool m_autoincrement; //! this is stored here for simplification
};
typedef QList<Field*> FieldList;
class Table
{
public:
Table(const QString& name): m_name(name) {}
virtual ~Table();
const QString& name() const { return m_name; }
QString sql() const;
void addField(Field* f);
bool setPrimaryKey(const FieldList& pk);
bool setPrimaryKey(Field* pk, bool autoincrement = false);
private:
QStringList fieldList() const;
bool hasAutoIncrement() const;
private:
QString m_name;
FieldList m_fields;
FieldList m_primarykey;
};
} //namespace sqlb
#endif // SQLITETYPES_H

View File

@@ -7,8 +7,7 @@ TARGET = sqlitebrowser
#INCLUDEPATH += sqlite_source/
CONFIG += qt \
warn_on \
debug
warn_on
HEADERS += \
sqlitedb.h \
@@ -24,12 +23,12 @@ HEADERS += \
EditDialog.h \
ExportCsvDialog.h \
ImportCsvDialog.h \
sqltextedit.h
sqltextedit.h \
sqlitetypes.h
SOURCES += \
sqlitedb.cpp \
sqlbrowser_util.c \
main.cpp \
MainWindow.cpp \
SQLiteSyntaxHighlighter.cpp \
CreateIndexDialog.cpp \
@@ -41,7 +40,16 @@ SOURCES += \
EditDialog.cpp \
ExportCsvDialog.cpp \
ImportCsvDialog.cpp \
sqltextedit.cpp
sqltextedit.cpp \
sqlitetypes.cpp
# create a unittest option
CONFIG(unittest) {
CONFIG += qtestlib
SOURCES += tests/testsqlobjects.cpp
} else {
SOURCES += main.cpp
}
QMAKE_CXXFLAGS += -DAPP_VERSION=\\\"`cd $$PWD;git log -n1 --format=%h_git`\\\"

View File

@@ -0,0 +1,72 @@
#include "../sqlitetypes.h"
#include <QtTest/QtTest>
using namespace sqlb;
class TestTable: public QObject
{
Q_OBJECT
private slots:
void sqlOutput();
void autoincrement();
void notnull();
};
void TestTable::sqlOutput()
{
Table tt("testtable");
Field* f = new Field("id", "integer");
Field* fkm = new Field("km", "integer", false, "km > 1000");
tt.addField(f);
tt.addField(new Field("car", "text"));
tt.addField(fkm);
QList<Field*> pk;
pk.append(f);
pk.append(fkm);
tt.setPrimaryKey(pk);
QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n"
"\tid\tinteger,\n"
"\tcar\ttext,\n"
"\tkm\tinteger CHECK(km > 1000),\n"
"\tPRIMARY KEY(id,km)\n"
")"));
}
void TestTable::autoincrement()
{
Table tt("testtable");
Field* f = new Field("id", "integer");
Field* fkm = new Field("km", "integer");
tt.addField(f);
tt.addField(new Field("car", "text"));
tt.addField(fkm);
tt.setPrimaryKey(f, true);
QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n"
"\tid\tinteger PRIMARY KEY AUTOINCREMENT,\n"
"\tcar\ttext,\n"
"\tkm\tinteger\n"
")"));
}
void TestTable::notnull()
{
Table tt("testtable");
Field* f = new Field("id", "integer");
Field* fkm = new Field("km", "integer");
tt.addField(f);
tt.addField(new Field("car", "text", true));
tt.addField(fkm);
tt.setPrimaryKey(f, true);
QCOMPARE(tt.sql(), QString("CREATE TABLE `testtable` (\n"
"\tid\tinteger PRIMARY KEY AUTOINCREMENT,\n"
"\tcar\ttext NOT NULL,\n"
"\tkm\tinteger\n"
")"));
}
QTEST_MAIN(TestTable)
#include "testsqlobjects.moc"