Merge branch 'master' of github.com:yandex/ClickHouse

This commit is contained in:
Alexey Milovidov 2016-10-12 03:42:50 +03:00
commit 422dd9e6ef
77 changed files with 504 additions and 176608 deletions

View File

@ -78,7 +78,7 @@ option(ENABLE_NETSSL "Enable NetSSL" ON)
option(ENABLE_NETSSL_WIN "Enable NetSSL Windows" OFF)
option(ENABLE_CRYPTO "Enable Crypto" ON)
option(ENABLE_DATA "Enable Data" ON)
option(ENABLE_DATA_SQLITE "Enable Data SQlite" ON)
option(ENABLE_DATA_SQLITE "Enable Data SQlite" OFF)
option(ENABLE_DATA_MYSQL "Enable Data MySQL" ON)
option(ENABLE_DATA_ODBC "Enable Data ODBC" ON)
option(ENABLE_SEVENZIP "Enable SevenZip" OFF)

View File

@ -28,11 +28,6 @@ set_target_properties( "${LIBNAME}"
target_link_libraries( "${LIBNAME}" PocoFoundation)
if(ENABLE_DATA_SQLITE)
# SQlite3 is built in any case
add_subdirectory( SQLite )
endif(ENABLE_DATA_SQLITE)
if(ENABLE_DATA_MYSQL)
find_package(MySQL)
if(MYSQL_FOUND)

View File

@ -1,50 +0,0 @@
set(LIBNAME "PocoDataSQLite")
set(POCO_LIBNAME "${LIBNAME}")
# Sources
file(GLOB SRCS_G "src/*.cpp")
POCO_SOURCES_AUTO( SQLITE_SRCS ${SRCS_G})
# Headers
file(GLOB_RECURSE HDRS_G "include/*.h" )
POCO_HEADERS_AUTO( SQLITE_SRCS ${HDRS_G})
if (POCO_UNBUNDLED)
find_package(SQLite3)
set(DATASQLITELIBS ${SQLITE3_LIBRARIES})
include_directories("${SQLITE3_INCLUDE_DIRS}")
else()
# sqlite3
POCO_SOURCES( SQLITE_SRCS sqlite3
src/sqlite3.c
)
POCO_HEADERS( SQLITE_SRCS sqlite3
src/sqlite3.h
)
set(DATASQLITELIBS "")
endif()
if(WINCE)
add_definitions(-DSQLITE_MSVC_LOCALTIME_API)
endif(WINCE)
add_definitions(-DSQLITE_THREADSAFE=1 -DSQLITE_DISABLE_LFS -DSQLITE_OMIT_UTF16 -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_COMPLETE -DSQLITE_OMIT_TCL_VARIABLE -DSQLITE_OMIT_DEPRECATED)
include_directories(src)
add_library( "${LIBNAME}" ${LIB_MODE} ${SQLITE_SRCS} )
set_target_properties( "${LIBNAME}"
PROPERTIES
VERSION ${SHARED_LIBRARY_VERSION} SOVERSION ${SHARED_LIBRARY_VERSION}
OUTPUT_NAME ${POCO_LIBNAME}
DEFINE_SYMBOL SQLite_EXPORTS
)
target_link_libraries( "${LIBNAME}" PocoFoundation PocoData ${DATASQLITELIBS} )
if (ENABLE_TESTS)
add_subdirectory(testsuite)
endif ()

View File

@ -1,4 +0,0 @@
include(CMakeFindDependencyMacro)
find_dependency(PocoFoundation)
find_dependency(PocoData)
include("${CMAKE_CURRENT_LIST_DIR}/PocoDataSQLiteTargets.cmake")

View File

@ -1,222 +0,0 @@
//
// Binder.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/Binder.h#4 $
//
// Library: SQLite
// Package: SQLite
// Module: Binder
//
// Definition of the Binder class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_SQLite_Binder_INCLUDED
#define Data_SQLite_Binder_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/AbstractBinder.h"
#include "Poco/Data/LOB.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "sqlite3.h"
namespace Poco {
namespace Data {
namespace SQLite {
class SQLite_API Binder: public Poco::Data::AbstractBinder
/// Binds placeholders in the sql query to the provided values. Performs data types mapping.
{
public:
Binder(sqlite3_stmt* pStmt);
/// Creates the Binder.
~Binder();
/// Destroys the Binder.
void bind(std::size_t pos, const Poco::Int8 &val, Direction dir);
/// Binds an Int8.
void bind(std::size_t pos, const Poco::UInt8 &val, Direction dir);
/// Binds an UInt8.
void bind(std::size_t pos, const Poco::Int16 &val, Direction dir);
/// Binds an Int16.
void bind(std::size_t pos, const Poco::UInt16 &val, Direction dir);
/// Binds an UInt16.
void bind(std::size_t pos, const Poco::Int32 &val, Direction dir);
/// Binds an Int32.
void bind(std::size_t pos, const Poco::UInt32 &val, Direction dir);
/// Binds an UInt32.
void bind(std::size_t pos, const Poco::Int64 &val, Direction dir);
/// Binds an Int64.
void bind(std::size_t pos, const Poco::UInt64 &val, Direction dir);
/// Binds an UInt64.
#ifndef POCO_LONG_IS_64_BIT
void bind(std::size_t pos, const long &val, Direction dir);
/// Binds a long
void bind(std::size_t pos, const unsigned long &val, Direction dir);
/// Binds an unsigned long
#endif
void bind(std::size_t pos, const bool &val, Direction dir);
/// Binds a boolean.
void bind(std::size_t pos, const float &val, Direction dir);
/// Binds a float.
void bind(std::size_t pos, const double &val, Direction dir);
/// Binds a double.
void bind(std::size_t pos, const char &val, Direction dir);
/// Binds a single character.
void bind(std::size_t pos, const char* const &pVal, Direction dir);
/// Binds a const char ptr.
void bind(std::size_t pos, const std::string& val, Direction dir);
/// Binds a string.
void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir);
/// Binds a BLOB.
void bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir);
/// Binds a CLOB.
void bind(std::size_t pos, const Date& val, Direction dir);
/// Binds a Date.
void bind(std::size_t pos, const Time& val, Direction dir);
/// Binds a Time.
void bind(std::size_t pos, const DateTime& val, Direction dir);
/// Binds a DateTime.
void bind(std::size_t pos, const NullData& val, Direction dir);
/// Binds a null.
private:
void checkReturn(int rc);
/// Checks the SQLite return code and throws an appropriate exception
/// if error has occurred.
template <typename T>
void bindLOB(std::size_t pos, const Poco::Data::LOB<T>& val, Direction dir)
{
// convert a blob to a an unsigned char* array
const T* pData = reinterpret_cast<const T*>(val.rawContent());
int valSize = static_cast<int>(val.size());
int rc = sqlite3_bind_blob(_pStmt, static_cast<int>(pos), pData, valSize, SQLITE_STATIC); // no deep copy, do not free memory
checkReturn(rc);
}
sqlite3_stmt* _pStmt;
};
//
// inlines
//
inline void Binder::bind(std::size_t pos, const Poco::Int8 &val, Direction dir)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const Poco::UInt8 &val, Direction dir)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const Poco::Int16 &val, Direction dir)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const Poco::UInt16 &val, Direction dir)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const Poco::UInt32 &val, Direction dir)
{
Poco::Int32 tmp = static_cast<Poco::Int32>(val);
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const Poco::UInt64 &val, Direction dir)
{
Poco::Int64 tmp = static_cast<Poco::Int64>(val);
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const bool &val, Direction dir)
{
Poco::Int32 tmp = (val ? 1 : 0);
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const float &val, Direction dir)
{
double tmp = val;
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const char &val, Direction dir)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
}
inline void Binder::bind(std::size_t pos, const char* const &pVal, Direction dir)
{
std::string val(pVal);
bind(pos, val, dir);
}
inline void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
{
bindLOB<Poco::Data::BLOB::ValueType>(pos, val, dir);
}
inline void Binder::bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir)
{
bindLOB<Poco::Data::CLOB::ValueType>(pos, val, dir);
}
} } } // namespace Poco::Data::SQLite
#endif // Data_SQLite_Binder_INCLUDED

View File

@ -1,145 +0,0 @@
//
// Connector.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/Connector.h#2 $
//
// Library: SQLite
// Package: SQLite
// Module: Connector
//
// Definition of the Connector class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_SQLite_Connector_INCLUDED
#define Data_SQLite_Connector_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/Connector.h"
// Note: to avoid static (de)initialization problems,
// during connector automatic (un)registration, it is
// best to have this as a macro.
#define POCO_DATA_SQLITE_CONNECTOR_NAME "sqlite"
namespace Poco {
namespace Data {
namespace SQLite {
class SQLite_API Connector: public Poco::Data::Connector
/// Connector instantiates SqLite SessionImpl objects.
{
public:
static const std::string KEY;
/// Keyword for creating SQLite sessions ("SQLite").
Connector();
/// Creates the Connector.
~Connector();
/// Destroys the Connector.
const std::string& name() const;
/// Returns the name associated with this connector.
Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString,
std::size_t timeout = Poco::Data::SessionImpl::LOGIN_TIMEOUT_DEFAULT);
/// Creates a SQLite SessionImpl object and initializes it with the given connectionString.
static void registerConnector();
/// Registers the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory.
static void unregisterConnector();
/// Unregisters the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory.
static void enableSharedCache(bool flag = true);
/// Enables or disables SQlite shared cache mode
/// (see http://www.sqlite.org/sharedcache.html for a discussion).
static void enableSoftHeapLimit(int limit);
/// Sets a soft upper limit to the amount of memory allocated
/// by SQLite. For more information, please see the SQLite
/// sqlite_soft_heap_limit() function (http://www.sqlite.org/c3ref/soft_heap_limit.html).
};
///
/// inlines
///
inline const std::string& Connector::name() const
{
static const std::string n(POCO_DATA_SQLITE_CONNECTOR_NAME);
return n;
}
} } } // namespace Poco::Data::SQLite
//
// Automatic Connector registration
//
struct SQLite_API SQLiteConnectorRegistrator
/// Connector registering class.
/// A global instance of this class is instantiated
/// with sole purpose to automatically register the
/// SQLite connector with central Poco Data registry.
{
SQLiteConnectorRegistrator()
/// Calls Poco::Data::SQLite::registerConnector();
{
Poco::Data::SQLite::Connector::registerConnector();
}
~SQLiteConnectorRegistrator()
/// Calls Poco::Data::SQLite::unregisterConnector();
{
try
{
Poco::Data::SQLite::Connector::unregisterConnector();
}
catch (...)
{
poco_unexpected();
}
}
};
#if !defined(POCO_NO_AUTOMATIC_LIB_INIT)
#if defined(POCO_OS_FAMILY_WINDOWS) && !defined(__GNUC__)
extern "C" const struct SQLite_API SQLiteConnectorRegistrator pocoSQLiteConnectorRegistrator;
#if defined(SQLite_EXPORTS)
#if defined(_WIN64) || defined(_WIN32_WCE)
#define POCO_DATA_SQLITE_FORCE_SYMBOL(s) __pragma(comment (linker, "/export:"#s))
#elif defined(_WIN32)
#define POCO_DATA_SQLITE_FORCE_SYMBOL(s) __pragma(comment (linker, "/export:_"#s))
#endif
#else // !SQLite_EXPORTS
#if defined(_WIN64) || defined(_WIN32_WCE)
#define POCO_DATA_SQLITE_FORCE_SYMBOL(s) __pragma(comment (linker, "/include:"#s))
#elif defined(_WIN32)
#define POCO_DATA_SQLITE_FORCE_SYMBOL(s) __pragma(comment (linker, "/include:_"#s))
#endif
#endif // SQLite_EXPORTS
#else // !POCO_OS_FAMILY_WINDOWS
#define POCO_DATA_SQLITE_FORCE_SYMBOL(s) extern "C" const struct SQLiteConnectorRegistrator s;
#endif // POCO_OS_FAMILY_WINDOWS
POCO_DATA_SQLITE_FORCE_SYMBOL(pocoSQLiteConnectorRegistrator)
#endif // POCO_NO_AUTOMATIC_LIB_INIT
//
// End automatic Connector registration
//
#endif // Data_SQLite_Connector_INCLUDED

View File

