# Conflicts:
#	.gitignore
main
HwangKC 2024-09-14 22:53:36 +08:00
commit 0a14ee1735
107 changed files with 6399 additions and 2082 deletions

View File

@ -222,4 +222,111 @@ bool OpDatabase::queryUser(const std::string& user_id, const std::string& passwd
hloge("Failed to connect to database: %s", ss.str().c_str()); hloge("Failed to connect to database: %s", ss.str().c_str());
return false; return false;
} }
}
bool OpDatabase::queryInnerDevice(int dev_id, std::string& jsonResult)
{
try
{
#if 0
// 数据库连接配置
std::string server = "tcp://127.0.0.1:3306";
std::string dbuser = "root";
std::string password = "Hj57471000";
std::string database = "hjems";
// 创建连接
sql::mysql::MySQL_Driver* driver;
driver = sql::mysql::get_mysql_driver_instance();
//m_pDbConnection.reset(driver->connect(server, dbuser, password));
sql::Connection* pDbConnection = driver->connect(server, dbuser, password);
if( !pDbConnection )
{
hloge("Failed to connect to database.");
return false;
}
// 设置为使用指定数据库
pDbConnection->setSchema(database);
hloge("%s : %s", user_id.c_str(), passwd_md5.c_str());
#endif
// 准备SQL查询语句
std::string sql = "SELECT uid,uname, upasswd,usalt,email,mobile1,mobile2,memo FROM tbl_user WHERE uid = ?";
// 创建预编译的prepared statement
std::unique_ptr<sql::PreparedStatement> pstmt(m_pDbConnection->prepareStatement(sql));
// 绑定参数
pstmt->setString(1, user_id); // 替换为你要查询的用户名
// 执行查询
std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());
bool ret = false;
OpenJson json;
auto& nodeRoot = json["user"];
int i = 0;
// 处理结果集
while( res->next() )
{
auto& node = nodeRoot[i++];
node["valid"] = 0;
node["uid"] = res->getString("uid");
// 假设username和password都是字符串类型
std::string pass = res->getString("upasswd");
std::string salt = res->getString("usalt");
//计算passwd和salt之间的关系
//!passwd=md5(passwd_md5+salt+salt)
// passwd_md5 是大写的,需要确保一下
std::string tmp2(passwd_md5);
std::transform(tmp2.begin(), tmp2.end(), tmp2.begin(),
[](unsigned char c)
{
return std::toupper(c);
});
std::string tmp = tmp2 + salt + salt;
std::string smd5 = CalculateMD5(tmp);
if( pass == smd5 )
{
node["valid"] = 1;
node["uname"] = res->getString("uname");
node["email"] = res->getString("email");
node["mobile1"] = res->getString("mobile1");
node["mobile2"] = res->getString("mobile2");
node["memo"] = res->getString("memo");
ret = true;
break;
}
else
{
hloge("upass=[%s],calc=[%s],src=[%s]", pass.c_str(), smd5.c_str(), tmp.c_str());
}
}
jsonResult = json.encode();
//pDbConnection->close();
//delete pDbConnection;
return ret;
}
catch( sql::SQLException& e )
{
std::ostringstream ss;
ss << "SQLException: " << e.what();
ss << " (MySQL error code: " << e.getErrorCode();
ss << ", SQLState: " << e.getSQLState() << " )";
hloge("Failed to connect to database: %s", ss.str().c_str());
return false;
}
} }

View File

@ -21,6 +21,9 @@ public:
void InsertMessage(const std::string& ts, const std::string& msg_type, const std::string& fsu, const std::string& content, int topic, int dev_id); void InsertMessage(const std::string& ts, const std::string& msg_type, const std::string& fsu, const std::string& content, int topic, int dev_id);
bool queryUser(const std::string& user_id, const std::string& passwd_md5, std::string& jsonResult); bool queryUser(const std::string& user_id, const std::string& passwd_md5, std::string& jsonResult);
//查询设备,dev_id=0则返回全部
bool queryInnerDevice(int dev_id, std::string& jsonResult);
protected: protected:
//std::unique_ptr<sql::Connection> m_pDbConnection; //std::unique_ptr<sql::Connection> m_pDbConnection;
sql::Connection* m_pDbConnection; sql::Connection* m_pDbConnection;

View File

@ -0,0 +1,74 @@
# 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*
CMakeLists.txt.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

View File

@ -0,0 +1,254 @@
INSTALLATION INSTRUCTIONS
These instructions refer to the package you are installing as
some-package.tar.gz or some-package.zip. The .zip file is intended for use
on Windows.
The directory you choose for the installation will be referred to as
your-install-dir.
Note to Qt Visual Studio Integration users: In the instructions below,
instead of building from command line with nmake, you can use the menu
command 'Qt->Open Solution from .pro file' on the .pro files in the
example and plugin directories, and then build from within Visual
Studio.
Unpacking and installation
--------------------------
1. Unpacking the archive (if you have not done so already).
On Unix and Mac OS X (in a terminal window):
cd your-install-dir
gunzip some-package.tar.gz
tar xvf some-package.tar
This creates the subdirectory some-package containing the files.
On Windows:
Unpack the .zip archive by right-clicking it in explorer and
choosing "Extract All...". If your version of Windows does not
have zip support, you can use the infozip tools available
from www.info-zip.org.
If you are using the infozip tools (in a command prompt window):
cd your-install-dir
unzip some-package.zip
2. Configuring the package.
The configure script is called "configure" on unix/mac and
"configure.bat" on Windows. It should be run from a command line
after cd'ing to the package directory.
You can choose whether you want to use the component by including
its source code directly into your project, or build the component
as a dynamic shared library (DLL) that is loaded into the
application at run-time. The latter may be preferable for
technical or licensing (LGPL) reasons. If you want to build a DLL,
run the configure script with the argument "-library". Also see
the note about usage below.
(Components that are Qt plugins, e.g. styles and image formats,
are by default built as a plugin DLL.)
The configure script will prompt you in some cases for further
information. Answer these questions and carefully read the license text
before accepting the license conditions. The package cannot be used if
you do not accept the license conditions.
3. Building the component and examples (when required).
If a DLL is to be built, or if you would like to build the
examples, next give the commands
qmake
make [or nmake if your are using Microsoft Visual C++]
The example program(s) can be found in the directory called
"examples" or "example".
Components that are Qt plugins, e.g. styles and image formats, are
ready to be used as soon as they are built, so the rest of this
installation instruction can be skipped.
4. Building the Qt Designer plugin (optional).
Some of the widget components are provided with plugins for Qt
Designer. To build and install the plugin, cd into the
some-package/plugin directory and give the commands
qmake
make [or nmake if your are using Microsoft Visual C++]
Restart Qt Designer to make it load the new widget plugin.
Note: If you are using the built-in Qt Designer from the Qt Visual
Studio Integration, you will need to manually copy the plugin DLL
file, i.e. copy
%QTDIR%\plugins\designer\some-component.dll
to the Qt Visual Studio Integration plugin path, typically:
C:\Program Files\Trolltech\Qt VS Integration\plugins
Note: If you for some reason are using a Qt Designer that is built
in debug mode, you will need to build the plugin in debug mode
also. Edit the file plugin.pro in the plugin directory, changing
'release' to 'debug' in the CONFIG line, before running qmake.
Solutions components are intended to be used directly from the package
directory during development, so there is no 'make install' procedure.
Using a component in your project
---------------------------------
To use this component in your project, add the following line to the
project's .pro file (or do the equivalent in your IDE):
include(your-install-dir/some-package/src/some-package.pri)
This adds the package's sources and headers to the SOURCES and HEADERS
project variables respectively (or, if the component has been
configured as a DLL, it adds that library to the LIBS variable), and
updates INCLUDEPATH to contain the package's src
directory. Additionally, the .pri file may include some dependencies
needed by the package.
To include a header file from the package in your sources, you can now
simply use:
#include <SomeClass>
or alternatively, in pre-Qt 4 style:
#include <some-class.h>
Refer to the documentation to see the classes and headers this
components provides.
Install documentation (optional)
--------------------------------
The HTML documentation for the package's classes is located in the
your-install-dir/some-package/doc/html/index.html. You can open this
file and read the documentation with any web browser.
To install the documentation into Qt Assistant (for Qt version 4.4 and
later):
1. In Assistant, open the Edit->Preferences dialog and choose the
Documentation tab. Click the Add... button and select the file
your-install-dir/some-package/doc/html/some-package.qch
For Qt versions prior to 4.4, do instead the following:
1. The directory your-install-dir/some-package/doc/html contains a
file called some-package.dcf. Execute the following commands in a
shell, command prompt or terminal window:
cd your-install-dir/some-package/doc/html/
assistant -addContentFile some-package.dcf
The next time you start Qt Assistant, you can access the package's
documentation.
Removing the documentation from assistant
-----------------------------------------
If you have installed the documentation into Qt Assistant, and want to uninstall it, do as follows, for Qt version 4.4 and later:
1. In Assistant, open the Edit->Preferences dialog and choose the
Documentation tab. In the list of Registered Documentation, select
the item com.nokia.qtsolutions.some-package_version, and click
the Remove button.
For Qt versions prior to 4.4, do instead the following:
1. The directory your-install-dir/some-package/doc/html contains a
file called some-package.dcf. Execute the following commands in a
shell, command prompt or terminal window:
cd your-install-dir/some-package/doc/html/
assistant -removeContentFile some-package.dcf
Using the component as a DLL
----------------------------
1. Normal components
The shared library (DLL) is built and placed in the
some-package/lib directory. It is intended to be used directly
from there during development. When appropriate, both debug and
release versions are built, since the run-time linker will in some
cases refuse to load a debug-built DLL into a release-built
application or vice versa.
The following steps are taken by default to help the dynamic
linker to locate the DLL at run-time (during development):
Unix: The some-package.pri file will add linker instructions to
add the some-package/lib directory to the rpath of the
executable. (When distributing, or if your system does not support
rpath, you can copy the shared library to another place that is
searched by the dynamic linker, e.g. the "lib" directory of your
Qt installation.)
Mac: The full path to the library is hardcoded into the library
itself, from where it is copied into the executable at link time,
and ready by the dynamic linker at run-time. (When distributing,
you will want to edit these hardcoded paths in the same way as for
the Qt DLLs. Refer to the document "Deploying an Application on
Mac OS X" in the Qt Reference Documentation.)
Windows: the .dll file(s) are copied into the "bin" directory of
your Qt installation. The Qt installation will already have set up
that directory to be searched by the dynamic linker.
2. Plugins
For Qt Solutions plugins (e.g. image formats), both debug and
release versions of the plugin are built by default when
appropriate, since in some cases the release Qt library will not
load a debug plugin, and vice versa. The plugins are automatically
copied into the plugins directory of your Qt installation when
built, so no further setup is required.
Plugins may also be built statically, i.e. as a library that will be
linked into your application executable, and so will not need to
be redistributed as a separate plugin DLL to end users. Static
building is required if Qt itself is built statically. To do it,
just add "static" to the CONFIG variable in the plugin/plugin.pro
file before building. Refer to the "Static Plugins" section in the
chapter "How to Create Qt Plugins" for explanation of how to use a
static plugin in your application. The source code of the example
program(s) will also typically contain the relevant instructions
as comments.
Uninstalling
------------
The following command will remove any fils that have been
automatically placed outside the package directory itself during
installation and building
make distclean [or nmake if your are using Microsoft Visual C++]
If Qt Assistant documentation or Qt Designer plugins have been
installed, they can be uninstalled manually, ref. above.
Enjoy! :)
- The Qt Solutions Team.

View File

@ -0,0 +1 @@
#include "qtlockedfile.h"

View File

@ -0,0 +1,33 @@
Qt Solutions Component: Single Application
The QtSingleApplication component provides support for
applications that can be only started once per user.
Version history:
2.0: - Version 1.3 ported to Qt 4.
2.1: - Fix compilation problem on Mac.
2.2: - Really fix the Mac compilation problem.
- Mac: fix crash due to wrong object releasing.
- Mac: Fix memory leak.
2.3: - Windows: Force creation of internal widget to make it work
with Qt 4.2.
2.4: - Fix the system for automatic window raising on message
reception. NOTE: minor API change.
2.5: - Mac: Fix isRunning() to work and report correctly.
2.6: - - initialize() is now obsolete, no longer necessary to call
it
- - Fixed race condition where multiple instances migth be started
- - QtSingleCoreApplication variant provided for non-GUI (console)
usage
- Complete reimplementation. Visible changes:
- LGPL release.

View File

@ -0,0 +1,205 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qtlocalpeer.h"
#include <QCoreApplication>
#include <QTime>
#include <QDataStream>
#include <QRegularExpression>
#if defined(Q_OS_WIN)
#include <QLibrary>
#include <qt_windows.h>
typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
static PProcessIdToSessionId pProcessIdToSessionId = 0;
#endif
#if defined(Q_OS_UNIX)
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#endif
namespace QtLP_Private {
#include "qtlockedfile.cpp"
#if defined(Q_OS_WIN)
#include "qtlockedfile_win.cpp"
#else
#include "qtlockedfile_unix.cpp"
#endif
}
const char* QtLocalPeer::ack = "ack";
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
: QObject(parent), id(appId)
{
QString prefix = id;
if (id.isEmpty()) {
id = QCoreApplication::applicationFilePath();
#if defined(Q_OS_WIN)
id = id.toLower();
#endif
prefix = id.section(QLatin1Char('/'), -1);
}
prefix.remove(QRegularExpression ("[^a-zA-Z]"));
prefix.truncate(6);
QByteArray idc = id.toUtf8();
quint16 idNum = qChecksum(idc.constData(), idc.size());
socketName = QLatin1String("qtsingleapp-") + prefix
+ QLatin1Char('-') + QString::number(idNum, 16);
#if defined(Q_OS_WIN)
if (!pProcessIdToSessionId) {
QLibrary lib("kernel32");
pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
}
if (pProcessIdToSessionId) {
DWORD sessionId = 0;
pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
socketName += QLatin1Char('-') + QString::number(sessionId, 16);
}
#else
socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
#endif
server = new QLocalServer(this);
QString lockName = QDir(QDir::tempPath()).absolutePath()
+ QLatin1Char('/') + socketName
+ QLatin1String("-lockfile");
lockFile.setFileName(lockName);
lockFile.open(QIODevice::ReadWrite);
}
bool QtLocalPeer::isClient()
{
if (lockFile.isLocked())
return false;
if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
return true;
bool res = server->listen(socketName);
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
// ### Workaround
if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
res = server->listen(socketName);
}
#endif
if (!res)
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
return false;
}
bool QtLocalPeer::sendMessage(const QString &message, int timeout)
{
if (!isClient())
return false;
QLocalSocket socket;
bool connOk = false;
for(int i = 0; i < 2; i++) {
// Try twice, in case the other instance is just starting up
socket.connectToServer(socketName);
connOk = socket.waitForConnected(timeout/2);
if (connOk || i)
break;
int ms = 250;
#if defined(Q_OS_WIN)
Sleep(DWORD(ms));
#else
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, NULL);
#endif
}
if (!connOk)
return false;
QByteArray uMsg(message.toUtf8());
QDataStream ds(&socket);
ds.writeBytes(uMsg.constData(), uMsg.size());
bool res = socket.waitForBytesWritten(timeout);
if (res) {
res &= socket.waitForReadyRead(timeout); // wait for ack
if (res)
res &= (socket.read(qstrlen(ack)) == ack);
}
return res;
}
void QtLocalPeer::receiveConnection()
{
QLocalSocket* socket = server->nextPendingConnection();
if (!socket)
return;
while (socket->bytesAvailable() < (int)sizeof(quint32))
socket->waitForReadyRead();
QDataStream ds(socket);
QByteArray uMsg;
quint32 remaining;
ds >> remaining;
uMsg.resize(remaining);
int got = 0;
char* uMsgBuf = uMsg.data();
do {
got = ds.readRawData(uMsgBuf, remaining);
remaining -= got;
uMsgBuf += got;
} while (remaining && got >= 0 && socket->waitForReadyRead(2000));
if (got < 0) {
qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
delete socket;
return;
}
QString message(QString::fromUtf8(uMsg));
socket->write(ack, qstrlen(ack));
socket->waitForBytesWritten(1000);
socket->waitForDisconnected(1000); // make sure client reads ack
delete socket;
emit messageReceived(message); //### (might take a long time to return)
}

View File

@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QTLOCALPEER_H
#define QTLOCALPEER_H
#include <QLocalServer>
#include <QLocalSocket>
#include <QDir>
#include "qtlockedfile.h"
class QtLocalPeer : public QObject
{
Q_OBJECT
public:
QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
bool isClient();
bool sendMessage(const QString &message, int timeout);
QString applicationId() const
{ return id; }
Q_SIGNALS:
void messageReceived(const QString &message);
protected Q_SLOTS:
void receiveConnection();
protected:
QString id;
QString socketName;
QLocalServer* server;
QtLP_Private::QtLockedFile lockFile;
private:
static const char* ack;
};
#endif // QTLOCALPEER_H

View File

@ -0,0 +1,193 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qtlockedfile.h"
/*!
\class QtLockedFile
\brief The QtLockedFile class extends QFile with advisory locking
functions.
A file may be locked in read or write mode. Multiple instances of
\e QtLockedFile, created in multiple processes running on the same
machine, may have a file locked in read mode. Exactly one instance
may have it locked in write mode. A read and a write lock cannot
exist simultaneously on the same file.
The file locks are advisory. This means that nothing prevents
another process from manipulating a locked file using QFile or
file system functions offered by the OS. Serialization is only
guaranteed if all processes that access the file use
QLockedFile. Also, while holding a lock on a file, a process
must not open the same file again (through any API), or locks
can be unexpectedly lost.
The lock provided by an instance of \e QtLockedFile is released
whenever the program terminates. This is true even when the
program crashes and no destructors are called.
*/
/*! \enum QtLockedFile::LockMode
This enum describes the available lock modes.
\value ReadLock A read lock.
\value WriteLock A write lock.
\value NoLock Neither a read lock nor a write lock.
*/
/*!
Constructs an unlocked \e QtLockedFile object. This constructor
behaves in the same way as \e QFile::QFile().
\sa QFile::QFile()
*/
QtLockedFile::QtLockedFile()
: QFile()
{
#ifdef Q_OS_WIN
wmutex = 0;
rmutex = 0;
#endif
m_lock_mode = NoLock;
}
/*!
Constructs an unlocked QtLockedFile object with file \a name. This
constructor behaves in the same way as \e QFile::QFile(const
QString&).
\sa QFile::QFile()
*/
QtLockedFile::QtLockedFile(const QString &name)
: QFile(name)
{
#ifdef Q_OS_WIN
wmutex = 0;
rmutex = 0;
#endif
m_lock_mode = NoLock;
}
/*!
Opens the file in OpenMode \a mode.
This is identical to QFile::open(), with the one exception that the
Truncate mode flag is disallowed. Truncation would conflict with the
advisory file locking, since the file would be modified before the
write lock is obtained. If truncation is required, use resize(0)
after obtaining the write lock.
Returns true if successful; otherwise false.
\sa QFile::open(), QFile::resize()
*/
bool QtLockedFile::open(OpenMode mode)
{
if (mode & QIODevice::Truncate) {
qWarning("QtLockedFile::open(): Truncate mode not allowed.");
return false;
}
return QFile::open(mode);
}
/*!
Returns \e true if this object has a in read or write lock;
otherwise returns \e false.
\sa lockMode()
*/
bool QtLockedFile::isLocked() const
{
return m_lock_mode != NoLock;
}
/*!
Returns the type of lock currently held by this object, or \e
QtLockedFile::NoLock.
\sa isLocked()
*/
QtLockedFile::LockMode QtLockedFile::lockMode() const
{
return m_lock_mode;
}
/*!
\fn bool QtLockedFile::lock(LockMode mode, bool block = true)
Obtains a lock of type \a mode. The file must be opened before it
can be locked.
If \a block is true, this function will block until the lock is
aquired. If \a block is false, this function returns \e false
immediately if the lock cannot be aquired.
If this object already has a lock of type \a mode, this function
returns \e true immediately. If this object has a lock of a
different type than \a mode, the lock is first released and then a
new lock is obtained.
This function returns \e true if, after it executes, the file is
locked by this object, and \e false otherwise.
\sa unlock(), isLocked(), lockMode()
*/
/*!
\fn bool QtLockedFile::unlock()
Releases a lock.
If the object has no lock, this function returns immediately.
This function returns \e true if, after it executes, the file is
not locked by this object, and \e false otherwise.
\sa lock(), isLocked(), lockMode()
*/
/*!
\fn QtLockedFile::~QtLockedFile()
Destroys the \e QtLockedFile object. If any locks were held, they
are released.
*/

View File

@ -0,0 +1,97 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QTLOCKEDFILE_H
#define QTLOCKEDFILE_H
#include <QFile>
#ifdef Q_OS_WIN
#include <QVector>
#endif
#if defined(Q_OS_WIN)
# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
# define QT_QTLOCKEDFILE_EXPORT
# elif defined(QT_QTLOCKEDFILE_IMPORT)
# if defined(QT_QTLOCKEDFILE_EXPORT)
# undef QT_QTLOCKEDFILE_EXPORT
# endif
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
# elif defined(QT_QTLOCKEDFILE_EXPORT)
# undef QT_QTLOCKEDFILE_EXPORT
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
# endif
#else
# define QT_QTLOCKEDFILE_EXPORT
#endif
namespace QtLP_Private {
class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
{
public:
enum LockMode { NoLock = 0, ReadLock, WriteLock };
QtLockedFile();
QtLockedFile(const QString &name);
~QtLockedFile();
bool open(OpenMode mode);
bool lock(LockMode mode, bool block = true);
bool unlock();
bool isLocked() const;
LockMode lockMode() const;
private:
#ifdef Q_OS_WIN
Qt::HANDLE wmutex;
Qt::HANDLE rmutex;
QVector<Qt::HANDLE> rmutexes;
QString mutexname;
Qt::HANDLE getMutexHandle(int idx, bool doCreate);
bool waitMutex(Qt::HANDLE mutex, bool doBlock);
#endif
LockMode m_lock_mode;
};
}
#endif

View File

@ -0,0 +1,115 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "qtlockedfile.h"
bool QtLockedFile::lock(LockMode mode, bool block)
{
if (!isOpen()) {
qWarning("QtLockedFile::lock(): file is not opened");
return false;
}
if (mode == NoLock)
return unlock();
if (mode == m_lock_mode)
return true;
if (m_lock_mode != NoLock)
unlock();
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
int cmd = block ? F_SETLKW : F_SETLK;
int ret = fcntl(handle(), cmd, &fl);
if (ret == -1) {
if (errno != EINTR && errno != EAGAIN)
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
return false;
}
m_lock_mode = mode;
return true;
}
bool QtLockedFile::unlock()
{
if (!isOpen()) {
qWarning("QtLockedFile::unlock(): file is not opened");
return false;
}
if (!isLocked())
return true;
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = F_UNLCK;
int ret = fcntl(handle(), F_SETLKW, &fl);
if (ret == -1) {
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
return false;
}
m_lock_mode = NoLock;
return true;
}
QtLockedFile::~QtLockedFile()
{
if (isOpen())
unlock();
}

View File

@ -0,0 +1,211 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qtlockedfile.h"
#include <qt_windows.h>
#include <QFileInfo>
#define MUTEX_PREFIX "QtLockedFile mutex "
// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS
#define MAX_READERS MAXIMUM_WAIT_OBJECTS
#if QT_VERSION >= 0x050000
#define QT_WA(unicode, ansi) unicode
#endif
Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
{
if (mutexname.isEmpty()) {
QFileInfo fi(*this);
mutexname = QString::fromLatin1(MUTEX_PREFIX)
+ fi.absoluteFilePath().toLower();
}
QString mname(mutexname);
if (idx >= 0)
mname += QString::number(idx);
Qt::HANDLE mutex;
if (doCreate) {
QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); },
{ mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } );
if (!mutex) {
qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
return 0;
}
}
else {
QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); },
{ mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } );
if (!mutex) {
if (GetLastError() != ERROR_FILE_NOT_FOUND)
qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
return 0;
}
}
return mutex;
}
bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock)
{
Q_ASSERT(mutex);
DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
switch (res) {
case WAIT_OBJECT_0:
case WAIT_ABANDONED:
return true;
break;
case WAIT_TIMEOUT:
break;
default:
qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
}
return false;
}
bool QtLockedFile::lock(LockMode mode, bool block)
{
if (!isOpen()) {
qWarning("QtLockedFile::lock(): file is not opened");
return false;
}
if (mode == NoLock)
return unlock();
if (mode == m_lock_mode)
return true;
if (m_lock_mode != NoLock)
unlock();
if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
return false;
if (!waitMutex(wmutex, block))
return false;
if (mode == ReadLock) {
int idx = 0;
for (; idx < MAX_READERS; idx++) {
rmutex = getMutexHandle(idx, false);
if (!rmutex || waitMutex(rmutex, false))
break;
CloseHandle(rmutex);
}
bool ok = true;
if (idx >= MAX_READERS) {
qWarning("QtLockedFile::lock(): too many readers");
rmutex = 0;
ok = false;
}
else if (!rmutex) {
rmutex = getMutexHandle(idx, true);
if (!rmutex || !waitMutex(rmutex, false))
ok = false;
}
if (!ok && rmutex) {
CloseHandle(rmutex);
rmutex = 0;
}
ReleaseMutex(wmutex);
if (!ok)
return false;
}
else {
Q_ASSERT(rmutexes.isEmpty());
for (int i = 0; i < MAX_READERS; i++) {
Qt::HANDLE mutex = getMutexHandle(i, false);
if (mutex)
rmutexes.append(mutex);
}
if (rmutexes.size()) {
DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
TRUE, block ? INFINITE : 0);
if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
if (res != WAIT_TIMEOUT)
qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
unlock();
return false;
}
}
}
m_lock_mode = mode;
return true;
}
bool QtLockedFile::unlock()
{
if (!isOpen()) {
qWarning("QtLockedFile::unlock(): file is not opened");
return false;
}
if (!isLocked())
return true;
if (m_lock_mode == ReadLock) {
ReleaseMutex(rmutex);
CloseHandle(rmutex);
rmutex = 0;
}
else {
foreach(Qt::HANDLE mutex, rmutexes) {
ReleaseMutex(mutex);
CloseHandle(mutex);
}
rmutexes.clear();
ReleaseMutex(wmutex);
}
m_lock_mode = QtLockedFile::NoLock;
return true;
}
QtLockedFile::~QtLockedFile()
{
if (isOpen())
unlock();
if (wmutex)
CloseHandle(wmutex);
}

View File

