Commit 06abf602 by NitefullWind

1. 添加创建、查询、查询数据库的单元测试。 2. 数据库模式添加版本号。

parent 1722bcde
......@@ -5,9 +5,13 @@
#include <memory> // std::auto_ptr
#include <cstdlib> // std::exit
#include <iostream>
#include <fstream>
#include <odb/database.hxx>
#include "item.h"
#include <QDebug>
#if defined(DATABASE_MYSQL)
# include <odb/mysql/database.hxx>
#elif defined(DATABASE_SQLITE)
......@@ -25,10 +29,17 @@
# error unknown database; did you forget to define the DATABASE_* macros?
#endif
#include <odb/database.hxx>
#include <odb/session.hxx>
#include <odb/transaction.hxx>
#include "item.h"
#include "item-odb.hxx"
namespace DB {
inline std::auto_ptr<odb::database>
createDatabase (const char *dbName)
OpenDatabase (const char *dbName = "Test.db")
{
using namespace std;
using namespace odb::core;
......@@ -39,21 +50,36 @@ createDatabase (const char *dbName)
auto_ptr<database> db (
new odb::sqlite::database (dbName, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE));
// Create the database schema. Due to bugs in SQLite foreign key
// support for DDL statements, we need to temporarily disable
// foreign keys.
//
{
connection_ptr c (db->connection ());
fstream dbFile;
dbFile.open(dbName, ios::in);
if(!dbFile) {
// Create the database schema. Due to bugs in SQLite foreign key
// support for DDL statements, we need to temporarily disable
// foreign keys.
//
{
connection_ptr c (db->connection ());
c->execute ("PRAGMA foreign_keys=OFF");
c->execute ("PRAGMA foreign_keys=OFF");
transaction t (c->begin ());
schema_catalog::create_schema (*db, "", false);
t.commit ();
transaction t (c->begin ());
schema_catalog::create_schema (*db);
t.commit ();
c->execute ("PRAGMA foreign_keys=ON");
}
} else if(db->schema_version() < schema_catalog::current_version(*db)) {
qDebug() << "Schema migrate. Schema version: " << db->schema_version() << " Current version: " << schema_catalog::current_version(*db) << " Base version: " << schema_catalog::base_version(*db);
c->execute ("PRAGMA foreign_keys=ON");
try {
transaction t(db->begin ());
schema_catalog::migrate(*db);
t.commit ();
} catch (const odb::exception &e) {
qDebug() << "Exception: schema migrate. " << e.what();
}
}
#elif defined(DATABASE_PGSQL)
auto_ptr<database> db (new odb::pgsql::database (dbName));
#elif defined(DATABASE_ORACLE)
......
......@@ -13,7 +13,17 @@ Item::~Item()
}
Order::Order() :
Item()
Item(),
_id(0),
_orderId(""),
_fmOrderId(""),
_orderAmount(0),
_paidAmount(0),
_undisAmount(0),
_fmOpenId(""),
_productText(""),
_settled(false),
_refunded(false)
{
}
......@@ -133,8 +143,28 @@ void Order::setStoreInfo(const QLazySharedPointer<StoreInfo> &storeInfo)
_storeInfo = storeInfo;
}
unsigned long Order::id() const
{
return _id;
}
void Order::setId(unsigned long id)
{
_id = id;
}
Pay::Pay():
Item()
Item(),
_id(0),
_payId(""),
_payStr(""),
_payAmount(0),
_refundAmount(0),
_disAmount(0),
_account(""),
_transId(""),
_fmTransId(""),
_thirdTransId("")
{
}
......@@ -244,7 +274,22 @@ void Pay::setOrder(const QLazySharedPointer<Order> &order)
_order = order;
}
StoreInfo::StoreInfo()
unsigned long Pay::id() const
{
return _id;
}
void Pay::setId(unsigned long id)
{
_id = id;
}
StoreInfo::StoreInfo() :
Item(),
_storeId(""),
_posId(""),
_operatorId(""),
_businessDate("")
{
}
......@@ -294,5 +339,15 @@ void StoreInfo::setBusinessDate(const QString &businessDate)
_businessDate = businessDate;
}
unsigned long StoreInfo::id() const
{
return _id;
}
void StoreInfo::setId(unsigned long id)
{
_id = id;
}
}
......@@ -12,6 +12,10 @@
#include <odb/core.hxx>
#include <odb/qt/lazy-ptr.hxx>
#define DB_VERSION_BASE 1
#define DB_VERSION_CURRENT 9
#pragma db model version(DB_VERSION_BASE, DB_VERSION_CURRENT)
namespace DB {
class Order;
......@@ -81,6 +85,9 @@ public:
QLazySharedPointer<StoreInfo> storeInfo() const;
void setStoreInfo(const QLazySharedPointer<StoreInfo> &storeInfo);
unsigned long id() const;
void setId(unsigned long id);
private:
friend class odb::access;
......@@ -105,6 +112,8 @@ private:
#pragma db not_null
QLazySharedPointer<StoreInfo> _storeInfo;
QString _testCol;
};
//! Pay
......@@ -145,6 +154,9 @@ public:
QLazySharedPointer<Order> order() const;
void setOrder(const QLazySharedPointer<Order> &order);
unsigned long id() const;
void setId(unsigned long id);
private:
friend class odb::access;
......@@ -168,7 +180,7 @@ private:
//! StoreInfo
#pragma db object
class StoreInfo
class StoreInfo : public Item
{
public:
StoreInfo();
......@@ -187,10 +199,13 @@ public:
QString businessDate() const;
void setBusinessDate(const QString &businessDate);
unsigned long id() const;
void setId(unsigned long id);
private:
friend class odb::access;
#pragma db id auto
#pragma db id auto
unsigned long _id;
QString _storeId;
......
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="sqlite" version="1">
<changeset version="9"/>
<changeset version="8"/>
<changeset version="7"/>
<changeset version="6">
<add-table name="Order" kind="object">
<column name="id" type="INTEGER" null="false"/>
<column name="orderId" type="TEXT" null="true" default="''"/>
<column name="fmOrderId" type="TEXT" null="true" default="''"/>
<column name="orderAmount" type="INTEGER" null="true" default="0"/>
<column name="paidAmount" type="INTEGER" null="true" default="0"/>
<column name="undisAmount" type="INTEGER" null="true" default="0"/>
<column name="fmOpenId" type="TEXT" null="true" default="''"/>
<column name="productText" type="TEXT" null="true" default="''"/>
<column name="settled" type="INTEGER" null="true" default="0"/>
<column name="refunded" type="INTEGER" null="true" default="0"/>
<column name="storeInfo" type="INTEGER" null="false"/>
<column name="testCol" type="TEXT" null="true" default="''"/>
<primary-key auto="true">
<column name="id"/>
</primary-key>
<foreign-key name="storeInfo_fk" deferrable="DEFERRED">
<column name="storeInfo"/>
<references table="StoreInfo">
<column name="id"/>
</references>
</foreign-key>
</add-table>
<add-table name="Pay" kind="object">
<column name="id" type="INTEGER" null="false"/>
<column name="payId" type="TEXT" null="true" default="''"/>
<column name="payStr" type="TEXT" null="true" default="''"/>
<column name="payAmount" type="INTEGER" null="true" default="0"/>
<column name="refundAmount" type="INTEGER" null="true" default="0"/>
<column name="disAmount" type="INTEGER" null="true" default="0"/>
<column name="account" type="TEXT" null="true" default="''"/>
<column name="transId" type="TEXT" null="true" default="''"/>
<column name="fmTransId" type="TEXT" null="true" default="''"/>
<column name="thirdTransId" type="TEXT" null="true" default="''"/>
<column name="order" type="INTEGER" null="false"/>
<primary-key auto="true">
<column name="id"/>
</primary-key>
<foreign-key name="order_fk" deferrable="DEFERRED">
<column name="order"/>
<references table="Order">
<column name="id"/>
</references>
</foreign-key>
</add-table>
<add-table name="StoreInfo" kind="object">
<column name="id" type="INTEGER" null="false"/>
<column name="storeId" type="TEXT" null="true" default="''"/>
<column name="posId" type="TEXT" null="true" default="''"/>
<column name="operatorId" type="TEXT" null="true" default="''"/>
<column name="businessDate" type="TEXT" null="true" default="''"/>
<primary-key auto="true">
<column name="id"/>
</primary-key>
</add-table>
</changeset>
<model version="1"/>
</changelog>
......@@ -135,7 +135,7 @@ ODB_FILES += db/item.h
# ODB compiler flags.
#
ODB_FLAGS = --database sqlite --profile qt --generate-schema --generate-query --generate-session
ODB_FLAGS = --database sqlite --profile qt --generate-schema --generate-query --generate-prepared --generate-session
#--profile qt
# Select the database we are going to use.
......
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
include(gtest_dependency.pri)
include(../../fmvip/fmvip.pri)
TEMPLATE = app
QT += gui
CONFIG += qt console warn_on depend_includepath testcase
HEADERS += \
tst_db_query.h \
tst_db_create.h
SOURCES += main.cpp
CONFIG(debug, debug|release) {
LIBS += -lCTKCored -lCTKPluginFrameworkd
DESTDIR = $$PWD/../../../debug/bins
} else {
LIBS += -lCTKCore -lCTKPluginFramework
DESTDIR = $$PWD/../../../release/bins
}
isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR)
isEmpty(GOOGLETEST_DIR) {
warning("Using googletest src dir specified at Qt Creator wizard")
message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message")
GOOGLETEST_DIR = E:/Code/googletest
}
!isEmpty(GOOGLETEST_DIR): {
GTEST_SRCDIR = $$GOOGLETEST_DIR/googletest
GMOCK_SRCDIR = $$GOOGLETEST_DIR/googlemock
}
requires(exists($$GTEST_SRCDIR):exists($$GMOCK_SRCDIR))
!exists($$GOOGLETEST_DIR):message("No googletest src dir found - set GOOGLETEST_DIR to enable.")
INCLUDEPATH *= \
$$GTEST_SRCDIR \
$$GTEST_SRCDIR/include \
$$GMOCK_SRCDIR \
$$GMOCK_SRCDIR/include
SOURCES += \
$$GTEST_SRCDIR/src/gtest-all.cc \
$$GMOCK_SRCDIR/src/gmock-all.cc
#include "tst_db_create.h"
#include "tst_db_query.h"
#include <gtest/gtest.h>
int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#include <gtest/gtest.h>
#include <gmock/gmock-matchers.h>
#include "database.h" // createDatabse
// add necessary includes here
#include <QFile>
#include <QDebug>
using namespace odb;
using namespace DB;
using namespace testing;
class TestDBCreate : public ::testing::Test
{
protected:
void SetUp()
{
QFile dbFile("Test.db");
if(dbFile.exists()) {
ASSERT_TRUE(dbFile.remove());
}
try {
_db = OpenDatabase();
ASSERT_NE(_db.get(), nullptr);
} catch (const odb::exception& e) {
FAIL() << "Exception: " << e.what() << std::endl;
}
}
void TearDown()
{
}
std::auto_ptr<database> _db;
};
TEST_F(TestDBCreate, Insert)
{
QSharedPointer<StoreInfo> storeInfo(new StoreInfo());
storeInfo->setStoreId("fm9999");
storeInfo->setPosId("1");
storeInfo->setOperatorId("001");
storeInfo->setBusinessDate("20180122");
QSharedPointer<Order> order(new Order());
order->setOrderId("2018001");
order->setFmOrderId("fm2018001");
order->setOrderAmount(100);
order->setPaidAmount(0);
order->setStoreInfo(storeInfo);
QSharedPointer<Pay> pay(new Pay());
pay->setTransId("201800101");
pay->setFmTransId("fm201800101");
pay->setPayAmount(10);
pay->setRefundAmount(10);
pay->setOrder(order);
// 插入数据
try {
transaction t(_db->begin());
_db->persist(storeInfo);
t.commit();
EXPECT_NE(storeInfo->id(), 0);
t.reset(_db->begin());
_db->persist(order);
t.commit();
EXPECT_NE(order->id(), 0);
EXPECT_EQ(order->storeInfo()->id(), storeInfo->id());
t.reset(_db->begin());
_db->persist(pay);
t.commit();
EXPECT_NE(pay->id(), 0);
EXPECT_EQ(pay->order()->id(), order->id());
} catch (const odb::exception& e) {
FAIL() << "Exception: " << e.what() << std::endl;
}
}
#ifndef TST_DB_QUERY_H
#define TST_DB_QUERY_H
#include <gtest/gtest.h>
#include <gmock/gmock-matchers.h>
#include "database.h" // createDatabse
// add necessary includes here
#include <QFile>
#include <QDebug>
using namespace odb;
using namespace DB;
using namespace testing;
class TestDBQuery : public ::testing::Test
{
protected:
void SetUp()
{
_db = OpenDatabase();
ASSERT_NE(_db.get(), nullptr);
}
void TearDown()
{
}
std::auto_ptr<database> _db;
};
TEST_F(TestDBQuery, Query)
{
try {
transaction t(_db->begin());
QString orderId = "2018001";
query<Order> q(query<Order>::orderId == orderId);
result<Order> r1(_db->query<Order>(q));
EXPECT_FALSE(r1.empty());
t.commit();
} catch (const odb::exception& e) {
FAIL() << "Exception: " << e.what() << std::endl;
}
}
TEST_F(TestDBQuery, QueryAnd)
{
try {
transaction t(_db->begin());
QString orderId = "2018001";
query<Order> q((query<Order>::orderId == orderId) && (query<Order>::fmOrderId == orderId));
result<Order> r(_db->query<Order>(q));
EXPECT_TRUE(r.empty());
t.commit();
} catch (const odb::exception& e) {
FAIL() << "Exception: " << e.what() << std::endl;
}
}
#endif // TST_DB_QUERY_H
TEMPLATE = subdirs
SUBDIRS += \
testitem \
testplugin
# testplugin \
autotest
CONFIG += ordered
......@@ -5,7 +5,7 @@
#define VER_MINOR 1
#define VER_REVISION 0
#define VER_BUILD 37
#define VER_BUILD 38
//! Convert version numbers to string
#define _STR(S) #S
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment