sqlite support many types :-)

This commit is contained in:
Hamed Masafi 2019-02-10 13:05:35 +03:30
parent 60b3ecf93a
commit c208908b3a
13 changed files with 240 additions and 69 deletions

2
3rdparty/serializer vendored

@ -1 +1 @@
Subproject commit dc55dc615a935b077b2cb0ba4d75257dfea1df8e
Subproject commit 7a56ae8cb5cf48fcd6952c2adcc15f1c957c4462

View File

@ -115,9 +115,9 @@ QString MySqlGenerator::escapeValue(const QVariant &v) const
}
}
QVariant MySqlGenerator::readValue(const QVariant::Type &type, const QVariant &dbValue)
QVariant MySqlGenerator::readValue(const QMetaType::Type &type, const QVariant &dbValue)
{
if (type == QVariant::PointF) {
if (type == QMetaType::QPointF) {
qDebug() << "QVariant::PointF" << dbValue;
}
return SqlGeneratorBase::readValue(type, dbValue);

View File

@ -33,7 +33,7 @@ public:
QString fieldType(FieldModel *field);
QString escapeValue(const QVariant &v) const;
QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
QVariant readValue(const QMetaType::Type &type, const QVariant &dbValue);
// QString phrase(const PhraseData *d) const;
// QString selectCommand(AgregateType t, QString agregateArg, QString tableName, QList<WherePhrase> &wheres, QList<WherePhrase> &orders, QList<RelationModel *> joins, int skip, int take);
};

View File

@ -31,7 +31,7 @@
#include "../table.h"
#include "../databasemodel.h"
#include "../tablemodel.h"
#include "stringserializer.h"
#include "sqlserializer.h"
NUT_BEGIN_NAMESPACE
@ -58,7 +58,7 @@ SqlGeneratorBase::SqlGeneratorBase(Database *parent)
if (parent)
_database = parent;
_serializer = new StringSerializer;
_serializer = new SqlSerializer;
}
SqlGeneratorBase::~SqlGeneratorBase()
@ -798,7 +798,7 @@ QString SqlGeneratorBase::escapeValue(const QVariant &v) const
if (v.type() == QVariant::String && v.toString().isEmpty())
return "''";
QString serialized = _serializer->toString(v);
QString serialized = _serializer->serialize(v);
if (serialized.isEmpty()) {
qWarning("No field escape rule for: %s", v.typeName());
return QString();
@ -840,7 +840,7 @@ QString SqlGeneratorBase::escapeValue(const QVariant &v) const
case QVariant::PointF:
case QVariant::Polygon:
case QVariant::PolygonF:
return "'" + _serializer->toString(v) + "'";
return "'" + _serializer->serialize(v) + "'";
case QVariant::Invalid:
qFatal("Invalud field value");
@ -852,11 +852,10 @@ QString SqlGeneratorBase::escapeValue(const QVariant &v) const
}
}
QVariant SqlGeneratorBase::readValue(const QVariant::Type &type,
QVariant SqlGeneratorBase::readValue(const QMetaType::Type &type,
const QVariant &dbValue)
{
Q_UNUSED(type);
return dbValue;
return _serializer->deserialize(dbValue.toString(), type);
}
QString SqlGeneratorBase::phrase(const PhraseData *d) const

View File

@ -27,7 +27,7 @@
#include "../phrase.h"
//#include "../wherephrase.h"
class StringSerializer;
class SqlSerializer;
NUT_BEGIN_NAMESPACE
@ -42,7 +42,7 @@ class SqlGeneratorBase : public QObject
// Q_OBJECT
Database *_database;
StringSerializer *_serializer;
SqlSerializer *_serializer;
public:
//TODO: remove this enum
@ -128,7 +128,7 @@ public:
// virtual QString updateCommand(WherePhrase &phrase, QList<WherePhrase> &wheres, QString tableName);
virtual QString escapeValue(const QVariant &v) const;
virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
virtual QVariant readValue(const QMetaType::Type &type, const QVariant &dbValue);
virtual QString phrase(const PhraseData *d) const;
virtual QString operatorString(const PhraseData::Condition &cond) const;
virtual void appendSkipTake(QString &sql, int skip = -1, int take = -1);

View File

@ -71,6 +71,8 @@ QString SqliteGenerator::fieldType(FieldModel *field)
case QMetaType::QPointF:
case QMetaType::QPolygon:
case QMetaType::QPolygonF:
case QMetaType::QStringList:
case QMetaType::QColor:
case QMetaType::QUuid: return "text";
// if (field->isAutoIncrement)

View File

@ -262,13 +262,14 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
qFatal("Could not create instance of %s",
qPrintable(data.table->name()));
qDebug() << data.table->name() << "created";
}
QStringList childFields = data.table->fieldsNames();
foreach (QString field, childFields)
table->setProperty(field.toLatin1().data(),
q.value(data.table->name() + "." + field));
QList<FieldModel*> childFields = data.table->fields();
foreach (FieldModel *field, childFields)
table->setProperty(field->name.toLatin1().data(),
d->database->sqlGenertor()->readValue(
field->type,
q.value(data.table->name() + "." + field->name)));
for (int i = 0; i < data.masters.count(); ++i) {
int master = data.masters[i];
@ -548,7 +549,7 @@ Q_OUTOFLINE_TEMPLATE QSqlQueryModel *Query<T>::toModel()
d->fieldPhrase,
d->wherePhrase, d->orderPhrase, d->relations,
d->skip, d->take);
qDebug() << d->sql;
DatabaseModel dbModel = d->database->model();
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery(d->sql, d->database->database());
@ -560,8 +561,6 @@ qDebug() << d->sql;
QString displayName = dbModel.tableByClassName(pd->className)
->field(pd->fieldName)->displayName;
qDebug() << "Display name for"<<pd->className<<pd->fieldName
<<"="<<displayName;
model->setHeaderData(fieldIndex++,
Qt::Horizontal,
displayName);