@ -0,0 +1,356 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qtsingleapplication.h"
#include "qtlocalpeer.h"
#include <QWidget>
/*!
\class QtSingleApplication qtsingleapplication.h
\brief The QtSingleApplication class provides an API to detect and
communicate with running instances of an application.
This class allows you to create applications where only one
instance should be running at a time. I.e., if the user tries to
launch another instance, the already running instance will be
activated instead. Another usecase is a client-server system,
where the first started instance will assume the role of server,
and the later instances will act as clients of that server.
By default, the full path of the executable file is used to
determine whether two processes are instances of the same
application. You can also provide an explicit identifier string
that will be compared instead.
The application should create the QtSingleApplication object early
in the startup phase, and call isRunning() to find out if another
instance of this application is already running. If isRunning()
returns false, it means that no other instance is running, and
this instance has assumed the role as the running instance. In
this case, the application should continue with the initialization
of the application user interface before entering the event loop
with exec(), as normal.
The messageReceived() signal will be emitted when the running
application receives messages from another instance of the same
application. When a message is received it might be helpful to the
user to raise the application so that it becomes visible. To
facilitate this, QtSingleApplication provides the
setActivationWindow() function and the activateWindow() slot.
If isRunning() returns true, another instance is already
running. It may be alerted to the fact that another instance has
started by using the sendMessage() function. Also data such as
startup parameters (e.g. the name of the file the user wanted this
new instance to open) can be passed to the running instance with
this function. Then, the application should terminate (or enter
client mode).
If isRunning() returns true, but sendMessage() fails, that is an
indication that the running instance is frozen.
Here's an example that shows how to convert an existing
application to use QtSingleApplication. It is very simple and does
not make use of all QtSingleApplication's functionality (see the
examples for that).
\code
// Original
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyMainWidget mmw;
mmw.show();
return app.exec();
}
// Single instance
int main(int argc, char **argv)
{
QtSingleApplication app(argc, argv);
if (app.isRunning())
return !app.sendMessage(someDataString);
MyMainWidget mmw;
app.setActivationWindow(&mmw);
mmw.show();
return app.exec();
}
\endcode
Once this QtSingleApplication instance is destroyed (normally when
the process exits or crashes), when the user next attempts to run the
application this instance will not, of course, be encountered. The
next instance to call isRunning() or sendMessage() will assume the
role as the new running instance.
For console (non-GUI) applications, QtSingleCoreApplication may be
used instead of this class, to avoid the dependency on the QtGui
library.
\sa QtSingleCoreApplication
*/
void QtSingleApplication::sysInit(const QString &appId)
{
actWin = 0;
peer = new QtLocalPeer(this, appId);
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
}
/*!
Creates a QtSingleApplication object. The application identifier
will be QCoreApplication::applicationFilePath(). \a argc, \a
argv, and \a GUIenabled are passed on to the QAppliation constructor.
If you are creating a console application (i.e. setting \a
GUIenabled to false), you may consider using
QtSingleCoreApplication instead.
*/
QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
: QApplication(argc, argv, GUIenabled)
{
sysInit();
}
/*!
Creates a QtSingleApplication object with the application
identifier \a appId. \a argc and \a argv are passed on to the
QAppliation constructor.
*/
QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
: QApplication(argc, argv),
peer(nullptr)
{
sysInit(appId);
}
QtSingleApplication::~QtSingleApplication()
{
if (peer)
{
delete peer;
}
}
#if QT_VERSION < 0x050000
/*!
Creates a QtSingleApplication object. The application identifier
will be QCoreApplication::applicationFilePath(). \a argc, \a
argv, and \a type are passed on to the QAppliation constructor.
*/
QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type)
: QApplication(argc, argv, type)
{
sysInit();
}
# if defined(Q_WS_X11)
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be QCoreApplication::applicationFilePath(). \a dpy, \a visual,
and \a cmap are passed on to the QApplication constructor.
*/
QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, visual, cmap)
{
sysInit();
}
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a
argv, \a visual, and \a cmap are passed on to the QApplication
constructor.
*/
QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, argc, argv, visual, cmap)
{
sysInit();
}
/*!
Special constructor for X11, ref. the documentation of
QApplication's corresponding constructor. The application identifier
will be \a appId. \a dpy, \a argc, \a
argv, \a visual, and \a cmap are passed on to the QApplication
constructor.
*/
QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
: QApplication(dpy, argc, argv, visual, cmap)
{
sysInit(appId);
}
# endif // Q_WS_X11
#endif // QT_VERSION < 0x050000
/*!
Returns true if another instance of this application is running;
otherwise false.
This function does not find instances of this application that are
being run by a different user (on Windows: that are running in
another session).
\sa sendMessage()
*/
bool QtSingleApplication::isRunning()
{
return peer->isClient();
}
/*!
Tries to send the text \a message to the currently running
instance. The QtSingleApplication object in the running instance
will emit the messageReceived() signal when it receives the
message.
This function returns true if the message has been sent to, and
processed by, the current instance. If there is no instance
currently running, or if the running instance fails to process the
message within \a timeout milliseconds, this function return false.
\sa isRunning(), messageReceived()
*/
bool QtSingleApplication::sendMessage(const QString &message, int timeout)
{
return peer->sendMessage(message, timeout);
}
/*!
Returns the application identifier. Two processes with the same
identifier will be regarded as instances of the same application.
*/
QString QtSingleApplication::id() const
{
return peer->applicationId();
}
/*!
Sets the activation window of this application to \a aw. The
activation window is the widget that will be activated by
activateWindow(). This is typically the application's main window.
If \a activateOnMessage is true (the default), the window will be
activated automatically every time a message is received, just prior
to the messageReceived() signal being emitted.
\sa activateWindow(), messageReceived()
*/
void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage)
{
actWin = aw;
if (activateOnMessage)
connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
else
disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
}
/*!
Returns the applications activation window if one has been set by
calling setActivationWindow(), otherwise returns 0.
\sa setActivationWindow()
*/
QWidget* QtSingleApplication::activationWindow() const
{
return actWin;
}
/*!
De-minimizes, raises, and activates this application's activation window.
This function does nothing if no activation window has been set.
This is a convenience function to show the user that this
application instance has been activated when he has tried to start
another instance.
This function should typically be called in response to the
messageReceived() signal. By default, that will happen
automatically, if an activation window has been set.
\sa setActivationWindow(), messageReceived(), initialize()
*/
void QtSingleApplication::activateWindow()
{
if (actWin) {
actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
actWin->raise();
actWin->activateWindow();
}
}
/*!
\fn void QtSingleApplication::messageReceived(const QString& message)
This signal is emitted when the current instance receives a \a
message from another instance of this application.
\sa sendMessage(), setActivationWindow(), activateWindow()
*/
/*!
\fn void QtSingleApplication::initialize(bool dummy = true)
\obsolete
*/

View File

@ -0,0 +1,107 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QTSINGLEAPPLICATION_H
#define QTSINGLEAPPLICATION_H
#include <QApplication>
class QtLocalPeer;
#if defined(Q_OS_WIN)
# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT)
# define QT_QTSINGLEAPPLICATION_EXPORT
# elif defined(QT_QTSINGLEAPPLICATION_IMPORT)
# if defined(QT_QTSINGLEAPPLICATION_EXPORT)
# undef QT_QTSINGLEAPPLICATION_EXPORT
# endif
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport)
# elif defined(QT_QTSINGLEAPPLICATION_EXPORT)
# undef QT_QTSINGLEAPPLICATION_EXPORT
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport)
# endif
#else
# define QT_QTSINGLEAPPLICATION_EXPORT
#endif
class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication
{
Q_OBJECT
public:
QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
QtSingleApplication(const QString &id, int &argc, char **argv);
virtual ~QtSingleApplication();
#if QT_VERSION < 0x050000
QtSingleApplication(int &argc, char **argv, Type type);
# if defined(Q_WS_X11)
QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0);
QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
# endif // Q_WS_X11
#endif // QT_VERSION < 0x050000
bool isRunning();
QString id() const;
void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
QWidget* activationWindow() const;
// Obsolete:
void initialize(bool dummy = true)
{ isRunning(); Q_UNUSED(dummy) }
public Q_SLOTS:
bool sendMessage(const QString &message, int timeout = 5000);
void activateWindow();
Q_SIGNALS:
void messageReceived(const QString &message);
private:
void sysInit(const QString &appId = QString());
QtLocalPeer *peer;
QWidget *actWin;
};
#endif // QTSINGLEAPPLICATION_H

View File

@ -0,0 +1,17 @@
#include(../common.pri)
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
QT *= network
greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets
qtsingleapplication-uselib:!qtsingleapplication-buildlib {
LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME
} else {
SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp
HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h
}
win32 {
contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT
else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT
}

View File

@ -0,0 +1,149 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qtsinglecoreapplication.h"
#include "qtlocalpeer.h"
/*!
\class QtSingleCoreApplication qtsinglecoreapplication.h
\brief A variant of the QtSingleApplication class for non-GUI applications.
This class is a variant of QtSingleApplication suited for use in
console (non-GUI) applications. It is an extension of
QCoreApplication (instead of QApplication). It does not require
the QtGui library.
The API and usage is identical to QtSingleApplication, except that
functions relating to the "activation window" are not present, for
obvious reasons. Please refer to the QtSingleApplication
documentation for explanation of the usage.
A QtSingleCoreApplication instance can communicate to a
QtSingleApplication instance if they share the same application
id. Hence, this class can be used to create a light-weight
command-line tool that sends commands to a GUI application.
\sa QtSingleApplication
*/
/*!
Creates a QtSingleCoreApplication object. The application identifier
will be QCoreApplication::applicationFilePath(). \a argc and \a
argv are passed on to the QCoreAppliation constructor.
*/
QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
: QCoreApplication(argc, argv)
{
peer = new QtLocalPeer(this);
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
}
/*!
Creates a QtSingleCoreApplication object with the application
identifier \a appId. \a argc and \a argv are passed on to the
QCoreAppliation constructor.
*/
QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv)
: QCoreApplication(argc, argv)
{
peer = new QtLocalPeer(this, appId);
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
}
/*!
Returns true if another instance of this application is running;
otherwise false.
This function does not find instances of this application that are
being run by a different user (on Windows: that are running in
another session).
\sa sendMessage()
*/
bool QtSingleCoreApplication::isRunning()
{
return peer->isClient();
}
/*!
Tries to send the text \a message to the currently running
instance. The QtSingleCoreApplication object in the running instance
will emit the messageReceived() signal when it receives the
message.
This function returns true if the message has been sent to, and
processed by, the current instance. If there is no instance
currently running, or if the running instance fails to process the
message within \a timeout milliseconds, this function return false.
\sa isRunning(), messageReceived()
*/
bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout)
{
return peer->sendMessage(message, timeout);
}
/*!
Returns the application identifier. Two processes with the same
identifier will be regarded as instances of the same application.
*/
QString QtSingleCoreApplication::id() const
{
return peer->applicationId();
}
/*!
\fn void QtSingleCoreApplication::messageReceived(const QString& message)
This signal is emitted when the current instance receives a \a
message from another instance of this application.
\sa sendMessage()
*/

View File

@ -0,0 +1,71 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Solutions component.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QTSINGLECOREAPPLICATION_H
#define QTSINGLECOREAPPLICATION_H
#include <QCoreApplication>
class QtLocalPeer;
class QtSingleCoreApplication : public QCoreApplication
{
Q_OBJECT
public:
QtSingleCoreApplication(int &argc, char **argv);
QtSingleCoreApplication(const QString &id, int &argc, char **argv);
bool isRunning();
QString id() const;
public Q_SLOTS:
bool sendMessage(const QString &message, int timeout = 5000);
Q_SIGNALS:
void messageReceived(const QString &message);
private:
QtLocalPeer* peer;
};
#endif // QTSINGLECOREAPPLICATION_H

View File

@ -0,0 +1,10 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h
SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp
QT *= network
win32:contains(TEMPLATE, lib):contains(CONFIG, shared) {
DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport)
}

View File

@ -0,0 +1,22 @@
#include "datafetcher.h"
#include "globalparameters.h"
DataFetcher::DataFetcher()
{
}
DataFetcher::~DataFetcher()
{
}
bool DataFetcher::Fetch(TableData& tbl_data)
{
return true;
}
int DataFetcher::VerifyStatus()
{
return STATUS_NORMAL;
}

View File

@ -0,0 +1,19 @@
#ifndef DATAFETCHER_H
#define DATAFETCHER_H
#include "globalparameters.h"
class DataFetcher
{
public:
DataFetcher();
virtual ~DataFetcher();
public:
virtual bool Fetch(TableData& tbl_data);
protected:
int VerifyStatus();
};
#endif // DATAFETCHER_H

View File

@ -0,0 +1,202 @@
#include "devicepropertypage.h"
#include <QGuiApplication>
#include <QTimer>
#include <QMessageBox>
#include <QTableView>
#include <QVBoxLayout>
#include <QPushButton>
#include <QScrollBar>
#include <QHeaderView>
#include "globalparameters.h"
#include "mytablemodel.h"
DevicePropertyPage::DevicePropertyPage(QWidget *parent) :
QWidget(parent),m_pTableView(nullptr),m_pButton(nullptr)
{
InitializeTable();
m_pTimer = new QTimer(this);
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(handleTimeout()));
//m_pTimer->start(AppData::getInstance()->nTimeOut);
}
DevicePropertyPage::~DevicePropertyPage()
{
}
void DevicePropertyPage::handleTimeout()
{
if(m_pTimer->isActive())
{
m_pTimer->stop();
Refresh();
int nInterval = 5000;
m_pTimer->start(nInterval*1000);
}
}
void DevicePropertyPage::InitializeTableView(MyTableModel *model, QTableView *tableView)
{
//设置tableview的model
model->setHeadData(AppData::getInstance()->lstDataTableHeaderText);
tableView->setModel(model);
QHeaderView* pHeaderView = tableView->horizontalHeader();
//pHeaderView->setStyleSheet("QHeaderView::section {color: black;padding-left: 4px;border: 1px solid #6c6c6c;}");
pHeaderView->setStyleSheet("QHeaderView::section{background:lightgray;}");
// pHeaderView->setSectionResizeMode(QHeaderView::Stretch); //Stretch
pHeaderView->setHidden(false); //false 显示行号列 true Hide
//pHeaderView->setVisible(true);
//pHeaderView->setFixedHeight(40);
//点击表时不对表头行光亮(获取焦点)
pHeaderView->setHighlightSections(false);
// pHeaderView->setDefaultSectionSize(200);
// //设置表头字体加粗
// QFont font = pHeaderView->font();
// font.setBold(true);
// pHeaderView->setFont(font);
//设置表头字体
pHeaderView->setFont(QFont("Arial", 12));
// 设置表头列宽自动调整
for (int i = 0; i < model->columnCount(); ++i)
{
pHeaderView->setSectionResizeMode(i, QHeaderView::Interactive);
}
// 允许用户通过拖动表头边缘调整列宽
//pHeaderView->setSectionResizeMode(QHeaderView::Interactive);
tableView->verticalHeader()->setDefaultSectionSize(30); //行高
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
tableView->setAlternatingRowColors(true);
tableView->setTextElideMode(Qt::ElideMiddle);
//所有单元格的字体 设置成一样
tableView->setFont(QFont("Arial", 9));
//设置表格数据区内的所有单元格都不允许编辑
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
#if 1
//设置列宽
int base = 120; //w / (model->columnCount()-1);
tableView->setColumnWidth(0,base-30);
tableView->setColumnWidth(1,base*3+40);
tableView->setColumnWidth(2,base);
tableView->setColumnWidth(3,base-40);
tableView->setColumnWidth(4,base+50);
#endif
tableView->show();
}
void DevicePropertyPage::InitializeTable()
{
m_myModel = new MyTableModel(this);
m_myModel->setHeadData(AppData::getInstance()->lstDataTableHeaderText);
m_pTableView = new QTableView(this);
m_pButton = new QPushButton(tr("Refresh"), this);
// 创建主布局
QVBoxLayout *mainLayout = new QVBoxLayout(this);
InitializeTableView(m_myModel,m_pTableView);
mainLayout->addWidget(m_pTableView);
// 创建一个水平布局来包含按钮
QHBoxLayout *buttonLayout = new QHBoxLayout();
buttonLayout->addStretch(); // 让按钮保持在右侧
buttonLayout->addWidget(m_pButton);
buttonLayout->setContentsMargins(0, 0, 0, 0); // 取消按钮的边距
// 将表格视图和按钮布局添加到主布局
mainLayout->addLayout(buttonLayout);
mainLayout->setContentsMargins(0, 0, 0, 0); // 取消主布局的边距
mainLayout->setSpacing(10); // 取消布局间的间距
// 设置固定大小和位置的按钮
m_pButton->setFixedSize(100, 30); // 设置按钮的固定大小
// 连接信号和槽
connect(m_pTableView, &QTableView::doubleClicked, this, &DevicePropertyPage::onTableViewDoubleClicked);
connect(m_pButton, &QPushButton::clicked, this, &DevicePropertyPage::onButtonClicked);
setLayout(mainLayout);
}
void DevicePropertyPage::Refresh()
{
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
TableData tbl_data;
if (Fetch(tbl_data))
{
m_myModel->setModelData(tbl_data);
}
QGuiApplication::restoreOverrideCursor();
}
void DevicePropertyPage::setBaseType(unsigned int base, unsigned int mask)
{
filterBaseType = base;
mask_code = mask;
}
void DevicePropertyPage::onButtonClicked()
{
m_pTimer->stop();
Refresh();
}
void DevicePropertyPage::onTableViewDoubleClicked(const QModelIndex &index)
{
//QAbstractItemModel *model=ui->tableView->model();
MyTableModel *model = (MyTableModel *)m_pTableView->model();
QModelIndex mindex = model->index(index.row(),7); //index.row()为算选择的行号。7为所选中行的第8列。。
QVariant datatemp=model->data(mindex);
}
void DevicePropertyPage::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
#if 0
// 获取当前QTableView的总宽度
int currentTotalWidth = m_pTableView->viewport()->width();
// 计算总的初始宽度
int initialTotalWidth = 0;
for (int width : columnWidths) {
initialTotalWidth += width;
}
// 计算比例因子
double scaleFactor = static_cast<double>(currentTotalWidth) / initialTotalWidth;
// 重新设置列宽,按比例调整
for (int i = 0; i < columnWidths.size(); ++i) {
int newWidth = static_cast<int>(columnWidths[i] * scaleFactor);
m_pTableView->setColumnWidth(i, newWidth);
}
#endif
}

View File

@ -0,0 +1,54 @@
#ifndef DEVICEPROPERTYPAGE_H
#define DEVICEPROPERTYPAGE_H
#pragma execution_character_set("utf-8")
#include <QWidget>
#include "datafetcher.h"
class MyTableModel;
class QTimer;
class QTableView;
class QPushButton;
class DevicePropertyPage : public QWidget,public DataFetcher
{
Q_OBJECT
public:
explicit DevicePropertyPage(QWidget *parent = nullptr);
~DevicePropertyPage();
void setBaseType(unsigned int base,unsigned int mask);
void InitializeTable();
public slots:
void handleTimeout(); //超时处理函数
private:
QTimer *m_pTimer;
private:
MyTableModel* m_myModel;
protected:
void Refresh();
void InitializeTableView(MyTableModel *model, QTableView *tableView);
// 重写resizeEvent当QTableView窗口大小变化时按比例调整列宽
void resizeEvent(QResizeEvent *event) override;
private slots:
void onButtonClicked();
void onTableViewDoubleClicked(const QModelIndex &index);
private:
unsigned int filterBaseType;
unsigned int mask_code;
QTableView* m_pTableView;
QPushButton* m_pButton;
QVector<int> columnWidths; // 存储初始列宽
};
#endif // DEVICEPROPERTYPAGE_H

View File

@ -0,0 +1,69 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
QMAKE_LFLAGS += /ignore:4099
QMAKE_CXXFLAGS_WARN_ON += -wd4100
include("$$PWD/QtSingleApplication/qtsingleapplication.pri")
DEFINES += HAVE_CONFIG_H
DEFINES += _CRT_SECURE_NO_WARNINGS
INCLUDEPATH += $$PWD/../../SDK/include
CONFIG(debug, debug|debug) {
INCLUDEPATH += "D:/Visual Leak Detector/include"
win32:LIBS += "D:/Visual Leak Detector/lib/Win64/vld.lib"
}
CONFIG(debug, debug|release) {
win32:LIBS += $$PWD/..\..\SDK\lib\libdesd.lib
win32:LIBS += $$PWD/..\..\SDK\lib\OpenSSL_VC\libcrypto64MDd.lib
win32:LIBS += $$PWD/..\..\SDK\lib\OpenSSL_VC\libssl64MDd.lib
win32:LIBS += $$PWD/..\..\SDK\lib\hv.lib
win32:LIBS += Ws2_32.lib
}else{
win32:LIBS += $$PWD/..\..\SDK\lib\libdes.lib
win32:LIBS += $$PWD/..\..\SDK\lib\OpenSSL_VC\libcrypto64MD.lib
win32:LIBS += $$PWD/..\..\SDK\lib\OpenSSL_VC\libssl64MD.lib
win32:LIBS += $$PWD/..\..\SDK\lib\hvd.lib
win32:LIBS += Ws2_32.lib
}
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
datafetcher.cpp \
devicepropertypage.cpp \
globalparameters.cpp \
main.cpp \
maindialog.cpp \
mainwindow.cpp \
mytablemodel.cpp
HEADERS += \
datafetcher.h \
devicepropertypage.h \
globalparameters.h \
maindialog.h \
mainwindow.h \
mytablemodel.h \
singleton.h
FORMS += \
maindialog.ui \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
emscfgres.qrc

View File

@ -0,0 +1,16 @@
<RCC>
<qresource prefix="/">
<file>images/emscfg-main.ico</file>
<file>images/hj-net.png</file>
<file>images/icon.png</file>
<file>images/PageAir.png</file>
<file>images/PageBattery.png</file>
<file>images/PageFan.png</file>
<file>images/PagePower.png</file>
<file>images/PagePV.png</file>
<file>images/PageSensor.png</file>
<file>images/PageSetting.png</file>
<file>images/PageSwitch.png</file>
<file>images/PageUps.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,114 @@
#include <QCoreApplication>
#include <QMessageBox>
#include <QString>
#include <QAbstractTableModel>
#include <QTableView>
#include <QHeaderView>
#include <QApplication>
#include <QCursor>
#include "globalparameters.h"
#include "mytablemodel.h"
AppData::~AppData()
{
}
AppData::AppData(token)
{
lstDataTableHeaderText << ("Status")
<< ("Parameter")
<< ("Value")
<< ("Unit")
<< ("Time");
nTimeOut = 5000;
qsDestinationIp = "127.0.0.1";
qsLastErrorString = "OK";
}
AppCommon::AppCommon(token)
{
}
AppCommon::~AppCommon()
{
}
void AppCommon::InitializeTableView(MyTableModel *model, QTableView *tableView)
{
//设置tableview的model
model->setHeadData(AppData::getInstance()->lstDataTableHeaderText);
tableView->setModel(model);
QHeaderView* pHeaderView = tableView->horizontalHeader();
//pHeaderView->setStyleSheet("QHeaderView::section {color: black;padding-left: 4px;border: 1px solid #6c6c6c;}");
pHeaderView->setStyleSheet("QHeaderView::section{background:lightgray;}");
// pHeaderView->setSectionResizeMode(QHeaderView::Stretch); //Stretch
pHeaderView->setHidden(false); //false 显示行号列 true Hide
//pHeaderView->setVisible(true);
//pHeaderView->setFixedHeight(40);
//点击表时不对表头行光亮(获取焦点)
pHeaderView->setHighlightSections(false);
//pHeaderView->setDefaultSectionSize(35);
// //设置表头字体加粗
// QFont font = pHeaderView->font();
// font.setBold(true);
// pHeaderView->setFont(font);
//设置表头字体
pHeaderView->setFont(QFont("Arial", 12));
// 设置表头列宽自动调整
for (int i = 0; i < model->columnCount(); ++i) {
pHeaderView->setSectionResizeMode(i, QHeaderView::Stretch);
}
// 允许用户通过拖动表头边缘调整列宽
pHeaderView->setSectionResizeMode(QHeaderView::Interactive);
tableView->verticalHeader()->setDefaultSectionSize(30); //行高
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
tableView->setAlternatingRowColors(true);
tableView->setTextElideMode(Qt::ElideMiddle);
//所有单元格的字体 设置成一样
tableView->setFont(QFont("Arial", 9));
//设置表格数据区内的所有单元格都不允许编辑
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
#if 0
//设置列宽
int w = tableView->width();
int base = w /(AppData::getInstance()->lstDataTableHeaderText.count()-1);
tableView->setColumnWidth(0,base-45);
tableView->setColumnWidth(1,base-20);
tableView->setColumnWidth(2,base+30);
tableView->setColumnWidth(3,base+10);
tableView->setColumnWidth(4,base);
#endif
tableView->show();
}
CWaitorCursor::CWaitorCursor()
{
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
}
CWaitorCursor::~CWaitorCursor()
{
QApplication::restoreOverrideCursor();
}

View File

@ -0,0 +1,78 @@
#ifndef GLOBALPARAMETERS_H
#define GLOBALPARAMETERS_H
#pragma execution_character_set("utf-8")
#include <QStringList>
#include "singleton.h"
class QAbstractTableModel;
class QTableView;
class MyTableModel;
//采集设备参数所处的状态
typedef enum _tagSignalStatus
{
STATUS_NORMAL = 0,
STATUS_WARN = 1,
STATUS_ERROR = 2,
STATUS_INFO = 3,
}SignalStatus;
typedef struct _ModelItem
{
SignalStatus status;
std::string ParameterName;
std::string value;
std::string unit;
std::string sampleTime;
}ModelItem;
typedef QList<ModelItem> TableData;
class CWaitorCursor
{
public:
CWaitorCursor();
~CWaitorCursor();
};
//全局变量
class AppData:public Singleton<AppData>
{
public:
AppData(token);
~AppData();
AppData(const AppData &other) = delete;
AppData& operator=(const AppData &other) = delete;
public:
//数据表格的表头
QStringList lstDataTableHeaderText;
//定时刷新间隔
int nTimeOut;
//目标机器IP
QString qsDestinationIp;
//最后的错误信息
QString qsLastErrorString;
};
//全局通用类
class AppCommon:public Singleton<AppCommon>
{
public:
AppCommon(token);
~AppCommon();
AppCommon(const AppCommon&)=delete;
AppCommon& operator =(const AppCommon&)= delete;
public:
void InitializeTableView(MyTableModel* model,QTableView* tableView);
};
#endif // GLOBALPARAMETERS_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -0,0 +1,73 @@
#ifdef _DEBUG
#include <vld.h>
#endif
#include "mainwindow.h"
#include "qtsingleapplication.h"
#include <QApplication>
#include <QTranslator>
#include <QMessageBox>
#include <QScreen>
#include <hv/hv.h>
#include <hv/hmain.h>
#include <hv/iniparser.h>
#include <hv/hloop.h>
#include <hv/hsocket.h>
#include <hv/hssl.h>
int main(int argc, char *argv[])
{
QString app_unique_name("emsConfigurer_application_name");
QtSingleApplication app(app_unique_name,argc, argv);
if(app.isRunning())
{
QMessageBox::information(nullptr, "EMS Configurer", "Another instance is already running.");
app.sendMessage("raise_window_noop", 1000); //1s后激活前个实例
return EXIT_SUCCESS;
}
main_ctx_init(argc, argv);
QString appDir = QCoreApplication::applicationDirPath();
std::string logFilePath = (appDir + QString::fromStdString("/emsConfigurer.log")).toStdString();
hlog_set_file(logFilePath.c_str());
hlogi("=========--- Welcome to the Earth ---=========");
hlogi("%s version: %s", argv[0], "1.1.0");
hlog_fsync();
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages)
{
const QString baseName = "emsConfigurer_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName))
{
app.installTranslator(&translator);
break;
}
}
MainWindow w;
//隐藏(不显示)最大化最小化按钮
w.setWindowFlags(w.windowFlags()&~Qt::WindowMinMaxButtonsHint);
//w.setWindowFlags(w.windowFlags() | Qt::WindowStaysOnTopHint);
w.setStyleSheet("{border-radius: 4px;}"); // 定制圆角
// ".QLabel{background: gray;}.QTextEdit{background: white;}");
//获取窗口尺寸并居中
QScreen *scr = app.primaryScreen();
int scr_w = scr->size().width();
int scr_h = scr->size().height();
w.move((scr_w - w.width()) / 2, (scr_h - w.height()) / 2);
w.show();
int ret = app.exec();
hlogi("=========--- I'll be back! ---=========");
return ret;
}

View File