@ -1,315 +0,0 @@
//
// Extractor.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/Extractor.h#4 $
//
// Library: SQLite
// Package: SQLite
// Module: Extractor
//
// Definition of the Extractor class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_SQLite_Extractor_INCLUDED
#define Data_SQLite_Extractor_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/AbstractExtractor.h"
#include "Poco/Data/MetaColumn.h"
#include "Poco/Data/DataException.h"
#include "Poco/Data/Constants.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "sqlite3.h"
#include <vector>
#include <utility>
namespace Poco {
namespace Data {
namespace SQLite {
class SQLite_API Extractor: public Poco::Data::AbstractExtractor
/// Extracts and converts data values form the result row returned by SQLite.
/// If NULL is received, the incoming val value is not changed and false is returned
{
public:
typedef std::vector<std::pair<bool, bool> > NullIndVec;
/// Type for null indicators container.
Extractor(sqlite3_stmt* pStmt);
/// Creates the Extractor.
~Extractor();
/// Destroys the Extractor.
bool extract(std::size_t pos, Poco::Int8& val);
/// Extracts an Int8.
bool extract(std::size_t pos, Poco::UInt8& val);
/// Extracts an UInt8.
bool extract(std::size_t pos, Poco::Int16& val);
/// Extracts an Int16.
bool extract(std::size_t pos, Poco::UInt16& val);
/// Extracts an UInt16.
bool extract(std::size_t pos, Poco::Int32& val);
/// Extracts an Int32.
bool extract(std::size_t pos, Poco::UInt32& val);
/// Extracts an UInt32.
bool extract(std::size_t pos, Poco::Int64& val);
/// Extracts an Int64.
bool extract(std::size_t pos, Poco::UInt64& val);
/// Extracts an UInt64.
#ifndef POCO_LONG_IS_64_BIT
bool extract(std::size_t pos, long& val);
/// Extracts a long.
bool extract(std::size_t pos, unsigned long& val);
/// Extracts an unsigned long.
#endif
bool extract(std::size_t pos, bool& val);
/// Extracts a boolean.
bool extract(std::size_t pos, float& val);
/// Extracts a float.
bool extract(std::size_t pos, double& val);
/// Extracts a double.
bool extract(std::size_t pos, char& val);
/// Extracts a single character.
bool extract(std::size_t pos, std::string& val);
/// Extracts a string.
bool extract(std::size_t pos, Poco::Data::BLOB& val);
/// Extracts a BLOB.
bool extract(std::size_t pos, Poco::Data::CLOB& val);
/// Extracts a CLOB.
bool extract(std::size_t pos, Poco::Data::Date& val);
/// Extracts a Date.
bool extract(std::size_t pos, Poco::Data::Time& val);
/// Extracts a Time.
bool extract(std::size_t pos, Poco::DateTime& val);
/// Extracts a DateTime.
bool extract(std::size_t pos, Poco::Any& val);
/// Extracts an Any.
bool extract(std::size_t pos, Poco::DynamicAny& val);
/// Extracts a DynamicAny.
bool isNull(std::size_t pos, std::size_t row = POCO_DATA_INVALID_ROW);
/// Returns true if the current row value at pos column is null.
/// Because of the loss of information about null-ness of the
/// underlying database values due to the nature of SQLite engine,
/// (once null value is converted to default value, SQLite API
/// treats it as non-null), a null indicator container member
/// variable is used to cache the indicators of the underlying nulls
/// thus rendering this function idempotent.
/// The container is a vector of [bool, bool] pairs.
/// The vector index corresponds to the column position, the first
/// bool value in the pair is true if the null indicator has
/// been set and the second bool value in the pair is true if
/// the column is actually null.
/// The row argument, needed for connectors with bulk capabilities,
/// is ignored in this implementation.
void reset();
/// Clears the cached nulls indicator vector.
private:
template <typename T>
bool extractImpl(std::size_t pos, T& val)
/// Utility function for extraction of Any and DynamicAny.
{
if (isNull(pos)) return false;
bool ret = false;
switch (Utility::getColumnType(_pStmt, pos))
{
case MetaColumn::FDT_BOOL:
{
bool i = false;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_INT8:
{
Poco::Int8 i = 0;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_UINT8:
{
Poco::UInt8 i = 0;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_INT16:
{
Poco::Int16 i = 0;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_UINT16:
{
Poco::UInt16 i = 0;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_INT32:
{
Poco::Int32 i = 0;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_UINT32:
{
Poco::UInt32 i = 0;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_INT64:
{
Poco::Int64 i = 0;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_UINT64:
{
Poco::UInt64 i = 0;
ret = extract(pos, i);
val = i;
break;
}
case MetaColumn::FDT_STRING:
{
std::string s;
ret = extract(pos, s);
val = s;
break;
}
case MetaColumn::FDT_DOUBLE:
{
double d(0.0);
ret = extract(pos, d);
val = d;
break;
}
case MetaColumn::FDT_FLOAT:
{
float f(0.0);
ret = extract(pos, f);
val = f;
break;
}
case MetaColumn::FDT_BLOB:
{
BLOB b;
ret = extract(pos, b);
val = b;
break;
}
case MetaColumn::FDT_DATE:
{
Date d;
ret = extract(pos, d);
val = d;
break;
}
case MetaColumn::FDT_TIME:
{
Time t;
ret = extract(pos, t);
val = t;
break;
}
case MetaColumn::FDT_TIMESTAMP:
{
DateTime dt;
ret = extract(pos, dt);
val = dt;
break;
}
default:
throw Poco::Data::UnknownTypeException("Unknown type during extraction");
}
return ret;
}
template <typename T>
bool extractLOB(std::size_t pos, Poco::Data::LOB<T>& val)
{
if (isNull(pos)) return false;
int size = sqlite3_column_bytes(_pStmt, (int) pos);
const T* pTmp = reinterpret_cast<const T*>(sqlite3_column_blob(_pStmt, (int) pos));
val = Poco::Data::LOB<T>(pTmp, size);
return true;
}
sqlite3_stmt* _pStmt;
NullIndVec _nulls;
};
///
/// inlines
///
inline void Extractor::reset()
{
_nulls.clear();
}
inline bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
{
return extractLOB<Poco::Data::BLOB::ValueType>(pos, val);
}
inline bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
{
return extractLOB<Poco::Data::CLOB::ValueType>(pos, val);
}
} } } // namespace Poco::Data::SQLite
#endif // Data_SQLite_Extractor_INCLUDED

View File

@ -1,197 +0,0 @@
//
// Notifier.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/Notifier.h#2 $
//
// Library: SQLite
// Package: SQLite
// Module: Notifier
//
// Definition of Notifier.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef SQLite_Notifier_INCLUDED
#define SQLite_Notifier_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/Session.h"
#include "Poco/Mutex.h"
#include "Poco/Types.h"
#include "Poco/Dynamic/Var.h"
#include "Poco/BasicEvent.h"
#include <map>
namespace Poco {
namespace Data {
namespace SQLite {
class SQLite_API Notifier
/// Notifier is a wrapper for SQLite callback calls. It supports event callbacks
/// for insert, update, delete, commit and rollback events. While (un)registering
/// callbacks is thread-safe, execution of the callbacks themselves are not;
/// it is the user's responsibility to ensure the thread-safey of the functions
/// they provide as callback target. Additionally, commit callbacks may prevent
/// database transactions from succeeding (see sqliteCommitCallbackFn documentation
/// for details).
///
/// There can be only one set of callbacks per session (i.e. registering a new
/// callback automatically unregisters the previous one). All callbacks are
/// registered and enabled at Notifier contruction time and can be disabled
/// at a later point time.
{
public:
typedef unsigned char EnabledEventType;
/// A type definition for events-enabled bitmap.
typedef Poco::BasicEvent<void> Event;
//
// Events
//
Event update;
Event insert;
Event erase;
Event commit;
Event rollback;
// Event types.
static const EnabledEventType SQLITE_NOTIFY_UPDATE = 1;
static const EnabledEventType SQLITE_NOTIFY_COMMIT = 2;
static const EnabledEventType SQLITE_NOTIFY_ROLLBACK = 4;
Notifier(const Session& session,
EnabledEventType enabled = SQLITE_NOTIFY_UPDATE | SQLITE_NOTIFY_COMMIT | SQLITE_NOTIFY_ROLLBACK);
/// Creates a Notifier and enables all callbacks.
Notifier(const Session& session,
const Any& value,
EnabledEventType enabled = SQLITE_NOTIFY_UPDATE | SQLITE_NOTIFY_COMMIT | SQLITE_NOTIFY_ROLLBACK);
/// Creates a Notifier, assigns the value to the internal storage and and enables all callbacks.
~Notifier();
/// Disables all callbacks and destroys the Notifier.
bool enableUpdate();
/// Enables update callbacks.
bool disableUpdate();
/// Disables update callbacks.
bool updateEnabled() const;
/// Returns true if update callbacks are enabled, false otherwise.
bool enableCommit();
/// Enables commit callbacks.
bool disableCommit();
/// Disables commit callbacks.
bool commitEnabled() const;
/// Returns true if update callbacks are enabled, false otherwise.
bool enableRollback();
/// Enables rollback callbacks.
bool disableRollback();
/// Disables rollback callbacks.
bool rollbackEnabled() const;
/// Returns true if rollback callbacks are enabled, false otherwise.
bool enableAll();
/// Enables all callbacks.
bool disableAll();
/// Disables all callbacks.
static void sqliteUpdateCallbackFn(void* pVal, int opCode, const char* pDB, const char* pTable, Poco::Int64 row);
/// Update callback event dispatcher. Determines the type of the event, updates the row number
/// and triggers the event.
static int sqliteCommitCallbackFn(void* pVal);
/// Commit callback event dispatcher. If an exception occurs, it is catched inside this function,
/// non-zero value is returned, which causes SQLite engine to turn commit into a rollback.
/// Therefore, callers should check for return value - if it is zero, callback completed succesfuly
/// and transaction was committed.
static void sqliteRollbackCallbackFn(void* pVal);
/// Rollback callback event dispatcher.
bool operator == (const Notifier& other) const;
/// Equality operator. Compares value, row and database handles and
/// returns true iff all are equal.
Poco::Int64 getRow() const;
/// Returns the row number.
void setRow(Poco::Int64 row);
/// Sets the row number.
const Poco::Dynamic::Var& getValue() const;
/// Returns the value.
template <typename T>
inline void setValue(const T& val)
/// Sets the value.
{
_value = val;
}
private:
Notifier();
Notifier(const Notifier&);
Notifier& operator=(const Notifier&);
const Session& _session;
Poco::Dynamic::Var _value;
Poco::Int64 _row;
EnabledEventType _enabledEvents;
Poco::Mutex _mutex;
};
//
// inlines
//
inline bool Notifier::operator == (const Notifier& other) const
{
return _value == other._value &&
_row == other._row &&
Utility::dbHandle(_session) == Utility::dbHandle(other._session);
}
inline Poco::Int64 Notifier::getRow() const
{
return _row;
}
inline void Notifier::setRow(Poco::Int64 row)
/// Sets the row number.
{
_row = row;
}
inline const Poco::Dynamic::Var& Notifier::getValue() const
{
return _value;
}
} } } // namespace Poco::Data::SQLite
#endif // SQLite_Notifier_INCLUDED

View File

@ -1,64 +0,0 @@
//
// SQLite.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/SQLite.h#3 $
//
// Library: SQLite
// Package: SQLite
// Module: SQLite
//
// Basic definitions for the Poco SQLite library.
// This file must be the first file included by every other SQLite
// header file.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef SQLite_SQLite_INCLUDED
#define SQLite_SQLite_INCLUDED
#include "Poco/Foundation.h"
//
// The following block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the SQLite_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// SQLite_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
//
#if defined(_WIN32) && defined(POCO_DLL)
#if defined(SQLite_EXPORTS)
#define SQLite_API __declspec(dllexport)
#else
#define SQLite_API __declspec(dllimport)
#endif
#endif
#if !defined(SQLite_API)
#if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4)
#define SQLite_API __attribute__ ((visibility ("default")))
#else
#define SQLite_API
#endif
#endif
//
// Automatically link SQLite library.
//
#if defined(_MSC_VER)
#if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(SQLite_EXPORTS)
#pragma comment(lib, "PocoDataSQLite" POCO_LIB_SUFFIX)
#endif
#endif
#endif // SQLite_SQLite_INCLUDED

View File

@ -1,62 +0,0 @@
//
// SQLiteException.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/SQLiteException.h#2 $
//
// Library: SQLite
// Package: SQLite
// Module: SQLiteException
//
// Definition of SQLiteException.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef SQLite_SQLiteException_INCLUDED
#define SQLite_SQLiteException_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/DataException.h"
namespace Poco {
namespace Data {
namespace SQLite {
POCO_DECLARE_EXCEPTION(SQLite_API, SQLiteException, Poco::Data::DataException)
POCO_DECLARE_EXCEPTION(SQLite_API, InvalidSQLStatementException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, InternalDBErrorException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, DBAccessDeniedException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, ExecutionAbortedException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, DBLockedException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, TableLockedException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, NoMemoryException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, ReadOnlyException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, InterruptException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, IOErrorException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, CorruptImageException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, TableNotFoundException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, DatabaseFullException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, CantOpenDBFileException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, LockProtocolException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, SchemaDiffersException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, RowTooBigException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, ConstraintViolationException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, DataTypeMismatchException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, ParameterCountMismatchException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, InvalidLibraryUseException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, OSFeaturesMissingException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, AuthorizationDeniedException, SQLiteException)
POCO_DECLARE_EXCEPTION(SQLite_API, TransactionException, SQLiteException)
} } } // namespace Poco::Data::SQLite
#endif

View File

@ -1,157 +0,0 @@
//
// SQLiteStatementImpl.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/SQLiteStatementImpl.h#4 $
//
// Library: SQLite
// Package: SQLite
// Module: SQLiteStatementImpl
//
// Definition of the SQLiteStatementImpl class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_SQLite_SQLiteStatementImpl_INCLUDED
#define Data_SQLite_SQLiteStatementImpl_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/SQLite/Binder.h"
#include "Poco/Data/SQLite/Extractor.h"
#include "Poco/Data/StatementImpl.h"
#include "Poco/Data/MetaColumn.h"
#include "Poco/SharedPtr.h"
extern "C"
{
typedef struct sqlite3 sqlite3;
typedef struct sqlite3_stmt sqlite3_stmt;
}
namespace Poco {
namespace Data {
namespace SQLite {
class SQLite_API SQLiteStatementImpl: public Poco::Data::StatementImpl
/// Implements statement functionality needed for SQLite
{
public:
SQLiteStatementImpl(Poco::Data::SessionImpl& rSession, sqlite3* pDB);
/// Creates the SQLiteStatementImpl.
~SQLiteStatementImpl();
/// Destroys the SQLiteStatementImpl.
protected:
std::size_t columnsReturned() const;
/// Returns number of columns returned by query.
int affectedRowCount() const;
/// Returns the number of affected rows.
/// Used to find out the number of rows affected by insert, delete or update.
/// All changes are counted, even if they are later undone by a ROLLBACK or ABORT.
/// Changes associated with creating and dropping tables are not counted.
const MetaColumn& metaColumn(std::size_t pos) const;
/// Returns column meta data.
bool hasNext();
/// Returns true if a call to next() will return data.
std::size_t next();
/// Retrieves the next row from the resultset and returns 1.
/// Will throw, if the resultset is empty.
bool canBind() const;
/// Returns true if a valid statement is set and we can bind.
bool canCompile() const;
/// Returns true if statement can compile.
void compileImpl();
/// Compiles the statement, doesn't bind yet.
/// Returns true if the statement was succesfully compiled.
/// The way SQLite handles batches of statmeents is by compiling
/// one at a time and returning a pointer to the next one.
/// The remainder of the statement is kept in a string
/// buffer pointed to by _pLeftover member.
void bindImpl();
/// Binds parameters
AbstractExtraction::ExtractorPtr extractor();
/// Returns the concrete extractor used by the statement.
AbstractBinding::BinderPtr binder();
/// Returns the concrete binder used by the statement.
private:
void clear();
/// Removes the _pStmt
typedef Poco::SharedPtr<Binder> BinderPtr;
typedef Poco::SharedPtr<Extractor> ExtractorPtr;
typedef Poco::Data::AbstractBindingVec Bindings;
typedef Poco::Data::AbstractExtractionVec Extractions;
typedef std::vector<Poco::Data::MetaColumn> MetaColumnVec;
typedef std::vector<MetaColumnVec> MetaColumnVecVec;
typedef Poco::SharedPtr<std::string> StrPtr;
typedef Bindings::iterator BindIt;
sqlite3* _pDB;
sqlite3_stmt* _pStmt;
bool _stepCalled;
int _nextResponse;
BinderPtr _pBinder;
ExtractorPtr _pExtractor;
MetaColumnVecVec _columns;
int _affectedRowCount;
StrPtr _pLeftover;
BindIt _bindBegin;
bool _canBind;
bool _isExtracted;
bool _canCompile;
static const int POCO_SQLITE_INV_ROW_CNT;
};
//
// inlines
//
inline AbstractExtraction::ExtractorPtr SQLiteStatementImpl::extractor()
{
return _pExtractor;
}
inline AbstractBinding::BinderPtr SQLiteStatementImpl::binder()
{
return _pBinder;
}
inline bool SQLiteStatementImpl::canBind() const
{
return _canBind;
}
inline bool SQLiteStatementImpl::canCompile() const
{
return _canCompile;
}
} } } // namespace Poco::Data::SQLite
#endif // Data_SQLite_SQLiteStatementImpl_INCLUDED

View File

@ -1,168 +0,0 @@
//
// SessionImpl.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/SessionImpl.h#2 $
//
// Library: SQLite
// Package: SQLite
// Module: SessionImpl
//
// Definition of the SessionImpl class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_SQLite_SessionImpl_INCLUDED
#define Data_SQLite_SessionImpl_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Data/SQLite/Binder.h"
#include "Poco/Data/AbstractSessionImpl.h"
#include "Poco/SharedPtr.h"
#include "Poco/Mutex.h"
extern "C"
{
typedef struct sqlite3 sqlite3;
}
namespace Poco {
namespace Data {
namespace SQLite {
class SQLite_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
/// Implements SessionImpl interface.
{
public:
SessionImpl(const std::string& fileName,
std::size_t loginTimeout = LOGIN_TIMEOUT_DEFAULT);
/// Creates the SessionImpl. Opens a connection to the database.
~SessionImpl();
/// Destroys the SessionImpl.
Poco::Data::StatementImpl* createStatementImpl();
/// Returns an SQLite StatementImpl.
void open(const std::string& connect = "");
/// Opens a connection to the Database.
///
/// An in-memory system database (sys), with a single table (dual)
/// containing single field (dummy) is attached to the database.
/// The in-memory system database is used to force change count
/// to be reset to zero on every new query (or batch of queries)
/// execution. Without this functionality, select statements
/// executions that do not return any rows return the count of
/// changes effected by the most recent insert, update or delete.
/// In-memory system database can be queried and updated but can not
/// be dropped. It may be used for other purposes
/// in the future.
void close();
/// Closes the session.
bool isConnected();
/// Returns true if connected, false otherwise.
void setConnectionTimeout(std::size_t timeout);
/// Sets the session connection timeout value.
std::size_t getConnectionTimeout();
/// Returns the session connection timeout value.
void begin();
/// Starts a transaction.
void commit();
/// Commits and ends a transaction.
void rollback();
/// Aborts a transaction.
bool canTransact();
/// Returns true if session has transaction capabilities.
bool isTransaction();
/// Returns true iff a transaction is a transaction is in progress, false otherwise.
void setTransactionIsolation(Poco::UInt32 ti);
/// Sets the transaction isolation level.
Poco::UInt32 getTransactionIsolation();
/// Returns the transaction isolation level.
bool hasTransactionIsolation(Poco::UInt32 ti);
/// Returns true iff the transaction isolation level corresponding
/// to the supplied bitmask is supported.
bool isTransactionIsolation(Poco::UInt32 ti);
/// Returns true iff the transaction isolation level corresponds
/// to the supplied bitmask.
void autoCommit(const std::string&, bool val);
/// Sets autocommit property for the session.
bool isAutoCommit(const std::string& name="");
/// Returns autocommit property value.
const std::string& connectorName() const;
/// Returns the name of the connector.
protected:
void setConnectionTimeout(const std::string& prop, const Poco::Any& value);
Poco::Any getConnectionTimeout(const std::string& prop);
private:
std::string _connector;
sqlite3* _pDB;
bool _connected;
bool _isTransaction;
int _timeout;
Poco::Mutex _mutex;
static const std::string DEFERRED_BEGIN_TRANSACTION;
static const std::string COMMIT_TRANSACTION;
static const std::string ABORT_TRANSACTION;
};
//
// inlines
//
inline bool SessionImpl::canTransact()
{
return true;
}
inline bool SessionImpl::isTransaction()
{
return _isTransaction;
}
inline const std::string& SessionImpl::connectorName() const
{
return _connector;
}
inline std::size_t SessionImpl::getConnectionTimeout()
{
return static_cast<std::size_t>(_timeout);
}
} } } // namespace Poco::Data::SQLite
#endif // Data_SQLite_SessionImpl_INCLUDED

View File

@ -1,230 +0,0 @@
//
// Utility.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/Utility.h#2 $
//
// Library: SQLite
// Package: SQLite
// Module: Utility
//
// Definition of Utility.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef SQLite_Utility_INCLUDED
#define SQLite_Utility_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/MetaColumn.h"
#include "Poco/Data/Session.h"
#include "Poco/Mutex.h"
#include "Poco/Types.h"
#include <map>
extern "C"
{
typedef struct sqlite3 sqlite3;
typedef struct sqlite3_stmt sqlite3_stmt;
}
namespace Poco {
namespace Data {
namespace SQLite {
class SQLite_API Utility
/// Various utility functions for SQLite.
{
public:
static const std::string SQLITE_DATE_FORMAT;
static const std::string SQLITE_TIME_FORMAT;
typedef std::map<std::string, MetaColumn::ColumnDataType> TypeMap;
static const int THREAD_MODE_SINGLE;
static const int THREAD_MODE_MULTI;
static const int THREAD_MODE_SERIAL;
static const int OPERATION_INSERT;
static const int OPERATION_DELETE;
static const int OPERATION_UPDATE;
static sqlite3* dbHandle(const Session& session);
/// Returns native DB handle.
static std::string lastError(sqlite3* pDb);
/// Retreives the last error code from sqlite and converts it to a string.
static std::string lastError(const Session& session);
/// Retreives the last error code from sqlite and converts it to a string.
static void throwException(int rc, const std::string& addErrMsg = std::string());
/// Throws for an error code the appropriate exception
static MetaColumn::ColumnDataType getColumnType(sqlite3_stmt* pStmt, std::size_t pos);
/// Returns column data type.
static bool fileToMemory(sqlite3* pInMemory, const std::string& fileName);
/// Loads the contents of a database file on disk into an opened
/// database in memory.
///
/// Returns true if succesful.
static bool fileToMemory(const Session& session, const std::string& fileName);
/// Loads the contents of a database file on disk into an opened
/// database in memory.
///
/// Returns true if succesful.
static bool memoryToFile(const std::string& fileName, sqlite3* pInMemory);
/// Saves the contents of an opened database in memory to the
/// database on disk.
///
/// Returns true if succesful.
static bool memoryToFile(const std::string& fileName, const Session& session);
/// Saves the contents of an opened database in memory to the
/// database on disk.
///
/// Returns true if succesful.
static bool isThreadSafe();
/// Returns true if SQLite was compiled in multi-thread or serialized mode.
/// See http://www.sqlite.org/c3ref/threadsafe.html for details.
///
/// Returns true if succesful
static bool setThreadMode(int mode);
/// Sets the threading mode to single, multi or serialized.
/// See http://www.sqlite.org/threadsafe.html for details.
///
/// Returns true if succesful
static int getThreadMode();
/// Returns the thread mode.
typedef void(*UpdateCallbackType)(void*, int, const char*, const char*, Poco::Int64);
/// Update callback function type.
typedef int(*CommitCallbackType)(void*);
/// Commit callback function type.
typedef void(*RollbackCallbackType)(void*);
/// Rollback callback function type.
template <typename T, typename CBT>
static bool registerUpdateHandler(sqlite3* pDB, CBT callbackFn, T* pParam)
/// Registers the callback for (1)(insert, delete, update), (2)(commit) or
/// or (3)(rollback) events. Only one function per group can be registered
/// at a time. Registration is not thread-safe. Storage pointed to by pParam
/// must remain valid as long as registration is active. Registering with
/// callbackFn set to zero disables notifications.
///
/// See http://www.sqlite.org/c3ref/update_hook.html and
/// http://www.sqlite.org/c3ref/commit_hook.html for details.
{
typedef std::pair<CBT, T*> CBPair;
typedef std::multimap<sqlite3*, CBPair> CBMap;
typedef typename CBMap::iterator CBMapIt;
typedef std::pair<CBMapIt, CBMapIt> CBMapItPair;
static CBMap retMap;
T* pRet = reinterpret_cast<T*>(eventHookRegister(pDB, callbackFn, pParam));
if (pRet == 0)
{
if (retMap.find(pDB) == retMap.end())
{
retMap.insert(std::make_pair(pDB, CBPair(callbackFn, pParam)));
return true;
}
}
else
{
CBMapItPair retMapRange = retMap.equal_range(pDB);
for (CBMapIt it = retMapRange.first; it != retMapRange.second; ++it)
{
poco_assert (it->second.first != 0);
if ((callbackFn == 0) && (*pRet == *it->second.second))
{
retMap.erase(it);
return true;
}
if ((callbackFn == it->second.first) && (*pRet == *it->second.second))
{
it->second.second = pParam;
return true;
}
}
}
return false;
}
template <typename T, typename CBT>
static bool registerUpdateHandler(const Session& session, CBT callbackFn, T* pParam)
/// Registers the callback by calling registerUpdateHandler(sqlite3*, CBT, T*).
{
return registerUpdateHandler(dbHandle(session), callbackFn, pParam);
}
private:
Utility();
/// Maps SQLite column declared types to Poco::Data types through
/// static TypeMap member.
///
/// Note: SQLite is type-agnostic and it is the end-user responsibility
/// to ensure that column declared data type corresponds to the type of
/// data actually held in the database.
///
/// Column types are case-insensitive.
Utility(const Utility&);
Utility& operator = (const Utility&);
static void* eventHookRegister(sqlite3* pDB, UpdateCallbackType callbackFn, void* pParam);
static void* eventHookRegister(sqlite3* pDB, CommitCallbackType callbackFn, void* pParam);
static void* eventHookRegister(sqlite3* pDB, RollbackCallbackType callbackFn, void* pParam);
static TypeMap _types;
static Poco::Mutex _mutex;
static int _threadMode;
};
//
// inlines
//
inline std::string Utility::lastError(const Session& session)
{
poco_assert_dbg ((0 == icompare(session.connector(), 0, 6, "sqlite")));
return lastError(dbHandle(session));
}
inline bool Utility::memoryToFile(const std::string& fileName, const Session& session)
{
poco_assert_dbg ((0 == icompare(session.connector(), 0, 6, "sqlite")));
return memoryToFile(fileName, dbHandle(session));
}
inline bool Utility::fileToMemory(const Session& session, const std::string& fileName)
{
poco_assert_dbg ((0 == icompare(session.connector(), 0, 6, "sqlite")));
return fileToMemory(dbHandle(session), fileName);
}
} } } // namespace Poco::Data::SQLite
#endif // SQLite_Utility_INCLUDED

View File

@ -1,129 +0,0 @@
//
// Binder.cpp
//
// $Id: //poco/Main/Data/SQLite/src/Binder.cpp#5 $
//
// Library: SQLite
// Package: SQLite
// Module: Binder
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Data/SQLite/Binder.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Exception.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include <cstdlib>
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
namespace Poco {
namespace Data {
namespace SQLite {
Binder::Binder(sqlite3_stmt* pStmt):
_pStmt(pStmt)
{
}
Binder::~Binder()
{
}
void Binder::bind(std::size_t pos, const Poco::Int32 &val, Direction dir)
{
int rc = sqlite3_bind_int(_pStmt, (int) pos, val);
checkReturn(rc);
}
void Binder::bind(std::size_t pos, const Poco::Int64 &val, Direction dir)
{
int rc = sqlite3_bind_int64(_pStmt, (int) pos, val);
checkReturn(rc);
}
#ifndef POCO_LONG_IS_64_BIT
void Binder::bind(std::size_t pos, const long &val, Direction dir)
{
long tmp = static_cast<long>(val);
int rc = sqlite3_bind_int(_pStmt, (int) pos, tmp);
checkReturn(rc);
}
void Binder::bind(std::size_t pos, const unsigned long &val, Direction dir)
{
long tmp = static_cast<long>(val);
int rc = sqlite3_bind_int(_pStmt, (int) pos, tmp);
checkReturn(rc);
}
#endif
void Binder::bind(std::size_t pos, const double &val, Direction dir)
{
int rc = sqlite3_bind_double(_pStmt, (int) pos, val);
checkReturn(rc);
}
void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
{
int rc = sqlite3_bind_text(_pStmt, (int) pos, val.c_str(), (int) val.size()*sizeof(char), SQLITE_TRANSIENT);
checkReturn(rc);
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
{
DateTime dt(val.year(), val.month(), val.day());
std::string str(DateTimeFormatter::format(dt, Utility::SQLITE_DATE_FORMAT));
bind(pos, str, dir);
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
{
DateTime dt;
dt.assign(dt.year(), dt.month(), dt.day(), val.hour(), val.minute(), val.second());
std::string str(DateTimeFormatter::format(dt, Utility::SQLITE_TIME_FORMAT));
bind(pos, str, dir);
}
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
{
std::string dt(DateTimeFormatter::format(val, DateTimeFormat::ISO8601_FORMAT));
bind(pos, dt, dir);
}
void Binder::bind(std::size_t pos, const NullData&, Direction)
{
sqlite3_bind_null(_pStmt, pos);
}
void Binder::checkReturn(int rc)
{
if (rc != SQLITE_OK)
Utility::throwException(rc);
}
} } } // namespace Poco::Data::SQLite

View File

@ -1,79 +0,0 @@
//
// Connector.cpp
//
// $Id: //poco/Main/Data/SQLite/src/Connector.cpp#2 $
//
// Library: SQLite
// Package: SQLite
// Module: Connector
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Data/SQLite/SessionImpl.h"
#include "Poco/Data/SessionFactory.h"
#if defined(POCO_UNBUNDLED)
#include <sqlite3.h>
#else
#include "sqlite3.h"
#endif
const SQLiteConnectorRegistrator pocoSQLiteConnectorRegistrator;
namespace Poco {
namespace Data {
namespace SQLite {
const std::string Connector::KEY(POCO_DATA_SQLITE_CONNECTOR_NAME);
Connector::Connector()
{
}
Connector::~Connector()
{
}
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString,
std::size_t timeout)
{
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString, timeout));
}
void Connector::registerConnector()
{
Poco::Data::SessionFactory::instance().add(new Connector());
}
void Connector::unregisterConnector()
{
Poco::Data::SessionFactory::instance().remove(POCO_DATA_SQLITE_CONNECTOR_NAME);
}
void Connector::enableSharedCache(bool flag)
{
sqlite3_enable_shared_cache(flag ? 1 : 0);
}
void Connector::enableSoftHeapLimit(int limit)
{
sqlite3_soft_heap_limit(limit);
}
} } } // namespace Poco::Data::SQLite

View File

@ -1,240 +0,0 @@
//
// Extractor.cpp
//
// $Id: //poco/Main/Data/SQLite/src/Extractor.cpp#5 $
//
// Library: SQLite
// Package: SQLite
// Module: Extractor
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Data/SQLite/Extractor.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/LOB.h"
#include "Poco/Data/DataException.h"
#include "Poco/DateTimeParser.h"
#include "Poco/Exception.h"
#if defined(POCO_UNBUNDLED)
#include <sqlite3.h>
#else
#include "sqlite3.h"
#endif
#include <cstdlib>
using Poco::DateTimeParser;
namespace Poco {
namespace Data {
namespace SQLite {
Extractor::Extractor(sqlite3_stmt* pStmt):
_pStmt(pStmt)
{
}
Extractor::~Extractor()
{
}
bool Extractor::extract(std::size_t pos, Poco::Int32& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, Poco::Int64& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int64(_pStmt, (int) pos);
return true;
}
#ifndef POCO_LONG_IS_64_BIT
bool Extractor::extract(std::size_t pos, long& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, unsigned long& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
#endif
bool Extractor::extract(std::size_t pos, double& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_double(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, std::string& val)
{
if (isNull(pos)) return false;
const char *pBuf = reinterpret_cast<const char*>(sqlite3_column_text(_pStmt, (int) pos));
if (!pBuf)
val.clear();
else
val.assign(pBuf);
return true;
}
bool Extractor::extract(std::size_t pos, Poco::Int8& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, Poco::Int16& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int64(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, bool& val)
{
if (isNull(pos)) return false;
val = (0 != sqlite3_column_int(_pStmt, (int) pos));
return true;
}
bool Extractor::extract(std::size_t pos, float& val)
{
if (isNull(pos)) return false;
val = static_cast<float>(sqlite3_column_double(_pStmt, (int) pos));
return true;
}
bool Extractor::extract(std::size_t pos, char& val)
{
if (isNull(pos)) return false;
val = sqlite3_column_int(_pStmt, (int) pos);
return true;
}
bool Extractor::extract(std::size_t pos, Date& val)
{
if (isNull(pos)) return false;
std::string str;
extract(pos, str);
int tzd;
DateTime dt = DateTimeParser::parse(Utility::SQLITE_DATE_FORMAT, str, tzd);
val = dt;
return true;
}
bool Extractor::extract(std::size_t pos, Time& val)
{
if (isNull(pos)) return false;
std::string str;
extract(pos, str);
int tzd;
DateTime dt = DateTimeParser::parse(Utility::SQLITE_TIME_FORMAT, str, tzd);
val = dt;
return true;
}
bool Extractor::extract(std::size_t pos, DateTime& val)
{
if (isNull(pos)) return false;
std::string dt;
extract(pos, dt);
int tzd;
DateTimeParser::parse(dt, val, tzd);
return true;
}
bool Extractor::extract(std::size_t pos, Poco::Any& val)
{
return extractImpl(pos, val);
}
bool Extractor::extract(std::size_t pos, Poco::DynamicAny& val)
{
return extractImpl(pos, val);
}
bool Extractor::isNull(std::size_t pos, std::size_t)
{
if (pos >= _nulls.size())
_nulls.resize(pos + 1);
if (!_nulls[pos].first)
{
_nulls[pos].first = true;
_nulls[pos].second = (SQLITE_NULL == sqlite3_column_type(_pStmt, pos));
}
return _nulls[pos].second;
}
} } } // namespace Poco::Data::SQLite

View File

@ -1,201 +0,0 @@
//
// Notifier.cpp
//
// $Id: //poco/Main/Data/SQLite/src/Notifier.cpp#5 $
//
// Library: SQLite
// Package: SQLite
// Module: Notifier
//
// Implementation of Notifier
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Data/SQLite/Notifier.h"
namespace Poco {
namespace Data {
namespace SQLite {
Notifier::Notifier(const Session& session, EnabledEventType enabled):
_session(session)
{
if (enabled & SQLITE_NOTIFY_UPDATE) enableUpdate();
if (enabled & SQLITE_NOTIFY_COMMIT) enableCommit();
if (enabled & SQLITE_NOTIFY_ROLLBACK) enableRollback();
}
Notifier::Notifier(const Session& session, const Any& value, EnabledEventType enabled):
_session(session),
_value(value)
{
if (enabled & SQLITE_NOTIFY_UPDATE) enableUpdate();
if (enabled & SQLITE_NOTIFY_COMMIT) enableCommit();
if (enabled & SQLITE_NOTIFY_ROLLBACK) enableRollback();
}
Notifier::~Notifier()
{
try
{
disableAll();
}
catch (...)
{
poco_unexpected();
}
}
bool Notifier::enableUpdate()
{
Poco::Mutex::ScopedLock l(_mutex);
if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteUpdateCallbackFn, this))
_enabledEvents |= SQLITE_NOTIFY_UPDATE;
return updateEnabled();
}
bool Notifier::disableUpdate()
{
Poco::Mutex::ScopedLock l(_mutex);
if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::UpdateCallbackType) 0, this))
_enabledEvents &= ~SQLITE_NOTIFY_UPDATE;
return !updateEnabled();
}
bool Notifier::updateEnabled() const
{
return 0 != (_enabledEvents & SQLITE_NOTIFY_UPDATE);
}
bool Notifier::enableCommit()
{
Poco::Mutex::ScopedLock l(_mutex);
if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteCommitCallbackFn, this))
_enabledEvents |= SQLITE_NOTIFY_COMMIT;
return commitEnabled();
}
bool Notifier::disableCommit()
{
Poco::Mutex::ScopedLock l(_mutex);
if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::CommitCallbackType) 0, this))
_enabledEvents &= ~SQLITE_NOTIFY_COMMIT;
return !commitEnabled();
}
bool Notifier::commitEnabled() const
{
return 0 != (_enabledEvents & SQLITE_NOTIFY_COMMIT);
}
bool Notifier::enableRollback()
{
Poco::Mutex::ScopedLock l(_mutex);
if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteRollbackCallbackFn, this))
_enabledEvents |= SQLITE_NOTIFY_ROLLBACK;
return rollbackEnabled();
}
bool Notifier::disableRollback()
{
Poco::Mutex::ScopedLock l(_mutex);
if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::RollbackCallbackType) 0, this))
_enabledEvents &= ~SQLITE_NOTIFY_ROLLBACK;
return !rollbackEnabled();
}
bool Notifier::rollbackEnabled() const
{
return 0 != (_enabledEvents & SQLITE_NOTIFY_ROLLBACK);
}
bool Notifier::enableAll()
{
return enableUpdate() && enableCommit() && enableRollback();
}
bool Notifier::disableAll()
{
return disableUpdate() && disableCommit() && disableRollback();
}
void Notifier::sqliteUpdateCallbackFn(void* pVal, int opCode, const char* pDB, const char* pTable, Poco::Int64 row)
{
poco_check_ptr(pVal);
Notifier* pV = reinterpret_cast<Notifier*>(pVal);
if (opCode == Utility::OPERATION_INSERT)
{
pV->_row = row;
pV->insert.notify(pV);
}
else if (opCode == Utility::OPERATION_UPDATE)
{
pV->_row = row;
pV->update.notify(pV);
}
else if (opCode == Utility::OPERATION_DELETE)
{
pV->_row = row;
pV->erase.notify(pV);
}
}
int Notifier::sqliteCommitCallbackFn(void* pVal)
{
Notifier* pV = reinterpret_cast<Notifier*>(pVal);
try
{
pV->commit.notify(pV);
}
catch (...)
{
return -1;
}
return 0;
}
void Notifier::sqliteRollbackCallbackFn(void* pVal)
{
Notifier* pV = reinterpret_cast<Notifier*>(pVal);
pV->rollback.notify(pV);
}
} } } // namespace Poco::Data::SQLite