View File

@ -8,23 +8,11 @@
.arg(timer.elapsed() / 1000.) \
.arg(__func__)
//#define DRIVER "QPSQL"
//#define HOST "127.0.0.1"
//#define DATABASE "nutdb2"
//#define USERNAME "postgres"
//#define PASSWORD "856856"
#define DRIVER "QSQLITE"
#define HOST "127.0.0.1"
#define DATABASE "nutdb1"
#define USERNAME "root"
#define PASSWORD "onlyonlyi"
//#define DRIVER "QODBC"
//#define HOST "127.0.0.1"
//#define DATABASE "DRIVER={SQL Server};Server=.;Database=Nut2;Uid=sa;Port=1433;Pwd=qwe123!@#;WSID=."
//#define USERNAME "sa"
//#define PASSWORD "qwe123!@#"
#define DATABASE QString(typeid(*this).name()) + ".db"
#define HOST ""
#define USERNAME ""
#define PASSWORD ""
#ifdef Q_OS_LINUX
# define OS "Linux"

View File

@ -51,8 +51,8 @@ void MainTest::insert1kPost()
db.posts()->append(newPost);
}
qDebug("1k post inserted in %d ms", t.elapsed());
db.saveChanges();
qDebug("1k post inserted in %d ms", t.elapsed());
}

View File

@ -16,4 +16,6 @@ public:
DB();
};
Q_DECLARE_METATYPE(DB*)
#endif // DB_H

View File