@ -0,0 +1,217 @@
#include "maindialog.h"
#include "ui_maindialog.h"
#include <QToolBar>
#include <QListWidget>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <QIcon>
#include <QSize>
#include <QPushButton>
#include <QSplitter>
#include <QSettings>
#include <QCloseEvent>
#include <QMessageBox>
#include <QTableView>
#include <QStandardItemModel>
#include "devicepropertypage.h"
MainDialog::MainDialog(QWidget *parent) :
QMainWindow (parent),
ui(new Ui::MainDialog)
{
//ui->setupUi(this);
this->setWindowIcon(QIcon(":/images/icon.png"));
InitializeUI();
// Load the window state
loadWindowState();
}
MainDialog::~MainDialog()
{
delete ui;
}
void MainDialog::InitializeUI()
{
// Create central widget and layout
this->takeCentralWidget();
QWidget *centralWidget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
//Create toolbar
CreateToolbar();
// Set up the QListWidget
m_pDeviceListWidget = new QListWidget(this);
m_pDeviceListWidget->setStyleSheet("background-color:transparent");
m_pDeviceListWidget->setViewMode(QListView::IconMode);
m_pDeviceListWidget->setIconSize(QSize(70, 70));
m_pDeviceListWidget->setGridSize(QSize(145, 100)); // item 的大小
m_pDeviceListWidget->setMovement(QListView::Static);
m_pDeviceListWidget->setMaximumWidth(170);
m_pDeviceListWidget->setMinimumWidth(170); // Set minimum width
m_pDeviceListWidget->setResizeMode(QListView::Fixed);
m_pDeviceListWidget->setSpacing(25);
//m_pDeviceListWidget->setUniformItemSizes(true); // 所有的 item 一样大
m_pDeviceListWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
CreateIcon(QIcon(":/images/PagePower.png"),tr("Power"));
CreateIcon(QIcon(":/images/PageBattery.png"),tr("Battery"));
CreateIcon(QIcon(":/images/PageSwitch.png"),tr("Switch"));
CreateIcon(QIcon(":/images/PageAir.png"),tr("Air"));
CreateIcon(QIcon(":/images/PageFan.png"),tr("Fan"));
CreateIcon(QIcon(":/images/PageSensor.png"),tr("Sensor"));
// Set up the QStackedWidget
CreateTablePage();
// Set up the QSplitter to manage the resizing of QListWidget and QStackedWidget
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
splitter->addWidget(m_pDeviceListWidget);
splitter->addWidget(m_pDevicestackedWidget);
splitter->setSizes(QList<int>({200, 600})); // Set initial sizes (200 for QListWidget, 600 for QStackedWidget)
// Disable splitter dragging
splitter->setChildrenCollapsible(false);
// 将工具栏添加到主窗口的顶部
//addToolBar(Qt::TopToolBarArea, m_pMainToolBar);
// Set up layout
mainLayout->addWidget(m_pMainToolBar);
mainLayout->addWidget(splitter);
centralWidget->setLayout(mainLayout);
// Set central widget
setCentralWidget(centralWidget);
// Set initial size of the dialog
setWindowTitle(tr("EMS Configurer "));
//resize(800, 600);
setMinimumSize(1024, 768);
connect(m_pDeviceListWidget, &QListWidget::currentItemChanged, this, &MainDialog::changePage);
}
void MainDialog::CreateToolbar()
{
m_pMainToolBar = new QToolBar(this);
m_pMainToolBar->setIconSize(QSize(48, 48));
// 创建一个水平布局以容纳图标和占位符
QWidget *toolBarWidget = new QWidget(this);
QHBoxLayout *layout = new QHBoxLayout(toolBarWidget);
layout->setContentsMargins(0, 0, 0, 0); // 去除内边距
// 添加一个弹性空间以推送图标到右侧
QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
layout->addItem(spacer);
// Create actions for the toolbar
QAction *action1 = new QAction(QIcon(":/images/icon.png"), "Button 1", this);
QAction *action2 = new QAction(QIcon(":/images/icon.png"), "Button 2", this);
QAction *action3 = new QAction(QIcon(":/images/icon.png"), "About...", this);
// Add actions to the toolbar
m_pMainToolBar->addAction(action1);
m_pMainToolBar->addAction(action2);
m_pMainToolBar->addAction(action3);
// 将工具栏的 widget 设置为包含图标和占位符的 widget
m_pMainToolBar->addWidget(toolBarWidget);
// Connect actions to slots
connect(action1, &QAction::triggered, this, &MainDialog::onToolButton1Clicked);
connect(action2, &QAction::triggered, this, &MainDialog::onToolButton1Clicked);
connect(action3, &QAction::triggered, this, &MainDialog::onAboutButtonClicked);
}
void MainDialog::CreateTablePage()
{
m_pDevicestackedWidget = new QStackedWidget(this);
QVBoxLayout *stackedWidgetLayout = new QVBoxLayout(m_pDevicestackedWidget);
#if 1
//m_pDevicestackedWidget->setLayout(stackedWidgetLayout);
stackedWidgetLayout->addWidget(m_pDevicestackedWidget);
DevicePropertyPage *page1 = new DevicePropertyPage(m_pDevicestackedWidget);
DevicePropertyPage *page2 = new DevicePropertyPage(m_pDevicestackedWidget);
m_pDevicestackedWidget->addWidget(page1); // Add QTableView as a page
m_pDevicestackedWidget->addWidget(page2);
m_pDevicestackedWidget->addWidget(new QPushButton("Page 3"));
m_pDevicestackedWidget->addWidget(new QPushButton("Page 4"));
m_pDevicestackedWidget->addWidget(new QPushButton("Page 5"));
m_pDevicestackedWidget->addWidget(new QPushButton("Page 6"));
#endif
// setLayout(stackedWidgetLayout);
}
void MainDialog::CreateIcon(const QIcon& icon,QString text)
{
QListWidgetItem *itemButton = new QListWidgetItem(m_pDeviceListWidget);
itemButton->setIcon(icon);
itemButton->setText(text);
itemButton->setTextAlignment(Qt::AlignHCenter);
itemButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
}
void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
{
if (!current)
current = previous;
m_pDevicestackedWidget->setCurrentIndex(m_pDeviceListWidget->row(current));
}
void MainDialog::closeEvent(QCloseEvent *event)
{
// Save the window state
saveWindowState();
QMainWindow::closeEvent(event);
}
void MainDialog::saveWindowState()
{
QSettings settings("HJ-NET", "EMSCFG");
settings.setValue("geometry", saveGeometry());
settings.setValue("windowState", saveState());
}
void MainDialog::loadWindowState()
{
QSettings settings("HJ-NET", "EMSCFG");
restoreGeometry(settings.value("geometry").toByteArray());
restoreState(settings.value("windowState").toByteArray());
}
void MainDialog::onToolButton1Clicked()
{
QMessageBox::information(this, "Button Clicked", "Button 1 was clicked!");
}
void MainDialog::onToolButton2Clicked()
{
QMessageBox::information(this, "Button Clicked", "Button 2 was clicked!");
}
void MainDialog::onAboutButtonClicked()
{
QMessageBox::information(this, "Button Clicked", "About");
}

View File

@ -0,0 +1,53 @@
#ifndef MAINDIALOG_H
#define MAINDIALOG_H
#include <QMainWindow>
#include <QListWidget>
#include <QListWidgetItem>
#include <QIcon>
#include <QStackedWidget>
#include <QToolBar>
namespace Ui {
class MainDialog;
}
class MainDialog : public QMainWindow
{
Q_OBJECT
public:
explicit MainDialog(QWidget *parent = nullptr);
~MainDialog();
void InitializeUI();
void loadWindowState();
public slots:
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
private slots:
void onToolButton1Clicked();
void onToolButton2Clicked();
void onAboutButtonClicked();
private:
Ui::MainDialog *ui;
QListWidget *m_pDeviceListWidget;
QStackedWidget *m_pDevicestackedWidget;
QToolBar *m_pMainToolBar;
private:
void CreateToolbar();
void CreateIcon(const QIcon& icon,QString text);
void CreateTablePage();
protected:
void closeEvent(QCloseEvent *event) override;
void saveWindowState();
};
#endif // MAINDIALOG_H

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainDialog</class>
<widget class="QDialog" name="MainDialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>867</width>
<height>665</height>
</rect>
</property>
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,53 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPixmap>
#include <QMessageBox>
#include <QRegularExpression>
#include <QRegularExpressionValidator>
#include "MainDialog.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_pMainDialog(nullptr)
{
ui->setupUi(this);
this->setWindowIcon(QIcon(":/images/icon.png"));
QPixmap pixmap(":/images/hj-net.png");
pixmap = pixmap.scaled(250, 75, Qt::KeepAspectRatio, Qt::SmoothTransformation); // 按比例缩放
ui->label_logo->setPixmap(pixmap);
QString qsLineEditStyle("QLineEdit { min-height: 20px; min-width: 120px; }");
ui->userToken->setStyleSheet(qsLineEditStyle);
ui->serverIp->setStyleSheet(qsLineEditStyle);
QRegularExpression rx("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$");
QRegularExpressionValidator* ipValidator = new QRegularExpressionValidator(rx, this);
ui->serverIp->setValidator(ipValidator);
setIp("127.0.0.1");
}
MainWindow::~MainWindow()
{
delete ui;
if (m_pMainDialog)
{
delete m_pMainDialog;
m_pMainDialog = nullptr;
}
}
void MainWindow::setIp(const QString &ip)
{
ui->serverIp->setText(ip);
}
void MainWindow::on_pb_Logon_clicked()
{
m_pMainDialog = new MainDialog();
m_pMainDialog->show();
this->close();
}

View File

@ -0,0 +1,30 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainDialog;
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void setIp(const QString &ip);
private slots:
void on_pb_Logon_clicked();
private:
Ui::MainWindow *ui;
MainDialog* m_pMainDialog;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>551</width>
<height>352</height>
</rect>
</property>
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
</property>
<property name="windowTitle">
<string>EMS Configurer</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>130</x>
<y>176</y>
<width>61</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Host IP</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>140</x>
<y>60</y>
<width>231</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>26</pointsize>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Configurer</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLineEdit" name="serverIp">
<property name="geometry">
<rect>
<x>220</x>
<y>173</y>
<width>124</width>
<height>23</height>
</rect>
</property>
<property name="inputMask">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>370</x>
<y>88</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>for EMU Host</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPushButton" name="pb_Test">
<property name="geometry">
<rect>
<x>350</x>
<y>173</y>
<width>51</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Test</string>
</property>
</widget>
<widget class="QLabel" name="label_logo">
<property name="geometry">
<rect>
<x>7</x>
<y>7</y>
<width>261</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string>WWW.HJ-NET.COM</string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>140</x>
<y>280</y>
<width>251</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pb_Logon">
<property name="text">
<string>Logon</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pb_Close">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QLineEdit" name="userToken">
<property name="geometry">
<rect>
<x>220</x>
<y>233</y>
<width>181</width>
<height>23</height>
</rect>
</property>
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="inputMethodHints">
<set>Qt::ImhHiddenText|Qt::ImhNoAutoUppercase|Qt::ImhNoEditMenu|Qt::ImhNoPredictiveText|Qt::ImhSensitiveData</set>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>130</x>
<y>200</y>
<width>68</width>
<height>30</height>
</rect>
</property>
<property name="text">
<string>Login name</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>130</x>
<y>233</y>
<width>56</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Password</string>
</property>
</widget>
<widget class="QLineEdit" name="userName">
<property name="geometry">
<rect>
<x>220</x>
<y>203</y>
<width>181</width>
<height>23</height>
</rect>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,151 @@
#include <QColor>
#include "mytablemodel.h"
MyTableModel::MyTableModel(QObject* parent)
:QAbstractTableModel(parent)
{
for(int i=0;i<100;i++)
{
ModelItem item;
item.status = STATUS_WARN;
item.ParameterName= "Visual Leak Detector detected 1 memory leak (84 bytes)";
item.sampleTime = "2024-9-10 11:22:33.444";
item.unit = "C";
item.value = "100";
m_modelData.append(item);
}
}
int MyTableModel::rowCount(const QModelIndex & /*parent*/) const
{
return m_modelData.size();
}
int MyTableModel::columnCount(const QModelIndex & /*parent*/) const
{
return AppData::getInstance()->lstDataTableHeaderText.count();
}
QVariant MyTableModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
const int row = index.row();
switch (index.column())
{
case 0:
{
if (m_modelData.at(row).status == STATUS_NORMAL) return tr("Normal");
if (m_modelData.at(row).status == STATUS_INFO) return tr("INFO");
if (m_modelData.at(row).status == STATUS_WARN) return tr("WARN");
if (m_modelData.at(row).status == STATUS_ERROR) return tr("ERROR");
}
case 1:
{
return m_modelData.at(row).ParameterName.c_str();
}
case 2: return m_modelData.at(row).value.c_str();
case 3: return m_modelData.at(row).unit.c_str();
case 4: return m_modelData.at(row).sampleTime.c_str();
}
}
//对齐处理
if (role == Qt::TextAlignmentRole)
{
//const int row = index.row();
switch (index.column())
{
case 1:
case 2:
case 3:
return QVariant(Qt::AlignLeft|Qt::AlignVCenter);
break;
//case 4:
// return QVariant(Qt::AlignRight|Qt::AlignVCenter);
// break;
default:
return Qt::AlignCenter;
break;
}
}
if (role == Qt::BackgroundRole)
{
const int row = index.row();
switch (index.column())
{
case 0: //状态
case 2: //数值
{
if (m_modelData.at(row).status == STATUS_WARN)
return QVariant(QColor(Qt::yellow));
else if (m_modelData.at(row).status == STATUS_ERROR)
return QVariant(QColor(Qt::red));
}
}
}
return QVariant();
}
QVariant MyTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
if (section < m_headeList.size())
{
return m_headeList[section];
}
}
return QAbstractItemModel::headerData(section, orientation, role);
}
const TableData *MyTableModel::getModelData() const
{
return &m_modelData;
}
bool MyTableModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
//beginResetModel();
if (!index.isValid())
return false;
//endResetModel(); //在结束前添加此函数
return QAbstractTableModel::setData(index, value, role);
}
Qt::ItemFlags MyTableModel::flags(const QModelIndex &index) const
{
return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}
void MyTableModel::setModelData(TableData data)
{
//修改数据前后用beginResetModel()和endResetModel()
beginResetModel(); //通过这个告诉我要开始修改model了
m_modelData.clear();
for (int i = 0;i < data.count();++i)
{
m_modelData.append(data[i]);
}
endResetModel(); //通过这个告诉我修改model结束了
}
void MyTableModel::clearModelData()
{
m_modelData.clear();
}
void MyTableModel::setHeadData(QStringList i_list)
{
m_headeList=i_list;
}

View File

@ -0,0 +1,37 @@
#pragma execution_character_set("utf-8")
#ifndef MYTABLEMODEL_H
#define MYTABLEMODEL_H
#include <QAbstractTableModel>
#include <QString>
#include "globalparameters.h"
class MyTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
MyTableModel(QObject* parent);
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex& index) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
const TableData *getModelData() const;
private:
TableData m_modelData;
QStringList m_headeList;
public:
void setHeadData(QStringList i_list);
void setModelData(TableData data);
void clearModelData();
};
#endif // MYTABLEMODEL_H

View File

@ -0,0 +1,24 @@
#ifndef SINGLETON_H
#define SINGLETON_H
#include <iostream>
template<typename T>
class Singleton
{
public:
static T* getInstance() noexcept(std::is_nothrow_constructible<T>::value)
{
static T instance{token()};
return &instance;
}
virtual ~Singleton() =default;
Singleton(const Singleton&)=delete;
Singleton& operator =(const Singleton&)=delete;
protected:
struct token{}; // helper class
Singleton() noexcept=default;
};
#endif // SINGLETON_H

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.35130.168
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinDataHubs", "WinDataHubs.vcxproj", "{2192CF4F-DE56-4896-9EA1-4C61B40590A5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Debug|x64.ActiveCfg = Debug|x64
{2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Debug|x64.Build.0 = Debug|x64
{2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Debug|x86.ActiveCfg = Debug|Win32
{2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Debug|x86.Build.0 = Debug|Win32
{2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Release|x64.ActiveCfg = Release|x64
{2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Release|x64.Build.0 = Release|x64
{2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Release|x86.ActiveCfg = Release|Win32
{2192CF4F-DE56-4896-9EA1-4C61B40590A5}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {81B0EBA0-C45B-4F9A-B3E8-4780447CB231}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{2192cf4f-de56-4896-9ea1-4c61b40590a5}</ProjectGuid>
<RootNamespace>WinDataHubs</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)\..\..\sdk\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)\..\..\sdk\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)\..\..\sdk\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)\..\..\sdk\Lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>hv.lib;zlibd.lib;mysqlcppconn.lib;libiconvD.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="eventhandler.cpp" />
<ClCompile Include="iconv-utils.cpp" />
<ClCompile Include="kutilities.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="openjson.cpp" />
<ClCompile Include="opmysql.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="eventhandler.h" />
<ClInclude Include="frame_define.h" />
<ClInclude Include="iconv-utils.h" />
<ClInclude Include="kdefine.h" />
<ClInclude Include="kutilities.h" />
<ClInclude Include="mqtt_msg.h" />
<ClInclude Include="openjson.h" />
<ClInclude Include="opmysql.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -8,7 +8,8 @@ log_filesize = 16M
# worker_processes = auto # auto = ncpu # worker_processes = auto # auto = ncpu
# worker_processes = auto # worker_processes = auto
worker_processed = 0 worker_processed = 0
worker_threads = auto # worker_threads = auto
worker_threads = 1
host = 0.0.0.0 host = 0.0.0.0
port = 44242 port = 44242

View File

@ -76,20 +76,27 @@
<ImportGroup Label="PropertySheets" /> <ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>D:\My Documents\汇珏网络\15. EMS\projects\sdk\include;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)\..\..\sdk\include;$(IncludePath)</IncludePath>
<ProjectPublicIncludePath>-I/usr/local/include</ProjectPublicIncludePath> <ProjectPublicIncludePath>-I/usr/local/include</ProjectPublicIncludePath>
<LibraryPath>$(SolutionDir)\..\..\sdk\lib;</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<IncludePath>D:\My Documents\汇珏网络\15. EMS\projects\emsApplication\sdk\include;$(IncludePath)</IncludePath> <IncludePath>..\..\..\emsApplication\sdk\include;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="eventhandler.cpp" />
<ClCompile Include="iconv-utils.cpp" /> <ClCompile Include="iconv-utils.cpp" />
<ClCompile Include="kutilities.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="openjson.cpp" /> <ClCompile Include="openjson.cpp" />
<ClCompile Include="opmysql.cpp" /> <ClCompile Include="opmysql.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="eventhandler.h" />
<ClInclude Include="frame_define.h" />
<ClInclude Include="iconv-utils.h" /> <ClInclude Include="iconv-utils.h" />
<ClInclude Include="kdefine.h" />
<ClInclude Include="kutilities.h" />
<ClInclude Include="mqtt_msg.h" /> <ClInclude Include="mqtt_msg.h" />
<ClInclude Include="openjson.h" /> <ClInclude Include="openjson.h" />
<ClInclude Include="opmysql.h" /> <ClInclude Include="opmysql.h" />
@ -103,6 +110,7 @@
<Link> <Link>
<AdditionalOptions>-L/usr/local/lib</AdditionalOptions> <AdditionalOptions>-L/usr/local/lib</AdditionalOptions>
<LibraryDependencies>hv;sqlite3;dl</LibraryDependencies> <LibraryDependencies>hv;sqlite3;dl</LibraryDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">

View File

@ -0,0 +1,249 @@
#include "eventhandler.h"
#include <hv/hv.h>
#include <hv/hmain.h>
#include <hv/iniparser.h>
#include <hv/hloop.h>
#include <hv/hsocket.h>
#include <hv/hssl.h>
#include "kdefine.h"
#include "frame_define.h"
#include "openjson.h"
#include "iconv-utils.h"
#include "kutilities.h"
#include "opmysql.h"
#include "mqtt_msg.h"
EventHandler::EventHandler()
{
}
EventHandler::~EventHandler()
{
}
void EventHandler::onRecvHandler(hio_t* io, void* buf, int readbytes)
{
__USING_NAMESPACE_HJ__;
char localaddrstr[SOCKADDR_STRLEN] = { 0 };
char peeraddrstr[SOCKADDR_STRLEN] = { 0 };
hlogi("### 1 ### on_recv fd=%d readbytes=%d [%s] <==== [%s]", hio_fd(io), readbytes,
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
MessageFrame respFrame;
if( readbytes > 0xFFFF - 1 )
{
hloge("too large data buffer to process: %d", readbytes);
respFrame.setErrorFrame(ERR_INVALID_BUF_LEN);
hio_write(io, (void*)&respFrame, sizeof respFrame);
return;
}
hlogi("<=== decode OK [\n%s\n]", printHex(buf, readbytes).c_str());
MessageFrame* pReadFrame = (MessageFrame*)buf;
hlogi("on_recv fd=%d frame_len=%d [0x%x] ", hio_fd(io), pReadFrame->frame_len, pReadFrame->frame_len);
if( pReadFrame->frame_len > 0xFFFF - 1 )
{
hloge("too big string buffer to process: %d, it should be less than %d", pReadFrame->frame_len, 0xFFFF);
respFrame.setErrorFrame(ERR_INVALID_LEN);
hio_write(io, (void*)&respFrame, sizeof respFrame);
return;
}
if( Frame_DeviceData_Request == pReadFrame->frame_type )
{
handleGatherData(io, buf, readbytes);
}
else
{
assert(false);
}
}
void EventHandler::handleGatherData(hio_t* io, void* buf, int readbytes)
{
assert(buf);
__USING_NAMESPACE_HJ__;
MessageFrame respFrame;
MessageFrame* pReadFrame = (MessageFrame*)buf;
hlogi("<=== reveive device data request");
OpenJson json;
CODING buf_code = GetCoding((unsigned char*)pReadFrame->frame_content, pReadFrame->frame_len); //判断是否是utf-8
hlogi("<=== recieve buffer coding is [%s]", buf_code == GBK ? "GBK" : (buf_code == UTF8 ? "UTF8" : "UNKNOWN CODING"));
MessageData* pData = (MessageData*)pReadFrame->frame_content;
#ifdef _DEBUG
hlogd("<=== MessageData structure [\n%s\n]", printHex(pData, pReadFrame->frame_len).c_str());
#endif
//这里将帧内帧的内容转换为字符串符合json格式的字符串详见mqtt_msg.h的MessageData结构定义
std::string msg((char*)pReadFrame->frame_content + MSG_HEADER_LENGTH, pReadFrame->frame_len - MSG_HEADER_LENGTH);
#ifdef _DEBUG
hlogd("<=== json content [\n%s\n]", msg.c_str());
#endif
if( buf_code == CODING::GBK
|| buf_code == CODING::UNKOWN )
{
std::string str_result;
//转换为UTF8
if( !GBKToUTF8(msg, str_result) )
{
hloge("Failed to transfer code from GBK to UTF-8");
respFrame.setErrorFrame(ERR_INVALID_UTF8);
hio_write(io, (void*)&respFrame, sizeof respFrame);
return;
}
hlogi("Successfuly transfer code from GBK to UTF-8!");
msg = str_result;
}
#ifdef _DEBUG
hlogd("<=== recieve !!VALID!! mqtt pack len =[%d] data=[%s]", msg.length(), msg.c_str()); //这里还是好的
#endif
unsigned int len = msg.length();
char* pTmp = new char[len];
memcpy(pTmp, msg.c_str(), len);
std::shared_ptr<char> ptr; //放个智能指针省得忘记删除
ptr.reset(pTmp);
//hlogi("<=== decode OK, msg=[%s]", msg.c_str());
#if 0
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 17).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 18).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 19).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 20).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 21).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 22).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 23).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 24).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 25).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 26).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 27).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 28).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 29).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 30).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 31).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 32).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 33).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 34).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 61).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 62).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 63).c_str());
#endif
//hlogd("<=== decode OK [\n%s\n]", printHex(pTmp, len).c_str());
try
{
if( !json.decode(msg) )
{
hloge("Failed to decode json string pack , length=%d", readbytes);
respFrame.setErrorFrame(ERR_INVALID_JSON_FMT);
hio_write(io, (void*)&respFrame, sizeof respFrame);
return;
}
std::string fsucode = json["FsuCode"].s();
std::string msg_type = json["type"].s();
std::string timestamp = get_current_timestamp(); // json["TimeStamp"].s();
if( fsucode.length() == 0 )
{
//delete[] pTmp;
hlogw("!!empty fsucode recieved!");
respFrame.setErrorFrame(ERR_INVALID_FSUCODE);
hio_write(io, (void*)&respFrame, sizeof respFrame);
return;
}
hlogi("<=== decode OK, recieve fsucode=[%s] type=[%s] ts=[%s]", fsucode.c_str(), msg_type.c_str(), timestamp.c_str());
hio_write(io, (void*)&respFrame, sizeof respFrame);
#ifdef _DEBUG
hlogd("<<<<Check Mem after decode here>>>> \n[\n%s\n]\n", printHex(pTmp, len).c_str());
#endif
std::string out_compress;
int zip_ret = 0;
if( (zip_ret = CompressString(pTmp, len, out_compress, Z_DEFAULT_COMPRESSION)) != Z_OK )
{
hloge("Failed to compress source data, zip return value %d", zip_ret);
return;
}
hlogd("<<<<Compress result: string size from original [%d] to [%d]", len, out_compress.size());
#ifdef _DEBUG
hlogd("<<<<Compressed string here>>>> \n[\n%s\n]\n", printHex(out_compress.c_str(), out_compress.size()).c_str());
#endif
//std::string msg2(pTmp, len);
if( msg_type == "gateway-data"
|| msg_type == "gateway-alarmdata"
|| msg_type == "gateway-writedata"
|| msg_type == "gateway-readdata"
|| msg_type == "web-write"
|| msg_type == "web-alarm" )
{
auto& IdCodeContent = json["IdCodeContent"];
if( IdCodeContent.size() <= 0 )
{
//delete[] pTmp;
hloge("invalid IdCodeContent's size: %d", IdCodeContent.size());
return;
}
auto& pNode = IdCodeContent[0]; //这是只解析第一个节点
std::string oid = pNode["OID"].s();
OpDatabase::getInstance()->InsertMessage(timestamp, msg_type, fsucode, out_compress, (int)pData->mqtt_topic, (int)pData->device_id);
}
if( msg_type == "web-read" )
{
auto& IdCodeContent = json["IdCodes"];
if( IdCodeContent.size() <= 0 )
{
hloge("invalid IdCodes's size: %d", IdCodeContent.size());
//delete[] pTmp;
return;
}
auto& pNode = IdCodeContent[0]; //这是只解析第一个节点
std::string oid = pNode.s();
OpDatabase::getInstance()->InsertMessage(timestamp, msg_type, fsucode, out_compress, (int)pData->mqtt_topic, (int)pData->device_id);
}
//delete[] pTmp;
}
catch( const char* errMsg )
{
hloge("Failed to decode json string pack , catch error:%s", errMsg);
respFrame.setErrorFrame(ERR_INVALID_JSON_FMT);
hio_write(io, (void*)&respFrame, sizeof respFrame);
return;
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include <hv/hloop.h>
class EventHandler
{
public:
EventHandler();
virtual ~EventHandler();
public:
static void onRecvHandler(hio_t* io, void* buf, int readbytes);
protected:
//处理采集程序上传的数据以JSON数据上报
static void handleGatherData(hio_t* io, void* buf, int readbytes);
};

View File

@ -0,0 +1,54 @@
#pragma once
#pragma pack(1)
#include "kdefine.h"
__NAMESPACE_BEGIN__(HJ)
#define FRAME_HEADER_LENGTH (5)
#define FRAME_TAILE_LENGTH (4)
typedef enum tagErrorCode : unsigned char
{
ERR_OK = 0X00,
ERR_INVALID_LEN = 0X01,
ERR_INVALID_UTF8 = 0X02,
ERR_INVALID_BUF_LEN = 0X03,
ERR_INVALID_JSON_FMT = 0X04,
ERR_INVALID_FSUCODE = 0X05,
ERR_UNKOWN = 0XFF
}ErrorCode;
typedef enum tagFrameType : unsigned char
{
Frame_Response = 0x00, //返回帧
Frame_Request = 0x01, //请求帧
Frame_DeviceData_Request = 0x02, //来自采集程序的数据请求包,将数据保存到数据库中
}FrameType;
typedef struct tagFrameTail
{
unsigned char frame_delimiter[4] = { 0xEE,0xFF,0xEE,0xFF };
}FrameTail;
typedef struct tagFrame
{
FrameType frame_type; //帧类型
unsigned int frame_len; //帧数据长度
unsigned char frame_content[1]; //帧的内容实际应为json字符串由json内容自解释
tagFrame()
{
frame_type = Frame_Response;
frame_len = 1;
frame_content[0] = ERR_OK;
}
void setErrorFrame(ErrorCode err = ERR_OK)
{
frame_len = 1;
frame_content[0] = err;
}
}MessageFrame;
__NAMESPACE_END__(HJ)
#pragma pack()

View File

@ -135,8 +135,11 @@ int code_convert(const char* from_charset, const char* to_charset, char* inbuf,
return -1; return -1;
} }
iconv_close(cd); iconv_close(cd);
*pout = '\0'; #ifndef _WIN32
* pout = '\0';
#else
*pout = (char*)'\0';
#endif
return 0; return 0;
} }