View File

@ -1,53 +0,0 @@
//
// SQLiteException.cpp
//
// $Id: //poco/Main/Data/SQLite/src/SQLiteException.cpp#2 $
//
// Library: SQLite
// Package: SQLite
// Module: SQLiteException
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Data/SQLite/SQLiteException.h"
#include <typeinfo>
namespace Poco {
namespace Data {
namespace SQLite {
POCO_IMPLEMENT_EXCEPTION(SQLiteException, Poco::Data::DataException, "Generic SQLite error")
POCO_IMPLEMENT_EXCEPTION(InvalidSQLStatementException, SQLiteException, "SQL Statement invalid")
POCO_IMPLEMENT_EXCEPTION(InternalDBErrorException, SQLiteException, "Internal error")
POCO_IMPLEMENT_EXCEPTION(DBAccessDeniedException, SQLiteException, "Access permission denied")
POCO_IMPLEMENT_EXCEPTION(ExecutionAbortedException, SQLiteException, "Execution of SQL statement aborted")
POCO_IMPLEMENT_EXCEPTION(DBLockedException, SQLiteException, "The database is locked")
POCO_IMPLEMENT_EXCEPTION(TableLockedException, SQLiteException, "A table in the database is locked")
POCO_IMPLEMENT_EXCEPTION(NoMemoryException, SQLiteException, "Out of Memory")
POCO_IMPLEMENT_EXCEPTION(ReadOnlyException, SQLiteException, "Attempt to write a readonly database")
POCO_IMPLEMENT_EXCEPTION(InterruptException, SQLiteException, "Operation terminated by an interrupt")
POCO_IMPLEMENT_EXCEPTION(IOErrorException, SQLiteException, "Some kind of disk I/O error occurred")
POCO_IMPLEMENT_EXCEPTION(CorruptImageException, SQLiteException, "The database disk image is malformed")
POCO_IMPLEMENT_EXCEPTION(TableNotFoundException, SQLiteException, "Table not found")
POCO_IMPLEMENT_EXCEPTION(DatabaseFullException, SQLiteException, "Insertion failed because database is full")
POCO_IMPLEMENT_EXCEPTION(CantOpenDBFileException, SQLiteException, "Unable to open the database file")
POCO_IMPLEMENT_EXCEPTION(LockProtocolException, SQLiteException, "Database lock protocol error")
POCO_IMPLEMENT_EXCEPTION(SchemaDiffersException, SQLiteException, "The database schema changed")
POCO_IMPLEMENT_EXCEPTION(RowTooBigException, SQLiteException, "Too much data for one row of a table")
POCO_IMPLEMENT_EXCEPTION(ConstraintViolationException, SQLiteException, "Abort due to constraint violation")
POCO_IMPLEMENT_EXCEPTION(DataTypeMismatchException, SQLiteException, "Data type mismatch")
POCO_IMPLEMENT_EXCEPTION(ParameterCountMismatchException, SQLiteException, "Parameter count mismatch")
POCO_IMPLEMENT_EXCEPTION(InvalidLibraryUseException, SQLiteException, "Library used incorrectly")
POCO_IMPLEMENT_EXCEPTION(OSFeaturesMissingException, SQLiteException, "Uses OS features not supported on host")
POCO_IMPLEMENT_EXCEPTION(AuthorizationDeniedException, SQLiteException, "Authorization denied")
POCO_IMPLEMENT_EXCEPTION(TransactionException, SQLiteException, "Transaction exception")
} } } // namespace Poco::Data::SQLite