@ -18,7 +18,7 @@
#define PRINT(x) qDebug() << #x "=" << x;
#define REGISTER(x) qDebug() << #x << "type id:" << qRegisterMetaType<x*>()
#define REGISTER(x) qDebug() << #x << "type id:" << qMetaTypeId<x*>()
MainTest::MainTest(QObject *parent) : QObject(parent)
{
@ -32,11 +32,51 @@ void MainTest::initTestCase()
db.setDriver(DRIVER);
db.setHostName(HOST);
db.setDatabaseName("nut_tst_basic");
// db.setUserName(USERNAME);
// db.setPassword(PASSWORD);
db.setDatabaseName(DATABASE);
db.setUserName(USERNAME);
db.setPassword(PASSWORD);
QFile::remove(DATABASE);
bool ok = db.open();
n8 = 8;
n16 = 16;
n32 = 32l;
n64 = 64ll;
nu8 = 8u;
nu16 = 16u;
nu32 = 32ul;
nu64 = 64ull;
r = 1.2;
f = 2.3f;
point = QPoint(1, 2);
pointf = QPointF(1.2, 3.4);
polygon = QPolygon() << QPoint(1, 2) << QPoint(3, 4) << QPoint(5, 6);
polygonf = QPolygonF() << QPointF(1.2, 2.3) << QPointF(3.4, 4.5) << QPointF(5.6, 6.7);
url = QUrl("http://google.com/search?q=nut");
time = QTime::currentTime();
date = QDate::currentDate();
dateTime = QDateTime::currentDateTime();
uuid = QUuid::createUuid();
jsonDoc = QJsonDocument::fromJson("{\"a\": 1}");
jsonObj = jsonDoc.object();
jsonArr.insert(0, QJsonValue(1));
jsonArr.insert(1, QJsonValue("Hi"));
jsonArr.insert(2, QJsonValue(true));
jsonValue = QJsonValue(true);
stringList.append("One");
stringList.append("Two");
stringList.append("Three");
string = "this is \n sample ' unescapped \r\n text";
qchar = QChar('z');
color = Qt::red;
QTEST_ASSERT(ok);
}
@ -95,11 +135,10 @@ void MainTest::types()
// << QMetaType::QByteArrayList
;
Nut::SqliteGenerator g;
Nut::FieldModel m;
foreach (QMetaType::Type t, types) {
m.type = t;
QString fn = g.fieldType(&m);
QString fn = db.sqlGenertor()->fieldType(&m);
Q_ASSERT(!fn.isEmpty());
}
// for (int i = 0; i < en.keyCount(); i++)
@ -109,24 +148,94 @@ void MainTest::types()
void MainTest::insert()
{
SampleTable t;
t.setFint8(1);
t.setFreal(1.2);
t.setFfloat(4.5f);
t.setFint16(16);
t.setFint32(65000);
t.setFint64(3255465232);
t.setFuint8(2);
t.setPoint(QPoint(1, 2));
t.setPolygon(QPolygon() << QPoint(1, 2) << QPoint(3, 4) << QPoint(5, 6));
t.setInt8(n8);
t.setInt16(n16);
t.setInt32(n32);
t.setInt64(n64);
t.setUint8(nu8);
t.setUint16(nu16);
t.setUint32(nu32);
t.setUint64(nu64);
t.setReal(r);
t.setFloat(f);
t.setPoint(point);
t.setPointf(pointf);
t.setPolygon(polygon);
t.setPolygonf(polygonf);
t.setUrl(url);
t.setTime(time);
t.setDate(date);
t.setDateTime(dateTime);
t.setUuid(uuid);
t.setJsonDoc(jsonDoc);
t.setJsonObj(jsonObj);
t.setJsonArray(jsonArr);
t.setJsonValue(jsonValue);
t.setString(string);
t.setStringList(stringList);
t.setQchar(qchar);
t.setColor(color);
db.sampleTables()->append(&t);
db.saveChanges();
}
void MainTest::retrive()
{
QList<SampleTable*> list = db.sampleTables()->query()->toList();
QTEST_ASSERT(list.count() == 1);
SampleTable *t = list.first();
QTEST_ASSERT(t->f_int8() == n8);
QTEST_ASSERT(t->f_int16() == n16);
QTEST_ASSERT(t->f_int32() == n32);
QTEST_ASSERT(t->f_int64() == n64);
QTEST_ASSERT(t->f_uint8() == nu8);
QTEST_ASSERT(t->f_uint16() == nu16);
QTEST_ASSERT(t->f_uint32() == nu32);
QTEST_ASSERT(t->f_uint64() == nu64);
QTEST_ASSERT(qFuzzyCompare(t->f_real(), r));
QTEST_ASSERT(qFuzzyCompare(t->f_float(), f));
QTEST_ASSERT(t->f_point() == point);
QTEST_ASSERT(t->f_pointf() == pointf);
QTEST_ASSERT(t->f_polygon() == polygon);
QTEST_ASSERT(t->f_polygonf() == polygonf);
QTEST_ASSERT(t->f_url() == url);
QTEST_ASSERT(t->f_uuid() == uuid);
QTEST_ASSERT(t->f_time() == time);
QTEST_ASSERT(t->f_date() == date);
QTEST_ASSERT(t->f_dateTime() == dateTime);
QTEST_ASSERT(t->f_jsonDoc() == jsonDoc);
QTEST_ASSERT(t->f_jsonObj() == jsonObj);
QTEST_ASSERT(t->f_jsonArray() == jsonArr);
QTEST_ASSERT(t->f_jsonValue() == jsonValue);
qDebug() << t->f_string() << string;
QTEST_ASSERT(t->f_string() == string);
QTEST_ASSERT(t->f_stringList() == stringList);
QTEST_ASSERT(t->f_qchar() == qchar);
QTEST_ASSERT(t->f_color() == color);
}
void MainTest::cleanupTestCase()
{
db.sampleTables()->query()->remove();
db.close();
QFile::remove("nut_tst_basic");
PRINT_FORM(db);
}

View File

@ -4,13 +4,53 @@
#include <QtCore/QObject>
#include <QtCore/qglobal.h>
#include <QColor>
#include <QDateTime>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QPolygonF>
#include <QUrl>
#include <QUuid>
#include "db.h"
class MainTest : public QObject
{
Q_OBJECT
DB db;
// void test_generator();
qint8 n8;
qint16 n16;
qint32 n32;
qint64 n64;
quint8 nu8;
quint16 nu16;
quint32 nu32;
quint64 nu64;
qreal r;
float f;
QPoint point;
QPointF pointf;
QPolygon polygon;
QPolygonF polygonf;
QUrl url;
QTime time;
QDate date;
QDateTime dateTime;
QUuid uuid;
QJsonDocument jsonDoc;
QJsonObject jsonObj;
QJsonArray jsonArr;
QJsonValue jsonValue;
QString string;
QStringList stringList;
QChar qchar;
QColor color;
public:
explicit MainTest(QObject *parent = nullptr);
@ -21,6 +61,7 @@ private slots:
void types();
void insert();
void retrive();
void cleanupTestCase();
};