View File

@ -0,0 +1,41 @@
#ifndef __KDEFINE_INCLUDE__
#define __KDEFINE_INCLUDE__
#define K22_STR_EXP(__A) #__A
#define K22_STR(__A) K22_STR_EXP(__A)
#define K22_STRW_EXP(__A) L ## #__A
#define K22_STRW(__A) K22_STRW_EXP(__A)
#define K22_CMS_VERSION_MAJOR 1
#define K22_CMS_VERSION_MINOR 215
#define K22_CMS_VERSION_REVISION 0
#define K22_VERSION K22_STR(K22_CMS_VERSION_MAJOR) "." K22_STR(K22_CMS_VERSION_MINOR) "." K22_STR(K22_CMS_VERSION_REVISION) ""
#ifdef __cplusplus
# ifndef EXTERN_C
# define EXTERN_C extern "C"
# endif
# ifndef BEGIN_EXTERN_C
# define BEGIN_EXTERN_C extern "C" {
# endif
# ifndef END_EXTERN_C
# define END_EXTERN_C } // extern "C"
# endif
#else
# define EXTERN_C extern
# define BEGIN_EXTERN_C
# define END_EXTERN_C
#endif // __cplusplus
#define __NAMESPACE_BEGIN__(X) namespace X {
#define __NAMESPACE_END__(X) }
#define __USING_NAMESPACE__(X) using namespace X
#define __USING_NAMESPACE_HJ__ using namespace HJ
#endif //__KDEFINE_INCLUDE__

View File

@ -0,0 +1,269 @@
#include "kutilities.h"
#include <iomanip>
#include <string>
#include <memory>
#include <sstream>
#include <chrono>
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int CompressString(const char* in_str, size_t in_len, std::string& out_str, int level)
{
if( !in_str )
return Z_DATA_ERROR;
int ret, flush;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if( ret != Z_OK )
return ret;
std::shared_ptr<z_stream> sp_strm(&strm, [](z_stream* strm)
{
(void)deflateEnd(strm);
});
const char* end = in_str + in_len;
//size_t pos_index = 0;
size_t distance = 0;
/* compress until end of file */
do
{
distance = end - in_str;
strm.avail_in = (distance >= CHUNK) ? CHUNK : distance;
strm.next_in = (Bytef*)in_str;
// next pos
in_str += strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
if( ret == Z_STREAM_ERROR )
break;
have = CHUNK - strm.avail_out;
out_str.append((const char*)out, have);
}
while( strm.avail_out == 0 );
if( strm.avail_in != 0 ); /* all input will be used */
break;
/* done when last data in file processed */
}
while( flush != Z_FINISH );
if( ret != Z_STREAM_END ) /* stream will be complete */
return Z_STREAM_ERROR;
/* clean up and return */
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int DecompressString(const char* in_str, size_t in_len, std::string& out_str)
{
if( !in_str )
return Z_DATA_ERROR;
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if( ret != Z_OK )
return ret;
std::shared_ptr<z_stream> sp_strm(&strm, [](z_stream* strm)
{
(void)inflateEnd(strm);
});
const char* end = in_str + in_len;
//size_t pos_index = 0;
size_t distance = 0;
int flush = 0;
/* decompress until deflate stream ends or end of file */
do
{
distance = end - in_str;
strm.avail_in = (distance >= CHUNK) ? CHUNK : distance;
strm.next_in = (Bytef*)in_str;
// next pos
in_str += strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
/* run inflate() on input until output buffer not full */
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
if( ret == Z_STREAM_ERROR ) /* state not clobbered */
break;
switch( ret )
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
return ret;
}
have = CHUNK - strm.avail_out;
out_str.append((const char*)out, have);
}
while( strm.avail_out == 0 );
/* done when inflate() says it's done */
}
while( flush != Z_FINISH );
/* clean up and return */
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
// 函数用于将内存块转换为十六进制字符串
std::string printHex(const void* data, size_t size)
{
std::ostringstream oss;
std::ostringstream oss2;
std::ostringstream ossrow;
const size_t lineSize = 16; // 每行输出的字节数
const unsigned char* p = static_cast<const unsigned char*>(data);
int ic = 0;
int row = 0;
ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : ";
oss << ossrow.str().c_str();
for( size_t i = 0; i < size; ++i )
{
ic++;
// 每个字节之间用空格分隔
oss << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << static_cast<int>(p[i]);
char ch = (isprint(p[i]) != 0) ? p[i] : '.';
oss2 << ch;
// 每lineSize个字节换行
if( (i + 1) % lineSize == 0 )
{
ossrow.clear();
ossrow.str("");
oss << " [" << oss2.str().c_str() << "]" << std::endl;
oss2.clear();
oss2.str("");
ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : ";
oss << ossrow.str().c_str();
ic = 0;
}
else if( i == size - 1 )
{
if( (i + 1) % lineSize != 0 )
{
if( i % 2 != 0 )
{
for( size_t j = 0; j < (lineSize - ic); j++ )
{
oss << " --";
}
}
else
{
for( size_t j = 0; j < (lineSize - ic); j++ )
{
oss << " --";
}
}
}
oss << " [" << oss2.str().c_str();
if( (i + 1) % lineSize != 0 )
{
for( size_t j = 0; j < (lineSize - ic); j++ )
{
oss << " ";
}
}
oss << "]" << std::endl;
oss2.clear();
oss2.str("");
ic = 0;
}
#if 0
else if( (i + 1) % 8 == 0 )
{
oss << " ";
oss2 << " ";
}
#endif
else
{
oss << " ";
}
}
return oss.str();
}
std::string get_current_timestamp()
{
auto now = std::chrono::system_clock::now();
//通过不同精度获取相差的毫秒数
uint64_t dis_millseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count()
- std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count() * 1000;
time_t tt = std::chrono::system_clock::to_time_t(now);
auto time_tm = localtime(&tt);
char strTime[25] = { 0 };
sprintf(strTime, "%d-%02d-%02d %02d:%02d:%02d.%03d", time_tm->tm_year + 1900,
time_tm->tm_mon + 1, time_tm->tm_mday, time_tm->tm_hour,
time_tm->tm_min, time_tm->tm_sec, (int)dis_millseconds);
return std::string(strTime);
}

View File

@ -0,0 +1,9 @@
#pragma once
#include <string>
#include <zlib/zlib.h>
int CompressString(const char* in_str, size_t in_len, std::string& out_str, int level);
int DecompressString(const char* in_str, size_t in_len, std::string& out_str);
std::string printHex(const void* data, size_t size);
std::string get_current_timestamp();

View File