View File

@ -1,312 +0,0 @@
//
// SQLiteStatementImpl.cpp
//
// $Id: //poco/Main/Data/SQLite/src/SQLiteStatementImpl.cpp#8 $
//
// Library: SQLite
// Package: SQLite
// Module: SQLiteStatementImpl
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Data/SQLite/SQLiteStatementImpl.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/SQLite/SQLiteException.h"
#include "Poco/String.h"
#include <cstdlib>
#include <cstring>
#if defined(POCO_UNBUNDLED)
#include <sqlite3.h>
#else
#include "sqlite3.h"
#endif
namespace Poco {
namespace Data {
namespace SQLite {
const int SQLiteStatementImpl::POCO_SQLITE_INV_ROW_CNT = -1;
SQLiteStatementImpl::SQLiteStatementImpl(Poco::Data::SessionImpl& rSession, sqlite3* pDB):
StatementImpl(rSession),
_pDB(pDB),
_pStmt(0),
_stepCalled(false),
_nextResponse(0),
_affectedRowCount(POCO_SQLITE_INV_ROW_CNT),
_canBind(false),
_isExtracted(false),
_canCompile(true)
{
_columns.resize(1);
}
SQLiteStatementImpl::~SQLiteStatementImpl()
{
try
{
clear();
}
catch (...)
{
poco_unexpected();
}
}
void SQLiteStatementImpl::compileImpl()
{
if (!_pLeftover)
{
_bindBegin = bindings().begin();
}
std::string statement(toString());
sqlite3_stmt* pStmt = 0;
const char* pSql = _pLeftover ? _pLeftover->c_str() : statement.c_str();
if (0 == std::strlen(pSql))
throw InvalidSQLStatementException("Empty statements are illegal");
int rc = SQLITE_OK;
const char* pLeftover = 0;
bool queryFound = false;
do
{
rc = sqlite3_prepare_v2(_pDB, pSql, -1, &pStmt, &pLeftover);
if (rc != SQLITE_OK)
{
if (pStmt) sqlite3_finalize(pStmt);
pStmt = 0;
std::string errMsg = sqlite3_errmsg(_pDB);
Utility::throwException(rc, errMsg);
}
else if (rc == SQLITE_OK && pStmt)
{
queryFound = true;
}
else if (rc == SQLITE_OK && !pStmt) // comment/whitespace ignore
{
pSql = pLeftover;
if (std::strlen(pSql) == 0)
{
// empty statement or an conditional statement! like CREATE IF NOT EXISTS
// this is valid
queryFound = true;
}
}
} while (rc == SQLITE_OK && !pStmt && !queryFound);
//Finalization call in clear() invalidates the pointer, so the value is remembered here.
//For last statement in a batch (or a single statement), pLeftover == "", so the next call
// to compileImpl() shall return false immediately when there are no more statements left.
std::string leftOver(pLeftover);
trimInPlace(leftOver);
clear();
_pStmt = pStmt;
if (!leftOver.empty())
{
_pLeftover = new std::string(leftOver);
_canCompile = true;
}
else _canCompile = false;
_pBinder = new Binder(_pStmt);
_pExtractor = new Extractor(_pStmt);
if (SQLITE_DONE == _nextResponse && _isExtracted)
{
//if this is not the first compile and there has already been extraction
//during previous step, switch to the next set if there is one provided
if (hasMoreDataSets())
{
activateNextDataSet();
_isExtracted = false;
}
}
int colCount = sqlite3_column_count(_pStmt);
if (colCount)
{
std::size_t curDataSet = currentDataSet();
if (curDataSet >= _columns.size()) _columns.resize(curDataSet + 1);
for (int i = 0; i < colCount; ++i)
{
MetaColumn mc(i, sqlite3_column_name(_pStmt, i), Utility::getColumnType(_pStmt, i));
_columns[curDataSet].push_back(mc);
}
}
}
void SQLiteStatementImpl::bindImpl()
{
_stepCalled = false;
_nextResponse = 0;
if (_pStmt == 0) return;
sqlite3_reset(_pStmt);
int paramCount = sqlite3_bind_parameter_count(_pStmt);
BindIt bindEnd = bindings().end();
if (0 == paramCount || bindEnd == _bindBegin)
{
_canBind = false;
return;
}
std::size_t availableCount = 0;
Bindings::difference_type bindCount = 0;
Bindings::iterator it = _bindBegin;
for (; it != bindEnd; ++it)
{
availableCount += (*it)->numOfColumnsHandled();
if (availableCount <= (size_t)paramCount) ++bindCount;
else break;
}
Bindings::difference_type remainingBindCount = bindEnd - _bindBegin;
if (bindCount < remainingBindCount)
{
bindEnd = _bindBegin + bindCount;
_canBind = true;
}
else if (bindCount > remainingBindCount)
throw ParameterCountMismatchException();
std::size_t boundRowCount;
if (_bindBegin != bindings().end())
{
boundRowCount = (*_bindBegin)->numOfRowsHandled();
Bindings::iterator oldBegin = _bindBegin;
for (std::size_t pos = 1; _bindBegin != bindEnd && (*_bindBegin)->canBind(); ++_bindBegin)
{
if (boundRowCount != (*_bindBegin)->numOfRowsHandled())
throw BindingException("Size mismatch in Bindings. All Bindings MUST have the same size");
(*_bindBegin)->bind(pos);
pos += (*_bindBegin)->numOfColumnsHandled();
}
if ((*oldBegin)->canBind())
{
//container binding will come back for more, so we must rewind
_bindBegin = oldBegin;
_canBind = true;
}
else _canBind = false;
}
}
void SQLiteStatementImpl::clear()
{
_columns[currentDataSet()].clear();
_affectedRowCount = POCO_SQLITE_INV_ROW_CNT;
if (_pStmt)
{
sqlite3_finalize(_pStmt);
_pStmt=0;
}
_pLeftover = 0;
}
bool SQLiteStatementImpl::hasNext()
{
if (_stepCalled)
return (_nextResponse == SQLITE_ROW);
// _pStmt is allowed to be null for conditional SQL statements
if (_pStmt == 0)
{
_stepCalled = true;
_nextResponse = SQLITE_DONE;
return false;
}
_stepCalled = true;
_nextResponse = sqlite3_step(_pStmt);
if (_affectedRowCount == POCO_SQLITE_INV_ROW_CNT) _affectedRowCount = 0;
if (!sqlite3_stmt_readonly(_pStmt))
_affectedRowCount += sqlite3_changes(_pDB);
if (_nextResponse != SQLITE_ROW && _nextResponse != SQLITE_OK && _nextResponse != SQLITE_DONE)
Utility::throwException(_nextResponse);
_pExtractor->reset();//clear the cached null indicators
return (_nextResponse == SQLITE_ROW);
}
std::size_t SQLiteStatementImpl::next()
{
if (SQLITE_ROW == _nextResponse)
{
poco_assert (columnsReturned() == (size_t)sqlite3_column_count(_pStmt));
Extractions& extracts = extractions();
Extractions::iterator it = extracts.begin();
Extractions::iterator itEnd = extracts.end();
std::size_t pos = 0; // sqlite starts with pos 0 for results!
for (; it != itEnd; ++it)
{
(*it)->extract(pos);
pos += (*it)->numOfColumnsHandled();
_isExtracted = true;
}
_stepCalled = false;
if (_affectedRowCount == POCO_SQLITE_INV_ROW_CNT) _affectedRowCount = 0;
_affectedRowCount += (*extracts.begin())->numOfRowsHandled();
}
else if (SQLITE_DONE == _nextResponse)
{
throw Poco::Data::DataException("No data received");
}
else
{
Utility::throwException(_nextResponse, std::string("Iterator Error: trying to access the next value"));
}
return 1u;
}
std::size_t SQLiteStatementImpl::columnsReturned() const
{
return (std::size_t) _columns[currentDataSet()].size();
}
const MetaColumn& SQLiteStatementImpl::metaColumn(std::size_t pos) const
{
std::size_t curDataSet = currentDataSet();
poco_assert (pos >= 0 && pos <= _columns[curDataSet].size());
return _columns[curDataSet][pos];
}
int SQLiteStatementImpl::affectedRowCount() const
{
if (_affectedRowCount != POCO_SQLITE_INV_ROW_CNT) return _affectedRowCount;
return _pStmt == 0 || sqlite3_stmt_readonly(_pStmt) ? 0 : sqlite3_changes(_pDB);
}
} } } // namespace Poco::Data::SQLite

View File

@ -1,272 +0,0 @@
//
// SessionImpl.cpp
//
// $Id: //poco/Main/Data/SQLite/src/SessionImpl.cpp#5 $
//
// Library: SQLite
// Package: SQLite
// Module: SessionImpl
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Data/SQLite/SessionImpl.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/SQLite/SQLiteStatementImpl.h"
#include "Poco/Data/SQLite/SQLiteException.h"
#include "Poco/Data/Session.h"
#include "Poco/ActiveMethod.h"
#include "Poco/ActiveResult.h"
#include "Poco/String.h"
#include "Poco/Mutex.h"
#include "Poco/Data/DataException.h"
#if defined(POCO_UNBUNDLED)
#include <sqlite3.h>
#else
#include "sqlite3.h"
#endif
#include <cstdlib>
#ifndef SQLITE_OPEN_URI
#define SQLITE_OPEN_URI 0
#endif
namespace Poco {
namespace Data {
namespace SQLite {
const std::string SessionImpl::DEFERRED_BEGIN_TRANSACTION("BEGIN DEFERRED");
const std::string SessionImpl::COMMIT_TRANSACTION("COMMIT");
const std::string SessionImpl::ABORT_TRANSACTION("ROLLBACK");
SessionImpl::SessionImpl(const std::string& fileName, std::size_t loginTimeout):
Poco::Data::AbstractSessionImpl<SessionImpl>(fileName, loginTimeout),
_connector(Connector::KEY),
_pDB(0),
_connected(false),
_isTransaction(false)
{
open();
setConnectionTimeout(CONNECTION_TIMEOUT_DEFAULT);
setProperty("handle", _pDB);
addFeature("autoCommit",
&SessionImpl::autoCommit,
&SessionImpl::isAutoCommit);
addProperty("connectionTimeout", &SessionImpl::setConnectionTimeout, &SessionImpl::getConnectionTimeout);
}
SessionImpl::~SessionImpl()
{
try
{
close();
}
catch (...)
{
poco_unexpected();
}
}
Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
{
poco_check_ptr (_pDB);
return new SQLiteStatementImpl(*this, _pDB);
}
void SessionImpl::begin()
{
Poco::Mutex::ScopedLock l(_mutex);
SQLiteStatementImpl tmp(*this, _pDB);
tmp.add(DEFERRED_BEGIN_TRANSACTION);
tmp.execute();
_isTransaction = true;
}
void SessionImpl::commit()
{
Poco::Mutex::ScopedLock l(_mutex);
SQLiteStatementImpl tmp(*this, _pDB);
tmp.add(COMMIT_TRANSACTION);
tmp.execute();
_isTransaction = false;
}
void SessionImpl::rollback()
{
Poco::Mutex::ScopedLock l(_mutex);
SQLiteStatementImpl tmp(*this, _pDB);
tmp.add(ABORT_TRANSACTION);
tmp.execute();
_isTransaction = false;
}
void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
{
if (ti != Session::TRANSACTION_READ_COMMITTED)
throw Poco::InvalidArgumentException("setTransactionIsolation()");
}
Poco::UInt32 SessionImpl::getTransactionIsolation()
{
return Session::TRANSACTION_READ_COMMITTED;
}
bool SessionImpl::hasTransactionIsolation(Poco::UInt32 ti)
{
if (ti == Session::TRANSACTION_READ_COMMITTED) return true;
return false;
}
bool SessionImpl::isTransactionIsolation(Poco::UInt32 ti)
{
if (ti == Session::TRANSACTION_READ_COMMITTED) return true;
return false;
}
class ActiveConnector
{
public:
ActiveConnector(const std::string& connectString, sqlite3** ppDB):
connect(this, &ActiveConnector::connectImpl),
_connectString(connectString),
_ppDB(ppDB)
{
poco_check_ptr(_ppDB);
}
ActiveMethod<int, void, ActiveConnector> connect;
private:
ActiveConnector();
inline int connectImpl()
{
return sqlite3_open_v2(_connectString.c_str(), _ppDB, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI, NULL);
}
std::string _connectString;
sqlite3** _ppDB;
};
void SessionImpl::open(const std::string& connect)
{
if (connect != connectionString())
{
if (isConnected())
throw InvalidAccessException("Session already connected");
if (!connect.empty())
setConnectionString(connect);
}
poco_assert_dbg (!connectionString().empty());
try
{
ActiveConnector connector(connectionString(), &_pDB);
ActiveResult<int> result = connector.connect();
if (!result.tryWait(getLoginTimeout() * 1000))
throw ConnectionFailedException("Timed out.");
int rc = result.data();
if (rc != 0)
{
close();
Utility::throwException(rc);
}
}
catch (SQLiteException& ex)
{
throw ConnectionFailedException(ex.displayText());
}
_connected = true;
}
void SessionImpl::close()
{
if (_pDB)
{
sqlite3_close(_pDB);
_pDB = 0;
}
_connected = false;
}
bool SessionImpl::isConnected()
{
return _connected;
}
void SessionImpl::setConnectionTimeout(std::size_t timeout)
{
int tout = 1000 * timeout;
int rc = sqlite3_busy_timeout(_pDB, tout);
if (rc != 0) Utility::throwException(rc);
_timeout = tout;
}
void SessionImpl::setConnectionTimeout(const std::string& prop, const Poco::Any& value)
{
setConnectionTimeout(Poco::RefAnyCast<std::size_t>(value));
}
Poco::Any SessionImpl::getConnectionTimeout(const std::string& prop)
{
return Poco::Any(_timeout/1000);
}
void SessionImpl::autoCommit(const std::string&, bool)
{
// The problem here is to decide whether to call commit or rollback
// when autocommit is set to true. Hence, it is best not to implement
// this explicit call and only implicitly support autocommit setting.
throw NotImplementedException(
"SQLite autocommit is implicit with begin/commit/rollback.");
}
bool SessionImpl::isAutoCommit(const std::string&)
{
Poco::Mutex::ScopedLock l(_mutex);
return (0 != sqlite3_get_autocommit(_pDB));
}
// NOTE: Utility::dbHandle() has been moved here from Utility.cpp
// as a workaround for a failing AnyCast with Clang.
// See <https://github.com/pocoproject/poco/issues/578>
// for a discussion.
sqlite3* Utility::dbHandle(const Session& session)
{
return AnyCast<sqlite3*>(session.getProperty("handle"));
}
} } } // namespace Poco::Data::SQLite