View File

@ -1,8 +1,18 @@
#ifndef SAMPLETABLE_H
#define SAMPLETABLE_H
#include <QColor>
#include <QPoint>
#include <QTime>
#include <QDate>
#include <QDateTime>
#include <QPolygon>
#include <QUrl>
#include <QUuid>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include "table.h"
#define FIELD_Q(type) NUT_DECLARE_FIELD(q##type, f##type, f##type, setF##type)
@ -14,25 +24,46 @@ class SampleTable : public Nut::Table
NUT_PRIMARY_AUTO_INCREMENT(id)
NUT_DECLARE_FIELD(int, id, id, setId)
NUT_DECLARE_FIELD(qint8, fint8, fint8, setFint8)
NUT_DECLARE_FIELD(qint16, fint16, fint16, setFint16)
NUT_DECLARE_FIELD(qint32, fint32, fint32, setFint32)
NUT_DECLARE_FIELD(qint64, fint64, fint64, setFint64)
NUT_DECLARE_FIELD(qint8, f_int8, f_int8, setInt8)
NUT_DECLARE_FIELD(qint16, f_int16, f_int16, setInt16)
NUT_DECLARE_FIELD(qint32, f_int32, f_int32, setInt32)
NUT_DECLARE_FIELD(qint64, f_int64, f_int64, setInt64)
NUT_DECLARE_FIELD(quint8, fuint8, fuint8, setFuint8)
NUT_DECLARE_FIELD(quint16, fuint16, fuint16, setFuint16)
NUT_DECLARE_FIELD(quint32, fuint32, fuint32, setFuint32)
NUT_DECLARE_FIELD(quint64, fuint64, fuint64, setFuint64)
NUT_DECLARE_FIELD(quint8, f_uint8, f_uint8, setUint8)
NUT_DECLARE_FIELD(quint16, f_uint16, f_uint16, setUint16)
NUT_DECLARE_FIELD(quint32, f_uint32, f_uint32, setUint32)
NUT_DECLARE_FIELD(quint64, f_uint64, f_uint64, setUint64)
NUT_DECLARE_FIELD(qreal, freal, freal, setFreal)
NUT_DECLARE_FIELD(float, ffloat, ffloat, setFfloat)
NUT_DECLARE_FIELD(qreal, f_real, f_real, setReal)
NUT_DECLARE_FIELD(float, f_float, f_float, setFloat)
// NUT_DECLARE_FIELD(long double, fldouble, fldouble, setFldouble)
NUT_DECLARE_FIELD(QString, string, string, setString)
NUT_DECLARE_FIELD(QPoint, point, point, setPoint)
NUT_DECLARE_FIELD(QPolygon, polygon, polygon, setPolygon)
NUT_DECLARE_FIELD(QString, f_string, f_string, setString)
NUT_DECLARE_FIELD(QPoint, f_point, f_point, setPoint)
NUT_DECLARE_FIELD(QPointF, f_pointf, f_pointf, setPointf)
NUT_DECLARE_FIELD(QPolygon, f_polygon, f_polygon, setPolygon)
NUT_DECLARE_FIELD(QPolygonF, f_polygonf, f_polygonf, setPolygonf)
NUT_DECLARE_FIELD(QTime, f_time, f_time, setTime)
NUT_DECLARE_FIELD(QDate, f_date, f_date, setDate)
NUT_DECLARE_FIELD(QDateTime, f_dateTime, f_dateTime, setDateTime)
NUT_DECLARE_FIELD(QUuid, f_uuid, f_uuid, setUuid)
NUT_DECLARE_FIELD(QUrl, f_url, f_url, setUrl)
NUT_DECLARE_FIELD(QJsonDocument, f_jsonDoc, f_jsonDoc, setJsonDoc)
NUT_DECLARE_FIELD(QJsonObject, f_jsonObj, f_jsonObj, setJsonObj)
NUT_DECLARE_FIELD(QJsonArray, f_jsonArray, f_jsonArray, setJsonArray)
NUT_DECLARE_FIELD(QJsonValue, f_jsonValue, f_jsonValue, setJsonValue)
NUT_DECLARE_FIELD(QStringList, f_stringList, f_stringList, setStringList)
NUT_DECLARE_FIELD(QChar, f_qchar, f_qchar, setQchar)
NUT_DECLARE_FIELD(QColor, f_color, f_color, setColor)
public:
Q_INVOKABLE SampleTable(QObject *parent = Q_NULLPTR);
};
Q_DECLARE_METATYPE(SampleTable*)
#endif // SAMPLETABLE_H