@ -1,11 +1,10 @@
#include <string> #include <string>
#include <chrono>
#include <fcntl.h> #include <fcntl.h>
#ifndef _WIN32
#include <unistd.h> #include <unistd.h>
#endif
#include <fstream> #include <fstream>
#include <memory>
#include <iomanip> #include <iomanip>
#include <sstream>
#include <hv/hv.h> #include <hv/hv.h>
#include <hv/hmain.h> #include <hv/hmain.h>
@ -13,180 +12,28 @@
#include <hv/hloop.h> #include <hv/hloop.h>
#include <hv/hsocket.h> #include <hv/hsocket.h>
#include <hv/hssl.h> #include <hv/hssl.h>
#include <zlib/zlib.h>
#include "mqtt_msg.h" #include "kdefine.h"
#include "openjson.h"
#include "opmysql.h" #include "opmysql.h"
#include "eventhandler.h"
#include "iconv-utils.h" #ifndef TEST_UNPACK
#define TEST_UNPACK 1 #define TEST_UNPACK 1
#endif
#define K22_STR_EXP(__A) #__A
#define K22_STR(__A) K22_STR_EXP(__A)
#define K22_CMS_VERSION_MAJOR 1
#define K22_CMS_VERSION_MINOR 215
#define K22_CMS_VERSION_REVISION 0
#define K22_VERSION K22_STR(K22_CMS_VERSION_MAJOR) "." K22_STR(K22_CMS_VERSION_MINOR) "." K22_STR(K22_CMS_VERSION_REVISION) ""
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int CompressString(const char* in_str, size_t in_len, std::string& out_str, int level)
{
if (!in_str)
return Z_DATA_ERROR;
int ret, flush;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
std::shared_ptr<z_stream> sp_strm(&strm, [](z_stream* strm)
{
(void)deflateEnd(strm);
});
const char* end = in_str + in_len;
//size_t pos_index = 0;
size_t distance = 0;
/* compress until end of file */
do
{
distance = end - in_str;
strm.avail_in = (distance >= CHUNK) ? CHUNK : distance;
strm.next_in = (Bytef*)in_str;
// next pos
in_str += strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
if (ret == Z_STREAM_ERROR)
break;
have = CHUNK - strm.avail_out;
out_str.append((const char*)out, have);
} while (strm.avail_out == 0);
if (strm.avail_in != 0); /* all input will be used */
break;
/* done when last data in file processed */
} while (flush != Z_FINISH);
if (ret != Z_STREAM_END) /* stream will be complete */
return Z_STREAM_ERROR;
/* clean up and return */
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int DecompressString(const char* in_str, size_t in_len, std::string& out_str)
{
if (!in_str)
return Z_DATA_ERROR;
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
std::shared_ptr<z_stream> sp_strm(&strm, [](z_stream* strm)
{
(void)inflateEnd(strm);
});
const char* end = in_str + in_len;
//size_t pos_index = 0;
size_t distance = 0;
int flush = 0;
/* decompress until deflate stream ends or end of file */
do
{
distance = end - in_str;
strm.avail_in = (distance >= CHUNK) ? CHUNK : distance;
strm.next_in = (Bytef*)in_str;
// next pos
in_str += strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
/* run inflate() on input until output buffer not full */
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR) /* state not clobbered */
break;
switch (ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
return ret;
}
have = CHUNK - strm.avail_out;
out_str.append((const char*)out, have);
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (flush != Z_FINISH);
/* clean up and return */
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
//static OpDatabase gOpDatabase;
#if TEST_UNPACK #if TEST_UNPACK
static unpack_setting_t unpack_setting; static unpack_setting_t unpack_setting;
#endif #endif
//连接关闭回调
static void on_close(hio_t* io);
//接入回调
static void on_accept(hio_t* io);
//接收到数据
static void on_recv(hio_t* io, void* buf, int readbytes);
//重载参数回调
static void on_reload(void* userdata);
/* /*
* @build: make * @build: make
* @usage: datahubs -h * @usage: datahubs -h
@ -212,6 +59,7 @@ typedef struct conf_ctx_s
std::string dbuser; std::string dbuser;
std::string dbname; std::string dbname;
} conf_ctx_t; } conf_ctx_t;
conf_ctx_t g_conf_ctx; conf_ctx_t g_conf_ctx;
inline void conf_ctx_init(conf_ctx_t* ctx) inline void conf_ctx_init(conf_ctx_t* ctx)
@ -284,6 +132,7 @@ int parse_confile(const char* confile)
strncpy(g_main_ctx.logfile, str.c_str(), sizeof(g_main_ctx.logfile)); strncpy(g_main_ctx.logfile, str.c_str(), sizeof(g_main_ctx.logfile));
} }
hlog_set_file(g_main_ctx.logfile); hlog_set_file(g_main_ctx.logfile);
#if 1
// loglevel // loglevel
str = g_conf_ctx.parser->GetValue("loglevel"); str = g_conf_ctx.parser->GetValue("loglevel");
if (!str.empty()) if (!str.empty())
@ -308,14 +157,26 @@ int parse_confile(const char* confile)
{ {
logger_enable_fsync(hlog, hv_getboolean(str.c_str())); logger_enable_fsync(hlog, hv_getboolean(str.c_str()));
} }
// first log here #endif
// first log here // first log here
hlogi("=========--- Welcome to the Earth ---========="); hlogi("=========--- Welcome to the Earth ---=========");
hlogi("%s version: %s", g_main_ctx.program_name, K22_VERSION); hlogi("%s version: %s", g_main_ctx.program_name, K22_VERSION);
hlog_fsync(); hlog_fsync();
#if 0
g_conf_ctx.worker_processes = 1;
g_conf_ctx.worker_threads = 1;
g_conf_ctx.host = "0.0.0.0";
g_conf_ctx.port = 44242;
g_conf_ctx.dbname = "hjems";
g_conf_ctx.dbuser = "root";
g_conf_ctx.dbserver = "tcp://127.0.0.1:3306";
#endif
// worker_processes // worker_processes
int worker_processes = 0; int worker_processes = 0;
#if 1
#ifdef DEBUG #ifdef DEBUG
// Disable multi-processes mode for debugging // Disable multi-processes mode for debugging
worker_processes = 0; worker_processes = 0;
@ -351,6 +212,7 @@ int parse_confile(const char* confile)
worker_threads = atoi(str.c_str()); worker_threads = atoi(str.c_str());
} }
} }
g_conf_ctx.worker_threads = LIMIT(0, worker_threads, 64); g_conf_ctx.worker_threads = LIMIT(0, worker_threads, 64);
//host //host
@ -422,15 +284,10 @@ int parse_confile(const char* confile)
hlogi("dbserver = ('%s')", g_conf_ctx.dbserver.c_str()); hlogi("dbserver = ('%s')", g_conf_ctx.dbserver.c_str());
hlogi("parse_confile('%s') OK", confile); hlogi("parse_confile('%s') OK", confile);
#endif
return 0; return 0;
} }
static void on_reload(void* userdata)
{
hlogi("reload confile [%s]", g_main_ctx.confile);
parse_confile(g_main_ctx.confile);
}
//////1/////////////////////////////// //////1///////////////////////////////
#if 0 #if 0
#define LOCKFILE "/var/lock/datahub.lock" #define LOCKFILE "/var/lock/datahub.lock"
@ -537,6 +394,14 @@ int main(int argc, char** argv)
exit(0); exit(0);
} }
// signal
signal_init(on_reload);
const char* signal = get_arg("s");
if( signal )
{
signal_handle(signal);
}
// g_conf_ctx // g_conf_ctx
conf_ctx_init(&g_conf_ctx); conf_ctx_init(&g_conf_ctx);
const char* confile = get_arg("c"); const char* confile = get_arg("c");
@ -553,13 +418,6 @@ int main(int argc, char** argv)
exit(0); exit(0);
} }
// signal
signal_init(on_reload);
const char* signal = get_arg("s");
if (signal)
{
signal_handle(signal);
}
#ifdef OS_UNIX #ifdef OS_UNIX
// daemon // daemon
@ -596,294 +454,55 @@ int main(int argc, char** argv)
return 0; return 0;
} }
void worker_fn(void* userdata)
{
conf_ctx_t* ptrCtx = (conf_ctx_t*)(intptr_t)(userdata);
long port = ptrCtx->port;
//initialize database connection
bool dbok = OpDatabase::getInstance()->OpenDatabase(ptrCtx->dbserver,ptrCtx->dbuser,ptrCtx->dbname);
if (!dbok)
{
hloge("failed to open database, exit now...");
return;
}
hlogi("database connection created!");
hloop_t* loop = hloop_new(0);
const char* host = ptrCtx->host.c_str();
hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept);
if (listenio == NULL)
{
hloge("worker process finished");
return;
}
hlogi("port=%ld pid=%ld tid=%ld listenfd=%d", port, hv_getpid(), hv_gettid(), hio_fd(listenio));
hloop_run(loop);
hlogi("database connection close!");
OpDatabase::getInstance()->CloseDatabase();
hloop_free(&loop);
}
/// 各回调函数定义
static void on_reload(void* userdata)
{
hlogi("reload confile [%s]", g_main_ctx.confile);
parse_confile(g_main_ctx.confile);
}
static void on_close(hio_t* io) static void on_close(hio_t* io)
{ {
hlogi("on_close fd=%d error=%d", hio_fd(io), hio_error(io)); hlogi("on_close fd=%d error=%d", hio_fd(io), hio_error(io));
} }
std::string get_current_timestamp()
{
auto now = std::chrono::system_clock::now();
//通过不同精度获取相差的毫秒数
uint64_t dis_millseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count()
- std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count() * 1000;
time_t tt = std::chrono::system_clock::to_time_t(now);
auto time_tm = localtime(&tt);
char strTime[25] = { 0 };
sprintf(strTime, "%d-%02d-%02d %02d:%02d:%02d.%03d", time_tm->tm_year + 1900,
time_tm->tm_mon + 1, time_tm->tm_mday, time_tm->tm_hour,
time_tm->tm_min, time_tm->tm_sec, (int)dis_millseconds);
return std::string(strTime);
}
// 函数用于将内存块转换为十六进制字符串
std::string printHex(const void* data, size_t size)
{
std::ostringstream oss;
std::ostringstream oss2;
std::ostringstream ossrow;
const size_t lineSize = 16; // 每行输出的字节数
const unsigned char* p = static_cast<const unsigned char*>(data);
int ic = 0;
int row = 0;
ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : ";
oss << ossrow.str().c_str();
for (size_t i = 0; i < size; ++i)
{
ic++;
// 每个字节之间用空格分隔
oss << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << static_cast<int>(p[i]);
char ch = (isprint(p[i]) != 0) ? p[i] : '.';
oss2 << ch;
// 每lineSize个字节换行
if ((i + 1) % lineSize == 0)
{
ossrow.clear();
ossrow.str("");
oss << " [" << oss2.str().c_str() << "]" << std::endl;
oss2.clear();
oss2.str("");
ossrow << std::setw(8) << std::setfill('0') << std::hex << row++ << "h : ";
oss << ossrow.str().c_str();
ic = 0;
}
else if (i == size - 1)
{
if ((i + 1) % lineSize != 0)
{
if (i % 2 != 0)
{
for (size_t j = 0; j < (lineSize - ic); j++)
{
oss << " --";
}
}
else
{
for (size_t j = 0; j < (lineSize - ic); j++)
{
oss << " --";
}
}
}
oss << " [" << oss2.str().c_str();
if ((i + 1) % lineSize != 0)
{
for (size_t j = 0; j < (lineSize - ic); j++)
{
oss << " ";
}
}
oss << "]" << std::endl;
oss2.clear();
oss2.str("");
ic = 0;
}
#if 0
else if ((i + 1) % 8 == 0)
{
oss << " ";
oss2 << " ";
}
#endif
else
{
oss << " ";
}
}
return oss.str();
}
//接收到数据
static void on_recv(hio_t* io, void* buf, int readbytes)
{
char localaddrstr[SOCKADDR_STRLEN] = { 0 };
char peeraddrstr[SOCKADDR_STRLEN] = { 0 };
hlogi("### 1 ### on_recv fd=%d readbytes=%d [%s] <==== [%s]", hio_fd(io), readbytes,
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
char ret[1] = { 0 };
if (readbytes > 0xFFFF - 1)
{
hloge("too large data buffer to process: %d", readbytes);
ret[0] = 1;
hio_write(io, (void*)ret, 1);
return;
}
MessageData* pData = (MessageData*)buf;
OpenJson json;
if (pData->content_len > 0xFFFF - 1)
{
hloge("too big string buffer to process: %d, it should be less than %d", pData->content_len, 0xFFFF);
ret[0] = 1;
hio_write(io, (void*)ret, 1);
return;
}
CODING buf_code = GetCoding((unsigned char*)pData->content_data, pData->content_len); //判断是否是utf-8
hlogi("<=== recieve buffer code is [%d]", buf_code);
std::string msg(pData->content_data, pData->content_len);
if (buf_code == CODING::GBK
|| buf_code == CODING::UNKOWN)
{
std::string str_result;
//转换为UTF8
if (!GBKToUTF8(msg, str_result))
{
hloge("Failed to transfer code from GBK to UTF-8");
ret[0] = 1;
hio_write(io, (void*)ret, 1);
return;
}
hlogi("Successfuly transfer code from GBK to UTF-8!");
msg = str_result;
}
#ifdef _DEBUG
hlogd("<=== recieve !!VALID!! mqtt pack len =[%d] data=[%s]", msg.length(), msg.c_str()); //这里还是好的
#endif
unsigned int len = msg.length();
char* pTmp = new char[len];
memcpy(pTmp, msg.c_str(), len);
std::shared_ptr<char> ptr; //放个智能指针省得忘记删除
ptr.reset(pTmp);
//hlogi("<=== decode OK, msg=[%s]", msg.c_str());
#if 0
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 17).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 18).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 19).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 20).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 21).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 22).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 23).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 24).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 25).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 26).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 27).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 28).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 29).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 30).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 31).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 32).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 33).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 34).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 61).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 62).c_str());
hlogi("<=== decode OK [\n%s\n]", printHex(pTmp, 63).c_str());
#endif
//hlogd("<=== decode OK [\n%s\n]", printHex(pTmp, len).c_str());
if (!json.decode(msg))
{
//delete[] pTmp;
hloge("Failed to decode json string pack , length=%d", readbytes);
ret[0] = 1;
hio_write(io, (void*)ret, 1);
return;
}
hio_write(io, (void*)ret, 1);
std::string fsucode = json["FsuCode"].s();
std::string msg_type = json["type"].s();
std::string timestamp = get_current_timestamp(); // json["TimeStamp"].s();
if (fsucode.length() == 0)
{
//delete[] pTmp;
hlogw("!!empty fsucode recieved!");
return;
}
hlogi("<=== decode OK, recieve fsucode=[%s] type=[%s] ts=[%s]", fsucode.c_str(), msg_type.c_str(), timestamp.c_str());
#ifdef _DEBUG
hlogd("<<<<Check Mem after decode here>>>> \n[\n%s\n]\n", printHex(pTmp, len).c_str());
#endif
std::string out_compress;
int zip_ret = 0;
if ((zip_ret = CompressString(pTmp, len, out_compress, Z_DEFAULT_COMPRESSION)) != Z_OK)
{
hloge("Failed to compress source data, zip return value %d", zip_ret);
return;
}
hlogd("<<<<Compress result: string size from original [%d] to [%d]", len, out_compress.size());
#ifdef _DEBUG
hlogd("<<<<Compress string here>>>> \n[\n%s\n]\n", printHex(out_compress.c_str(), out_compress.size()).c_str());
#endif
//std::string msg2(pTmp, len);
if (msg_type == "gateway-data"
|| msg_type == "gateway-alarmdata"
|| msg_type == "gateway-writedata"
|| msg_type == "gateway-readdata"
|| msg_type == "web-write"
|| msg_type == "web-alarm")
{
auto& IdCodeContent = json["IdCodeContent"];
if (IdCodeContent.size() <= 0)
{
//delete[] pTmp;
hloge("invalid IdCodeContent's size: %d", IdCodeContent.size());
return;
}
auto& pNode = IdCodeContent[0]; //这是只解析第一个节点
std::string oid = pNode["OID"].s();
OpDatabase::getInstance()->InsertMessage(timestamp, msg_type, fsucode, out_compress, (int)pData->mqtt_topic, (int)pData->device_id);
}
if (msg_type == "web-read")
{
auto& IdCodeContent = json["IdCodes"];
if (IdCodeContent.size() <= 0)
{
hloge("invalid IdCodes's size: %d", IdCodeContent.size());
//delete[] pTmp;
return;
}
auto& pNode = IdCodeContent[0]; //这是只解析第一个节点
std::string oid = pNode.s();
OpDatabase::getInstance()->InsertMessage(timestamp, msg_type, fsucode, out_compress, (int)pData->mqtt_topic, (int)pData->device_id);
}
//delete[] pTmp;
}
//接入回调 //接入回调
static void on_accept(hio_t* io) static void on_accept(hio_t* io)
{ {
@ -905,37 +524,9 @@ static void on_accept(hio_t* io)
hio_read_start(io); hio_read_start(io);
} }
void worker_fn(void* userdata) //接收到数据
static void on_recv(hio_t* io, void* buf, int readbytes)
{ {
conf_ctx_t* ptrCtx = (conf_ctx_t*)(intptr_t)(userdata); EventHandler::onRecvHandler(io, buf, readbytes);
long port = ptrCtx->port;
//initialize database connection
bool dbok = OpDatabase::getInstance()->OpenDatabase(ptrCtx->dbserver,ptrCtx->dbuser,ptrCtx->dbname);
if (!dbok)
{
hloge("failed to open database, exit now...");
return;
}
hlogi("database connection created!");
hloop_t* loop = hloop_new(0);
const char* host = ptrCtx->host.c_str();
hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept);
if (listenio == NULL)
{
hlogw("worker process finished");
return;
}
hlogi("port=%ld pid=%ld tid=%ld listenfd=%d", port, hv_getpid(), hv_gettid(), hio_fd(listenio));
hloop_run(loop);
hlogi("database connection close!");
OpDatabase::getInstance()->CloseDatabase();
hloop_free(&loop);
} }

View File

@ -1,10 +1,17 @@
#pragma once #pragma once
#include "kdefine.h"
#pragma pack(1) #pragma pack(1)
__NAMESPACE_BEGIN__(HJ)
#define MSG_HEADER_LENGTH (8)
typedef enum tagTopic : char typedef enum tagTopic : char
{ {
GateWayPublicTopic_Server = 0, GateWayPublicTopic_Server = 0,
ServerPublicTopic_GateWay = 1, ServerPublicTopic_GateWay = 1,
}MQTT_Topic; } MQTT_Topic;
typedef enum tagDataType : char typedef enum tagDataType : char
{ {
@ -15,7 +22,9 @@ typedef enum tagDataType : char
DT_GATEWAY_CTRLDATA = 4, DT_GATEWAY_CTRLDATA = 4,
DT_WEB_CTRL = 5, DT_WEB_CTRL = 5,
DT_WEB_WRITE = 6, DT_WEB_WRITE = 6,
DT_GATEWAY_WRITE = 7 DT_GATEWAY_WRITE = 7,
FRAME_REQUEST = 8,
FRAME_RESPONSE = 9,
}MQTT_DataType; }MQTT_DataType;
/* /*
@ -47,4 +56,6 @@ typedef struct tagMsgData
char content_data[1]; //MQTT包字符串的内容 char content_data[1]; //MQTT包字符串的内容
}MessageData; }MessageData;
__NAMESPACE_END__(HJ)
#pragma pack() #pragma pack()

View File

@ -20,10 +20,13 @@
#include <stdarg.h> #include <stdarg.h>
#include <string> #include <string>
#include <hv/hlog.h>
#include "openjson.h" #include "openjson.h"
//#define PRINTF printf
#define PRINTF hloge
#define PRINTF printf
#if (defined(_MSC_VER) && (_MSC_VER >= 1400 )) #if (defined(_MSC_VER) && (_MSC_VER >= 1400 ))
inline int SNPRINTF(char* buffer, size_t size, const char* format, ...) inline int SNPRINTF(char* buffer, size_t size, const char* format, ...)
{ {
@ -188,10 +191,10 @@ bool OpenJson::Box::remove(OpenJson* node)
//JsonContext //JsonContext
OpenJson::Context::Context() OpenJson::Context::Context()
: :
offset_(0),
data_(0), data_(0),
root_(0), size_(0),
size_(0) offset_(0),
root_(0)
{ {
} }
@ -278,10 +281,10 @@ OpenJson::OpenJson(JsonType type)
:type_(type), :type_(type),
context_(0), context_(0),
wcontext_(0), wcontext_(0),
box_(0),
idx_(0), idx_(0),
key_(0),
len_(0), len_(0),
box_(0),
key_(0),
segment_(0) segment_(0)
{ {
} }
@ -783,12 +786,16 @@ OpenJson& OpenJson::object(const char* key)
{ {
if (type_ == ARRAY) if (type_ == ARRAY)
{ {
Log("JsonNode must be OBJECT, not ARRAY"); PRINTF("JsonNode must be OBJECT, not ARRAY");
} }
type_ = OBJECT; type_ = OBJECT;
} }
else else
{ {
if( !box_ )
{
PRINTF("JsonNode must be OBJECT, not NOTHING! key:[%s]", key);
}
assert(box_); assert(box_);
} }
if (!box_) box_ = new Box; if (!box_) box_ = new Box;
@ -828,7 +835,7 @@ void OpenJson::addNode(OpenJson* node)
if (!node) return; if (!node) return;
if (type_ != OBJECT && type_ != ARRAY) if (type_ != OBJECT && type_ != ARRAY)
{ {
Log("JsonNode must be OBJECT or ARRAY"); PRINTF("JsonNode must be OBJECT or ARRAY");
type_ = node->key_ ? OBJECT : ARRAY; type_ = node->key_ ? OBJECT : ARRAY;
} }
if (box_ == 0) box_ = new Box; if (box_ == 0) box_ = new Box;

View File

@ -34,7 +34,8 @@ bool OpDatabase::OpenDatabase(const std::string& server, const std::string& dbus
// 数据库连接配置 // 数据库连接配置
//std::string server = "tcp://127.0.0.1:3306"; //std::string server = "tcp://127.0.0.1:3306";
//std::string dbuser = "root"; //std::string dbuser = "root";
std::string password = "Hj57471000"; //std::string password = "Hj57471000";
std::string password = "L2ysc1s1kr";
//std::string database = "hjems"; //std::string database = "hjems";
// 创建连接 // 创建连接

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_BUILD_CONFIG_H_ #ifndef _SQL_BUILD_CONFIG_H_
#define _SQL_BUILD_CONFIG_H_ #define _SQL_BUILD_CONFIG_H_

View File

@ -1,13 +1,32 @@
/* /*
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
*
The MySQL Connector/C++ is licensed under the terms of the GPL * This program is free software; you can redistribute it and/or modify
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most * it under the terms of the GNU General Public License, version 2.0, as
MySQL Connectors. There are special exceptions to the terms and * published by the Free Software Foundation.
conditions of the GPL as it is applied to this software, see the *
FLOSS License Exception * This program is also distributed with certain software (including
<http://www.mysql.com/about/legal/licensing/foss-exception.html>. * but not limited to OpenSSL) that is licensed under separate terms,
*/ * as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// libmysql defines HAVE_STRTOUL (on win), so we have to follow different pattern in definitions names // libmysql defines HAVE_STRTOUL (on win), so we have to follow different pattern in definitions names
// to avoid annoying warnings. // to avoid annoying warnings.
@ -35,27 +54,34 @@
#define HAVE_UINT32_T 1 #define HAVE_UINT32_T 1
#define HAVE_INT64_T 1 #define HAVE_INT64_T 1
#define HAVE_UINT64_T 1 #define HAVE_UINT64_T 1
/* #undef HAVE_MS_INT8 */ #define HAVE_MS_INT8 1
/* #undef HAVE_MS_UINT8 */ #define HAVE_MS_UINT8 1
/* #undef HAVE_MS_INT16 */ #define HAVE_MS_INT16 1
/* #undef HAVE_MS_UINT16 */ #define HAVE_MS_UINT16 1
/* #undef HAVE_MS_INT32 */ #define HAVE_MS_INT32 1
/* #undef HAVE_MS_UINT32 */ #define HAVE_MS_UINT32 1
/* #undef HAVE_MS_INT64 */ #define HAVE_MS_INT64 1
/* #undef HAVE_MS_UINT64 */ #define HAVE_MS_UINT64 1
#ifdef HAVE_STDINT_H #ifdef HAVE_STDINT_H
#include <stdint.h> #include <stdint.h>
#endif #endif
#ifdef HAVE_INTTYPES_H
#if defined(HAVE_INTTYPES_H) && !defined(_WIN32)
#include <inttypes.h> #include <inttypes.h>
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
#ifndef CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES #ifndef CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES
#if _MSC_VER >= 1600
#include <stdint.h>
#else
#if !defined(HAVE_INT8_T) && defined(HAVE_MS_INT8) #if !defined(HAVE_INT8_T) && defined(HAVE_MS_INT8)
typedef __int8 int8_t; typedef __int8 int8_t;
#endif #endif
@ -86,5 +112,6 @@ typedef __int64 int64_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
#endif #endif
#endif // _MSC_VER >= 1600
#endif // CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES #endif // CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES
#endif // _WIN32 #endif // _WIN32

View File

@ -1,42 +1,49 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_CONNECTION_H_ #ifndef _SQL_CONNECTION_H_
#define _SQL_CONNECTION_H_ #define _SQL_CONNECTION_H_
#include <map> #include <map>
#include <boost/variant.hpp>
#include "build_config.h" #include "build_config.h"
#include "warning.h" #include "warning.h"
#include "sqlstring.h" #include "sqlstring.h"
#include "variant.h"
namespace sql namespace sql
{ {
typedef sql::Variant ConnectPropertyVal;
typedef boost::variant<int, double, bool, sql::SQLString > ConnectPropertyVal;
typedef std::map< sql::SQLString, ConnectPropertyVal > ConnectOptionsMap; typedef std::map< sql::SQLString, ConnectPropertyVal > ConnectOptionsMap;
@ -47,107 +54,121 @@ class Driver;
typedef enum transaction_isolation typedef enum transaction_isolation
{ {
TRANSACTION_NONE= 0, TRANSACTION_NONE= 0,
TRANSACTION_READ_COMMITTED, TRANSACTION_READ_COMMITTED,
TRANSACTION_READ_UNCOMMITTED, TRANSACTION_READ_UNCOMMITTED,
TRANSACTION_REPEATABLE_READ, TRANSACTION_REPEATABLE_READ,
TRANSACTION_SERIALIZABLE TRANSACTION_SERIALIZABLE
} enum_transaction_isolation; } enum_transaction_isolation;
enum ssl_mode
{
SSL_MODE_DISABLED= 1, SSL_MODE_PREFERRED, SSL_MODE_REQUIRED,
SSL_MODE_VERIFY_CA, SSL_MODE_VERIFY_IDENTITY
};
class Savepoint class Savepoint
{ {
/* Prevent use of these */ /* Prevent use of these */
Savepoint(const Savepoint &); Savepoint(const Savepoint &);
void operator=(Savepoint &); void operator=(Savepoint &);
public: public:
Savepoint() {}; Savepoint() {};
virtual ~Savepoint() {}; virtual ~Savepoint() {};
virtual int getSavepointId() = 0; virtual int getSavepointId() = 0;
virtual sql::SQLString getSavepointName() = 0; virtual sql::SQLString getSavepointName() = 0;
}; };
class CPPCONN_PUBLIC_FUNC Connection class CPPCONN_PUBLIC_FUNC Connection
{ {
/* Prevent use of these */ /* Prevent use of these */
Connection(const Connection &); Connection(const Connection &);
void operator=(Connection &); void operator=(Connection &);
public: public:
Connection() {}; Connection() {};
virtual ~Connection() {}; virtual ~Connection() {};
virtual void clearWarnings() = 0; virtual void clearWarnings() = 0;
virtual Statement *createStatement() = 0; virtual Statement *createStatement() = 0;
virtual void close() = 0; virtual void close() = 0;
virtual void commit() = 0; virtual void commit() = 0;
virtual bool getAutoCommit() = 0; virtual bool getAutoCommit() = 0;
virtual sql::SQLString getCatalog() = 0; virtual sql::SQLString getCatalog() = 0;
virtual Driver *getDriver() = 0; virtual Driver *getDriver() = 0;
virtual sql::SQLString getSchema() = 0; virtual sql::SQLString getSchema() = 0;
virtual sql::SQLString getClientInfo() = 0; virtual sql::SQLString getClientInfo() = 0;
virtual void getClientOption(const sql::SQLString & optionName, void * optionValue) = 0; virtual void getClientOption(const sql::SQLString & optionName, void * optionValue) = 0;
virtual DatabaseMetaData * getMetaData() = 0; virtual sql::SQLString getClientOption(const sql::SQLString & optionName) = 0;
virtual enum_transaction_isolation getTransactionIsolation() = 0; virtual DatabaseMetaData * getMetaData() = 0;
virtual const SQLWarning * getWarnings() = 0; virtual enum_transaction_isolation getTransactionIsolation() = 0;
virtual bool isClosed() = 0; virtual const SQLWarning * getWarnings() = 0;
virtual bool isReadOnly() = 0; virtual bool isClosed() = 0;
virtual sql::SQLString nativeSQL(const sql::SQLString& sql) = 0; virtual bool isReadOnly() = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql) = 0; virtual bool isValid() = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys) = 0; virtual bool reconnect() = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int* columnIndexes) = 0; virtual sql::SQLString nativeSQL(const sql::SQLString& sql) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int* columnIndexes) = 0;
virtual void releaseSavepoint(Savepoint * savepoint) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency) = 0;
virtual void rollback() = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) = 0;
virtual void rollback(Savepoint * savepoint) = 0; virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]) = 0;
virtual void setAutoCommit(bool autoCommit) = 0; virtual void releaseSavepoint(Savepoint * savepoint) = 0;
virtual void setCatalog(const sql::SQLString& catalog) = 0; virtual void rollback() = 0;
virtual void setSchema(const sql::SQLString& catalog) = 0; virtual void rollback(Savepoint * savepoint) = 0;
virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue) = 0; virtual void setAutoCommit(bool autoCommit) = 0;
virtual void setHoldability(int holdability) = 0; virtual void setCatalog(const sql::SQLString& catalog) = 0;
virtual void setReadOnly(bool readOnly) = 0; virtual void setSchema(const sql::SQLString& catalog) = 0;
virtual Savepoint * setSavepoint() = 0; virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue) = 0;
virtual Savepoint * setSavepoint(const sql::SQLString& name) = 0; virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue) = 0;
virtual void setTransactionIsolation(enum_transaction_isolation level) = 0; virtual void setHoldability(int holdability) = 0;
/* virtual void setTypeMap(Map map) = 0; */ virtual void setReadOnly(bool readOnly) = 0;
virtual Savepoint * setSavepoint() = 0;
virtual Savepoint * setSavepoint(const sql::SQLString& name) = 0;
virtual void setTransactionIsolation(enum_transaction_isolation level) = 0;
/* virtual void setTypeMap(Map map) = 0; */
}; };
} /* namespace sql */ } /* namespace sql */

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_DATATYPE_H_ #ifndef _SQL_DATATYPE_H_
#define _SQL_DATATYPE_H_ #define _SQL_DATATYPE_H_
@ -30,35 +38,36 @@ namespace sql
class DataType class DataType
{ {
DataType(); DataType();
public: public:
enum { enum {
UNKNOWN = 0, UNKNOWN = 0,
BIT, BIT,
TINYINT, TINYINT,
SMALLINT, SMALLINT,
MEDIUMINT, MEDIUMINT,
INTEGER, INTEGER,
BIGINT, BIGINT,
REAL, REAL,
DOUBLE, DOUBLE,
DECIMAL, DECIMAL,
NUMERIC, NUMERIC,
CHAR, CHAR,
BINARY, BINARY,
VARCHAR, VARCHAR,
VARBINARY, VARBINARY,
LONGVARCHAR, LONGVARCHAR,
LONGVARBINARY, LONGVARBINARY,
TIMESTAMP, TIMESTAMP,
DATE, DATE,
TIME, TIME,
YEAR, YEAR,
GEOMETRY, GEOMETRY,
ENUM, ENUM,
SET, SET,
SQLNULL SQLNULL,
}; JSON
};
}; };
} /* namespace */ } /* namespace */

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_DRIVER_H_ #ifndef _SQL_DRIVER_H_
#define _SQL_DRIVER_H_ #define _SQL_DRIVER_H_
@ -34,35 +42,35 @@ namespace sql
class CPPCONN_PUBLIC_FUNC Driver class CPPCONN_PUBLIC_FUNC Driver
{ {
protected: protected:
virtual ~Driver() {} virtual ~Driver() {}
public: public:
// Attempts to make a database connection to the given URL. // Attempts to make a database connection to the given URL.
virtual Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) = 0; virtual Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) = 0;
virtual Connection * connect(ConnectOptionsMap & options) = 0; virtual Connection * connect(ConnectOptionsMap & options) = 0;
virtual int getMajorVersion() = 0; virtual int getMajorVersion() = 0;
virtual int getMinorVersion() = 0; virtual int getMinorVersion() = 0;
virtual int getPatchVersion() = 0; virtual int getPatchVersion() = 0;
virtual const sql::SQLString & getName() = 0; virtual const sql::SQLString & getName() = 0;
virtual void threadInit() = 0; virtual void threadInit() = 0;
virtual void threadEnd() = 0; virtual void threadEnd() = 0;
}; };
} /* namespace sql */ } /* namespace sql */
extern "C" extern "C"
{ {
CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance(); CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance();
/* If dynamic loading is disabled in a driver then this function works just like get_driver_instance() */ /* If dynamic loading is disabled in a driver then this function works just like get_driver_instance() */
CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance_by_name(const char * const clientlib); CPPCONN_PUBLIC_FUNC sql::Driver * get_driver_instance_by_name(const char * const clientlib);
} }
#endif /* _SQL_DRIVER_H_ */ #endif /* _SQL_DRIVER_H_ */

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_EXCEPTION_H_ #ifndef _SQL_EXCEPTION_H_
#define _SQL_EXCEPTION_H_ #define _SQL_EXCEPTION_H_
@ -33,15 +41,26 @@
namespace sql namespace sql
{ {
#if (__cplusplus < 201103L)
#define MEMORY_ALLOC_OPERATORS(Class) \ #define MEMORY_ALLOC_OPERATORS(Class) \
void* operator new(size_t size) throw (std::bad_alloc) { return ::operator new(size); } \ void* operator new(size_t size) throw (std::bad_alloc) { return ::operator new(size); } \
void* operator new(size_t, void*) throw(); \ void* operator new(size_t, void*) throw(); \
void* operator new(size_t, const std::nothrow_t&) throw(); \ void* operator new(size_t, const std::nothrow_t&) throw(); \
void* operator new[](size_t) throw (std::bad_alloc); \ void* operator new[](size_t) throw (std::bad_alloc); \
void* operator new[](size_t, void*) throw(); \ void* operator new[](size_t, void*) throw(); \
void* operator new[](size_t, const std::nothrow_t&) throw(); \ void* operator new[](size_t, const std::nothrow_t&) throw(); \
void* operator new(size_t N, std::allocator<Class>&); void* operator new(size_t N, std::allocator<Class>&);
#else
#define MEMORY_ALLOC_OPERATORS(Class) \
void* operator new(size_t size){ return ::operator new(size); } \
void* operator new(size_t, void*) noexcept; \
void* operator new(size_t, const std::nothrow_t&) noexcept; \
void* operator new[](size_t); \
void* operator new[](size_t, void*) noexcept; \
void* operator new[](size_t, const std::nothrow_t&) noexcept; \
void* operator new(size_t N, std::allocator<Class>&);
#endif
#ifdef _WIN32 #ifdef _WIN32
#pragma warning (disable : 4290) #pragma warning (disable : 4290)
//warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow) //warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
@ -56,71 +75,94 @@ class CPPCONN_PUBLIC_FUNC SQLException : public std::runtime_error
#pragma warning(pop) #pragma warning(pop)
#endif #endif
protected: protected:
const std::string sql_state; const std::string sql_state;
const int errNo; const int errNo;
public: public:
SQLException(const SQLException& e) : std::runtime_error(e.what()), sql_state(e.sql_state), errNo(e.errNo) {} SQLException(const SQLException& e) : std::runtime_error(e.what()), sql_state(e.sql_state), errNo(e.errNo) {}
SQLException(const std::string& reason, const std::string& SQLState, int vendorCode) : SQLException(const std::string& reason, const std::string& SQLState, int vendorCode) :
std::runtime_error (reason ), std::runtime_error (reason ),
sql_state (SQLState ), sql_state (SQLState ),
errNo (vendorCode) errNo (vendorCode)
{} {}
SQLException(const std::string& reason, const std::string& SQLState) : std::runtime_error(reason), sql_state(SQLState), errNo(0) {} SQLException(const std::string& reason, const std::string& SQLState) : std::runtime_error(reason), sql_state(SQLState), errNo(0) {}
SQLException(const std::string& reason) : std::runtime_error(reason), sql_state("HY000"), errNo(0) {} SQLException(const std::string& reason) : std::runtime_error(reason), sql_state("HY000"), errNo(0) {}
SQLException() : std::runtime_error(""), sql_state("HY000"), errNo(0) {} SQLException() : std::runtime_error(""), sql_state("HY000"), errNo(0) {}
const std::string & getSQLState() const const std::string & getSQLState() const
{ {
return sql_state; return sql_state;
} }
const char * getSQLStateCStr() const const char * getSQLStateCStr() const
{ {
return sql_state.c_str(); return sql_state.c_str();
} }
int getErrorCode() const int getErrorCode() const
{ {
return errNo; return errNo;
} }
virtual ~SQLException() throw () {}; virtual ~SQLException() throw () {};
protected: protected:
MEMORY_ALLOC_OPERATORS(SQLException) MEMORY_ALLOC_OPERATORS(SQLException)
}; };
struct CPPCONN_PUBLIC_FUNC MethodNotImplementedException : public SQLException struct CPPCONN_PUBLIC_FUNC MethodNotImplementedException : public SQLException
{ {
MethodNotImplementedException(const MethodNotImplementedException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } MethodNotImplementedException(const MethodNotImplementedException& e) : SQLException(e.what(), e.sql_state, e.errNo) { }
MethodNotImplementedException(const std::string& reason) : SQLException(reason, "", 0) {} MethodNotImplementedException(const std::string& reason) : SQLException(reason, "", 0) {}
}; };
struct CPPCONN_PUBLIC_FUNC InvalidArgumentException : public SQLException struct CPPCONN_PUBLIC_FUNC InvalidArgumentException : public SQLException
{ {
InvalidArgumentException(const InvalidArgumentException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } InvalidArgumentException(const InvalidArgumentException& e) : SQLException(e.what(), e.sql_state, e.errNo) { }
InvalidArgumentException(const std::string& reason) : SQLException(reason, "", 0) {} InvalidArgumentException(const std::string& reason) : SQLException(reason, "", 0) {}
}; };
struct CPPCONN_PUBLIC_FUNC InvalidInstanceException : public SQLException struct CPPCONN_PUBLIC_FUNC InvalidInstanceException : public SQLException
{ {
InvalidInstanceException(const InvalidInstanceException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } InvalidInstanceException(const InvalidInstanceException& e) : SQLException(e.what(), e.sql_state, e.errNo) { }
InvalidInstanceException(const std::string& reason) : SQLException(reason, "", 0) {} InvalidInstanceException(const std::string& reason) : SQLException(reason, "", 0) {}
}; };
struct CPPCONN_PUBLIC_FUNC NonScrollableException : public SQLException struct CPPCONN_PUBLIC_FUNC NonScrollableException : public SQLException
{ {
NonScrollableException(const NonScrollableException& e) : SQLException(e.what(), e.sql_state, e.errNo) { } NonScrollableException(const NonScrollableException& e) : SQLException(e.what(), e.sql_state, e.errNo) { }
NonScrollableException(const std::string& reason) : SQLException(reason, "", 0) {} NonScrollableException(const std::string& reason) : SQLException(reason, "", 0) {}
}; };
struct CPPCONN_PUBLIC_FUNC SQLUnsupportedOptionException : public SQLException
{
SQLUnsupportedOptionException(const SQLUnsupportedOptionException& e, const std::string conn_option) :
SQLException(e.what(), e.sql_state, e.errNo),
option(conn_option )
{}
SQLUnsupportedOptionException(const std::string& reason, const std::string conn_option) :
SQLException(reason, "", 0),
option(conn_option )
{}
const char *getConnectionOption() const
{
return option.c_str();
}
~SQLUnsupportedOptionException() throw () {};
protected:
const std::string option;
};
} /* namespace sql */ } /* namespace sql */
#endif /* _SQL_EXCEPTION_H_ */ #endif /* _SQL_EXCEPTION_H_ */

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_METADATA_H_ #ifndef _SQL_METADATA_H_
#define _SQL_METADATA_H_ #define _SQL_METADATA_H_
@ -37,438 +45,446 @@ class ResultSet;
class DatabaseMetaData class DatabaseMetaData
{ {
protected: protected:
virtual ~DatabaseMetaData() {} virtual ~DatabaseMetaData() {}
public: public:
enum enum
{ {
attributeNoNulls = 0, attributeNoNulls = 0,
attributeNullable, attributeNullable,
attributeNullableUnknown attributeNullableUnknown
}; };
enum enum
{ {
bestRowTemporary = 0, bestRowTemporary = 0,
bestRowTransaction, bestRowTransaction,
bestRowSession bestRowSession
}; };
enum enum
{ {
bestRowUnknown = 0, bestRowUnknown = 0,
bestRowNotPseudo, bestRowNotPseudo,
bestRowPseudo bestRowPseudo
}; };
enum enum
{ {
columnNoNulls = 0, columnNoNulls = 0,
columnNullable, columnNullable,
columnNullableUnknown columnNullableUnknown
}; };
enum enum
{ {
importedKeyCascade = 0, importedKeyCascade = 0,
importedKeyInitiallyDeferred, importedKeyInitiallyDeferred,
importedKeyInitiallyImmediate, importedKeyInitiallyImmediate,
importedKeyNoAction, importedKeyNoAction,
importedKeyNotDeferrable, importedKeyNotDeferrable,
importedKeyRestrict, importedKeyRestrict,
importedKeySetDefault, importedKeySetDefault,
importedKeySetNull importedKeySetNull
}; };
enum enum
{ {
procedureColumnIn = 0, procedureColumnIn = 0,
procedureColumnInOut, procedureColumnInOut,
procedureColumnOut, procedureColumnOut,
procedureColumnResult, procedureColumnResult,
procedureColumnReturn, procedureColumnReturn,
procedureColumnUnknown, procedureColumnUnknown,
procedureNoNulls, procedureNoNulls,
procedureNoResult, procedureNoResult,
procedureNullable, procedureNullable,
procedureNullableUnknown, procedureNullableUnknown,
procedureResultUnknown, procedureResultUnknown,
procedureReturnsResult procedureReturnsResult
}; };
enum enum
{ {
sqlStateSQL99 = 0, sqlStateSQL99 = 0,
sqlStateXOpen sqlStateXOpen
}; };
enum enum
{ {
tableIndexClustered = 0, tableIndexClustered = 0,
tableIndexHashed, tableIndexHashed,
tableIndexOther, tableIndexOther,
tableIndexStatistic tableIndexStatistic
}; };
enum enum
{ {
versionColumnUnknown = 0, versionColumnUnknown = 0,
versionColumnNotPseudo = 1, versionColumnNotPseudo = 1,
versionColumnPseudo = 2 versionColumnPseudo = 2
}; };
enum enum
{ {
typeNoNulls = 0, typeNoNulls = 0,
typeNullable = 1, typeNullable = 1,
typeNullableUnknown = 2 typeNullableUnknown = 2
}; };
enum enum
{ {
typePredNone = 0, typePredNone = 0,
typePredChar = 1, typePredChar = 1,
typePredBasic= 2, typePredBasic= 2,
typeSearchable = 3 typeSearchable = 3
}; };
virtual bool allProceduresAreCallable() = 0; virtual bool allProceduresAreCallable() = 0;
virtual bool allTablesAreSelectable() = 0; virtual bool allTablesAreSelectable() = 0;
virtual bool dataDefinitionCausesTransactionCommit() = 0; virtual bool dataDefinitionCausesTransactionCommit() = 0;
virtual bool dataDefinitionIgnoredInTransactions() = 0; virtual bool dataDefinitionIgnoredInTransactions() = 0;
virtual bool deletesAreDetected(int type) = 0; virtual bool deletesAreDetected(int type) = 0;
virtual bool doesMaxRowSizeIncludeBlobs() = 0; virtual bool doesMaxRowSizeIncludeBlobs() = 0;
virtual ResultSet * getAttributes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, const sql::SQLString& attributeNamePattern) = 0; virtual ResultSet * getAttributes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, const sql::SQLString& attributeNamePattern) = 0;
virtual ResultSet * getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int scope, bool nullable) = 0; virtual ResultSet * getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int scope, bool nullable) = 0;
virtual ResultSet * getCatalogs() = 0; virtual ResultSet * getCatalogs() = 0;
virtual const sql::SQLString& getCatalogSeparator() = 0; virtual const sql::SQLString& getCatalogSeparator() = 0;
virtual const sql::SQLString& getCatalogTerm() = 0; virtual const sql::SQLString& getCatalogTerm() = 0;
virtual ResultSet * getColumnPrivileges(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern) = 0; virtual ResultSet * getColumnPrivileges(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern) = 0;
virtual ResultSet * getColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern) = 0; virtual ResultSet * getColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern) = 0;
virtual Connection * getConnection() = 0; virtual Connection * getConnection() = 0;
virtual ResultSet * getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog, const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable) = 0; virtual ResultSet * getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog, const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable) = 0;
virtual unsigned int getDatabaseMajorVersion() = 0; virtual unsigned int getDatabaseMajorVersion() = 0;
virtual unsigned int getDatabaseMinorVersion() = 0; virtual unsigned int getDatabaseMinorVersion() = 0;
virtual unsigned int getDatabasePatchVersion() = 0; virtual unsigned int getDatabasePatchVersion() = 0;
virtual const sql::SQLString& getDatabaseProductName() = 0; virtual const sql::SQLString& getDatabaseProductName() = 0;
virtual SQLString getDatabaseProductVersion() = 0; virtual SQLString getDatabaseProductVersion() = 0;
virtual int getDefaultTransactionIsolation() = 0; virtual int getDefaultTransactionIsolation() = 0;
virtual unsigned int getDriverMajorVersion() = 0; virtual unsigned int getDriverMajorVersion() = 0;
virtual unsigned int getDriverMinorVersion() = 0; virtual unsigned int getDriverMinorVersion() = 0;
virtual unsigned int getDriverPatchVersion() = 0; virtual unsigned int getDriverPatchVersion() = 0;
virtual const sql::SQLString& getDriverName() = 0; virtual const sql::SQLString& getDriverName() = 0;
virtual const sql::SQLString& getDriverVersion() = 0; virtual const sql::SQLString& getDriverVersion() = 0;
virtual ResultSet * getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; virtual ResultSet * getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0;
virtual const sql::SQLString& getExtraNameCharacters() = 0; virtual const sql::SQLString& getExtraNameCharacters() = 0;
virtual const sql::SQLString& getIdentifierQuoteString() = 0; virtual const sql::SQLString& getIdentifierQuoteString() = 0;
virtual ResultSet * getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; virtual ResultSet * getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0;
virtual ResultSet * getIndexInfo(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool approximate) = 0; virtual ResultSet * getIndexInfo(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool approximate) = 0;
virtual unsigned int getCDBCMajorVersion() = 0; virtual unsigned int getCDBCMajorVersion() = 0;
virtual unsigned int getCDBCMinorVersion() = 0; virtual unsigned int getCDBCMinorVersion() = 0;
virtual unsigned int getMaxBinaryLiteralLength() = 0; virtual unsigned int getMaxBinaryLiteralLength() = 0;
virtual unsigned int getMaxCatalogNameLength() = 0; virtual unsigned int getMaxCatalogNameLength() = 0;
virtual unsigned int getMaxCharLiteralLength() = 0; virtual unsigned int getMaxCharLiteralLength() = 0;
virtual unsigned int getMaxColumnNameLength() = 0; virtual unsigned int getMaxColumnNameLength() = 0;
virtual unsigned int getMaxColumnsInGroupBy() = 0; virtual unsigned int getMaxColumnsInGroupBy() = 0;
virtual unsigned int getMaxColumnsInIndex() = 0; virtual unsigned int getMaxColumnsInIndex() = 0;
virtual unsigned int getMaxColumnsInOrderBy() = 0; virtual unsigned int getMaxColumnsInOrderBy() = 0;
virtual unsigned int getMaxColumnsInSelect() = 0; virtual unsigned int getMaxColumnsInSelect() = 0;
virtual unsigned int getMaxColumnsInTable() = 0; virtual unsigned int getMaxColumnsInTable() = 0;
virtual unsigned int getMaxConnections() = 0; virtual unsigned int getMaxConnections() = 0;
virtual unsigned int getMaxCursorNameLength() = 0; virtual unsigned int getMaxCursorNameLength() = 0;
virtual unsigned int getMaxIndexLength() = 0; virtual unsigned int getMaxIndexLength() = 0;
virtual unsigned int getMaxProcedureNameLength() = 0; virtual unsigned int getMaxProcedureNameLength() = 0;
virtual unsigned int getMaxRowSize() = 0; virtual unsigned int getMaxRowSize() = 0;
virtual unsigned int getMaxSchemaNameLength() = 0; virtual unsigned int getMaxSchemaNameLength() = 0;
virtual unsigned int getMaxStatementLength() = 0; virtual unsigned int getMaxStatementLength() = 0;
virtual unsigned int getMaxStatements() = 0; virtual unsigned int getMaxStatements() = 0;
virtual unsigned int getMaxTableNameLength() = 0; virtual unsigned int getMaxTableNameLength() = 0;
virtual unsigned int getMaxTablesInSelect() = 0; virtual unsigned int getMaxTablesInSelect() = 0;
virtual unsigned int getMaxUserNameLength() = 0; virtual unsigned int getMaxUserNameLength() = 0;
virtual const sql::SQLString& getNumericFunctions() = 0; virtual const sql::SQLString& getNumericFunctions() = 0;
virtual ResultSet * getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; virtual ResultSet * getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0;
virtual ResultSet * getProcedureColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern, const sql::SQLString& columnNamePattern) = 0; virtual ResultSet * getProcedureColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern, const sql::SQLString& columnNamePattern) = 0;
virtual ResultSet * getProcedures(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern) = 0; virtual ResultSet * getProcedures(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern) = 0;
virtual const sql::SQLString& getProcedureTerm() = 0; virtual const sql::SQLString& getProcedureTerm() = 0;
virtual int getResultSetHoldability() = 0; virtual int getResultSetHoldability() = 0;
virtual ResultSet * getSchemas() = 0; virtual ResultSet * getSchemas() = 0;
virtual const sql::SQLString& getSchemaTerm() = 0; virtual const sql::SQLString& getSchemaTerm() = 0;
virtual const sql::SQLString& getSearchStringEscape() = 0; virtual ResultSet * getSchemaCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0;
virtual const sql::SQLString& getSQLKeywords() = 0; virtual ResultSet * getSchemaCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0;
virtual int getSQLStateType() = 0; virtual const sql::SQLString& getSearchStringEscape() = 0;
virtual const sql::SQLString& getStringFunctions() = 0; virtual const sql::SQLString& getSQLKeywords() = 0;
virtual ResultSet * getSuperTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; virtual int getSQLStateType() = 0;
virtual ResultSet * getSuperTypes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern) = 0; virtual const sql::SQLString& getStringFunctions() = 0;
virtual const sql::SQLString& getSystemFunctions() = 0; virtual ResultSet * getSuperTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0;
virtual ResultSet * getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0; virtual ResultSet * getSuperTypes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern) = 0;
virtual ResultSet * getTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list<sql::SQLString> &types) = 0; virtual const sql::SQLString& getSystemFunctions() = 0;
virtual ResultSet * getTableTypes() = 0; virtual ResultSet * getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0;
virtual const sql::SQLString& getTimeDateFunctions() = 0; virtual ResultSet * getTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list<sql::SQLString> &types) = 0;
virtual ResultSet * getTypeInfo() = 0; virtual ResultSet * getTableTypes() = 0;
virtual ResultSet * getUDTs(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, std::list<int> &types) = 0; virtual ResultSet * getTableCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0;
virtual SQLString getURL() = 0; virtual ResultSet * getTableCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0;
virtual SQLString getUserName() = 0; virtual const sql::SQLString& getTimeDateFunctions() = 0;
virtual ResultSet * getVersionColumns(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0; virtual ResultSet * getTypeInfo() = 0;
virtual bool insertsAreDetected(int type) = 0; virtual ResultSet * getUDTs(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, std::list<int> &types) = 0;
virtual bool isCatalogAtStart() = 0; virtual SQLString getURL() = 0;
virtual bool isReadOnly() = 0; virtual SQLString getUserName() = 0;
virtual bool locatorsUpdateCopy() = 0; virtual ResultSet * getVersionColumns(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0;
virtual bool nullPlusNonNullIsNull() = 0; virtual bool insertsAreDetected(int type) = 0;
virtual bool nullsAreSortedAtEnd() = 0; virtual bool isCatalogAtStart() = 0;
virtual bool nullsAreSortedAtStart() = 0; virtual bool isReadOnly() = 0;
virtual bool nullsAreSortedHigh() = 0; virtual bool locatorsUpdateCopy() = 0;
virtual bool nullsAreSortedLow() = 0; virtual bool nullPlusNonNullIsNull() = 0;
virtual bool othersDeletesAreVisible(int type) = 0; virtual bool nullsAreSortedAtEnd() = 0;
virtual bool othersInsertsAreVisible(int type) = 0; virtual bool nullsAreSortedAtStart() = 0;
virtual bool othersUpdatesAreVisible(int type) = 0; virtual bool nullsAreSortedHigh() = 0;
virtual bool ownDeletesAreVisible(int type) = 0; virtual bool nullsAreSortedLow() = 0;
virtual bool ownInsertsAreVisible(int type) = 0; virtual bool othersDeletesAreVisible(int type) = 0;
virtual bool ownUpdatesAreVisible(int type) = 0; virtual bool othersInsertsAreVisible(int type) = 0;
virtual bool storesLowerCaseIdentifiers() = 0; virtual bool othersUpdatesAreVisible(int type) = 0;
virtual bool storesLowerCaseQuotedIdentifiers() = 0; virtual bool ownDeletesAreVisible(int type) = 0;
virtual bool storesMixedCaseIdentifiers() = 0; virtual bool ownInsertsAreVisible(int type) = 0;
virtual bool storesMixedCaseQuotedIdentifiers() = 0; virtual bool ownUpdatesAreVisible(int type) = 0;
virtual bool storesUpperCaseIdentifiers() = 0; virtual bool storesLowerCaseIdentifiers() = 0;
virtual bool storesUpperCaseQuotedIdentifiers() = 0; virtual bool storesLowerCaseQuotedIdentifiers() = 0;
virtual bool supportsAlterTableWithAddColumn() = 0; virtual bool storesMixedCaseIdentifiers() = 0;
virtual bool supportsAlterTableWithDropColumn() = 0; virtual bool storesMixedCaseQuotedIdentifiers() = 0;
virtual bool supportsANSI92EntryLevelSQL() = 0; virtual bool storesUpperCaseIdentifiers() = 0;
virtual bool supportsANSI92FullSQL() = 0; virtual bool storesUpperCaseQuotedIdentifiers() = 0;
virtual bool supportsANSI92IntermediateSQL() = 0; virtual bool supportsAlterTableWithAddColumn() = 0;
virtual bool supportsBatchUpdates() = 0; virtual bool supportsAlterTableWithDropColumn() = 0;
virtual bool supportsCatalogsInDataManipulation() = 0; virtual bool supportsANSI92EntryLevelSQL() = 0;
virtual bool supportsCatalogsInIndexDefinitions() = 0; virtual bool supportsANSI92FullSQL() = 0;
virtual bool supportsCatalogsInPrivilegeDefinitions() = 0; virtual bool supportsANSI92IntermediateSQL() = 0;
virtual bool supportsCatalogsInProcedureCalls() = 0; virtual bool supportsBatchUpdates() = 0;
virtual bool supportsCatalogsInTableDefinitions() = 0; virtual bool supportsCatalogsInDataManipulation() = 0;
virtual bool supportsColumnAliasing() = 0; virtual bool supportsCatalogsInIndexDefinitions() = 0;
virtual bool supportsConvert() = 0; virtual bool supportsCatalogsInPrivilegeDefinitions() = 0;
virtual bool supportsConvert(int fromType, int toType) = 0; virtual bool supportsCatalogsInProcedureCalls() = 0;
virtual bool supportsCoreSQLGrammar() = 0; virtual bool supportsCatalogsInTableDefinitions() = 0;
virtual bool supportsCorrelatedSubqueries() = 0; virtual bool supportsColumnAliasing() = 0;
virtual bool supportsDataDefinitionAndDataManipulationTransactions() = 0; virtual bool supportsConvert() = 0;
virtual bool supportsDataManipulationTransactionsOnly() = 0; virtual bool supportsConvert(int fromType, int toType) = 0;
virtual bool supportsDifferentTableCorrelationNames() = 0; virtual bool supportsCoreSQLGrammar() = 0;
virtual bool supportsExpressionsInOrderBy() = 0; virtual bool supportsCorrelatedSubqueries() = 0;
virtual bool supportsExtendedSQLGrammar() = 0; virtual bool supportsDataDefinitionAndDataManipulationTransactions() = 0;
virtual bool supportsFullOuterJoins() = 0; virtual bool supportsDataManipulationTransactionsOnly() = 0;
virtual bool supportsGetGeneratedKeys() = 0; virtual bool supportsDifferentTableCorrelationNames() = 0;
virtual bool supportsGroupBy() = 0; virtual bool supportsExpressionsInOrderBy() = 0;
virtual bool supportsGroupByBeyondSelect() = 0; virtual bool supportsExtendedSQLGrammar() = 0;
virtual bool supportsGroupByUnrelated() = 0; virtual bool supportsFullOuterJoins() = 0;
virtual bool supportsIntegrityEnhancementFacility() = 0; virtual bool supportsGetGeneratedKeys() = 0;
virtual bool supportsLikeEscapeClause() = 0; virtual bool supportsGroupBy() = 0;
virtual bool supportsLimitedOuterJoins() = 0; virtual bool supportsGroupByBeyondSelect() = 0;
virtual bool supportsMinimumSQLGrammar() = 0; virtual bool supportsGroupByUnrelated() = 0;
virtual bool supportsMixedCaseIdentifiers() = 0; virtual bool supportsIntegrityEnhancementFacility() = 0;
virtual bool supportsMixedCaseQuotedIdentifiers() = 0; virtual bool supportsLikeEscapeClause() = 0;
virtual bool supportsMultipleOpenResults() = 0; virtual bool supportsLimitedOuterJoins() = 0;
virtual bool supportsMultipleResultSets() = 0; virtual bool supportsMinimumSQLGrammar() = 0;
virtual bool supportsMultipleTransactions() = 0; virtual bool supportsMixedCaseIdentifiers() = 0;
virtual bool supportsNamedParameters() = 0; virtual bool supportsMixedCaseQuotedIdentifiers() = 0;
virtual bool supportsNonNullableColumns() = 0; virtual bool supportsMultipleOpenResults() = 0;
virtual bool supportsOpenCursorsAcrossCommit() = 0; virtual bool supportsMultipleResultSets() = 0;
virtual bool supportsOpenCursorsAcrossRollback() = 0; virtual bool supportsMultipleTransactions() = 0;
virtual bool supportsOpenStatementsAcrossCommit() = 0; virtual bool supportsNamedParameters() = 0;
virtual bool supportsOpenStatementsAcrossRollback() = 0; virtual bool supportsNonNullableColumns() = 0;
virtual bool supportsOrderByUnrelated() = 0; virtual bool supportsOpenCursorsAcrossCommit() = 0;
virtual bool supportsOuterJoins() = 0; virtual bool supportsOpenCursorsAcrossRollback() = 0;
virtual bool supportsPositionedDelete() = 0; virtual bool supportsOpenStatementsAcrossCommit() = 0;
virtual bool supportsPositionedUpdate() = 0; virtual bool supportsOpenStatementsAcrossRollback() = 0;
virtual bool supportsResultSetConcurrency(int type, int concurrency) = 0; virtual bool supportsOrderByUnrelated() = 0;
virtual bool supportsResultSetHoldability(int holdability) = 0; virtual bool supportsOuterJoins() = 0;
virtual bool supportsResultSetType(int type) = 0; virtual bool supportsPositionedDelete() = 0;
virtual bool supportsSavepoints() = 0; virtual bool supportsPositionedUpdate() = 0;
virtual bool supportsSchemasInDataManipulation() = 0; virtual bool supportsResultSetConcurrency(int type, int concurrency) = 0;
virtual bool supportsSchemasInIndexDefinitions() = 0; virtual bool supportsResultSetHoldability(int holdability) = 0;
virtual bool supportsSchemasInPrivilegeDefinitions() = 0; virtual bool supportsResultSetType(int type) = 0;
virtual bool supportsSchemasInProcedureCalls() = 0; virtual bool supportsSavepoints() = 0;
virtual bool supportsSchemasInTableDefinitions() = 0; virtual bool supportsSchemasInDataManipulation() = 0;
virtual bool supportsSelectForUpdate() = 0; virtual bool supportsSchemasInIndexDefinitions() = 0;
virtual bool supportsStatementPooling() = 0; virtual bool supportsSchemasInPrivilegeDefinitions() = 0;
virtual bool supportsStoredProcedures() = 0; virtual bool supportsSchemasInProcedureCalls() = 0;
virtual bool supportsSubqueriesInComparisons() = 0; virtual bool supportsSchemasInTableDefinitions() = 0;
virtual bool supportsSubqueriesInExists() = 0; virtual bool supportsSelectForUpdate() = 0;
virtual bool supportsSubqueriesInIns() = 0; virtual bool supportsStatementPooling() = 0;
virtual bool supportsSubqueriesInQuantifieds() = 0; virtual bool supportsStoredProcedures() = 0;
virtual bool supportsTableCorrelationNames() = 0; virtual bool supportsSubqueriesInComparisons() = 0;
virtual bool supportsTransactionIsolationLevel(int level) = 0; virtual bool supportsSubqueriesInExists() = 0;
virtual bool supportsTransactions() = 0; virtual bool supportsSubqueriesInIns() = 0;
virtual bool supportsTypeConversion() = 0; /* SDBC */ virtual bool supportsSubqueriesInQuantifieds() = 0;
virtual bool supportsUnion() = 0; virtual bool supportsTableCorrelationNames() = 0;
virtual bool supportsUnionAll() = 0; virtual bool supportsTransactionIsolationLevel(int level) = 0;
virtual bool updatesAreDetected(int type) = 0; virtual bool supportsTransactions() = 0;
virtual bool usesLocalFilePerTable() = 0; virtual bool supportsTypeConversion() = 0; /* SDBC */
virtual bool usesLocalFiles() = 0; virtual bool supportsUnion() = 0;
virtual ResultSet *getSchemata(const sql::SQLString& catalogName = "") = 0; virtual bool supportsUnionAll() = 0;
virtual ResultSet *getSchemaObjects(const sql::SQLString& catalogName = "", virtual bool updatesAreDetected(int type) = 0;
const sql::SQLString& schemaName = "",
const sql::SQLString& objectType = "",
bool includingDdl = true,
const sql::SQLString& objectName = "",
const sql::SQLString& contextTableName = "") = 0;
virtual ResultSet *getSchemaObjectTypes() = 0; virtual bool usesLocalFilePerTable() = 0;
virtual bool usesLocalFiles() = 0;
virtual ResultSet *getSchemata(const sql::SQLString& catalogName = "") = 0;
virtual ResultSet *getSchemaObjects(const sql::SQLString& catalogName = "",
const sql::SQLString& schemaName = "",
const sql::SQLString& objectType = "",
bool includingDdl = true,
const sql::SQLString& objectName = "",
const sql::SQLString& contextTableName = "") = 0;
virtual ResultSet *getSchemaObjectTypes() = 0;
}; };

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_PARAMETER_METADATA_H_ #ifndef _SQL_PARAMETER_METADATA_H_
#define _SQL_PARAMETER_METADATA_H_ #define _SQL_PARAMETER_METADATA_H_
@ -34,40 +42,40 @@ namespace sql
class ParameterMetaData class ParameterMetaData
{ {
public: public:
enum enum
{ {
parameterModeIn, parameterModeIn,
parameterModeInOut, parameterModeInOut,
parameterModeOut, parameterModeOut,
parameterModeUnknown parameterModeUnknown
}; };
enum enum
{ {
parameterNoNulls, parameterNoNulls,
parameterNullable, parameterNullable,
parameterNullableUnknown parameterNullableUnknown
}; };
virtual sql::SQLString getParameterClassName(unsigned int param) = 0; virtual sql::SQLString getParameterClassName(unsigned int param) = 0;
virtual int getParameterCount() = 0; virtual int getParameterCount() = 0;
virtual int getParameterMode(unsigned int param) = 0; virtual int getParameterMode(unsigned int param) = 0;
virtual int getParameterType(unsigned int param) = 0; virtual int getParameterType(unsigned int param) = 0;
virtual sql::SQLString getParameterTypeName(unsigned int param) = 0; virtual sql::SQLString getParameterTypeName(unsigned int param) = 0;
virtual int getPrecision(unsigned int param) = 0; virtual int getPrecision(unsigned int param) = 0;
virtual int getScale(unsigned int param) = 0; virtual int getScale(unsigned int param) = 0;
virtual int isNullable(unsigned int param) = 0; virtual int isNullable(unsigned int param) = 0;
virtual bool isSigned(unsigned int param) = 0; virtual bool isSigned(unsigned int param) = 0;
protected: protected:
virtual ~ParameterMetaData() {} virtual ~ParameterMetaData() {}
}; };

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_PREPARED_STATEMENT_H_ #ifndef _SQL_PREPARED_STATEMENT_H_
@ -41,46 +49,48 @@ class ParameterMetaData;
class PreparedStatement : public Statement class PreparedStatement : public Statement
{ {
public: public:
virtual ~PreparedStatement() {} virtual ~PreparedStatement() {}
virtual void clearParameters() = 0; virtual void clearParameters() = 0;
virtual bool execute(const sql::SQLString& sql) = 0; virtual bool execute(const sql::SQLString& sql) = 0;
virtual bool execute() = 0; virtual bool execute() = 0;
virtual ResultSet *executeQuery(const sql::SQLString& sql) = 0; virtual ResultSet *executeQuery(const sql::SQLString& sql) = 0;
virtual ResultSet *executeQuery() = 0; virtual ResultSet *executeQuery() = 0;
virtual int executeUpdate(const sql::SQLString& sql) = 0; virtual int executeUpdate(const sql::SQLString& sql) = 0;
virtual int executeUpdate() = 0; virtual int executeUpdate() = 0;
virtual ResultSetMetaData * getMetaData() = 0; virtual ResultSetMetaData * getMetaData() = 0;
virtual ParameterMetaData * getParameterMetaData() = 0; virtual ParameterMetaData * getParameterMetaData() = 0;
virtual void setBigInt(unsigned int parameterIndex, const sql::SQLString& value) = 0; virtual bool getMoreResults() = 0;
virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0; virtual void setBigInt(unsigned int parameterIndex, const sql::SQLString& value) = 0;
virtual void setBoolean(unsigned int parameterIndex, bool value) = 0; virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0;
virtual void setDateTime(unsigned int parameterIndex, const sql::SQLString& value) = 0; virtual void setBoolean(unsigned int parameterIndex, bool value) = 0;
virtual void setDouble(unsigned int parameterIndex, double value) = 0; virtual void setDateTime(unsigned int parameterIndex, const sql::SQLString& value) = 0;
virtual void setInt(unsigned int parameterIndex, int32_t value) = 0; virtual void setDouble(unsigned int parameterIndex, double value) = 0;
virtual void setUInt(unsigned int parameterIndex, uint32_t value) = 0; virtual void setInt(unsigned int parameterIndex, int32_t value) = 0;
virtual void setInt64(unsigned int parameterIndex, int64_t value) = 0; virtual void setUInt(unsigned int parameterIndex, uint32_t value) = 0;
virtual void setUInt64(unsigned int parameterIndex, uint64_t value) = 0; virtual void setInt64(unsigned int parameterIndex, int64_t value) = 0;
virtual void setNull(unsigned int parameterIndex, int sqlType) = 0; virtual void setUInt64(unsigned int parameterIndex, uint64_t value) = 0;
virtual void setString(unsigned int parameterIndex, const sql::SQLString& value) = 0; virtual void setNull(unsigned int parameterIndex, int sqlType) = 0;
virtual PreparedStatement * setResultSetType(sql::ResultSet::enum_type type) = 0; virtual void setString(unsigned int parameterIndex, const sql::SQLString& value) = 0;
virtual PreparedStatement * setResultSetType(sql::ResultSet::enum_type type) = 0;
}; };

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_RESULTSET_H_ #ifndef _SQL_RESULTSET_H_
#define _SQL_RESULTSET_H_ #define _SQL_RESULTSET_H_
@ -42,137 +50,137 @@ class Statement;
class RowID class RowID
{ {
public: public:
virtual ~RowID() {} virtual ~RowID() {}
}; };
class ResultSet class ResultSet
{ {
public: public:
enum enum
{ {
CLOSE_CURSORS_AT_COMMIT, CLOSE_CURSORS_AT_COMMIT,
HOLD_CURSORS_OVER_COMMIT HOLD_CURSORS_OVER_COMMIT
}; };
enum enum
{ {
CONCUR_READ_ONLY, CONCUR_READ_ONLY,
CONCUR_UPDATABLE CONCUR_UPDATABLE
}; };
enum enum
{ {
FETCH_FORWARD, FETCH_FORWARD,
FETCH_REVERSE, FETCH_REVERSE,
FETCH_UNKNOWN FETCH_UNKNOWN
}; };
typedef enum typedef enum
{ {
TYPE_FORWARD_ONLY, TYPE_FORWARD_ONLY,
TYPE_SCROLL_INSENSITIVE, TYPE_SCROLL_INSENSITIVE,
TYPE_SCROLL_SENSITIVE TYPE_SCROLL_SENSITIVE
} enum_type; } enum_type;
virtual ~ResultSet() {} virtual ~ResultSet() {}
virtual bool absolute(int row) = 0; virtual bool absolute(int row) = 0;
virtual void afterLast() = 0; virtual void afterLast() = 0;
virtual void beforeFirst() = 0; virtual void beforeFirst() = 0;
virtual void cancelRowUpdates() = 0; virtual void cancelRowUpdates() = 0;
virtual void clearWarnings() = 0; virtual void clearWarnings() = 0;
virtual void close() = 0; virtual void close() = 0;
virtual uint32_t findColumn(const sql::SQLString& columnLabel) const = 0; virtual uint32_t findColumn(const sql::SQLString& columnLabel) const = 0;
virtual bool first() = 0; virtual bool first() = 0;
virtual std::istream * getBlob(uint32_t columnIndex) const = 0; virtual std::istream * getBlob(uint32_t columnIndex) const = 0;
virtual std::istream * getBlob(const sql::SQLString& columnLabel) const = 0; virtual std::istream * getBlob(const sql::SQLString& columnLabel) const = 0;
virtual bool getBoolean(uint32_t columnIndex) const = 0; virtual bool getBoolean(uint32_t columnIndex) const = 0;
virtual bool getBoolean(const sql::SQLString& columnLabel) const = 0; virtual bool getBoolean(const sql::SQLString& columnLabel) const = 0;
virtual int getConcurrency() = 0; virtual int getConcurrency() = 0;
virtual SQLString getCursorName() = 0; virtual SQLString getCursorName() = 0;
virtual long double getDouble(uint32_t columnIndex) const = 0; virtual long double getDouble(uint32_t columnIndex) const = 0;
virtual long double getDouble(const sql::SQLString& columnLabel) const = 0; virtual long double getDouble(const sql::SQLString& columnLabel) const = 0;
virtual int getFetchDirection() = 0; virtual int getFetchDirection() = 0;
virtual size_t getFetchSize() = 0; virtual size_t getFetchSize() = 0;
virtual int getHoldability() = 0; virtual int getHoldability() = 0;
virtual int32_t getInt(uint32_t columnIndex) const = 0; virtual int32_t getInt(uint32_t columnIndex) const = 0;
virtual int32_t getInt(const sql::SQLString& columnLabel) const = 0; virtual int32_t getInt(const sql::SQLString& columnLabel) const = 0;
virtual uint32_t getUInt(uint32_t columnIndex) const = 0; virtual uint32_t getUInt(uint32_t columnIndex) const = 0;
virtual uint32_t getUInt(const sql::SQLString& columnLabel) const = 0; virtual uint32_t getUInt(const sql::SQLString& columnLabel) const = 0;
virtual int64_t getInt64(uint32_t columnIndex) const = 0; virtual int64_t getInt64(uint32_t columnIndex) const = 0;
virtual int64_t getInt64(const sql::SQLString& columnLabel) const = 0; virtual int64_t getInt64(const sql::SQLString& columnLabel) const = 0;
virtual uint64_t getUInt64(uint32_t columnIndex) const = 0; virtual uint64_t getUInt64(uint32_t columnIndex) const = 0;
virtual uint64_t getUInt64(const sql::SQLString& columnLabel) const = 0; virtual uint64_t getUInt64(const sql::SQLString& columnLabel) const = 0;
virtual ResultSetMetaData * getMetaData() const = 0; virtual ResultSetMetaData * getMetaData() const = 0;
virtual size_t getRow() const = 0; virtual size_t getRow() const = 0;
virtual RowID * getRowId(uint32_t columnIndex) = 0; virtual RowID * getRowId(uint32_t columnIndex) = 0;
virtual RowID * getRowId(const sql::SQLString & columnLabel) = 0; virtual RowID * getRowId(const sql::SQLString & columnLabel) = 0;
virtual const Statement * getStatement() const = 0; virtual const Statement * getStatement() const = 0;
virtual SQLString getString(uint32_t columnIndex) const = 0; virtual SQLString getString(uint32_t columnIndex) const = 0;
virtual SQLString getString(const sql::SQLString& columnLabel) const = 0; virtual SQLString getString(const sql::SQLString& columnLabel) const = 0;
virtual enum_type getType() const = 0; virtual enum_type getType() const = 0;
virtual void getWarnings() = 0; virtual void getWarnings() = 0;
virtual void insertRow() = 0; virtual void insertRow() = 0;
virtual bool isAfterLast() const = 0; virtual bool isAfterLast() const = 0;
virtual bool isBeforeFirst() const = 0; virtual bool isBeforeFirst() const = 0;
virtual bool isClosed() const = 0; virtual bool isClosed() const = 0;
virtual bool isFirst() const = 0; virtual bool isFirst() const = 0;
virtual bool isLast() const = 0; virtual bool isLast() const = 0;
virtual bool isNull(uint32_t columnIndex) const = 0; virtual bool isNull(uint32_t columnIndex) const = 0;
virtual bool isNull(const sql::SQLString& columnLabel) const = 0; virtual bool isNull(const sql::SQLString& columnLabel) const = 0;
virtual bool last() = 0; virtual bool last() = 0;
virtual bool next() = 0; virtual bool next() = 0;
virtual void moveToCurrentRow() = 0; virtual void moveToCurrentRow() = 0;
virtual void moveToInsertRow() = 0; virtual void moveToInsertRow() = 0;
virtual bool previous() = 0; virtual bool previous() = 0;
virtual void refreshRow() = 0; virtual void refreshRow() = 0;
virtual bool relative(int rows) = 0; virtual bool relative(int rows) = 0;
virtual bool rowDeleted() = 0; virtual bool rowDeleted() = 0;
virtual bool rowInserted() = 0; virtual bool rowInserted() = 0;
virtual bool rowUpdated() = 0; virtual bool rowUpdated() = 0;
virtual void setFetchSize(size_t rows) = 0; virtual void setFetchSize(size_t rows) = 0;
virtual size_t rowsCount() const = 0; virtual size_t rowsCount() const = 0;
virtual bool wasNull() const = 0; virtual bool wasNull() const = 0;
}; };
} /* namespace sql */ } /* namespace sql */

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_RESULTSET_METADATA_H_ #ifndef _SQL_RESULTSET_METADATA_H_
#define _SQL_RESULTSET_METADATA_H_ #define _SQL_RESULTSET_METADATA_H_
@ -34,57 +42,63 @@ namespace sql
class ResultSetMetaData class ResultSetMetaData
{ {
public: public:
enum enum
{ {
columnNoNulls, columnNoNulls,
columnNullable, columnNullable,
columnNullableUnknown columnNullableUnknown
}; };
virtual SQLString getCatalogName(unsigned int column) = 0; virtual SQLString getCatalogName(unsigned int column) = 0;
virtual unsigned int getColumnCount() = 0; virtual unsigned int getColumnCount() = 0;
virtual unsigned int getColumnDisplaySize(unsigned int column) = 0; virtual unsigned int getColumnDisplaySize(unsigned int column) = 0;
virtual SQLString getColumnLabel(unsigned int column) = 0; virtual SQLString getColumnLabel(unsigned int column) = 0;
virtual SQLString getColumnName(unsigned int column) = 0; virtual SQLString getColumnName(unsigned int column) = 0;
virtual int getColumnType(unsigned int column) = 0; virtual int getColumnType(unsigned int column) = 0;
virtual SQLString getColumnTypeName(unsigned int column) = 0; virtual SQLString getColumnTypeName(unsigned int column) = 0;
virtual unsigned int getPrecision(unsigned int column) = 0; virtual SQLString getColumnCharset(unsigned int columnIndex) = 0;
virtual unsigned int getScale(unsigned int column) = 0; virtual SQLString getColumnCollation(unsigned int columnIndex) = 0;
virtual SQLString getSchemaName(unsigned int column) = 0; virtual unsigned int getPrecision(unsigned int column) = 0;
virtual SQLString getTableName(unsigned int column) = 0; virtual unsigned int getScale(unsigned int column) = 0;
virtual bool isAutoIncrement(unsigned int column) = 0; virtual SQLString getSchemaName(unsigned int column) = 0;
virtual bool isCaseSensitive(unsigned int column) = 0; virtual SQLString getTableName(unsigned int column) = 0;
virtual bool isCurrency(unsigned int column) = 0; virtual bool isAutoIncrement(unsigned int column) = 0;
virtual bool isDefinitelyWritable(unsigned int column) = 0; virtual bool isCaseSensitive(unsigned int column) = 0;
virtual int isNullable(unsigned int column) = 0; virtual bool isCurrency(unsigned int column) = 0;
virtual bool isReadOnly(unsigned int column) = 0; virtual bool isDefinitelyWritable(unsigned int column) = 0;
virtual bool isSearchable(unsigned int column) = 0; virtual int isNullable(unsigned int column) = 0;
virtual bool isSigned(unsigned int column) = 0; virtual bool isNumeric(unsigned int column) = 0;
virtual bool isWritable(unsigned int column) = 0; virtual bool isReadOnly(unsigned int column) = 0;
virtual bool isZerofill(unsigned int column) = 0; virtual bool isSearchable(unsigned int column) = 0;
virtual bool isSigned(unsigned int column) = 0;
virtual bool isWritable(unsigned int column) = 0;
virtual bool isZerofill(unsigned int column) = 0;
protected: protected:
virtual ~ResultSetMetaData() {} virtual ~ResultSetMetaData() {}
}; };