View File

@ -1,325 +0,0 @@
//
// Utility.cpp
//
// $Id: //poco/Main/Data/SQLite/src/Utility.cpp#5 $
//
// Library: SQLite
// Package: SQLite
// Module: Utility
//
// Implementation of Utility
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/SQLite/SQLiteException.h"
#include "Poco/NumberFormatter.h"
#include "Poco/String.h"
#include "Poco/Any.h"
#include "Poco/Exception.h"
#if defined(POCO_UNBUNDLED)
#include <sqlite3.h>
#else
#include "sqlite3.h"
#endif
#ifndef SQLITE_OPEN_URI
#define SQLITE_OPEN_URI 0
#endif
namespace Poco {
namespace Data {
namespace SQLite {
const int Utility::THREAD_MODE_SINGLE = SQLITE_CONFIG_SINGLETHREAD;
const int Utility::THREAD_MODE_MULTI = SQLITE_CONFIG_MULTITHREAD;
const int Utility::THREAD_MODE_SERIAL = SQLITE_CONFIG_SERIALIZED;
int Utility::_threadMode =
#if (SQLITE_THREADSAFE == 0)
SQLITE_CONFIG_SINGLETHREAD;
#elif (SQLITE_THREADSAFE == 1)
SQLITE_CONFIG_SERIALIZED;
#elif (SQLITE_THREADSAFE == 2)
SQLITE_CONFIG_MULTITHREAD;
#endif
const int Utility::OPERATION_INSERT = SQLITE_INSERT;
const int Utility::OPERATION_DELETE = SQLITE_DELETE;
const int Utility::OPERATION_UPDATE = SQLITE_UPDATE;
const std::string Utility::SQLITE_DATE_FORMAT = "%Y-%m-%d";
const std::string Utility::SQLITE_TIME_FORMAT = "%H:%M:%S";
Utility::TypeMap Utility::_types;
Poco::Mutex Utility::_mutex;
Utility::Utility()
{
if (_types.empty())
{
_types.insert(TypeMap::value_type("", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("BOOL", MetaColumn::FDT_BOOL));
_types.insert(TypeMap::value_type("BOOLEAN", MetaColumn::FDT_BOOL));
_types.insert(TypeMap::value_type("BIT", MetaColumn::FDT_BOOL));
_types.insert(TypeMap::value_type("UINT8", MetaColumn::FDT_UINT8));
_types.insert(TypeMap::value_type("UTINY", MetaColumn::FDT_UINT8));
_types.insert(TypeMap::value_type("UINTEGER8", MetaColumn::FDT_UINT8));
_types.insert(TypeMap::value_type("INT8", MetaColumn::FDT_INT8));
_types.insert(TypeMap::value_type("TINY", MetaColumn::FDT_INT8));
_types.insert(TypeMap::value_type("INTEGER8", MetaColumn::FDT_INT8));
_types.insert(TypeMap::value_type("UINT16", MetaColumn::FDT_UINT16));
_types.insert(TypeMap::value_type("USHORT", MetaColumn::FDT_UINT16));
_types.insert(TypeMap::value_type("UINTEGER16", MetaColumn::FDT_UINT16));
_types.insert(TypeMap::value_type("INT16", MetaColumn::FDT_INT16));
_types.insert(TypeMap::value_type("SHORT", MetaColumn::FDT_INT16));
_types.insert(TypeMap::value_type("INTEGER16", MetaColumn::FDT_INT16));
_types.insert(TypeMap::value_type("UINT", MetaColumn::FDT_UINT32));
_types.insert(TypeMap::value_type("UINT32", MetaColumn::FDT_UINT32));
_types.insert(TypeMap::value_type("UINTEGER32", MetaColumn::FDT_UINT32));
_types.insert(TypeMap::value_type("INT", MetaColumn::FDT_INT32));
_types.insert(TypeMap::value_type("INT32", MetaColumn::FDT_INT32));
_types.insert(TypeMap::value_type("INTEGER", MetaColumn::FDT_INT32));
_types.insert(TypeMap::value_type("INTEGER32", MetaColumn::FDT_INT32));
_types.insert(TypeMap::value_type("UINT64", MetaColumn::FDT_UINT64));
_types.insert(TypeMap::value_type("ULONG", MetaColumn::FDT_INT64));
_types.insert(TypeMap::value_type("UINTEGER64", MetaColumn::FDT_UINT64));
_types.insert(TypeMap::value_type("INT64", MetaColumn::FDT_INT64));
_types.insert(TypeMap::value_type("LONG", MetaColumn::FDT_INT64));
_types.insert(TypeMap::value_type("INTEGER64", MetaColumn::FDT_INT64));
_types.insert(TypeMap::value_type("TINYINT", MetaColumn::FDT_INT8));
_types.insert(TypeMap::value_type("SMALLINT", MetaColumn::FDT_INT16));
_types.insert(TypeMap::value_type("BIGINT", MetaColumn::FDT_INT64));
_types.insert(TypeMap::value_type("COUNTER", MetaColumn::FDT_UINT64));
_types.insert(TypeMap::value_type("AUTOINCREMENT", MetaColumn::FDT_UINT64));
_types.insert(TypeMap::value_type("REAL", MetaColumn::FDT_DOUBLE));
_types.insert(TypeMap::value_type("FLOA", MetaColumn::FDT_DOUBLE));
_types.insert(TypeMap::value_type("FLOAT", MetaColumn::FDT_DOUBLE));
_types.insert(TypeMap::value_type("DOUB", MetaColumn::FDT_DOUBLE));
_types.insert(TypeMap::value_type("DOUBLE", MetaColumn::FDT_DOUBLE));
_types.insert(TypeMap::value_type("DECIMAL", MetaColumn::FDT_DOUBLE));
_types.insert(TypeMap::value_type("NUMERIC", MetaColumn::FDT_DOUBLE));
_types.insert(TypeMap::value_type("CHAR", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("CLOB", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("TEXT", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("VARCHAR", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("NCHAR", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("NCLOB", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("NTEXT", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("NVARCHAR", MetaColumn::FDT_STRING));
_types.insert(TypeMap::value_type("BLOB", MetaColumn::FDT_BLOB));
_types.insert(TypeMap::value_type("DATE", MetaColumn::FDT_DATE));
_types.insert(TypeMap::value_type("TIME", MetaColumn::FDT_TIME));
_types.insert(TypeMap::value_type("DATETIME", MetaColumn::FDT_TIMESTAMP));
_types.insert(TypeMap::value_type("TIMESTAMP", MetaColumn::FDT_TIMESTAMP));
}
}
std::string Utility::lastError(sqlite3* pDB)
{
return std::string(sqlite3_errmsg(pDB));
}
MetaColumn::ColumnDataType Utility::getColumnType(sqlite3_stmt* pStmt, std::size_t pos)
{
poco_assert_dbg (pStmt);
// Ensure statics are initialized
{
Poco::Mutex::ScopedLock lock(_mutex);
static Utility u;
}
const char* pc = sqlite3_column_decltype(pStmt, (int) pos);
std::string sqliteType = pc ? pc : "";
Poco::toUpperInPlace(sqliteType);
sqliteType = sqliteType.substr(0, sqliteType.find_first_of(" ("));
TypeMap::const_iterator it = _types.find(Poco::trimInPlace(sqliteType));
if (_types.end() == it) throw Poco::NotFoundException();
return it->second;
}
void Utility::throwException(int rc, const std::string& addErrMsg)
{
switch (rc)
{
case SQLITE_OK:
break;
case SQLITE_ERROR:
throw InvalidSQLStatementException(std::string("SQL error or missing database"), addErrMsg);
case SQLITE_INTERNAL:
throw InternalDBErrorException(std::string("An internal logic error in SQLite"), addErrMsg);
case SQLITE_PERM:
throw DBAccessDeniedException(std::string("Access permission denied"), addErrMsg);
case SQLITE_ABORT:
throw ExecutionAbortedException(std::string("Callback routine requested an abort"), addErrMsg);
case SQLITE_BUSY:
case SQLITE_BUSY_RECOVERY:
case SQLITE_BUSY_SNAPSHOT:
throw DBLockedException(std::string("The database file is locked"), addErrMsg);
case SQLITE_LOCKED:
throw TableLockedException(std::string("A table in the database is locked"), addErrMsg);
case SQLITE_NOMEM:
throw NoMemoryException(std::string("A malloc() failed"), addErrMsg);
case SQLITE_READONLY:
throw ReadOnlyException(std::string("Attempt to write a readonly database"), addErrMsg);
case SQLITE_INTERRUPT:
throw InterruptException(std::string("Operation terminated by sqlite_interrupt()"), addErrMsg);
case SQLITE_IOERR:
throw IOErrorException(std::string("Some kind of disk I/O error occurred"), addErrMsg);
case SQLITE_CORRUPT:
throw CorruptImageException(std::string("The database disk image is malformed"), addErrMsg);
case SQLITE_NOTFOUND:
throw TableNotFoundException(std::string("Table or record not found"), addErrMsg);
case SQLITE_FULL:
throw DatabaseFullException(std::string("Insertion failed because database is full"), addErrMsg);
case SQLITE_CANTOPEN:
throw CantOpenDBFileException(std::string("Unable to open the database file"), addErrMsg);
case SQLITE_PROTOCOL:
throw LockProtocolException(std::string("Database lock protocol error"), addErrMsg);
case SQLITE_EMPTY:
throw InternalDBErrorException(std::string("(Internal Only) Database table is empty"), addErrMsg);
case SQLITE_SCHEMA:
throw SchemaDiffersException(std::string("The database schema changed"), addErrMsg);
case SQLITE_TOOBIG:
throw RowTooBigException(std::string("Too much data for one row of a table"), addErrMsg);
case SQLITE_CONSTRAINT:
throw ConstraintViolationException(std::string("Abort due to constraint violation"), addErrMsg);
case SQLITE_MISMATCH:
throw DataTypeMismatchException(std::string("Data type mismatch"), addErrMsg);
case SQLITE_MISUSE:
throw InvalidLibraryUseException(std::string("Library used incorrectly"), addErrMsg);
case SQLITE_NOLFS:
throw OSFeaturesMissingException(std::string("Uses OS features not supported on host"), addErrMsg);
case SQLITE_AUTH:
throw AuthorizationDeniedException(std::string("Authorization denied"), addErrMsg);
case SQLITE_FORMAT:
throw CorruptImageException(std::string("Auxiliary database format error"), addErrMsg);
case SQLITE_NOTADB:
throw CorruptImageException(std::string("File opened that is not a database file"), addErrMsg);
case SQLITE_RANGE:
throw InvalidSQLStatementException(std::string("Bind Parameter out of range (Access of invalid position 0? bind starts with 1!)"), addErrMsg);
case SQLITE_ROW:
break; // sqlite_step() has another row ready
case SQLITE_DONE:
break; // sqlite_step() has finished executing
default:
throw SQLiteException(std::string("Unknown error code: ") + Poco::NumberFormatter::format(rc), addErrMsg);
}
}
bool Utility::fileToMemory(sqlite3* pInMemory, const std::string& fileName)
{
int rc;
sqlite3* pFile;
sqlite3_backup* pBackup;
rc = sqlite3_open_v2(fileName.c_str(), &pFile, SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, NULL);
if(rc == SQLITE_OK )
{
pBackup = sqlite3_backup_init(pInMemory, "main", pFile, "main");
if( pBackup )
{
sqlite3_backup_step(pBackup, -1);
sqlite3_backup_finish(pBackup);
}
rc = sqlite3_errcode(pFile);
}
sqlite3_close(pFile);
return SQLITE_OK == rc;
}
bool Utility::memoryToFile(const std::string& fileName, sqlite3* pInMemory)
{
int rc;
sqlite3* pFile;
sqlite3_backup* pBackup;
rc = sqlite3_open_v2(fileName.c_str(), &pFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI, NULL);
if(rc == SQLITE_OK )
{
pBackup = sqlite3_backup_init(pFile, "main", pInMemory, "main");
if( pBackup )
{
sqlite3_backup_step(pBackup, -1);
sqlite3_backup_finish(pBackup);
}
rc = sqlite3_errcode(pFile);
}
sqlite3_close(pFile);
return SQLITE_OK == rc;
}
bool Utility::isThreadSafe()
{
return 0 != sqlite3_threadsafe();
}
int Utility::getThreadMode()
{
return _threadMode;
}
bool Utility::setThreadMode(int mode)
{
#if (SQLITE_THREADSAFE != 0)
if (SQLITE_OK == sqlite3_shutdown())
{
if (SQLITE_OK == sqlite3_config(mode))
{
_threadMode = mode;
if (SQLITE_OK == sqlite3_initialize())
return true;
}
sqlite3_initialize();
}
#endif
return false;
}
void* Utility::eventHookRegister(sqlite3* pDB, UpdateCallbackType callbackFn, void* pParam)
{
typedef void(*pF)(void*, int, const char*, const char*, sqlite3_int64);
return sqlite3_update_hook(pDB, reinterpret_cast<pF>(callbackFn), pParam);
}
void* Utility::eventHookRegister(sqlite3* pDB, CommitCallbackType callbackFn, void* pParam)
{
return sqlite3_commit_hook(pDB, callbackFn, pParam);
}
void* Utility::eventHookRegister(sqlite3* pDB, RollbackCallbackType callbackFn, void* pParam)
{
return sqlite3_rollback_hook(pDB, callbackFn, pParam);
}
// NOTE: Utility::dbHandle() has been moved to SessionImpl.cpp,
// as a workaround for a failing AnyCast with Clang.
// See <https://github.com/pocoproject/poco/issues/578>
// for a discussion.
} } } // namespace Poco::Data::SQLite

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +0,0 @@
set(TESTUNIT "${LIBNAME}-testrunner")
# Sources
file(GLOB SRCS_G "src/*.cpp")
POCO_SOURCES_AUTO( TEST_SRCS ${SRCS_G})
# Headers
file(GLOB_RECURSE HDRS_G "src/*.h" )
POCO_HEADERS_AUTO( TEST_SRCS ${HDRS_G})
POCO_SOURCES_AUTO_PLAT( TEST_SRCS OFF
src/WinDriver.cpp
)
POCO_SOURCES_AUTO_PLAT( TEST_SRCS WINCE
src/WinCEDriver.cpp
)
add_executable( ${TESTUNIT} ${TEST_SRCS} )
add_test(NAME ${LIBNAME} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${TESTUNIT} -all)
target_link_libraries( ${TESTUNIT} PocoDataSQLite PocoData PocoFoundation CppUnit )

View File

@ -1,19 +0,0 @@
//
// Driver.cpp
//
// $Id: //poco/Main/Data/SQLite/testsuite/src/Driver.cpp#2 $
//
// Console-based test driver for Poco SQLite.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "CppUnit/TestRunner.h"
#include "SQLiteTestSuite.h"
CppUnitMain(SQLiteTestSuite)

File diff suppressed because it is too large Load Diff

View File

@ -1,165 +0,0 @@
//
// SQLiteTest.h
//
// $Id: //poco/Main/Data/SQLite/testsuite/src/SQLiteTest.h#4 $
//
// Definition of the SQLiteTest class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef SQLiteTest_INCLUDED
#define SQLiteTest_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "CppUnit/TestCase.h"
namespace Poco {
namespace Data {
class Session;
} }
class SQLiteTest: public CppUnit::TestCase
{
public:
SQLiteTest(const std::string& name);
~SQLiteTest();
void testBinding();
void testZeroRows();
void testSimpleAccess();
void testInMemory();
void testNullCharPointer();
void testInsertCharPointer();
void testInsertCharPointer2();
void testComplexType();
void testSimpleAccessVector();
void testComplexTypeVector();
void testSharedPtrComplexTypeVector();
void testInsertVector();
void testInsertEmptyVector();
void testAffectedRows();
void testInsertSingleBulk();
void testInsertSingleBulkVec();
void testLimit();
void testLimitOnce();
void testLimitPrepare();
void testLimitZero();
void testPrepare();
void testSetSimple();
void testSetComplex();
void testSetComplexUnique();
void testMultiSetSimple();
void testMultiSetComplex();
void testMapComplex();
void testMapComplexUnique();
void testMultiMapComplex();
void testSelectIntoSingle();
void testSelectIntoSingleStep();
void testSelectIntoSingleFail();
void testLowerLimitOk();
void testLowerLimitFail();
void testCombinedLimits();
void testCombinedIllegalLimits();
void testRange();
void testIllegalRange();
void testSingleSelect();
void testEmptyDB();
void testCLOB();
void testTuple1();
void testTupleVector1();
void testTuple2();
void testTupleVector2();
void testTuple3();
void testTupleVector3();
void testTuple4();
void testTupleVector4();
void testTuple5();
void testTupleVector5();
void testTuple6();
void testTupleVector6();
void testTuple7();
void testTupleVector7();
void testTuple8();
void testTupleVector8();
void testTuple9();
void testTupleVector9();
void testTuple10();
void testTupleVector10();
void testDateTime();
void testInternalExtraction();
void testPrimaryKeyConstraint();
void testNullable();
void testNulls();
void testRowIterator();
void testAsync();
void testAny();
void testDynamicAny();
void testPair();
void testSQLChannel();
void testSQLLogger();
void testExternalBindingAndExtraction();
void testBindingCount();
void testMultipleResults();
void testReconnect();
void testThreadModes();
void testUpdateCallback();
void testCommitCallback();
void testRollbackCallback();
void testNotifier();
void testSessionTransaction();
void testTransaction();
void testTransactor();
void testFTS3();
void setUp();
void tearDown();
static void sqliteUpdateCallbackFn(void*, int, const char*, const char*, Poco::Int64);
static int sqliteCommitCallbackFn(void*);
static void sqliteRollbackCallbackFn(void*);
void onInsert(const void* pSender);
void onUpdate(const void* pSender);
void onDelete(const void* pSender);
void onCommit(const void* pSender);
void onRollback(const void* pSender);
static CppUnit::Test* suite();
private:
void setTransactionIsolation(Poco::Data::Session& session, Poco::UInt32 ti);
static int _insertCounter;
static int _updateCounter;
static int _deleteCounter;
int _commitCounter;
int _rollbackCounter;
};
#endif // SQLiteTest_INCLUDED

View File

@ -1,24 +0,0 @@
//
// SQLiteTestSuite.cpp
//
// $Id: //poco/Main/Data/SQLite/testsuite/src/SQLiteTestSuite.cpp#2 $
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "SQLiteTestSuite.h"
#include "SQLiteTest.h"
CppUnit::Test* SQLiteTestSuite::suite()
{
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SQLiteTestSuite");
pSuite->addTest(SQLiteTest::suite());
return pSuite;
}

View File

@ -1,29 +0,0 @@
//
// SQLiteTestSuite.h
//
// $Id: //poco/Main/Data/SQLite/testsuite/src/SQLiteTestSuite.h#2 $
//
// Definition of the SQLiteTestSuite class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef SQLiteTestSuite_INCLUDED
#define SQLiteTestSuite_INCLUDED
#include "CppUnit/TestSuite.h"
class SQLiteTestSuite
{
public:
static CppUnit::Test* suite();
};
#endif // SQLiteTestSuite_INCLUDED

View File

@ -1,32 +0,0 @@
//
// WinCEDriver.cpp
//
// $Id: //poco/1.3-WinCE/Net/testsuite/src/WinCEDriver.cpp#2 $
//
// Console-based test driver for Windows CE.
//
// Copyright (c) 2004-2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "CppUnit/TestRunner.h"
#include "SQLiteTestSuite.h"
#include <cstdlib>
int wmain(int argc, wchar_t* argv[])
{
std::vector<std::string> args;
for (int i = 0; i < argc; ++i)
{
char buffer[1024];
std::wcstombs(buffer, argv[i], sizeof(buffer));
args.push_back(std::string(buffer));
}
CppUnit::TestRunner runner;
runner.addTest("SQLiteTestSuite", SQLiteTestSuite::suite());
return runner.run(args) ? 0 : 1;
}

View File

@ -1,30 +0,0 @@
//
// WinDriver.cpp
//
// $Id: //poco/Main/Data/SQLite/testsuite/src/WinDriver.cpp#2 $
//
// Windows test driver for Poco SQLite.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "WinTestRunner/WinTestRunner.h"
#include "SQLiteTestSuite.h"
class TestDriver: public CppUnit::WinTestRunnerApp
{
void TestMain()
{
CppUnit::WinTestRunner runner;
runner.addTest(SQLiteTestSuite::suite());
runner.run();
}
};
TestDriver theDriver;

View File

@ -9,7 +9,7 @@ if ($ENV{DISABLE_MONGODB})
set (DISABLE_MONGODB TRUE)
endif()
if (${DISABLE_MONGODB})
if (DISABLE_MONGODB)
add_definitions(-D DISABLE_MONGODB)
else()
set (LINK_MONGOCLIENT libmongoclient.a libssl.a libcrypto.a libboost_thread.a)

View File

@ -14,7 +14,7 @@ namespace DB
class JSONCompactRowOutputStream : public JSONRowOutputStream
{
public:
JSONCompactRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool write_statistics_);
JSONCompactRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool write_statistics_, bool force_quoting_64bit_integers_ = true);
void writeField(const IColumn & column, const IDataType & type, size_t row_num) override;
void writeFieldDelimiter() override;

View File

@ -14,7 +14,7 @@ namespace DB
class JSONEachRowRowOutputStream : public IRowOutputStream
{
public:
JSONEachRowRowOutputStream(WriteBuffer & ostr_, const Block & sample);
JSONEachRowRowOutputStream(WriteBuffer & ostr_, const Block & sample, bool force_quoting_64bit_integers_ = true);
void writeField(const IColumn & column, const IDataType & type, size_t row_num) override;
void writeFieldDelimiter() override;
@ -30,6 +30,7 @@ private:
WriteBuffer & ostr;
size_t field_number = 0;
Names fields;
bool force_quoting_64bit_integers;
};
}

View File

@ -16,7 +16,7 @@ class JSONRowOutputStream : public IRowOutputStream
{
public:
JSONRowOutputStream(WriteBuffer & ostr_, const Block & sample_,
bool write_statistics_);
bool write_statistics_, bool force_quoting_64bit_integers_ = true);
void writeField(const IColumn & column, const IDataType & type, size_t row_num) override;
void writeFieldDelimiter() override;
@ -68,6 +68,7 @@ protected:
Progress progress;
Stopwatch watch;
bool write_statistics;
bool force_quoting_64bit_integers;
};
}

View File

@ -53,7 +53,7 @@ public:
void deserializeTextEscaped(IColumn & column, ReadBuffer & istr) const override;
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override;
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override;
void serializeTextXML(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;

View File

@ -46,7 +46,7 @@ public:
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override;
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override;
void serializeTextXML(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;

View File

@ -58,7 +58,7 @@ public:
static_cast<ColumnType &>(column).getData().push_back(x); /// Важно делать это в конце - для exception safety.
}
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override
{
writeChar('"', ostr);
serializeText(column, row_num, ostr);

View File

@ -58,7 +58,7 @@ public:
static_cast<ColumnType &>(column).getData().push_back(x); /// Важно делать это в конце - для exception safety.
}
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override
{
writeChar('"', ostr);
serializeText(column, row_num, ostr);

View File

@ -81,7 +81,7 @@ public:
void deserializeTextEscaped(IColumn & column, ReadBuffer & istr) const override;
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override;
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override;
void serializeTextXML(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;

View File

@ -52,7 +52,7 @@ public:
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override;
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override;
void serializeTextXML(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;

View File

@ -39,7 +39,7 @@ public:
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override;
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override;
void serializeTextXML(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;

View File

@ -31,7 +31,7 @@ public:
void deserializeTextEscaped(IColumn & column, ReadBuffer & istr) const override;
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override;
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override;
void serializeTextXML(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;

View File

@ -87,9 +87,10 @@ public:
*/
virtual void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr) const = 0;
/** Текстовая сериализация в виде литерала для использования в формате JSON.
/** Text serialization intended for using in JSON format.
* force_quoting_64bit_integers parameter forces to brace UInt64 and Int64 types into quotes.
*/
virtual void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const = 0;
virtual void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool force_quoting_64bit_integers) const = 0;
virtual void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const = 0;
/** Текстовая сериализация для подстановки в формат XML.

View File

@ -38,7 +38,7 @@ public:
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override { throwNoSerialization(); }
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override { throwNoSerialization(); }
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override { throwNoSerialization(); }
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override { throwNoSerialization(); }
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override { throwNoSerialization(); }
void serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override { throwNoSerialization(); }

View File

@ -56,7 +56,7 @@ public:
deserializeText(column, istr);
}
inline void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
inline void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override;
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override
{
@ -121,7 +121,7 @@ public:
void deserializeTextEscaped(IColumn & column, ReadBuffer & istr) const override {}
void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {}
void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override {}
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {}
void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const override {}
void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override {}
void serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {}
void deserializeTextCSV(IColumn & column, ReadBuffer & istr, const char delimiter) const override {}
@ -129,26 +129,30 @@ public:
Field getDefault() const override { return {}; }
};
template <typename FType> inline void IDataTypeNumber<FType>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
template <typename FType> inline void IDataTypeNumber<FType>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const
{
serializeText(column, row_num, ostr);
}
template <> inline void IDataTypeNumber<Int64>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
template <> inline void IDataTypeNumber<Int64>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool force_quoting_64bit_integers) const
{
writeChar('"', ostr);
if (force_quoting_64bit_integers)
writeChar('"', ostr);
serializeText(column, row_num, ostr);
writeChar('"', ostr);
if (force_quoting_64bit_integers)
writeChar('"', ostr);
}
template <> inline void IDataTypeNumber<UInt64>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
template <> inline void IDataTypeNumber<UInt64>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool force_quoting_64bit_integers) const
{
writeChar('"', ostr);
if (force_quoting_64bit_integers)
writeChar('"', ostr);
serializeText(column, row_num, ostr);
writeChar('"', ostr);
if (force_quoting_64bit_integers)
writeChar('"', ostr);
}
template <> inline void IDataTypeNumber<Float32>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
template <> inline void IDataTypeNumber<Float32>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const
{
auto x = static_cast<const ColumnType &>(column).getData()[row_num];
if (likely(std::isfinite(x)))
@ -157,7 +161,7 @@ template <> inline void IDataTypeNumber<Float32>::serializeTextJSON(const IColum
writeCString("null", ostr);
}
template <> inline void IDataTypeNumber<Float64>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
template <> inline void IDataTypeNumber<Float64>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const
{
auto x = static_cast<const ColumnType &>(column).getData()[row_num];
if (likely(std::isfinite(x)))

View File

@ -80,8 +80,9 @@ private:
using Shared = std::shared_ptr<ContextShared>;
Shared shared;
String user; /// Текущий пользователь.
Poco::Net::IPAddress ip_address; /// IP-адрес, с которого задан запрос.
String user; /// Current user
Poco::Net::IPAddress ip_address; /// IP address
UInt16 port; /// and port, from which current query was recieved
Interface interface = Interface::TCP;
HTTPMethod http_method = HTTPMethod::UNKNOWN; /// NOTE Возможно, перенести это в отдельный struct ClientInfo.
@ -121,9 +122,10 @@ public:
ConfigurationPtr getUsersConfig();
void setUser(const String & name, const String & password, const Poco::Net::IPAddress & address, const String & quota_key);
void setUser(const String & name, const String & password, const Poco::Net::IPAddress & address, UInt16 port, const String & quota_key);
String getUser() const { return user; }
Poco::Net::IPAddress getIPAddress() const { return ip_address; }
UInt16 getPort() const { return port; }
Interface getInterface() const { return interface; }
void setInterface(Interface interface_) { interface = interface_; }

View File

@ -33,6 +33,7 @@ struct ProcessInfo
String user;
String query_id;
Poco::Net::IPAddress ip_address;
UInt16 port;
double elapsed_seconds;
size_t rows;
size_t bytes;
@ -48,6 +49,7 @@ struct ProcessListElement
String user;
String query_id;
Poco::Net::IPAddress ip_address;
UInt16 port;
Stopwatch watch;
@ -67,9 +69,9 @@ struct ProcessListElement
ProcessListElement(const String & query_, const String & user_,
const String & query_id_, const Poco::Net::IPAddress & ip_address_,
size_t max_memory_usage, double memory_tracker_fault_probability,
UInt16 port_, size_t max_memory_usage, double memory_tracker_fault_probability,
QueryPriorities::Handle && priority_handle_)
: query(query_), user(user_), query_id(query_id_), ip_address(ip_address_), memory_tracker(max_memory_usage),
: query(query_), user(user_), query_id(query_id_), ip_address(ip_address_), port(port_), memory_tracker(max_memory_usage),
priority_handle(std::move(priority_handle_))
{
memory_tracker.setDescription("(for query)");
@ -101,6 +103,7 @@ struct ProcessListElement
.user = user,
.query_id = query_id,
.ip_address = ip_address,
.port = port,
.elapsed_seconds = watch.elapsedSeconds(),
.rows = progress.rows,
.bytes = progress.bytes,
@ -184,7 +187,7 @@ public:
* Если времени не хватило - кинуть исключение.
*/
EntryPtr insert(const String & query_, const String & user_, const String & query_id_, const Poco::Net::IPAddress & ip_address_,
const Settings & settings);
UInt16 port_, const Settings & settings);
/// Количество одновременно выполняющихся запросов.
size_t size() const { return cur_size; }

View File

@ -225,7 +225,10 @@ struct Settings
M(SettingBool, add_http_cors_header, false) \
\
/** Skip columns with unknown names from input data (it works for JSONEachRow and TSKV formats). */ \
M(SettingBool, input_format_skip_unknown_fields, false)
M(SettingBool, input_format_skip_unknown_fields, false) \
\
/** Controls quoting of 64-bit integers in JSON output format. */ \
M(SettingBool, output_format_json_quote_64bit_integers, true)
/// Всевозможные ограничения на выполнение запроса.
Limits limits;

View File

@ -26,8 +26,10 @@
#include <DB/IO/ReadBufferFromFileDescriptor.h>
#include <DB/IO/WriteBufferFromFileDescriptor.h>
#include <DB/IO/WriteBufferFromFile.h>
#include <DB/IO/ReadHelpers.h>
#include <DB/IO/WriteHelpers.h>
#include <DB/IO/Operators.h>
#include <DB/DataStreams/RemoteBlockInputStream.h>
@ -38,8 +40,8 @@
#include "InterruptListener.h"
/** Инструмент для измерения производительности ClickHouse
* при выполнении запросов с фиксированным количеством одновременных запросов.
/** A tool for evaluating ClickHouse performance.
* The tool emulates a case with fixed amount of simultaneously executing queries.
*/
namespace DB
@ -58,12 +60,13 @@ public:
Benchmark(unsigned concurrency_, double delay_,
const String & host_, UInt16 port_, const String & default_database_,
const String & user_, const String & password_, const String & stage,
bool randomize_,
const Settings & settings_)
: concurrency(concurrency_), delay(delay_), queue(concurrency),
bool randomize_, size_t max_iterations_, double max_time_,
const String & json_path_, const Settings & settings_)
:
concurrency(concurrency_), delay(delay_), queue(concurrency),
connections(concurrency, host_, port_, default_database_, user_, password_),
randomize(randomize_),
settings(settings_), pool(concurrency)
randomize(randomize_), max_iterations(max_iterations_), max_time(max_time_),
json_path(json_path_), settings(settings_), pool(concurrency)
{
std::cerr << std::fixed << std::setprecision(3);
@ -76,6 +79,11 @@ public:
else
throw Exception("Unknown query processing stage: " + stage, ErrorCodes::BAD_ARGUMENTS);
if (!json_path.empty() && Poco::File(json_path).exists()) /// Clear file with previous results
{
Poco::File(json_path).remove();
}
readQueries();
run();
}
@ -94,6 +102,9 @@ private:
ConnectionPool connections;
bool randomize;
size_t max_iterations;
double max_time;
String json_path;
Settings settings;
QueryProcessingStage::Enum query_processing_stage;
@ -183,18 +194,13 @@ private:
Stopwatch watch;
/// В цикле, кладём все запросы в очередь.
for (size_t i = 0; !interrupt_listener.check(); ++i)
for (size_t i = 0; !max_iterations || i < max_iterations; ++i)
{
if (i >= queries.size())
i = 0;
size_t query_index = randomize
? distribution(generator)
: i;
size_t query_index = randomize ? distribution(generator) : i % queries.size();
queue.push(queries[query_index]);
if (watch.elapsedSeconds() > delay)
if (delay > 0 && watch.elapsedSeconds() > delay)
{
auto total_queries = 0;
{
@ -206,6 +212,18 @@ private:
report(info_per_interval);
watch.restart();
}
if (max_time > 0 && info_total.watch.elapsedSeconds() >= max_time)
{
std::cout << "Stopping launch of queries. Requested time limit is exhausted.\n";
break;
}
if (interrupt_listener.check())
{
std::cout << "Stopping launch of queries. SIGINT recieved.\n";
break;
}
}
/// Попросим потоки завершиться.
@ -214,6 +232,9 @@ private:
pool.wait();
info_total.watch.stop();
if (!json_path.empty())
reportJSON(info_total, json_path);
printNumberOfQueriesExecuted(info_total.queries);
report(info_total);
}
@ -320,17 +341,67 @@ private:
<< "result MiB/s: " << (info.result_bytes / seconds / 1048576) << "."
<< "\n";
for (size_t percent = 0; percent <= 90; percent += 10)
auto print_percentile = [&](double percent)
{
std::cerr << percent << "%\t" << info.sampler.quantileInterpolated(percent / 100.0) << " sec." << std::endl;
};
std::cerr << "95%\t" << info.sampler.quantileInterpolated(0.95) << " sec.\n";
std::cerr << "99%\t" << info.sampler.quantileInterpolated(0.99) << " sec.\n";
std::cerr << "99.9%\t" << info.sampler.quantileInterpolated(0.999) << " sec.\n";
std::cerr << "99.99%\t" << info.sampler.quantileInterpolated(0.9999) << " sec.\n";
std::cerr << "100%\t" << info.sampler.quantileInterpolated(1) << " sec.\n";
for (int percent = 0; percent <= 90; percent += 10)
print_percentile(percent);
print_percentile(95);
print_percentile(99);
print_percentile(99.9);
print_percentile(99.99);
info.clear();
}
void reportJSON(Stats & info, const std::string & filename)
{
WriteBufferFromFile json_out(filename);
std::lock_guard<std::mutex> lock(mutex);
auto print_key_value = [&](auto key, auto value, bool with_comma = true)
{
json_out << double_quote << key << ": " << value << (with_comma ? ",\n" : "\n");
};
auto print_percentile = [&](auto percent, bool with_comma = true)
{
json_out << "\"" << percent << "\"" << ": " << info.sampler.quantileInterpolated(percent / 100.0) << (with_comma ? ",\n" : "\n");
};
json_out << "{\n";
json_out << double_quote << "statistics" << ": {\n";
double seconds = info.watch.elapsedSeconds();
print_key_value("QPS", info.queries / seconds);
print_key_value("RPS", info.queries / seconds);
print_key_value("MiBPS", info.queries / seconds);
print_key_value("RPS_result", info.queries / seconds);
print_key_value("MiBPS_result", info.queries / seconds);
print_key_value("num_queries", info.queries / seconds, false);
json_out << "},\n";
json_out << double_quote << "query_time_percentiles" << ": {\n";
for (int percent = 0; percent <= 90; percent += 10)
print_percentile(percent);
print_percentile(95);
print_percentile(99);
print_percentile(99.9);
print_percentile(99.99, false);
json_out << "}\n";
json_out << "}\n";
}
};
}
@ -342,18 +413,24 @@ int main(int argc, char ** argv)
try
{
using boost::program_options::value;
boost::program_options::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("concurrency,c", boost::program_options::value<unsigned>()->default_value(1), "number of parallel queries")
("delay,d", boost::program_options::value<double>()->default_value(1), "delay between reports in seconds")
("host,h", boost::program_options::value<std::string>()->default_value("localhost"), "")
("port", boost::program_options::value<UInt16>()->default_value(9000), "")
("user", boost::program_options::value<std::string>()->default_value("default"), "")
("password", boost::program_options::value<std::string>()->default_value(""), "")
("database", boost::program_options::value<std::string>()->default_value("default"), "")
("stage", boost::program_options::value<std::string>()->default_value("complete"), "request query processing up to specified stage")
("randomize,r", boost::program_options::value<bool>()->default_value(false), "randomize order of execution")
("help", "produce help message")
("concurrency,c", value<unsigned>()->default_value(1), "number of parallel queries")
("delay,d", value<double>()->default_value(1), "delay between intermediate reports in seconds (set 0 to disable reports)")
("stage", value<std::string>()->default_value("complete"), "request query processing up to specified stage")
("iterations,i", value<size_t>()->default_value(0), "amount of queries to be executed")
("timelimit,t", value<double>()->default_value(0.), "stop launch of queries after specified time limit")
("randomize,r", value<bool>()->default_value(false), "randomize order of execution")
("json", value<std::string>()->default_value(""), "write final report to specified file in JSON format")
("host,h", value<std::string>()->default_value("localhost"), "")
("port", value<UInt16>()->default_value(9000), "")
("user", value<std::string>()->default_value("default"), "")
("password", value<std::string>()->default_value(""), "")
("database", value<std::string>()->default_value("default"), "")
#define DECLARE_SETTING(TYPE, NAME, DEFAULT) (#NAME, boost::program_options::value<std::string> (), "Settings.h")
#define DECLARE_LIMIT(TYPE, NAME, DEFAULT) (#NAME, boost::program_options::value<std::string> (), "Limits.h")
APPLY_FOR_SETTINGS(DECLARE_SETTING)
@ -392,6 +469,9 @@ int main(int argc, char ** argv)
options["password"].as<std::string>(),
options["stage"].as<std::string>(),
options["randomize"].as<bool>(),
options["iterations"].as<size_t>(),
options["timelimit"].as<double>(),
options["json"].as<std::string>(),
settings);
}
catch (const Exception & e)

View File

@ -135,12 +135,13 @@ static BlockOutputStreamPtr getOutputImpl(const String & name, WriteBuffer & buf
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<ValuesRowOutputStream>(buf));
else if (name == "JSON")
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<JSONRowOutputStream>(buf, sample,
context.getSettingsRef().output_format_write_statistics));
context.getSettingsRef().output_format_write_statistics, context.getSettingsRef().output_format_json_quote_64bit_integers));
else if (name == "JSONCompact")
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<JSONCompactRowOutputStream>(buf, sample,
context.getSettingsRef().output_format_write_statistics));
context.getSettingsRef().output_format_write_statistics, context.getSettingsRef().output_format_json_quote_64bit_integers));
else if (name == "JSONEachRow")
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<JSONEachRowRowOutputStream>(buf, sample));
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<JSONEachRowRowOutputStream>(buf, sample,
context.getSettingsRef().output_format_json_quote_64bit_integers));
else if (name == "XML")
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<XMLRowOutputStream>(buf, sample,
context.getSettingsRef().output_format_write_statistics));