View File

@ -1,175 +1,208 @@
/* /*
Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_STRING_H_ #ifndef _SQL_STRING_H_
#define _SQL_STRING_H_ #define _SQL_STRING_H_
#include <string> #include <string>
#include <algorithm>
#include "build_config.h" #include "build_config.h"
#include <iostream> #include <iostream>
namespace sql namespace sql
{ {
class CPPCONN_PUBLIC_FUNC SQLString class CPPCONN_PUBLIC_FUNC SQLString
{ {
std::string realStr; std::string realStr;
public: public:
#ifdef _WIN32 #ifdef _WIN32
//TODO something less dirty-hackish. //TODO something less dirty-hackish.
static const size_t npos = static_cast<std::string::size_type>(-1); static const size_t npos = static_cast<std::string::size_type>(-1);
#else #else
static const size_t npos = std::string::npos; static const size_t npos = std::string::npos;
#endif #endif
~SQLString() {} ~SQLString() {}
SQLString() {} SQLString() {}
SQLString(const SQLString & other) : realStr(other.realStr) {} SQLString(const SQLString & other) : realStr(other.realStr) {}
SQLString(const std::string & other) : realStr(other) {} SQLString(const std::string & other) : realStr(other) {}
SQLString(const char other[]) : realStr(other) {} SQLString(const char other[]) : realStr(other) {}
SQLString(const char * s, size_t n) : realStr(s, n) {} SQLString(const char * s, size_t n) : realStr(s, n) {}
// Needed for stuff like SQLString str= "char * string constant" // Needed for stuff like SQLString str= "char * string constant"
const SQLString & operator=(const char * s) const SQLString & operator=(const char * s)
{ {
realStr = s; realStr = s;
return *this; return *this;
} }
const SQLString & operator=(const std::string & rhs) const SQLString & operator=(const std::string & rhs)
{ {
realStr = rhs; realStr = rhs;
return *this; return *this;
} }
const SQLString & operator=(const SQLString & rhs) const SQLString & operator=(const SQLString & rhs)
{ {
realStr = rhs.realStr; realStr = rhs.realStr;
return *this; return *this;
} }
// Conversion to st::string. Comes in play for stuff like std::string str= SQLString_var; // Conversion to st::string. Comes in play for stuff like std::string str= SQLString_var;
operator const std::string &() const operator const std::string &() const
{ {
return realStr; return realStr;
} }
/** For access std::string methods. Not sure we need it. Makes it look like some smart ptr. /** For access std::string methods. Not sure we need it. Makes it look like some smart ptr.
possibly operator* - will look even more like smart ptr */ possibly operator* - will look even more like smart ptr */
std::string * operator ->() std::string * operator ->()
{ {
return & realStr; return & realStr;
} }
int compare(const SQLString& str) const int compare(const SQLString& str) const
{ {
return realStr.compare(str.realStr); return realStr.compare(str.realStr);
} }
int compare(const char * s) const int compare(const char * s) const
{ {
return realStr.compare(s); return realStr.compare(s);
} }
int compare(size_t pos1, size_t n1, const char * s) const int compare(size_t pos1, size_t n1, const char * s) const
{ {
return realStr.compare(pos1, n1, s); return realStr.compare(pos1, n1, s);
} }
const std::string & asStdString() const int caseCompare(const SQLString &s) const
{ {
return realStr; std::string tmp(realStr), str(s);
} std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return tmp.compare(str);
}
const char * c_str() const int caseCompare(const char * s) const
{ {
return realStr.c_str(); std::string tmp(realStr), str(s);
} std::transform(str.begin(), str.end(), str.begin(), ::tolower);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
return tmp.compare(str);
}
size_t length() const int caseCompare(size_t pos1, size_t n1, const char * s) const
{ {
return realStr.length(); std::string tmp(realStr.c_str() + pos1, n1), str(s);
} std::transform(str.begin(), str.end(), str.begin(), ::tolower);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
return tmp.compare(str);
}
SQLString & append(const std::string & str) const std::string & asStdString() const
{ {
realStr.append(str); return realStr;
return *this; }
}
SQLString & append(const char * s) const char * c_str() const
{ {
realStr.append(s); return realStr.c_str();
return *this; }
}
const char& operator[](size_t pos) const size_t length() const
{ {
return realStr[pos]; return realStr.length();
} }
size_t find(char c, size_t pos = 0) const SQLString & append(const std::string & str)
{ {
return realStr.find(c, pos); realStr.append(str);
} return *this;
}
size_t find(const SQLString & s, size_t pos = 0) const SQLString & append(const char * s)
{ {
return realStr.find(s.realStr, pos); realStr.append(s);
} return *this;
}
SQLString substr(size_t pos = 0, size_t n = npos) const const char& operator[](size_t pos) const
{ {
return realStr.substr(pos, n); return realStr[pos];
} }
const SQLString& replace(size_t pos1, size_t n1, const SQLString & s) size_t find(char c, size_t pos = 0) const
{ {
realStr.replace(pos1, n1, s.realStr); return realStr.find(c, pos);
return *this; }
}
size_t find_first_of(char c, size_t pos = 0) const size_t find(const SQLString & s, size_t pos = 0) const
{ {
return realStr.find_first_of(c, pos); return realStr.find(s.realStr, pos);
} }
size_t find_last_of(char c, size_t pos = npos) const SQLString substr(size_t pos = 0, size_t n = npos) const
{ {
return realStr.find_last_of(c, pos); return realStr.substr(pos, n);
} }
const SQLString & operator+=(const SQLString & op2) const SQLString& replace(size_t pos1, size_t n1, const SQLString & s)
{ {
realStr += op2.realStr; realStr.replace(pos1, n1, s.realStr);
return *this; return *this;
} }
size_t find_first_of(char c, size_t pos = 0) const
{
return realStr.find_first_of(c, pos);
}
size_t find_last_of(char c, size_t pos = npos) const
{
return realStr.find_last_of(c, pos);
}
const SQLString & operator+=(const SQLString & op2)
{
realStr += op2.realStr;
return *this;
}
}; };
@ -178,22 +211,22 @@ namespace sql
*/ */
inline const SQLString operator+(const SQLString & op1, const SQLString & op2) inline const SQLString operator+(const SQLString & op1, const SQLString & op2)
{ {
return sql::SQLString(op1.asStdString() + op2.asStdString()); return sql::SQLString(op1.asStdString() + op2.asStdString());
} }
inline bool operator ==(const SQLString & op1, const SQLString & op2) inline bool operator ==(const SQLString & op1, const SQLString & op2)
{ {
return (op1.asStdString() == op2.asStdString()); return (op1.asStdString() == op2.asStdString());
} }
inline bool operator !=(const SQLString & op1, const SQLString & op2) inline bool operator !=(const SQLString & op1, const SQLString & op2)
{ {
return (op1.asStdString() != op2.asStdString()); return (op1.asStdString() != op2.asStdString());
} }
inline bool operator <(const SQLString & op1, const SQLString & op2) inline bool operator <(const SQLString & op1, const SQLString & op2)
{ {
return op1.asStdString() < op2.asStdString(); return op1.asStdString() < op2.asStdString();
} }
@ -202,10 +235,10 @@ inline bool operator <(const SQLString & op1, const SQLString & op2)
namespace std namespace std
{ {
// operator << for SQLString output // operator << for SQLString output
inline ostream & operator << (ostream & os, const sql::SQLString & str ) inline ostream & operator << (ostream & os, const sql::SQLString & str )
{ {
return os << str.asStdString(); return os << str.asStdString();
} }
} }
#endif #endif

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_STATEMENT_H_ #ifndef _SQL_STATEMENT_H_
#define _SQL_STATEMENT_H_ #define _SQL_STATEMENT_H_
@ -41,53 +49,53 @@ class SQLWarning;
class Statement class Statement
{ {
public: public:
virtual ~Statement() {}; virtual ~Statement() {};
virtual Connection * getConnection() = 0; virtual Connection * getConnection() = 0;
virtual void cancel() = 0; virtual void cancel() = 0;
virtual void clearWarnings() = 0; virtual void clearWarnings() = 0;
virtual void close() = 0; virtual void close() = 0;
virtual bool execute(const sql::SQLString& sql) = 0; virtual bool execute(const sql::SQLString& sql) = 0;
virtual ResultSet * executeQuery(const sql::SQLString& sql) = 0; virtual ResultSet * executeQuery(const sql::SQLString& sql) = 0;
virtual int executeUpdate(const sql::SQLString& sql) = 0; virtual int executeUpdate(const sql::SQLString& sql) = 0;
virtual size_t getFetchSize() = 0; virtual size_t getFetchSize() = 0;
virtual unsigned int getMaxFieldSize() = 0; virtual unsigned int getMaxFieldSize() = 0;
virtual uint64_t getMaxRows() = 0; virtual uint64_t getMaxRows() = 0;
virtual bool getMoreResults() = 0; virtual bool getMoreResults() = 0;
virtual unsigned int getQueryTimeout() = 0; virtual unsigned int getQueryTimeout() = 0;
virtual ResultSet * getResultSet() = 0; virtual ResultSet * getResultSet() = 0;
virtual sql::ResultSet::enum_type getResultSetType() = 0; virtual sql::ResultSet::enum_type getResultSetType() = 0;
virtual uint64_t getUpdateCount() = 0; virtual uint64_t getUpdateCount() = 0;
virtual const SQLWarning * getWarnings() = 0; virtual const SQLWarning * getWarnings() = 0;
virtual void setCursorName(const sql::SQLString & name) = 0; virtual void setCursorName(const sql::SQLString & name) = 0;
virtual void setEscapeProcessing(bool enable) = 0; virtual void setEscapeProcessing(bool enable) = 0;
virtual void setFetchSize(size_t rows) = 0; virtual void setFetchSize(size_t rows) = 0;
virtual void setMaxFieldSize(unsigned int max) = 0; virtual void setMaxFieldSize(unsigned int max) = 0;
virtual void setMaxRows(unsigned int max) = 0; virtual void setMaxRows(unsigned int max) = 0;
virtual void setQueryTimeout(unsigned int seconds) = 0; virtual void setQueryTimeout(unsigned int seconds) = 0;
virtual Statement * setResultSetType(sql::ResultSet::enum_type type) = 0; virtual Statement * setResultSetType(sql::ResultSet::enum_type type) = 0;
}; };
} /* namespace sql */ } /* namespace sql */