View File

@ -6,15 +6,15 @@
namespace DB
{
JSONCompactRowOutputStream::JSONCompactRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool write_statistics_)
: JSONRowOutputStream(ostr_, sample_, write_statistics_)
JSONCompactRowOutputStream::JSONCompactRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool write_statistics_, bool force_quoting_64bit_integers_)
: JSONRowOutputStream(ostr_, sample_, write_statistics_, force_quoting_64bit_integers_)
{
}
void JSONCompactRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num)
{
type.serializeTextJSON(column, row_num, *ostr);
type.serializeTextJSON(column, row_num, *ostr, force_quoting_64bit_integers);
++field_number;
}
@ -56,7 +56,7 @@ void JSONCompactRowOutputStream::writeTotals()
writeChar(',', *ostr);
const ColumnWithTypeAndName & column = totals.getByPosition(i);
column.type->serializeTextJSON(*column.column.get(), 0, *ostr);
column.type->serializeTextJSON(*column.column.get(), 0, *ostr, force_quoting_64bit_integers);
}
writeChar(']', *ostr);
@ -64,7 +64,7 @@ void JSONCompactRowOutputStream::writeTotals()
}
static void writeExtremesElement(const char * title, const Block & extremes, size_t row_num, WriteBuffer & ostr)
static void writeExtremesElement(const char * title, const Block & extremes, size_t row_num, WriteBuffer & ostr, bool force_quoting_64bit_integers)
{
writeCString("\t\t\"", ostr);
writeCString(title, ostr);
@ -77,7 +77,7 @@ static void writeExtremesElement(const char * title, const Block & extremes, siz
writeChar(',', ostr);
const ColumnWithTypeAndName & column = extremes.getByPosition(i);
column.type->serializeTextJSON(*column.column.get(), row_num, ostr);
column.type->serializeTextJSON(*column.column.get(), row_num, ostr, force_quoting_64bit_integers);
}
writeChar(']', ostr);
@ -92,9 +92,9 @@ void JSONCompactRowOutputStream::writeExtremes()
writeCString("\t\"extremes\":\n", *ostr);
writeCString("\t{\n", *ostr);
writeExtremesElement("min", extremes, 0, *ostr);
writeExtremesElement("min", extremes, 0, *ostr, force_quoting_64bit_integers);
writeCString(",\n", *ostr);
writeExtremesElement("max", extremes, 1, *ostr);
writeExtremesElement("max", extremes, 1, *ostr, force_quoting_64bit_integers);
writeChar('\n', *ostr);
writeCString("\t}", *ostr);

View File

@ -7,8 +7,8 @@ namespace DB
{
JSONEachRowRowOutputStream::JSONEachRowRowOutputStream(WriteBuffer & ostr_, const Block & sample)
: ostr(ostr_)
JSONEachRowRowOutputStream::JSONEachRowRowOutputStream(WriteBuffer & ostr_, const Block & sample, bool force_quoting_64bit_integers_)
: ostr(ostr_), force_quoting_64bit_integers(force_quoting_64bit_integers_)
{
size_t columns = sample.columns();
fields.resize(columns);
@ -25,7 +25,7 @@ void JSONEachRowRowOutputStream::writeField(const IColumn & column, const IDataT
{
writeString(fields[field_number], ostr);
writeChar(':', ostr);
type.serializeTextJSON(column, row_num, ostr);
type.serializeTextJSON(column, row_num, ostr, force_quoting_64bit_integers);
++field_number;
}

View File

@ -7,8 +7,8 @@ namespace DB
{
JSONRowOutputStream::JSONRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool write_statistics_)
: dst_ostr(ostr_), write_statistics(write_statistics_)
JSONRowOutputStream::JSONRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool write_statistics_, bool force_quoting_64bit_integers_)
: dst_ostr(ostr_), write_statistics(write_statistics_), force_quoting_64bit_integers(force_quoting_64bit_integers_)
{
NamesAndTypesList columns(sample_.getColumnsList());
fields.assign(columns.begin(), columns.end());
@ -72,7 +72,7 @@ void JSONRowOutputStream::writeField(const IColumn & column, const IDataType & t
writeCString("\t\t\t", *ostr);
writeString(fields[field_number].name, *ostr);
writeCString(": ", *ostr);
type.serializeTextJSON(column, row_num, *ostr);
type.serializeTextJSON(column, row_num, *ostr, force_quoting_64bit_integers);
++field_number;
}
@ -152,7 +152,7 @@ void JSONRowOutputStream::writeTotals()
writeCString("\t\t", *ostr);
writeJSONString(column.name, *ostr);
writeCString(": ", *ostr);
column.type->serializeTextJSON(*column.column.get(), 0, *ostr);
column.type->serializeTextJSON(*column.column.get(), 0, *ostr, force_quoting_64bit_integers);
}
writeChar('\n', *ostr);
@ -161,7 +161,7 @@ void JSONRowOutputStream::writeTotals()
}
static void writeExtremesElement(const char * title, const Block & extremes, size_t row_num, WriteBuffer & ostr)
static void writeExtremesElement(const char * title, const Block & extremes, size_t row_num, WriteBuffer & ostr, bool force_quoting_64bit_integers)
{
writeCString("\t\t\"", ostr);
writeCString(title, ostr);
@ -179,7 +179,7 @@ static void writeExtremesElement(const char * title, const Block & extremes, siz
writeCString("\t\t\t", ostr);
writeJSONString(column.name, ostr);
writeCString(": ", ostr);
column.type->serializeTextJSON(*column.column.get(), row_num, ostr);
column.type->serializeTextJSON(*column.column.get(), row_num, ostr, force_quoting_64bit_integers);
}
writeChar('\n', ostr);
@ -195,9 +195,9 @@ void JSONRowOutputStream::writeExtremes()
writeCString("\t\"extremes\":\n", *ostr);
writeCString("\t{\n", *ostr);
writeExtremesElement("min", extremes, 0, *ostr);
writeExtremesElement("min", extremes, 0, *ostr, force_quoting_64bit_integers);
writeCString(",\n", *ostr);
writeExtremesElement("max", extremes, 1, *ostr);
writeExtremesElement("max", extremes, 1, *ostr, force_quoting_64bit_integers);
writeChar('\n', *ostr);
writeCString("\t}", *ostr);

View File

@ -62,7 +62,7 @@ try
//copyData(row_input, row_output);
BlockInputStreamFromRowInputStream in(std::make_shared<TabSeparatedRowInputStream>(in_buf, sample, true, true), sample);
BlockOutputStreamFromRowOutputStream out(std::make_shared<JSONRowOutputStream>(out_buf, sample, false));
BlockOutputStreamFromRowOutputStream out(std::make_shared<JSONRowOutputStream>(out_buf, sample, false, true));
copyData(in, out);
}

View File

@ -195,7 +195,7 @@ void DataTypeAggregateFunction::deserializeTextQuoted(IColumn & column, ReadBuff
}
void DataTypeAggregateFunction::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
void DataTypeAggregateFunction::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const
{
writeJSONString(serializeToString(function, column, row_num), ostr);
}

View File

@ -288,7 +288,7 @@ void DataTypeArray::deserializeTextQuoted(IColumn & column, ReadBuffer & istr) c
}
void DataTypeArray::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
void DataTypeArray::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool force_quoting_64bit_integers) const
{
const ColumnArray & column_array = static_cast<const ColumnArray &>(column);
const ColumnArray::Offsets_t & offsets = column_array.getOffsets();
@ -303,7 +303,7 @@ void DataTypeArray::serializeTextJSON(const IColumn & column, size_t row_num, Wr
{
if (i != offset)
writeChar(',', ostr);
nested->serializeTextJSON(nested_column, i, ostr);
nested->serializeTextJSON(nested_column, i, ostr, force_quoting_64bit_integers);
}
writeChar(']', ostr);
}

View File

@ -170,7 +170,7 @@ void DataTypeEnum<Type>::deserializeTextQuoted(IColumn & column, ReadBuffer & is
}
template <typename Type>
void DataTypeEnum<Type>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
void DataTypeEnum<Type>::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const
{
writeJSONString(getNameForValue(static_cast<const ColumnType &>(column).getData()[row_num]), ostr);
}

View File

@ -158,7 +158,7 @@ void DataTypeFixedString::deserializeTextQuoted(IColumn & column, ReadBuffer & i
}
void DataTypeFixedString::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
void DataTypeFixedString::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const
{
const char * pos = reinterpret_cast<const char *>(&static_cast<const ColumnFixedString &>(column).getChars()[n * row_num]);
writeJSONString(pos, pos + n, ostr);

View File

@ -266,7 +266,7 @@ void DataTypeString::deserializeTextQuoted(IColumn & column, ReadBuffer & istr)
}
void DataTypeString::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
void DataTypeString::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool) const
{
writeJSONString(static_cast<const ColumnString &>(column).getDataAt(row_num), ostr);
}