View File

@ -1,26 +1,34 @@
/* /*
Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* 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, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
The MySQL Connector/C++ is licensed under the terms of the GPLv2
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
MySQL Connectors. There are special exceptions to the terms and
conditions of the GPLv2 as it is applied to this software, see the
FLOSS License Exception
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
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; version 2 of the License.
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, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_WARNING_H_ #ifndef _SQL_WARNING_H_
#define _SQL_WARNING_H_ #define _SQL_WARNING_H_
@ -43,26 +51,26 @@ class SQLWarning
{ {
public: public:
SQLWarning(){} SQLWarning(){}
virtual const sql::SQLString & getMessage() const = 0; virtual const sql::SQLString & getMessage() const = 0;
virtual const sql::SQLString & getSQLState() const = 0; virtual const sql::SQLString & getSQLState() const = 0;
virtual int getErrorCode() const = 0; virtual int getErrorCode() const = 0;
virtual const SQLWarning * getNextWarning() const = 0; virtual const SQLWarning * getNextWarning() const = 0;
virtual void setNextWarning(const SQLWarning * _next) = 0; virtual void setNextWarning(const SQLWarning * _next) = 0;
protected: protected:
virtual ~SQLWarning(){}; virtual ~SQLWarning(){};
SQLWarning(const SQLWarning& e){}; SQLWarning(const SQLWarning&){};
private: private:
const SQLWarning & operator = (const SQLWarning & rhs); const SQLWarning & operator = (const SQLWarning & rhs);
}; };

View File

@ -0,0 +1,164 @@
#ifndef HV_ASYNC_HTTP_CLIENT_H_
#define HV_ASYNC_HTTP_CLIENT_H_
#include <map>
#include <list>
#include "EventLoopThread.h"
#include "Channel.h"
#include "HttpMessage.h"
#include "HttpParser.h"
namespace hv {
template<typename Conn>
class ConnPool {
public:
int size() {
return conns_.size();
}
bool get(Conn& conn) {
if (conns_.empty()) return false;
conn = conns_.front();
conns_.pop_front();
return true;
}
bool add(const Conn& conn) {
conns_.push_back(conn);
return true;
}
bool remove(const Conn& conn) {
auto iter = conns_.begin();
while (iter != conns_.end()) {
if (*iter == conn) {
iter = conns_.erase(iter);
return true;
} else {
++iter;
}
}
return false;
}
private:
std::list<Conn> conns_;
};
struct HttpClientTask {
HttpRequestPtr req;
HttpResponseCallback cb;
uint64_t start_time;
};
typedef std::shared_ptr<HttpClientTask> HttpClientTaskPtr;
struct HttpClientContext {
HttpClientTaskPtr task;
HttpResponsePtr resp;
HttpParserPtr parser;
TimerID timerID;
HttpClientContext() {
timerID = INVALID_TIMER_ID;
}
~HttpClientContext() {
cancelTimer();
}
void cancelTimer() {
if (timerID != INVALID_TIMER_ID) {
killTimer(timerID);
timerID = INVALID_TIMER_ID;
}
}
void cancelTask() {
cancelTimer();
task = NULL;
}
void callback() {
cancelTimer();
if (task && task->cb) {
task->cb(resp);
}
// NOTE: task done
task = NULL;
}
void successCallback() {
callback();
resp = NULL;
}
void errorCallback() {
resp = NULL;
callback();
}
};
class HV_EXPORT AsyncHttpClient : private EventLoopThread {
public:
AsyncHttpClient(EventLoopPtr loop = NULL) : EventLoopThread(loop) {
if (loop == NULL) {
EventLoopThread::start(true);
}
}
~AsyncHttpClient() {
EventLoopThread::stop(true);
}
// thread-safe
int send(const HttpRequestPtr& req, HttpResponseCallback resp_cb);
int send(const HttpClientTaskPtr& task) {
EventLoopThread::loop()->queueInLoop(std::bind(&AsyncHttpClient::sendInLoop, this, task));
return 0;
}
protected:
void sendInLoop(HttpClientTaskPtr task) {
int err = doTask(task);
if (err != 0 && task->cb) {
task->cb(NULL);
}
}
int doTask(const HttpClientTaskPtr& task);
static int sendRequest(const SocketChannelPtr& channel);
// channel
const SocketChannelPtr& getChannel(int fd) {
return channels[fd];
// return fd < channels.capacity() ? channels[fd] : NULL;
}
const SocketChannelPtr& addChannel(hio_t* io) {
auto channel = std::make_shared<SocketChannel>(io);
channel->newContext<HttpClientContext>();
int fd = channel->fd();
channels[fd] = channel;
return channels[fd];
}
void removeChannel(const SocketChannelPtr& channel) {
channel->deleteContext<HttpClientContext>();
int fd = channel->fd();
channels.erase(fd);
}
private:
// NOTE: just one loop thread, no need mutex.
// fd => SocketChannelPtr
std::map<int, SocketChannelPtr> channels;
// peeraddr => ConnPool
std::map<std::string, ConnPool<int>> conn_pools;
};
}
#endif // HV_ASYNC_HTTP_CLIENT_H_

View File

@ -241,7 +241,7 @@ typedef std::shared_ptr<EventLoop> EventLoopPtr;
static inline EventLoop* tlsEventLoop() { static inline EventLoop* tlsEventLoop() {
return (EventLoop*)ThreadLocalStorage::get(ThreadLocalStorage::EVENT_LOOP); return (EventLoop*)ThreadLocalStorage::get(ThreadLocalStorage::EVENT_LOOP);
} }
#define currentThreadEventLoop tlsEventLoop() #define currentThreadEventLoop ::hv::tlsEventLoop()
static inline TimerID setTimer(int timeout_ms, TimerCallback cb, uint32_t repeat = INFINITE) { static inline TimerID setTimer(int timeout_ms, TimerCallback cb, uint32_t repeat = INFINITE) {
EventLoop* loop = tlsEventLoop(); EventLoop* loop = tlsEventLoop();

View File

@ -44,6 +44,7 @@ public:
Functor pre = Functor(), Functor pre = Functor(),
Functor post = Functor()) { Functor post = Functor()) {
if (status() >= kStarting && status() < kStopped) return; if (status() >= kStarting && status() < kStopped) return;
if (isRunning()) return;
setStatus(kStarting); setStatus(kStarting);
thread_ = std::make_shared<std::thread>(&EventLoopThread::loop_thread, this, pre, post); thread_ = std::make_shared<std::thread>(&EventLoopThread::loop_thread, this, pre, post);

View File

@ -8,7 +8,7 @@
/* /*
#include <stdio.h> #include <stdio.h>
#include "http_client.h" #include "HttpClient.h"
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
HttpRequest req; HttpRequest req;
@ -30,7 +30,6 @@ int main(int argc, char* argv[]) {
typedef struct http_client_s http_client_t; typedef struct http_client_s http_client_t;
HV_EXPORT http_client_t* http_client_new(const char* host = NULL, int port = DEFAULT_HTTP_PORT, int https = 0); HV_EXPORT http_client_t* http_client_new(const char* host = NULL, int port = DEFAULT_HTTP_PORT, int https = 0);
HV_EXPORT int http_client_close(http_client_t* cli);
HV_EXPORT int http_client_del(http_client_t* cli); HV_EXPORT int http_client_del(http_client_t* cli);
HV_EXPORT const char* http_client_strerror(int errcode); HV_EXPORT const char* http_client_strerror(int errcode);
@ -69,6 +68,15 @@ HV_EXPORT int http_client_send(HttpRequest* req, HttpResponse* resp);
// http_client_send_async(&default_async_client, ...) // http_client_send_async(&default_async_client, ...)
HV_EXPORT int http_client_send_async(HttpRequestPtr req, HttpResponseCallback resp_cb = NULL); HV_EXPORT int http_client_send_async(HttpRequestPtr req, HttpResponseCallback resp_cb = NULL);
// low-level api
// @retval >=0 connfd, <0 error
HV_EXPORT int http_client_connect(http_client_t* cli, const char* host, int port, int https, int timeout);
HV_EXPORT int http_client_send_header(http_client_t* cli, HttpRequest* req);
HV_EXPORT int http_client_send_data(http_client_t* cli, const char* data, int size);
HV_EXPORT int http_client_recv_data(http_client_t* cli, char* data, int size);
HV_EXPORT int http_client_recv_response(http_client_t* cli, HttpResponse* resp);
HV_EXPORT int http_client_close(http_client_t* cli);
namespace hv { namespace hv {
class HttpClient { class HttpClient {
@ -134,7 +142,22 @@ public:
return http_client_send_async(_client, req, std::move(resp_cb)); return http_client_send_async(_client, req, std::move(resp_cb));
} }
// close // low-level api
int connect(const char* host, int port = DEFAULT_HTTP_PORT, int https = 0, int timeout = DEFAULT_HTTP_CONNECT_TIMEOUT) {
return http_client_connect(_client, host, port, https, timeout);
}
int sendHeader(HttpRequest* req) {
return http_client_send_header(_client, req);
}
int sendData(const char* data, int size) {
return http_client_send_data(_client, data, size);
}
int recvData(char* data, int size) {
return http_client_recv_data(_client, data, size);
}
int recvResponse(HttpResponse* resp) {
return http_client_recv_response(_client, resp);
}
int close() { int close() {
return http_client_close(_client); return http_client_close(_client);
} }

View File

@ -46,19 +46,6 @@
#include "httpdef.h" #include "httpdef.h"
#include "http_content.h" #include "http_content.h"
namespace hv {
struct NetAddr {
std::string ip;
int port;
std::string ipport() {
return hv::asprintf("%s:%d", ip.c_str(), port);
}
};
}
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
// Cookie: sessionid=1; domain=.example.com; path=/; max-age=86400; secure; httponly // Cookie: sessionid=1; domain=.example.com; path=/; max-age=86400; secure; httponly
struct HV_EXPORT HttpCookie { struct HV_EXPORT HttpCookie {
@ -297,6 +284,7 @@ public:
void* Content() { void* Content() {
if (content == NULL && body.size() != 0) { if (content == NULL && body.size() != 0) {
content = (void*)body.data(); content = (void*)body.data();
content_length = body.size();
} }
return content; return content;
} }

View File

@ -3,9 +3,11 @@
#include "hexport.h" #include "hexport.h"
#include "hssl.h" #include "hssl.h"
// #include "EventLoop.h"
#include "HttpService.h" #include "HttpService.h"
// #include "WebSocketServer.h" // #include "WebSocketServer.h"
namespace hv { namespace hv {
class EventLoop;
struct WebSocketService; struct WebSocketService;
} }
using hv::HttpService; using hv::HttpService;
@ -72,18 +74,16 @@ int main() {
return 200; return 200;
}); });
HttpServer server; HttpServer server(&service);
server.registerHttpService(&service);
server.setPort(8080);
server.setThreadNum(4); server.setThreadNum(4);
server.run(); server.run(":8080");
return 0; return 0;
} }
*/ */
namespace hv { namespace hv {
class HttpServer : public http_server_t { class HV_EXPORT HttpServer : public http_server_t {
public: public:
HttpServer(HttpService* service = NULL) HttpServer(HttpService* service = NULL)
: http_server_t() : http_server_t()
@ -96,6 +96,8 @@ public:
this->service = service; this->service = service;
} }
std::shared_ptr<hv::EventLoop> loop(int idx = -1);
void setHost(const char* host = "0.0.0.0") { void setHost(const char* host = "0.0.0.0") {
if (host) strcpy(this->host, host); if (host) strcpy(this->host, host);
} }
@ -117,6 +119,11 @@ public:
this->worker_threads = num; this->worker_threads = num;
} }
void setMaxWorkerConnectionNum(uint32_t num) {
this->worker_connections = num;
}
size_t connectionNum();
// SSL/TLS // SSL/TLS
int setSslCtx(hssl_ctx_t ssl_ctx) { int setSslCtx(hssl_ctx_t ssl_ctx) {
this->ssl_ctx = ssl_ctx; this->ssl_ctx = ssl_ctx;
@ -130,12 +137,20 @@ public:
return setSslCtx(ssl_ctx); return setSslCtx(ssl_ctx);
} }
int run(bool wait = true) { // run(":8080")
// run("0.0.0.0:8080")
// run("[::]:8080")
int run(const char* ip_port = NULL, bool wait = true) {
if (ip_port) {
hv::NetAddr listen_addr(ip_port);
if (listen_addr.ip.size() != 0) setHost(listen_addr.ip.c_str());
if (listen_addr.port != 0) setPort(listen_addr.port);
}
return http_server_run(this, wait); return http_server_run(this, wait);
} }
int start() { int start(const char* ip_port = NULL) {
return run(false); return run(ip_port, false);
} }
int stop() { int stop() {

View File

@ -32,7 +32,11 @@ public:
} }
EventLoopPtr loop(int idx = -1) { EventLoopPtr loop(int idx = -1) {
return worker_threads.loop(idx); EventLoopPtr worker_loop = worker_threads.loop(idx);
if (worker_loop == NULL) {
worker_loop = acceptor_loop;
}
return worker_loop;
} }
//@retval >=0 listenfd, <0 error //@retval >=0 listenfd, <0 error
@ -294,7 +298,9 @@ public:
// start thread-safe // start thread-safe
void start(bool wait_threads_started = true) { void start(bool wait_threads_started = true) {
TcpServerEventLoopTmpl<TSocketChannel>::start(wait_threads_started); TcpServerEventLoopTmpl<TSocketChannel>::start(wait_threads_started);
EventLoopThread::start(wait_threads_started); if (!isRunning()) {
EventLoopThread::start(wait_threads_started);
}
} }
// stop thread-safe // stop thread-safe

View File

@ -60,6 +60,7 @@ public:
if (ret != 0) { if (ret != 0) {
perror("bind"); perror("bind");
} }
hio_set_localaddr(channel->io(), &local_addr.sa, SOCKADDR_LEN(&local_addr));
return ret; return ret;
} }

View File

@ -36,7 +36,11 @@ HV_INLINE std::string Base64Decode(const char* str, unsigned int len = 0) {
int decoded_size = BASE64_DECODE_OUT_SIZE(len); int decoded_size = BASE64_DECODE_OUT_SIZE(len);
std::string decoded_buf(decoded_size + 1, 0); std::string decoded_buf(decoded_size + 1, 0);
decoded_size = hv_base64_decode(str, len, (unsigned char*)decoded_buf.data()); decoded_size = hv_base64_decode(str, len, (unsigned char*)decoded_buf.data());
decoded_buf.resize(decoded_size); if (decoded_size > 0) {
decoded_buf.resize(decoded_size);
} else {
decoded_buf.clear();
}
return decoded_buf; return decoded_buf;
} }

View File

@ -1,105 +0,0 @@
#ifndef HV_DNS_H_
#define HV_DNS_H_
#include "hexport.h"
#include "hplatform.h"
#define DNS_PORT 53
#define DNS_QUERY 0
#define DNS_RESPONSE 1
#define DNS_TYPE_A 1 // ipv4
#define DNS_TYPE_NS 2
#define DNS_TYPE_CNAME 5
#define DNS_TYPE_SOA 6
#define DNS_TYPE_WKS 11
#define DNS_TYPE_PTR 12
#define DNS_TYPE_HINFO 13
#define DNS_TYPE_MX 15
#define DNS_TYPE_AAAA 28 // ipv6
#define DNS_TYPE_AXFR 252
#define DNS_TYPE_ANY 255
#define DNS_CLASS_IN 1
#define DNS_NAME_MAXLEN 256
// sizeof(dnshdr_t) = 12
typedef struct dnshdr_s {
uint16_t transaction_id;
// flags
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t rd:1;
uint8_t tc:1;
uint8_t aa:1;
uint8_t opcode:4;
uint8_t qr:1;
uint8_t rcode:4;
uint8_t cd:1;
uint8_t ad:1;
uint8_t res:1;
uint8_t ra:1;
#elif BYTE_ORDER == BIG_ENDIAN
uint8_t qr:1; // DNS_QUERY or DNS_RESPONSE
uint8_t opcode:4;
uint8_t aa:1; // authoritative
uint8_t tc:1; // truncated
uint8_t rd:1; // recursion desired
uint8_t ra:1; // recursion available
uint8_t res:1; // reserved
uint8_t ad:1; // authenticated data
uint8_t cd:1; // checking disable
uint8_t rcode:4;
#else
#error "BYTE_ORDER undefined!"
#endif
uint16_t nquestion;
uint16_t nanswer;
uint16_t nauthority;
uint16_t naddtional;
} dnshdr_t;
typedef struct dns_rr_s {
char name[DNS_NAME_MAXLEN]; // original domain, such as www.example.com
uint16_t rtype;
uint16_t rclass;
uint32_t ttl;
uint16_t datalen;
char* data;
} dns_rr_t;
typedef struct dns_s {
dnshdr_t hdr;
dns_rr_t* questions;
dns_rr_t* answers;
dns_rr_t* authorities;
dns_rr_t* addtionals;
} dns_t;
BEGIN_EXTERN_C
// www.example.com => 3www7example3com
HV_EXPORT int dns_name_encode(const char* domain, char* buf);
// 3www7example3com => www.example.com
HV_EXPORT int dns_name_decode(const char* buf, char* domain);
HV_EXPORT int dns_rr_pack(dns_rr_t* rr, char* buf, int len);
HV_EXPORT int dns_rr_unpack(char* buf, int len, dns_rr_t* rr, int is_question);
HV_EXPORT int dns_pack(dns_t* dns, char* buf, int len);
HV_EXPORT int dns_unpack(char* buf, int len, dns_t* dns);
// NOTE: free dns->rrs
HV_EXPORT void dns_free(dns_t* dns);
// dns_pack -> sendto -> recvfrom -> dns_unpack
HV_EXPORT int dns_query(dns_t* query, dns_t* response, const char* nameserver DEFAULT("127.0.1.1"));
// domain -> dns_t query; -> dns_query -> dns_t response; -> addrs
HV_EXPORT int nslookup(const char* domain, uint32_t* addrs, int naddr, const char* nameserver DEFAULT("127.0.1.1"));
END_EXTERN_C
#endif // HV_DNS_H_

View File

@ -1,96 +0,0 @@
#ifndef HV_FTP_H_
#define HV_FTP_H_
#include "hexport.h"
#define FTP_COMMAND_PORT 21
#define FTP_DATA_PORT 20
// ftp_command
// X(name)
#define FTP_COMMAND_MAP(X) \
X(HELP) \
X(USER) \
X(PASS) \
X(PWD) \
X(CWD) \
X(CDUP) \
X(MKD) \
X(RMD) \
X(STAT) \
X(SIZE) \
X(DELE) \
X(RNFR) \
X(RNTO) \
X(PORT) \
X(PASV) \
X(LIST) \
X(NLST) \
X(APPE) \
X(RETR) \
X(STOR) \
X(QUIT) \
enum ftp_command {
#define X(name) FTP_##name,
FTP_COMMAND_MAP(X)
#undef X
};
// ftp_status
// XXX(code, name, string)
#define FTP_STATUS_MAP(XXX) \
XXX(220, READY, Ready) \
XXX(221, BYE, Bye) \
XXX(226, TRANSFER_COMPLETE, Transfer complete) \
XXX(227, PASV, Entering Passive Mode) \
XXX(331, PASS, Password required) \
XXX(230, LOGIN_OK, Login OK) \
XXX(250, OK, OK) \
XXX(500, BAD_SYNTAX, Bad syntax) \
XXX(530, NOT_LOGIN, Not login) \
enum ftp_status {
#define XXX(code, name, string) FTP_STATUS_##name = code,
FTP_STATUS_MAP(XXX)
#undef XXX
};
// more friendly macros
#define FTP_MKDIR FTP_MKD
#define FTP_RMDIR FTP_RMD
#define FTP_APPEND FTP_APPE
#define FTP_REMOVE FTP_DELE
#define FTP_DOWNLOAD FTP_RETR
#define FTP_UPLOAD FTP_STOR
#define FTP_RECV_BUFSIZE 8192
typedef struct ftp_handle_s {
int sockfd;
char recvbuf[FTP_RECV_BUFSIZE];
void* userdata;
} ftp_handle_t;
BEGIN_EXTERN_C
HV_EXPORT const char* ftp_command_str(enum ftp_command cmd);
HV_EXPORT const char* ftp_status_str(enum ftp_status status);
HV_EXPORT int ftp_connect(ftp_handle_t* hftp, const char* host, int port);
HV_EXPORT int ftp_login(ftp_handle_t* hftp, const char* username, const char* password);
HV_EXPORT int ftp_quit(ftp_handle_t* hftp);
HV_EXPORT int ftp_exec(ftp_handle_t* hftp, const char* cmd, const char* param);
// local => remote
HV_EXPORT int ftp_upload(ftp_handle_t* hftp, const char* local_filepath, const char* remote_filepath);
// remote => local
HV_EXPORT int ftp_download(ftp_handle_t* hftp, const char* remote_filepath, const char* local_filepath);
typedef int (*ftp_download_cb)(ftp_handle_t* hftp, char* buf, int len);
HV_EXPORT int ftp_download_with_cb(ftp_handle_t* hftp, const char* filepath, ftp_download_cb cb);
END_EXTERN_C
#endif // HV_FTP_H_

View File

@ -82,6 +82,7 @@ HV_EXPORT char* hv_strncat(char* dest, const char* src, size_t n);
#endif #endif
HV_EXPORT char* hv_strnchr(const char* s, char c, size_t n); HV_EXPORT char* hv_strnchr(const char* s, char c, size_t n);
HV_EXPORT char* hv_strnrchr(const char* s, char c, size_t n);
#define hv_strrchr_dot(str) strrchr(str, '.') #define hv_strrchr_dot(str) strrchr(str, '.')
HV_EXPORT char* hv_strrchr_dir(const char* filepath); HV_EXPORT char* hv_strrchr_dir(const char* filepath);

View File

@ -10,7 +10,7 @@
#endif #endif
#ifndef HAVE_STDATOMIC_H #ifndef HAVE_STDATOMIC_H
#define HAVE_STDATOMIC_H 1 #define HAVE_STDATOMIC_H 0
#endif #endif
#ifndef HAVE_SYS_TYPES_H #ifndef HAVE_SYS_TYPES_H
@ -22,7 +22,7 @@
#endif #endif
#ifndef HAVE_SYS_TIME_H #ifndef HAVE_SYS_TIME_H
#define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TIME_H 0
#endif #endif
#ifndef HAVE_FCNTL_H #ifndef HAVE_FCNTL_H
@ -30,11 +30,11 @@
#endif #endif
#ifndef HAVE_PTHREAD_H #ifndef HAVE_PTHREAD_H
#define HAVE_PTHREAD_H 1 #define HAVE_PTHREAD_H 0
#endif #endif
#ifndef HAVE_ENDIAN_H #ifndef HAVE_ENDIAN_H
#define HAVE_ENDIAN_H 1 #define HAVE_ENDIAN_H 0
#endif #endif
#ifndef HAVE_SYS_ENDIAN_H #ifndef HAVE_SYS_ENDIAN_H
@ -54,46 +54,49 @@
#endif #endif
#ifndef HAVE_CLOCK_GETTIME #ifndef HAVE_CLOCK_GETTIME
#define HAVE_CLOCK_GETTIME 1 #define HAVE_CLOCK_GETTIME 0
#endif #endif
#ifndef HAVE_GETTIMEOFDAY #ifndef HAVE_GETTIMEOFDAY
#define HAVE_GETTIMEOFDAY 1 #define HAVE_GETTIMEOFDAY 0
#endif #endif
#ifndef HAVE_PTHREAD_SPIN_LOCK #ifndef HAVE_PTHREAD_SPIN_LOCK
#define HAVE_PTHREAD_SPIN_LOCK 1 #define HAVE_PTHREAD_SPIN_LOCK 0
#endif #endif
#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
#define HAVE_PTHREAD_MUTEX_TIMEDLOCK 1 #define HAVE_PTHREAD_MUTEX_TIMEDLOCK 0
#endif #endif
#ifndef HAVE_SEM_TIMEDWAIT #ifndef HAVE_SEM_TIMEDWAIT
#define HAVE_SEM_TIMEDWAIT 1 #define HAVE_SEM_TIMEDWAIT 0
#endif #endif
#ifndef HAVE_PIPE #ifndef HAVE_PIPE
#define HAVE_PIPE 1 #define HAVE_PIPE 0
#endif #endif
#ifndef HAVE_SOCKETPAIR #ifndef HAVE_SOCKETPAIR
#define HAVE_SOCKETPAIR 1 #define HAVE_SOCKETPAIR 0
#endif #endif
#ifndef HAVE_EVENTFD #ifndef HAVE_EVENTFD
#define HAVE_EVENTFD 1 #define HAVE_EVENTFD 0
#endif #endif
#ifndef HAVE_SETPROCTITLE #ifndef HAVE_SETPROCTITLE
#define HAVE_SETPROCTITLE 0 #define HAVE_SETPROCTITLE 0
#endif #endif
/* #undef WITH_OPENSSL */ #define WITH_OPENSSL 1
/* #undef WITH_GNUTLS */ /* #undef WITH_GNUTLS */
/* #undef WITH_MBEDTLS */ /* #undef WITH_MBEDTLS */
/* #undef ENABLE_UDS */ /* #undef ENABLE_UDS */
/* #undef USE_MULTIMAP */ /* #undef USE_MULTIMAP */
#define WITH_WEPOLL 1
/* #undef WITH_KCP */ /* #undef WITH_KCP */
#endif // HV_CONFIG_H_ #endif // HV_CONFIG_H_

View File

@ -37,32 +37,6 @@
#define HV_UNUSED #define HV_UNUSED
#endif #endif
// @param[IN | OUT | INOUT]
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef INOUT
#define INOUT
#endif
// @field[OPTIONAL | REQUIRED | REPEATED]
#ifndef OPTIONAL
#define OPTIONAL
#endif
#ifndef REQUIRED
#define REQUIRED
#endif
#ifndef REPEATED
#define REPEATED
#endif
#ifdef __cplusplus #ifdef __cplusplus
#ifndef EXTERN_C #ifndef EXTERN_C

View File

@ -11,16 +11,18 @@ typedef struct hevent_s hevent_t;
// NOTE: The following structures are subclasses of hevent_t, // NOTE: The following structures are subclasses of hevent_t,
// inheriting hevent_t data members and function members. // inheriting hevent_t data members and function members.
typedef struct hio_s hio_t;
typedef struct hidle_s hidle_t; typedef struct hidle_s hidle_t;
typedef struct htimer_s htimer_t; typedef struct htimer_s htimer_t;
typedef struct htimeout_s htimeout_t; typedef struct htimeout_s htimeout_t;
typedef struct hperiod_s hperiod_t; typedef struct hperiod_s hperiod_t;
typedef struct hio_s hio_t; typedef struct hevent_s hsignal_t;
typedef void (*hevent_cb) (hevent_t* ev); typedef void (*hevent_cb) (hevent_t* ev);
typedef void (*hio_cb) (hio_t* io);
typedef void (*hidle_cb) (hidle_t* idle); typedef void (*hidle_cb) (hidle_t* idle);
typedef void (*htimer_cb) (htimer_t* timer); typedef void (*htimer_cb) (htimer_t* timer);
typedef void (*hio_cb) (hio_t* io); typedef void (*hsignal_cb) (hsignal_t* sig);
typedef void (*haccept_cb) (hio_t* io); typedef void (*haccept_cb) (hio_t* io);
typedef void (*hconnect_cb) (hio_t* io); typedef void (*hconnect_cb) (hio_t* io);
@ -31,7 +33,8 @@ typedef void (*hclose_cb) (hio_t* io);
typedef enum { typedef enum {
HLOOP_STATUS_STOP, HLOOP_STATUS_STOP,
HLOOP_STATUS_RUNNING, HLOOP_STATUS_RUNNING,
HLOOP_STATUS_PAUSE HLOOP_STATUS_PAUSE,
HLOOP_STATUS_DESTROY
} hloop_status_e; } hloop_status_e;
typedef enum { typedef enum {
@ -41,6 +44,7 @@ typedef enum {
HEVENT_TYPE_PERIOD = 0x00000020, HEVENT_TYPE_PERIOD = 0x00000020,
HEVENT_TYPE_TIMER = HEVENT_TYPE_TIMEOUT|HEVENT_TYPE_PERIOD, HEVENT_TYPE_TIMER = HEVENT_TYPE_TIMEOUT|HEVENT_TYPE_PERIOD,
HEVENT_TYPE_IDLE = 0x00000100, HEVENT_TYPE_IDLE = 0x00000100,
HEVENT_TYPE_SIGNAL = 0x00000200,
HEVENT_TYPE_CUSTOM = 0x00000400, // 1024 HEVENT_TYPE_CUSTOM = 0x00000400, // 1024
} hevent_type_e; } hevent_type_e;
@ -93,6 +97,7 @@ typedef enum {
HIO_TYPE_STDIO = 0x0000000F, HIO_TYPE_STDIO = 0x0000000F,
HIO_TYPE_FILE = 0x00000010, HIO_TYPE_FILE = 0x00000010,
HIO_TYPE_PIPE = 0x00000020,
HIO_TYPE_IP = 0x00000100, HIO_TYPE_IP = 0x00000100,
HIO_TYPE_SOCK_RAW = 0x00000F00, HIO_TYPE_SOCK_RAW = 0x00000F00,
@ -182,6 +187,10 @@ HV_EXPORT void* hloop_userdata(hloop_t* loop);
// NOTE: hloop_post_event is thread-safe, used to post event from other thread to loop thread. // NOTE: hloop_post_event is thread-safe, used to post event from other thread to loop thread.
HV_EXPORT void hloop_post_event(hloop_t* loop, hevent_t* ev); HV_EXPORT void hloop_post_event(hloop_t* loop, hevent_t* ev);
// signal
HV_EXPORT hsignal_t* hsignal_add(hloop_t* loop, hsignal_cb cb, int signo);
HV_EXPORT void hsignal_del(hsignal_t* sig);
// idle // idle
HV_EXPORT hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE)); HV_EXPORT hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
HV_EXPORT void hidle_del(hidle_t* idle); HV_EXPORT void hidle_del(hidle_t* idle);
@ -435,6 +444,10 @@ HV_EXPORT hio_t* hloop_create_udp_server (hloop_t* loop, const char* host, int p
// @see examples/nc.c // @see examples/nc.c
HV_EXPORT hio_t* hloop_create_udp_client (hloop_t* loop, const char* host, int port); HV_EXPORT hio_t* hloop_create_udp_client (hloop_t* loop, const char* host, int port);
//-----------------pipe---------------------------------------------
// @see examples/pipe_test.c
HV_EXPORT int hio_create_pipe(hloop_t* loop, hio_t* pipeio[2]);
//-----------------upstream--------------------------------------------- //-----------------upstream---------------------------------------------
// hio_read(io) // hio_read(io)
// hio_read(io->upstream_io) // hio_read(io->upstream_io)

View File

@ -65,6 +65,7 @@ typedef struct option_s {
char short_opt; char short_opt;
const char* long_opt; const char* long_opt;
int arg_type; int arg_type;
const char* description;
} option_t; } option_t;
HV_EXPORT int main_ctx_init(int argc, char** argv); HV_EXPORT int main_ctx_init(int argc, char** argv);
@ -76,7 +77,8 @@ HV_EXPORT void main_ctx_free(void);
// watch -n10 ls // watch -n10 ls
HV_EXPORT int parse_opt(int argc, char** argv, const char* opt); HV_EXPORT int parse_opt(int argc, char** argv, const char* opt);
// gcc -g -Wall -O3 -std=cpp main.c // gcc -g -Wall -O3 -std=cpp main.c
HV_EXPORT int parse_opt_long(int argc, char** argv, const option_t* long_options, int size); HV_EXPORT int parse_opt_long(int argc, char** argv, const option_t* long_options, int opt_size);
HV_EXPORT int dump_opt_long(const option_t* long_options, int opt_size, char* out_str, int out_size);
HV_EXPORT const char* get_arg(const char* key); HV_EXPORT const char* get_arg(const char* key);
HV_EXPORT const char* get_env(const char* key); HV_EXPORT const char* get_env(const char* key);

View File

@ -41,6 +41,7 @@
#undef OS_UNIX #undef OS_UNIX
#define OS_WIN #define OS_WIN
#else #else
#undef OS_WIN
#define OS_UNIX #define OS_UNIX
#endif #endif
@ -142,6 +143,12 @@
// headers // headers
#ifdef OS_WIN #ifdef OS_WIN
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#elif _WIN32_WINNT < 0x0600
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif

View File

@ -82,9 +82,11 @@ HV_INLINE int nonblocking(int s) {
return fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); return fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
} }
#ifndef closesocket
HV_INLINE int closesocket(int sockfd) { HV_INLINE int closesocket(int sockfd) {
return close(sockfd); return close(sockfd);
} }
#endif
#endif #endif

View File

@ -75,6 +75,18 @@ HV_EXPORT std::string trim_pairs(const std::string& str, const char* pairs = PAI
HV_EXPORT std::string replace(const std::string& str, const std::string& find, const std::string& rep); HV_EXPORT std::string replace(const std::string& str, const std::string& find, const std::string& rep);
HV_EXPORT std::string replaceAll(const std::string& str, const std::string& find, const std::string& rep); HV_EXPORT std::string replaceAll(const std::string& str, const std::string& find, const std::string& rep);
struct HV_EXPORT NetAddr {
std::string ip;
int port;
NetAddr() : port(0) {}
NetAddr(const std::string& _ip, int _port) : ip(_ip), port(_port) {}
NetAddr(const std::string& ipport) { from_string(ipport); }
void from_string(const std::string& ipport);
std::string to_string();
};
} // end namespace hv } // end namespace hv
#endif // HV_STRING_H_ #endif // HV_STRING_H_

View File

@ -8,7 +8,7 @@ BEGIN_EXTERN_C
#define HV_VERSION_MAJOR 1 #define HV_VERSION_MAJOR 1
#define HV_VERSION_MINOR 3 #define HV_VERSION_MINOR 3
#define HV_VERSION_PATCH 2 #define HV_VERSION_PATCH 3
#define HV_VERSION_STRING STRINGIFY(HV_VERSION_MAJOR) "." \ #define HV_VERSION_STRING STRINGIFY(HV_VERSION_MAJOR) "." \
STRINGIFY(HV_VERSION_MINOR) "." \ STRINGIFY(HV_VERSION_MINOR) "." \

View File

@ -1,15 +0,0 @@
#ifndef HV_ICMP_H_
#define HV_ICMP_H_
#include "hexport.h"
BEGIN_EXTERN_C
// @param cnt: ping count
// @return: ok count
// @note: printd $CC -DPRINT_DEBUG
HV_EXPORT int ping(const char* host, int cnt DEFAULT(4));
END_EXTERN_C
#endif // HV_ICMP_H_

View File

@ -29,6 +29,7 @@ struct mqtt_client_s {
unsigned char alloced_ssl_ctx: 1; // intern unsigned char alloced_ssl_ctx: 1; // intern
unsigned char connected : 1; unsigned char connected : 1;
unsigned short keepalive; unsigned short keepalive;
int ping_cnt;
char client_id[64]; char client_id[64];
// will // will
mqtt_message_t* will; mqtt_message_t* will;
@ -47,7 +48,7 @@ struct mqtt_client_s {
// privdata // privdata
hloop_t* loop; hloop_t* loop;
hio_t* io; hio_t* io;
htimer_t* reconn_timer; htimer_t* timer;
// SSL/TLS // SSL/TLS
hssl_ctx_t ssl_ctx; hssl_ctx_t ssl_ctx;
// thread-safe // thread-safe
@ -101,6 +102,7 @@ HV_EXPORT int mqtt_client_reconnect(mqtt_client_t* cli);
// on_connect -> mqtt_client_login -> // on_connect -> mqtt_client_login ->
// on_connack // on_connack
HV_EXPORT void mqtt_client_set_connect_timeout(mqtt_client_t* cli, int ms); HV_EXPORT void mqtt_client_set_connect_timeout(mqtt_client_t* cli, int ms);
HV_EXPORT void mqtt_client_set_host(mqtt_client_t* cli, const char* host, int port, int ssl);
HV_EXPORT int mqtt_client_connect(mqtt_client_t* cli, HV_EXPORT int mqtt_client_connect(mqtt_client_t* cli,
const char* host, const char* host,
int port DEFAULT(DEFAULT_MQTT_PORT), int port DEFAULT(DEFAULT_MQTT_PORT),
@ -125,4 +127,214 @@ HV_EXPORT int mqtt_client_unsubscribe(mqtt_client_t* cli,
END_EXTERN_C END_EXTERN_C
#ifdef __cplusplus
#include <functional>
#include <map>
#include <mutex>
#include <string>
namespace hv {
// @usage examples/mqtt/mqtt_client_test.cpp
class MqttClient {
public:
mqtt_client_t* client;
// callbacks
typedef std::function<void(MqttClient*)> MqttCallback;
typedef std::function<void(MqttClient*, mqtt_message_t*)> MqttMessageCallback;
MqttCallback onConnect;
MqttCallback onClose;
MqttMessageCallback onMessage;
MqttClient(hloop_t* loop = NULL) {
client = mqtt_client_new(loop);
}
~MqttClient() {
if (client) {
mqtt_client_free(client);
client = NULL;
}
}
void run() {
mqtt_client_set_callback(client, on_mqtt);
mqtt_client_set_userdata(client, this);
mqtt_client_run(client);
}
void stop() {
mqtt_client_stop(client);
}
void setID(const char* id) {
mqtt_client_set_id(client, id);
}
void setWill(mqtt_message_t* will) {
mqtt_client_set_will(client, will);
}
void setAuth(const char* username, const char* password) {
mqtt_client_set_auth(client, username, password);
}
void setPingInterval(int sec) {
client->keepalive = sec;
}
int lastError() {
return mqtt_client_get_last_error(client);
}
// SSL/TLS
int setSslCtx(hssl_ctx_t ssl_ctx) {
return mqtt_client_set_ssl_ctx(client, ssl_ctx);
}
int newSslCtx(hssl_ctx_opt_t* opt) {
return mqtt_client_new_ssl_ctx(client, opt);
}
void setReconnect(reconn_setting_t* reconn) {
mqtt_client_set_reconnect(client, reconn);
}
void setConnectTimeout(int ms) {
mqtt_client_set_connect_timeout(client, ms);
}
void setHost(const char* host, int port = DEFAULT_MQTT_PORT, int ssl = 0) {
mqtt_client_set_host(client, host, port, ssl);
}
int connect(const char* host, int port = DEFAULT_MQTT_PORT, int ssl = 0) {
return mqtt_client_connect(client, host, port, ssl);
}
int reconnect() {
return mqtt_client_reconnect(client);
}
int disconnect() {
return mqtt_client_disconnect(client);
}
bool isConnected() {
return mqtt_client_is_connected(client);
}
int publish(mqtt_message_t* msg, MqttCallback ack_cb = NULL) {
int mid = mqtt_client_publish(client, msg);
if (msg->qos > 0 && mid >= 0 && ack_cb) {
setAckCallback(mid, ack_cb);
}
return mid;
}
int publish(const std::string& topic, const std::string& payload, int qos = 0, int retain = 0, MqttCallback ack_cb = NULL) {
mqtt_message_t msg;
memset(&msg, 0, sizeof(msg));
msg.topic_len = topic.size();
msg.topic = topic.c_str();
msg.payload_len = payload.size();
msg.payload = payload.c_str();
msg.qos = qos;
msg.retain = retain;
return publish(&msg, ack_cb);
}
int subscribe(const char* topic, int qos = 0, MqttCallback ack_cb = NULL) {
int mid = mqtt_client_subscribe(client, topic, qos);
if (qos > 0 && mid >= 0 && ack_cb) {
setAckCallback(mid, ack_cb);
}
return mid;
}
int unsubscribe(const char* topic, MqttCallback ack_cb = NULL) {
int mid = mqtt_client_unsubscribe(client, topic);
if (mid >= 0 && ack_cb) {
setAckCallback(mid, ack_cb);
}
return mid;
}
protected:
void setAckCallback(int mid, MqttCallback cb) {
ack_cbs_mutex.lock();
ack_cbs[mid] = std::move(cb);
ack_cbs_mutex.unlock();
}
void invokeAckCallback(int mid) {
MqttCallback ack_cb = NULL;
ack_cbs_mutex.lock();
auto iter = ack_cbs.find(mid);
if (iter != ack_cbs.end()) {
ack_cb = std::move(iter->second);
ack_cbs.erase(iter);
}
ack_cbs_mutex.unlock();
if (ack_cb) ack_cb(this);
}
static void on_mqtt(mqtt_client_t* cli, int type) {
MqttClient* client = (MqttClient*)mqtt_client_get_userdata(cli);
// printf("on_mqtt type=%d\n", type);
switch(type) {
case MQTT_TYPE_CONNECT:
// printf("mqtt connected!\n");
break;
case MQTT_TYPE_DISCONNECT:
// printf("mqtt disconnected!\n");
if (client->onClose) {
client->onClose(client);
}
break;
case MQTT_TYPE_CONNACK:
// printf("mqtt connack!\n");
if (client->onConnect) {
client->onConnect(client);
}
break;
case MQTT_TYPE_PUBLISH:
if (client->onMessage) {
client->onMessage(client, &cli->message);
}
break;
case MQTT_TYPE_PUBACK: /* qos = 1 */
// printf("mqtt puback mid=%d\n", cli->mid);
client->invokeAckCallback(cli->mid);
break;
case MQTT_TYPE_PUBREC: /* qos = 2 */
// printf("mqtt pubrec mid=%d\n", cli->mid);
// wait MQTT_TYPE_PUBCOMP
break;
case MQTT_TYPE_PUBCOMP: /* qos = 2 */
// printf("mqtt pubcomp mid=%d\n", cli->mid);
client->invokeAckCallback(cli->mid);
break;
case MQTT_TYPE_SUBACK:
// printf("mqtt suback mid=%d\n", cli->mid);
client->invokeAckCallback(cli->mid);
break;
case MQTT_TYPE_UNSUBACK:
// printf("mqtt unsuback mid=%d\n", cli->mid);
client->invokeAckCallback(cli->mid);
break;
default:
break;
}
}
private:
// mid => ack callback
std::map<int, MqttCallback> ack_cbs;
std::mutex ack_cbs_mutex;
};
}
#endif
#endif // HV_MQTT_CLIENT_H_ #endif // HV_MQTT_CLIENT_H_

Some files were not shown because too many files have changed in this diff Show More