View File

@ -144,14 +144,14 @@ void DataTypeTuple::deserializeTextQuoted(IColumn & column, ReadBuffer & istr) c
deserializeText(column, istr);
}
void DataTypeTuple::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const
void DataTypeTuple::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, bool force_quoting_64bit_integers) const
{
writeChar('[', ostr);
for (const auto i : ext::range(0, ext::size(elems)))
{
if (i != 0)
writeChar(',', ostr);
elems[i]->serializeTextJSON(extractElementColumn(column, i), row_num, ostr);
elems[i]->serializeTextJSON(extractElementColumn(column, i), row_num, ostr, force_quoting_64bit_integers);
}
writeChar(']', ostr);
}

View File

@ -283,7 +283,7 @@ ConfigurationPtr Context::getUsersConfig()
}
void Context::setUser(const String & name, const String & password, const Poco::Net::IPAddress & address, const String & quota_key)
void Context::setUser(const String & name, const String & password, const Poco::Net::IPAddress & address, UInt16 port, const String & quota_key)
{
auto lock = getLock();
@ -291,8 +291,9 @@ void Context::setUser(const String & name, const String & password, const Poco::
setSetting("profile", user_props.profile);
setQuota(user_props.quota, quota_key, name, address);
user = name;
ip_address = address;
this->user = name;
this->ip_address = address;
this->port = port;
}

View File

@ -12,7 +12,7 @@ namespace ErrorCodes
ProcessList::EntryPtr ProcessList::insert(
const String & query_, const String & user_, const String & query_id_, const Poco::Net::IPAddress & ip_address_,
const Settings & settings)
UInt16 port_, const Settings & settings)
{
EntryPtr res;
@ -54,7 +54,7 @@ ProcessList::EntryPtr ProcessList::insert(
++cur_size;
res = std::make_shared<Entry>(*this, cont.emplace(cont.end(),
query_, user_, query_id_, ip_address_,
query_, user_, query_id_, ip_address_, port_,
settings.limits.max_memory_usage, settings.memory_tracker_fault_probability,
priorities.insert(settings.priority)));

View File

@ -184,6 +184,7 @@ static std::tuple<ASTPtr, BlockIO> executeQueryImpl(
context.getUser(),
context.getCurrentQueryId(),
context.getIPAddress(),
context.getPort(),
settings);
context.setProcessListElement(&process_list_entry->get());

View File

@ -108,7 +108,7 @@ void HTTPHandler::processQuery(
Context context = *server.global_context;
context.setGlobalContext(*server.global_context);
context.setUser(user, password, request.clientAddress().host(), quota_key);
context.setUser(user, password, request.clientAddress().host(), request.clientAddress().port(), quota_key);
context.setCurrentQueryId(query_id);
std::unique_ptr<ReadBuffer> in_param = std::make_unique<ReadBufferFromString>(query_param);

View File

@ -464,7 +464,7 @@ void TCPHandler::receiveHello()
<< (!user.empty() ? ", user: " + user : "")
<< ".");
connection_context.setUser(user, password, socket().peerAddress().host(), "");
connection_context.setUser(user, password, socket().peerAddress().host(), socket().peerAddress().port(), "");
}

View File

@ -15,6 +15,7 @@ StorageSystemProcesses::StorageSystemProcesses(const std::string & name_)
, columns{
{ "user", std::make_shared<DataTypeString>() },
{ "address", std::make_shared<DataTypeString>() },
{ "port", std::make_shared<DataTypeUInt16>() },
{ "elapsed", std::make_shared<DataTypeFloat64>() },
{ "rows_read", std::make_shared<DataTypeUInt64>() },
{ "bytes_read", std::make_shared<DataTypeUInt64>() },
@ -46,6 +47,7 @@ BlockInputStreams StorageSystemProcesses::read(
ColumnWithTypeAndName col_user{std::make_shared<ColumnString>(), std::make_shared<DataTypeString>(), "user"};
ColumnWithTypeAndName col_address{std::make_shared<ColumnString>(), std::make_shared<DataTypeString>(), "address"};
ColumnWithTypeAndName col_port{std::make_shared<ColumnUInt16>(), std::make_shared<DataTypeUInt16>(), "port"};
ColumnWithTypeAndName col_elapsed{std::make_shared<ColumnFloat64>(), std::make_shared<DataTypeFloat64>(), "elapsed"};
ColumnWithTypeAndName col_rows_read{std::make_shared<ColumnUInt64>(), std::make_shared<DataTypeUInt64>(), "rows_read"};
ColumnWithTypeAndName col_bytes_read{std::make_shared<ColumnUInt64>(), std::make_shared<DataTypeUInt64>(), "bytes_read"};
@ -60,6 +62,7 @@ BlockInputStreams StorageSystemProcesses::read(
{
col_user.column->insert(process.user);
col_address.column->insert(process.ip_address.toString());
col_port.column->insert(static_cast<UInt64>(process.port));
col_elapsed.column->insert(process.elapsed_seconds);
col_rows_read.column->insert(process.rows);
col_bytes_read.column->insert(process.bytes);
@ -72,6 +75,7 @@ BlockInputStreams StorageSystemProcesses::read(
Block block{
col_user,
col_address,
col_port,
col_elapsed,
col_rows_read,
col_bytes_read,

View File

@ -1,4 +1,5 @@
clickhouse-client -n --query "DROP TABLE IF EXISTS test.json_noisy; CREATE TABLE test.json_noisy (d1 UInt8, d2 String) ENGINE = Memory"
#!/bin/bash
clickhouse-client -n --query "DROP TABLE IF EXISTS test.json_noisy; CREATE TABLE test.json_noisy (d1 UInt8, d2 String) ENGINE = Memory"
echo '{"d1" : 1, "d2" : "ok"}
{ }
@ -7,4 +8,4 @@ echo '{"d1" : 1, "d2" : "ok"}
{"d2":"ok","t1":[[[]],true, null, false, "1","2", 0.03, 1], "d1":"1", "t2":["1","2"]}' \
| clickhouse-client -n --query "SET input_format_skip_unknown_fields = 1; INSERT INTO test.json_noisy FORMAT JSONEachRow"
clickhouse-client -n --query "SELECT * FROM test.json_noisy; DROP TABLE IF EXISTS test.json_noisy;"
clickhouse-client -n --query "SELECT * FROM test.json_noisy; DROP TABLE IF EXISTS test.json_noisy;"

View File

@ -4,8 +4,7 @@ CREATE TABLE test.group_uniq_str ENGINE = Memory AS SELECT number % 10 as id, to
INSERT INTO test.group_uniq_str SELECT 2 as id, toString(number % 100) as v FROM system.numbers LIMIT 1000000;
INSERT INTO test.group_uniq_str SELECT 5 as id, toString(number % 100) as v FROM system.numbers LIMIT 10000000;
SELECT length(groupUniqArray(v)) FROM test.group_uniq_str GROUP BY id ORDER BY id
UNION ALL
SELECT length(groupUniqArray(v)) FROM test.group_uniq_str GROUP BY id ORDER BY id;
SELECT length(groupUniqArray(v)) FROM remote('127.0.0.{1,2,3,4}', 'test', 'group_uniq_str') GROUP BY id ORDER BY id;
DROP TABLE IF EXISTS test.group_uniq_str;

View File

@ -3,8 +3,7 @@ CREATE TABLE test.group_uniq_arr_int ENGINE = Memory AS
SELECT g as id, if(c == 0, [v], if(c == 1, emptyArrayInt64(), [v, v])) as v FROM
(SELECT intDiv(number%1000000, 100) as v, intDiv(number%100, 10) as g, number%10 as c FROM system.numbers WHERE c < 3 LIMIT 10000000);
SELECT length(groupUniqArray(v)) FROM test.group_uniq_arr_int GROUP BY id ORDER BY id
UNION ALL
SELECT length(groupUniqArray(v)) FROM test.group_uniq_arr_int GROUP BY id ORDER BY id;
SELECT length(groupUniqArray(v)) FROM remote('127.0.0.{1,2,3,4}', 'test', 'group_uniq_arr_int') GROUP BY id ORDER BY id;
DROP TABLE IF EXISTS test.group_uniq_arr_int;

View File

@ -3,8 +3,7 @@ CREATE TABLE test.group_uniq_arr_str ENGINE = Memory AS
SELECT hex(intHash32(g)) as id, if(c == 0, [hex(v)], if(c == 1, emptyArrayString(), [hex(v), hex(v)])) as v FROM
(SELECT intDiv(number%1000000, 100) as v, intDiv(number%100, 10) as g, number%10 as c FROM system.numbers WHERE c < 3 LIMIT 10000000);
SELECT length(groupUniqArray(v)) FROM test.group_uniq_arr_str GROUP BY id ORDER BY id
UNION ALL
SELECT length(groupUniqArray(v)) FROM test.group_uniq_arr_str GROUP BY id ORDER BY id;
SELECT length(groupUniqArray(v)) FROM remote('127.0.0.{1,2,3,4}', 'test', 'group_uniq_arr_str') GROUP BY id ORDER BY id;
DROP TABLE IF EXISTS test.group_uniq_arr_str;

View File

@ -0,0 +1,264 @@
{
"meta":
[
{
"name": "i0",
"type": "Int64"
},
{
"name": "u0",
"type": "UInt64"
},
{
"name": "ip",
"type": "Int64"
},
{
"name": "in",
"type": "Int64"
},
{
"name": "up",
"type": "UInt64"
},
{
"name": "arr",
"type": "Array(Int64)"
},
{
"name": "tuple",
"type": "Tuple(UInt64, UInt64)"
}
],
"data":
[
{
"i0": "0",
"u0": "0",
"ip": "9223372036854775807",
"in": "-9223372036854775808",
"up": "18446744073709551615",
"arr": ["0"],
"tuple": ["0","0"]
}
],
"totals":
{
"i0": "0",
"u0": "0",
"ip": "0",
"in": "0",
"up": "0",
"arr": [],
"tuple": ["0","0"]
},
"extremes":
{
"min":
{
"i0": "0",
"u0": "0",
"ip": "9223372036854775807",
"in": "-9223372036854775808",
"up": "18446744073709551615",
"arr": [],
"tuple": ["0","0"]
},
"max":
{
"i0": "0",
"u0": "0",
"ip": "9223372036854775807",
"in": "-9223372036854775808",
"up": "18446744073709551615",
"arr": [],
"tuple": ["0","0"]
}
},
"rows": 1
}
{
"meta":
[
{
"name": "i0",
"type": "Int64"
},
{
"name": "u0",
"type": "UInt64"
},
{
"name": "ip",
"type": "Int64"
},
{
"name": "in",
"type": "Int64"
},
{
"name": "up",
"type": "UInt64"
},
{
"name": "arr",
"type": "Array(Int64)"
},
{
"name": "tuple",
"type": "Tuple(UInt64, UInt64)"
}
],
"data":
[
["0", "0", "9223372036854775807", "-9223372036854775808", "18446744073709551615", ["0"], ["0","0"]]
],
"totals": ["0","0","0","0","0",[],["0","0"]],
"extremes":
{
"min": ["0","0","9223372036854775807","-9223372036854775808","18446744073709551615",[],["0","0"]],
"max": ["0","0","9223372036854775807","-9223372036854775808","18446744073709551615",[],["0","0"]]
},
"rows": 1
}
{"i0":"0","u0":"0","ip":"9223372036854775807","in":"-9223372036854775808","up":"18446744073709551615","arr":["0"],"tuple":["0","0"]}
{
"meta":
[
{
"name": "i0",
"type": "Int64"
},
{
"name": "u0",
"type": "UInt64"
},
{
"name": "ip",
"type": "Int64"
},
{
"name": "in",
"type": "Int64"
},
{
"name": "up",
"type": "UInt64"
},
{
"name": "arr",
"type": "Array(Int64)"
},
{
"name": "tuple",
"type": "Tuple(UInt64, UInt64)"
}
],
"data":
[
{
"i0": 0,
"u0": 0,
"ip": 9223372036854775807,
"in": -9223372036854775808,
"up": 18446744073709551615,
"arr": [0],
"tuple": [0,0]
}
],
"totals":
{
"i0": 0,
"u0": 0,
"ip": 0,
"in": 0,
"up": 0,
"arr": [],
"tuple": [0,0]
},
"extremes":
{
"min":
{
"i0": 0,
"u0": 0,
"ip": 9223372036854775807,
"in": -9223372036854775808,
"up": 18446744073709551615,
"arr": [],
"tuple": [0,0]
},
"max":
{
"i0": 0,
"u0": 0,
"ip": 9223372036854775807,
"in": -9223372036854775808,
"up": 18446744073709551615,
"arr": [],
"tuple": [0,0]
}
},
"rows": 1
}
{
"meta":
[
{
"name": "i0",
"type": "Int64"
},
{
"name": "u0",
"type": "UInt64"
},
{
"name": "ip",
"type": "Int64"
},
{
"name": "in",
"type": "Int64"
},
{
"name": "up",
"type": "UInt64"
},
{
"name": "arr",
"type": "Array(Int64)"
},
{
"name": "tuple",
"type": "Tuple(UInt64, UInt64)"
}
],
"data":
[
[0, 0, 9223372036854775807, -9223372036854775808, 18446744073709551615, [0], [0,0]]
],
"totals": [0,0,0,0,0,[],[0,0]],
"extremes":
{
"min": [0,0,9223372036854775807,-9223372036854775808,18446744073709551615,[],[0,0]],
"max": [0,0,9223372036854775807,-9223372036854775808,18446744073709551615,[],[0,0]]
},
"rows": 1
}
{"i0":0,"u0":0,"ip":9223372036854775807,"in":-9223372036854775808,"up":18446744073709551615,"arr":[0],"tuple":[0,0]}

View File

@ -0,0 +1,12 @@
SET output_format_write_statistics = 0;
SET extremes = 1;
SET output_format_json_quote_64bit_integers = 1;
SELECT toInt64(0) as i0, toUInt64(0) as u0, toInt64(9223372036854775807) as ip, toInt64(-9223372036854775808) as in, toUInt64(18446744073709551615) as up, [toInt64(0)] as arr, (toUInt64(0), toUInt64(0)) as tuple WITH TOTALS FORMAT JSON;
SELECT toInt64(0) as i0, toUInt64(0) as u0, toInt64(9223372036854775807) as ip, toInt64(-9223372036854775808) as in, toUInt64(18446744073709551615) as up, [toInt64(0)] as arr, (toUInt64(0), toUInt64(0)) as tuple WITH TOTALS FORMAT JSONCompact;
SELECT toInt64(0) as i0, toUInt64(0) as u0, toInt64(9223372036854775807) as ip, toInt64(-9223372036854775808) as in, toUInt64(18446744073709551615) as up, [toInt64(0)] as arr, (toUInt64(0), toUInt64(0)) as tuple WITH TOTALS FORMAT JSONEachRow;
SET output_format_json_quote_64bit_integers = 0;
SELECT toInt64(0) as i0, toUInt64(0) as u0, toInt64(9223372036854775807) as ip, toInt64(-9223372036854775808) as in, toUInt64(18446744073709551615) as up, [toInt64(0)] as arr, (toUInt64(0), toUInt64(0)) as tuple WITH TOTALS FORMAT JSON;
SELECT toInt64(0) as i0, toUInt64(0) as u0, toInt64(9223372036854775807) as ip, toInt64(-9223372036854775808) as in, toUInt64(18446744073709551615) as up, [toInt64(0)] as arr, (toUInt64(0), toUInt64(0)) as tuple WITH TOTALS FORMAT JSONCompact;
SELECT toInt64(0) as i0, toUInt64(0) as u0, toInt64(9223372036854775807) as ip, toInt64(-9223372036854775808) as in, toUInt64(18446744073709551615) as up, [toInt64(0)] as arr, (toUInt64(0), toUInt64(0)) as tuple WITH TOTALS FORMAT JSONEachRow;

View File

@ -0,0 +1,4 @@
#!/bin/bash
set -e
curl --local-port 1390 'http://localhost:8123?query=SELECT%20port%20FROM%20system.processes%20ORDER%20BY%20elapsed%20LIMIT%201'

View File

@ -6616,12 +6616,17 @@ Allows setting a default sampling coefficient for all SELECT queries.
(For tables that don&#39;t support sampling, an exception will be thrown.)
If set to 1, default sampling is not performed.
====input_format_skip_unknown_fields==
==input_format_skip_unknown_fields==
If the parameter is true, INSERT operation will skip columns with unknown names from input.
Otherwise, an exception will be generated.
Otherwise, an exception will be generated, it is default behavior.
The parameter works only for JSONEachRow and TSKV input formats.
==output_format_json_quote_64bit_integers==
If the parameter is true (default value), UInt64 and Int64 numbers are printed as quoted strings in all JSON output formats.
Such behavior is compatible with most JavaScript interpreters that stores all numbers as double-precision floating point numbers.
Otherwise, they are printed as regular numbers.
==Restrictions on query complexity==

View File

@ -3881,7 +3881,7 @@ Extremes:
}
%%
JSON совместим с JavaScript. Для этого, дополнительно эскейпятся некоторые символы: символ прямого слеша %%/%% экранируется в виде %%\/%%; альтернативные переводы строк %%U+2028%%, %%U+2029%%, на которых ломаются некоторые браузеры, экранируются в виде <span class="inline-example">\u<i>XXXX</i></span>-последовательностей. Эскейпятся ASCII control characters: backspace, form feed, line feed, carriage return, horizontal tab в виде %%\b%%, %%\f%%, %%\n%%, %%\r%%, %%\t%% соответственно, а также остальные байты из диапазона 00-1F с помощью <span class="inline-example">\u<i>XXXX</i></span>-последовательностей. Невалидные UTF-8 последовательности заменяются на replacement character %%<25>%% и, таким образом, выводимый текст будет состоять из валидных UTF-8 последовательностей. Числа типа UInt64 и Int64, для совместимости с JavaScript, выводятся в двойных кавычках.
JSON совместим с JavaScript. Для этого, дополнительно эскейпятся некоторые символы: символ прямого слеша %%/%% экранируется в виде %%\/%%; альтернативные переводы строк %%U+2028%%, %%U+2029%%, на которых ломаются некоторые браузеры, экранируются в виде <span class="inline-example">\u<i>XXXX</i></span>-последовательностей. Эскейпятся ASCII control characters: backspace, form feed, line feed, carriage return, horizontal tab в виде %%\b%%, %%\f%%, %%\n%%, %%\r%%, %%\t%% соответственно, а также остальные байты из диапазона 00-1F с помощью <span class="inline-example">\u<i>XXXX</i></span>-последовательностей. Невалидные UTF-8 последовательности заменяются на replacement character %%<25>%% и, таким образом, выводимый текст будет состоять из валидных UTF-8 последовательностей. Числа типа UInt64 и Int64, для совместимости с JavaScript, по-умолчанию выводятся в двойных кавычках, чтобы они выводились без кавычек можно установить конфигурационный параметр output_format_json_quote_64bit_integers равным 0.
%%rows%% - общее количество выведенных строчек.
%%rows_before_limit_at_least%% - не менее скольких строчек получилось бы, если бы не было LIMIT-а. Выводится только если запрос содержит LIMIT.
@ -6775,6 +6775,10 @@ regions_names_*.txt: TabSeparated (без заголовка), столбцы:
Если значение истино, то при выполнении INSERT из входных данных пропускаются (не рассматриваются) колонки с неизвестными именами, иначе в данной ситуации будет сгенерировано исключение.
Работает для форматов JSONEachRow и TSKV.
==output_format_json_quote_64bit_integers==
Если значение истино, то при использовании JSON* форматов UInt64 и Int64 числа выводятся в кавычках (из соображений совместимости с большинством реализаций JavaScript), иначе - без кавычек.
==Ограничения на сложность запроса==