diff options
Diffstat (limited to 'libodb-qt/odb/qt')
95 files changed, 7175 insertions, 0 deletions
diff --git a/libodb-qt/odb/qt/basic.options b/libodb-qt/odb/qt/basic.options new file mode 100644 index 0000000..306d949 --- /dev/null +++ b/libodb-qt/odb/qt/basic.options @@ -0,0 +1,4 @@ +# file : odb/qt/basic.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/basic/basic diff --git a/libodb-qt/odb/qt/basic/basic-common.options b/libodb-qt/odb/qt/basic/basic-common.options new file mode 100644 index 0000000..f704314 --- /dev/null +++ b/libodb-qt/odb/qt/basic/basic-common.options @@ -0,0 +1,4 @@ +# file : odb/qt/basic/basic-common.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version diff --git a/libodb-qt/odb/qt/basic/basic-mssql.options b/libodb-qt/odb/qt/basic/basic-mssql.options new file mode 100644 index 0000000..2234df5 --- /dev/null +++ b/libodb-qt/odb/qt/basic/basic-mssql.options @@ -0,0 +1,13 @@ +# file : odb/qt/basic/basic-mssql.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/basic/mssql/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/basic/mssql/qstring-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/mssql/qbyte-array-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/mssql/quuid-traits.hxx>' diff --git a/libodb-qt/odb/qt/basic/basic-mysql.options b/libodb-qt/odb/qt/basic/basic-mysql.options new file mode 100644 index 0000000..d049f4e --- /dev/null +++ b/libodb-qt/odb/qt/basic/basic-mysql.options @@ -0,0 +1,13 @@ +# file : odb/qt/basic/basic-mysql.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/basic/mysql/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/basic/mysql/qstring-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/mysql/qbyte-array-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/mysql/quuid-traits.hxx>' diff --git a/libodb-qt/odb/qt/basic/basic-oracle.options b/libodb-qt/odb/qt/basic/basic-oracle.options new file mode 100644 index 0000000..60ef9d0 --- /dev/null +++ b/libodb-qt/odb/qt/basic/basic-oracle.options @@ -0,0 +1,13 @@ +# file : odb/qt/basic/basic-oracle.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/basic/oracle/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/basic/oracle/qstring-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/oracle/qbyte-array-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/oracle/quuid-traits.hxx>' diff --git a/libodb-qt/odb/qt/basic/basic-pgsql.options b/libodb-qt/odb/qt/basic/basic-pgsql.options new file mode 100644 index 0000000..6f0dc6e --- /dev/null +++ b/libodb-qt/odb/qt/basic/basic-pgsql.options @@ -0,0 +1,13 @@ +# file : odb/qt/basic/basic-pgsql.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/basic/pgsql/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/basic/pgsql/qstring-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/pgsql/qbyte-array-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/pgsql/quuid-traits.hxx>' diff --git a/libodb-qt/odb/qt/basic/basic-sqlite.options b/libodb-qt/odb/qt/basic/basic-sqlite.options new file mode 100644 index 0000000..c64e37c --- /dev/null +++ b/libodb-qt/odb/qt/basic/basic-sqlite.options @@ -0,0 +1,13 @@ +# file : odb/qt/basic/basic-sqlite.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/basic/sqlite/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/basic/sqlite/qstring-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/sqlite/qbyte-array-traits.hxx>' +--hxx-prologue '#include <odb/qt/basic/sqlite/quuid-traits.hxx>' diff --git a/libodb-qt/odb/qt/basic/mssql/default-mapping.hxx b/libodb-qt/odb/qt/basic/mssql/default-mapping.hxx new file mode 100644 index 0000000..19fd43b --- /dev/null +++ b/libodb-qt/odb/qt/basic/mssql/default-mapping.hxx @@ -0,0 +1,29 @@ +// file : odb/qt/basic/mssql/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_MSSQL_DEFAULT_MAPPING_HXX +#define ODB_QT_BASIC_MSSQL_DEFAULT_MAPPING_HXX + +#include <QtCore/QString> +#include <QtCore/QByteArray> +#include <QtCore/QUuid> + +// By default map QString to SQL Server VARCHAR(512) for non-id members +// and to VARCHAR(256) for id members (the same as the default mapping +// for std::string). Allow NULL values by default as QString provides +// a null representation. +// +#pragma db value(QString) type("VARCHAR(512)") id_type("VARCHAR(256)") null + +// By default map QByteArray to SQL Server VARBINARY(max). Allow NULL +// values by default as QByteArray provides a null representation. +// +#pragma db value(QByteArray) type("VARBINARY(max)") null + +// By default map QUuid to SQL Server UNIQUEIDENTIFIER and use NULL to +// represent null UUIDs. If NULL is disabled (e.g., at the member level), +// then we store the null UUID (i.e., all bytes are zero). +// +#pragma db value(QUuid) type("UNIQUEIDENTIFIER") null + +#endif // ODB_QT_BASIC_MSSQL_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/basic/mssql/qbyte-array-traits.hxx b/libodb-qt/odb/qt/basic/mssql/qbyte-array-traits.hxx new file mode 100644 index 0000000..8047691 --- /dev/null +++ b/libodb-qt/odb/qt/basic/mssql/qbyte-array-traits.hxx @@ -0,0 +1,177 @@ +// file : odb/qt/basic/mssql/qbyte-array-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_MSSQL_QBYTE_ARRAY_TRAITS_HXX +#define ODB_QT_BASIC_MSSQL_QBYTE_ARRAY_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t +#include <cassert> + +#include <QtCore/QByteArray> + +#include <odb/mssql/traits.hxx> + +namespace odb +{ + namespace mssql + { + template <> + struct default_value_traits<QByteArray, id_binary> + { + typedef QByteArray value_type; + typedef QByteArray query_type; + typedef char* image_type; + + static void + set_value (QByteArray& v, const char* b, std::size_t n, bool is_null) + { + if (is_null) + v = QByteArray (); + else + { + // Note that we cannot use replace() here since a suitable + // overload was only added in Qt 4.7. + // + v.resize (static_cast<int> (n)); + std::memcpy (v.data (), b, n); + } + } + + static void + set_image (char* b, + std::size_t c, + std::size_t& n, + bool& is_null, + const QByteArray& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + n = static_cast<std::size_t> (v.size ()); + + if (n > c) + n = c; + + std::memcpy (b, v.constData (), n); + } + } + }; + + template <> + struct default_value_traits<QByteArray, id_long_binary> + { + typedef QByteArray value_type; + typedef QByteArray query_type; + typedef long_callback image_type; + + static void + set_value (QByteArray& v, + result_callback_type& cb, + void*& context) + { + cb = &result_callback; + context = &v; + } + + static void + set_image (param_callback_type& cb, + const void*& context, + bool& is_null, + const QByteArray& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + cb = ¶m_callback; + context = &v; + } + } + + static void + param_callback (const void* context, + std::size_t*, + const void** buffer, + std::size_t* size, + chunk_type* chunk, + void*, + std::size_t) + { + const QByteArray& v (*static_cast<const QByteArray*> (context)); + + *buffer = v.constData (); + *size = static_cast<std::size_t> (v.size ()); + *chunk = chunk_one; + } + + static void + result_callback (void* context, + std::size_t*, + void** buffer, + std::size_t* size, + chunk_type chunk, + std::size_t size_left, + void*, + std::size_t) + { + QByteArray& v (*static_cast<QByteArray*> (context)); + + switch (chunk) + { + case chunk_null: + { + v = QByteArray (); + break; + } + case chunk_one: + { + v.clear (); + break; + } + case chunk_first: + { + // The Native Client ODBC driver seems to always be able to + // return the total size. This makes things simple and + // efficient. + // + assert (size_left != 0); + + v.resize (static_cast<int> (size_left)); + *buffer = v.data (); + *size = size_left; + break; + } + case chunk_next: + { + // We should never get here. + // + assert (false); + break; + } + case chunk_last: + { + // Nothing to do here. The array is already of the correct size + // and should contain the data. + break; + } + } + } + }; + + template <> + struct default_type_traits<QByteArray> + { + static const database_type_id db_type_id = id_long_binary; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_MSSQL_QBYTE_ARRAY_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/mssql/qstring-traits.hxx b/libodb-qt/odb/qt/basic/mssql/qstring-traits.hxx new file mode 100644 index 0000000..779120e --- /dev/null +++ b/libodb-qt/odb/qt/basic/mssql/qstring-traits.hxx @@ -0,0 +1,372 @@ +// file : odb/qt/basic/mssql/qstring-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_MSSQL_QSTRING_TRAITS_HXX +#define ODB_QT_BASIC_MSSQL_QSTRING_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t +#include <cassert> + +#include <QtCore/QString> + +#include <odb/mssql/traits.hxx> + +namespace odb +{ + namespace mssql + { + template <> + struct default_value_traits<QString, id_string> + { + typedef QString value_type; + typedef QString query_type; + typedef char* image_type; + + static void + set_value (QString& v, + const char* b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QString (); + else + // On Windows the string data is in Windows code page. On Linux + // it is always UTF-8. + // +#ifdef _WIN32 + v = QString::fromLocal8Bit (b, static_cast<int> (n)); +#else + v = QString::fromUtf8 (b, static_cast<int> (n)); +#endif + } + + static void + set_image (char* b, + std::size_t c, + std::size_t& n, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + +#ifdef _WIN32 + const QByteArray& a (v.toLocal8Bit ()); +#else + const QByteArray& a (v.toUtf8 ()); +#endif + n = static_cast<std::size_t> (a.size ()); + + if (n > c) + n = c; + + std::memcpy (b, a.constData (), n); + } + } + }; + + template <> + struct default_value_traits<QString, id_nstring> + { + typedef QString value_type; + typedef QString query_type; + typedef ucs2_char* image_type; + + static void + set_value (QString& v, + const ucs2_char* b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QString (); + else + { + // Note that we cannot use replace() here since a suitable + // overload was only added in Qt 4.7. + // + v.resize (static_cast<int> (n)); + std::memcpy (v.data (), b, n * 2); + } + } + + static void + set_image (ucs2_char* b, + std::size_t c, + std::size_t& n, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + n = static_cast<std::size_t> (v.size ()); + + if (n > c) + n = c; + + std::memcpy (b, v.constData (), n * 2); + } + } + }; + + template <> + struct default_value_traits<QString, id_long_string> + { + typedef QString value_type; + typedef QString query_type; + typedef long_callback image_type; + + static void + set_value (QString& v, + result_callback_type& cb, + void*& context) + { + cb = &result_callback; + context = &v; + } + + static void + set_image (param_callback_type& cb, + const void*& context, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + cb = ¶m_callback; + context = &v; + } + } + + static void + param_callback (const void* context, + std::size_t* position, + const void** buffer, + std::size_t* size, + chunk_type* chunk, + void* tmp_buf, + std::size_t tmp_capacity) + { + const QString& s (*static_cast<const QString*> (context)); + +#ifdef _WIN32 + const QByteArray& v (s.toLocal8Bit ()); +#else + const QByteArray& v (s.toUtf8 ()); +#endif + + *size = static_cast<std::size_t> (v.size ()); + + if (*position == 0) + { + if (*size <= tmp_capacity) + *chunk = chunk_one; + else + { + *size = tmp_capacity; + *chunk = chunk_first; + } + } + else + { + *size -= *position; + + if (*size <= tmp_capacity) + *chunk = chunk_last; + else + { + *size = tmp_capacity; + *chunk = chunk_next; + } + } + + //@@ We might split a multi-byte sequence. Microsoft ODBC driver + // doesn't support this. + // + std::memcpy (tmp_buf, v.constData () + *position, *size); + *buffer = tmp_buf; + *position += *size; + } + + static void + result_callback (void* context, + std::size_t*, + void** buffer, + std::size_t* size, + chunk_type chunk, + std::size_t, + void* tmp_buf, + std::size_t tmp_capacity) + { + QString& v (*static_cast<QString*> (context)); + + switch (chunk) + { + case chunk_null: + { + v = QString (); + break; + } + case chunk_one: + { + v.clear (); + break; + } + case chunk_first: + { + break; + } + case chunk_next: + case chunk_last: + { + // Append the data from the temporary buffer. + // +#ifdef _WIN32 + v += QString::fromLocal8Bit (static_cast<char*> (tmp_buf), + static_cast<int> (*size)); +#else + v += QString::fromUtf8 (static_cast<char*> (tmp_buf), + static_cast<int> (*size)); +#endif + break; + } + } + + if (chunk == chunk_first || chunk == chunk_next) + { + *buffer = tmp_buf; + *size = tmp_capacity; + } + } + }; + + template <> + struct default_value_traits<QString, id_long_nstring> + { + typedef QString value_type; + typedef QString query_type; + typedef long_callback image_type; + + static void + set_value (QString& v, + result_callback_type& cb, + void*& context) + { + cb = &result_callback; + context = &v; + } + + static void + set_image (param_callback_type& cb, + const void*& context, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + cb = ¶m_callback; + context = &v; + } + } + + static void + param_callback (const void* context, + std::size_t*, + const void** buffer, + std::size_t* size, + chunk_type* chunk, + void*, + std::size_t) + { + const QString& v (*static_cast<const QString*> (context)); + + *buffer = v.constData (); + *size = static_cast<std::size_t> (v.size ()) * 2; + *chunk = chunk_one; + } + + static void + result_callback (void* context, + std::size_t*, + void** buffer, + std::size_t* size, + chunk_type chunk, + std::size_t size_left, + void*, + std::size_t) + { + QString& v (*static_cast<QString*> (context)); + + switch (chunk) + { + case chunk_null: + { + v = QString (); + break; + } + case chunk_one: + { + v.clear (); + break; + } + case chunk_first: + { + // The Native Client ODBC driver seems to always be able to + // return the total size. This makes things simple and + // efficient. + // + assert (size_left != 0); + + size_left /= 2; // Convert to characters. + size_left++; // One extra for the null terminator. + + v.resize (static_cast<int> (size_left)); + *buffer = v.data (); + *size = size_left * 2; // In bytes. + break; + } + case chunk_next: + { + // We should never get here. + // + assert (false); + break; + } + case chunk_last: + { + // Get rid of the null terminator. + // + v.resize (static_cast<int> (*size / 2)); + break; + } + } + } + }; + + template <> + struct default_type_traits<QString> + { + static const database_type_id db_type_id = id_long_string; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_MSSQL_QSTRING_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/mssql/quuid-traits.hxx b/libodb-qt/odb/qt/basic/mssql/quuid-traits.hxx new file mode 100644 index 0000000..d65b80f --- /dev/null +++ b/libodb-qt/odb/qt/basic/mssql/quuid-traits.hxx @@ -0,0 +1,58 @@ +// file : odb/qt/basic/mssql/uuid-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_MSSQL_UUID_TRAITS_HXX +#define ODB_QT_BASIC_MSSQL_UUID_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy + +#include <QtCore/QUuid> + +#include <odb/mssql/traits.hxx> + +namespace odb +{ + namespace mssql + { + template <> + class default_value_traits<QUuid, id_uniqueidentifier> + { + public: + typedef QUuid value_type; + typedef value_type query_type; + typedef uniqueidentifier image_type; + + static void + set_value (value_type& v, const uniqueidentifier& i, bool is_null) + { + if (!is_null) + std::memcpy (&v.data1, &i, 16); + else + v = QUuid (); + } + + static void + set_image (uniqueidentifier& i, bool& is_null, const value_type& v) + { + // If we can, store nil as NULL. Otherwise, store it as a value. + // + is_null = is_null && v.isNull (); + + if (!is_null) + std::memcpy (&i, &v.data1, 16); + } + }; + + template <> + struct default_type_traits<QUuid> + { + static const database_type_id db_type_id = id_uniqueidentifier; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_MSSQL_UUID_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/mysql/default-mapping.hxx b/libodb-qt/odb/qt/basic/mysql/default-mapping.hxx new file mode 100644 index 0000000..996895f --- /dev/null +++ b/libodb-qt/odb/qt/basic/mysql/default-mapping.hxx @@ -0,0 +1,28 @@ +// file : odb/qt/basic/mysql/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_MYSQL_DEFAULT_MAPPING_HXX +#define ODB_QT_BASIC_MYSQL_DEFAULT_MAPPING_HXX + +#include <QtCore/QString> +#include <QtCore/QByteArray> +#include <QtCore/QUuid> + +// Map QString to MySQL TEXT for non-id and to VARCHAR(128) for id members. +// MySQL cannot have primary key of the TEXT type. Allow NULL values by +// default as QString provides a null representation. +// +#pragma db value(QString) type("TEXT") id_type("VARCHAR(128)") null + +// Map QByteArray to MySQL BLOB by default. Allow NULL values by default as +// QByteArray provides a null representation. +// +#pragma db value(QByteArray) type("BLOB") null + +// By default map QUuid to MySQL BINARY(16) and use NULL to represent null +// UUIDs. If NULL is disabled (e.g., at the member level), then we store +// the null UUID (i.e., all bytes are zero). +// +#pragma db value(QUuid) type("BINARY(16)") null + +#endif // ODB_QT_BASIC_MYSQL_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/basic/mysql/qbyte-array-traits.hxx b/libodb-qt/odb/qt/basic/mysql/qbyte-array-traits.hxx new file mode 100644 index 0000000..bfcfc69 --- /dev/null +++ b/libodb-qt/odb/qt/basic/mysql/qbyte-array-traits.hxx @@ -0,0 +1,78 @@ +// file : odb/qt/basic/mysql/qbyte-array-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_MYSQL_QBYTE_ARRAY_TRAITS_HXX +#define ODB_QT_BASIC_MYSQL_QBYTE_ARRAY_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t + +#include <QtCore/QByteArray> + +#include <odb/details/buffer.hxx> +#include <odb/mysql/traits.hxx> + +namespace odb +{ + namespace mysql + { + template <> + struct default_value_traits<QByteArray, id_blob> + { + typedef QByteArray value_type; + typedef QByteArray query_type; + typedef details::buffer image_type; + + static void + set_value (QByteArray& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QByteArray (); + else + { + // Note that we cannot use replace() here since a suitable + // overload was only added in Qt 4.7. + // + v.resize (static_cast<int> (n)); + std::memcpy (v.data (), b.data (), n); + } + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const QByteArray& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + n = static_cast<std::size_t> (v.size ()); + + if (n > b.capacity ()) + b.capacity (n); + + std::memcpy (b.data (), v.data (), n); + } + } + }; + + template <> + struct default_type_traits<QByteArray> + { + static const database_type_id db_type_id = id_blob; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_MYSQL_QBYTE_ARRAY_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/mysql/qstring-traits.hxx b/libodb-qt/odb/qt/basic/mysql/qstring-traits.hxx new file mode 100644 index 0000000..6a5f315 --- /dev/null +++ b/libodb-qt/odb/qt/basic/mysql/qstring-traits.hxx @@ -0,0 +1,93 @@ +// file : odb/qt/basic/mysql/qstring-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_MYSQL_QSTRING_TRAITS_HXX +#define ODB_QT_BASIC_MYSQL_QSTRING_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t + +#include <QtCore/QString> + +#include <odb/details/buffer.hxx> +#include <odb/mysql/traits.hxx> + +namespace odb +{ + namespace mysql + { + class qstring_value_traits + { + public: + typedef QString value_type; + typedef QString query_type; + typedef details::buffer image_type; + + static void + set_value (QString& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QString (); + else + v = QString::fromUtf8 (b.data (), static_cast<int> (n)); + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + const QByteArray& a (v.toUtf8 ()); + n = static_cast<std::size_t> (a.size ()); + + if (n > b.capacity ()) + b.capacity (n); + + std::memcpy (b.data (), a.data (), n); + } + } + }; + + template <> + struct default_value_traits<QString, id_string>: qstring_value_traits + { + }; + + template <> + struct default_value_traits<QString, id_decimal>: qstring_value_traits + { + }; + + template <> + struct default_value_traits<QString, id_enum>: qstring_value_traits + { + }; + + template <> + struct default_value_traits<QString, id_set>: qstring_value_traits + { + }; + + template <> + struct default_type_traits<QString> + { + static const database_type_id db_type_id = id_string; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_MYSQL_QSTRING_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/mysql/quuid-traits.hxx b/libodb-qt/odb/qt/basic/mysql/quuid-traits.hxx new file mode 100644 index 0000000..c672ee8 --- /dev/null +++ b/libodb-qt/odb/qt/basic/mysql/quuid-traits.hxx @@ -0,0 +1,74 @@ +// file : odb/qt/basic/mysql/uuid-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_MYSQL_UUID_TRAITS_HXX +#define ODB_QT_BASIC_MYSQL_UUID_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cassert> + +#include <QtCore/QUuid> + +#include <odb/mysql/traits.hxx> + +namespace odb +{ + namespace mysql + { + template <> + struct default_value_traits<QUuid, id_blob> + { + typedef QUuid value_type; + typedef value_type query_type; + typedef details::buffer image_type; + + static void + set_value (value_type& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + if (!is_null) + { + assert (n == 16); + std::memcpy (&v.data1, b.data (), 16); + } + else + v = QUuid (); + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const value_type& v) + { + // If we can, store nil as NULL. Otherwise, store it as a value. + // + is_null = is_null && v.isNull (); + + if (!is_null) + { + n = 16; + + if (n > b.capacity ()) + b.capacity (n); + + std::memcpy (b.data (), &v.data1, n); + } + } + }; + + template <> + struct default_type_traits<QUuid> + { + static const database_type_id db_type_id = id_blob; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_MYSQL_UUID_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/oracle/default-mapping.hxx b/libodb-qt/odb/qt/basic/oracle/default-mapping.hxx new file mode 100644 index 0000000..8d72206 --- /dev/null +++ b/libodb-qt/odb/qt/basic/oracle/default-mapping.hxx @@ -0,0 +1,27 @@ +// file : odb/qt/basic/oracle/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_ORACLE_DEFAULT_MAPPING_HXX +#define ODB_QT_BASIC_ORACLE_DEFAULT_MAPPING_HXX + +#include <QtCore/QString> +#include <QtCore/QByteArray> +#include <QtCore/QUuid> + +// Map QString to Oracle VARCHAR2 by default. Allow NULL values by default as +// QString provides a null representation. +// +#pragma db value(QString) type("VARCHAR2(512)") null + +// Map QByteArray to Oracle BLOB by default. Allow NULL values by default as +// QByteArray provides a null representation. +// +#pragma db value(QByteArray) type("BLOB") null + +// By default map QUuid to Oracle RAW(16) and use NULL to represent null +// UUIDs. If NULL is disabled (e.g., at the member level), then we store +// the null UUID (i.e., all bytes are zero). +// +#pragma db value(QUuid) type("RAW(16)") null + +#endif // ODB_QT_BASIC_ORACLE_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/basic/oracle/qbyte-array-traits.hxx b/libodb-qt/odb/qt/basic/oracle/qbyte-array-traits.hxx new file mode 100644 index 0000000..6979cc9 --- /dev/null +++ b/libodb-qt/odb/qt/basic/oracle/qbyte-array-traits.hxx @@ -0,0 +1,167 @@ +// file : odb/qt/basic/oracle/qbyte-array-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_ORACLE_QBYTE_ARRAY_TRAITS_HXX +#define ODB_QT_BASIC_ORACLE_QBYTE_ARRAY_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t + +#include <QtCore/QByteArray> + +#include <odb/oracle/traits.hxx> + +namespace odb +{ + namespace oracle + { + template <> + struct default_value_traits<QByteArray, id_raw> + { + typedef QByteArray value_type; + typedef QByteArray query_type; + typedef char* image_type; + + static void + set_value (QByteArray& v, + const char* b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QByteArray (); + else + { + // Note that we cannot use replace() here since a suitable + // overload was only added in Qt 4.7. + // + v.resize (static_cast<int> (n)); + std::memcpy (v.data (), b, n); + } + } + + static void + set_image (char* b, + std::size_t c, + std::size_t& n, + bool& is_null, + const QByteArray& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + n = static_cast<std::size_t> (v.size ()); + + if (n > c) + n = c; + + std::memcpy (b, v.constData (), n); + } + } + }; + + template <> + struct default_value_traits<QByteArray, id_blob> + { + typedef QByteArray value_type; + typedef QByteArray query_type; + typedef lob_callback image_type; + + static void + set_value (QByteArray& v, + result_callback_type& cb, + void*& context, + bool is_null) + { + if (is_null) + v = QByteArray (); + else + { + cb = &result_callback; + context = &v; + } + } + + static void + set_image (param_callback_type& cb, + const void*& context, + bool& is_null, + const QByteArray& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + cb = ¶m_callback; + context = &v; + } + } + + static bool + result_callback (void* context, + ub4*, + void* b, + ub4 s, + chunk_position p) + { + QByteArray& v (*static_cast<QByteArray*> (context)); + + switch (p) + { + case chunk_one: + case chunk_first: + { + v.clear (); + + // Falling through. + } + case chunk_next: + case chunk_last: + { + v.append (static_cast<char*> (b), static_cast<int> (s)); + break; + } + } + + return true; + } + + static bool + param_callback (const void* context, + ub4*, + const void** b, + ub4* s, + chunk_position* p, + void*, + ub4) + { + const QByteArray& v (*static_cast<const QByteArray*> (context)); + + *p = chunk_one; + *s = static_cast<ub4> (v.size ()); + *b = v.constData (); + + return true; + } + }; + + template <> + struct default_type_traits<QByteArray> + { + // Allow use of QByteArray in query expressions by default by specifying + // the default type id as RAW. + // + static const database_type_id db_type_id = id_raw; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_ORACLE_QBYTE_ARRAY_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/oracle/qstring-traits.hxx b/libodb-qt/odb/qt/basic/oracle/qstring-traits.hxx new file mode 100644 index 0000000..418d30e --- /dev/null +++ b/libodb-qt/odb/qt/basic/oracle/qstring-traits.hxx @@ -0,0 +1,206 @@ +// file : odb/qt/basic/oracle/qstring-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_ORACLE_QSTRING_TRAITS_HXX +#define ODB_QT_BASIC_ORACLE_QSTRING_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t + +#include <QtCore/QString> + +#include <odb/oracle/traits.hxx> + +namespace odb +{ + namespace oracle + { + struct qstring_value_traits + { + public: + typedef QString value_type; + typedef QString query_type; + typedef char* image_type; + + static void + set_value (QString& v, + const char* b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QString (); + else + v = QString::fromUtf8 (b, static_cast<int> (n)); + } + + static void + set_image (char* b, + std::size_t c, + std::size_t& n, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + const QByteArray& a (v.toUtf8 ()); + + n = static_cast<std::size_t> (a.size ()); + + if (n > c) + n = c; + + std::memcpy (b, a.constData (), n); + } + } + }; + + template <> + struct default_value_traits <QString, id_string>: qstring_value_traits + { + }; + + template <> + struct default_value_traits <QString, id_nstring>: qstring_value_traits + { + }; + + class qstring_lob_value_traits + { + public: + typedef QString value_type; + typedef QString query_type; + typedef lob_callback image_type; + + static void + set_value (QString& v, + result_callback_type& cb, + void*& context, + bool is_null) + { + if (is_null) + v = QString (); + else + { + cb = &result_callback; + context = &v; + } + } + + static void + set_image (param_callback_type& cb, + const void*& context, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + cb = ¶m_callback; + context = &v; + } + } + + static bool + result_callback (void* context, + ub4*, + void* b, + ub4 s, + chunk_position p) + { + QString& v (*static_cast<QString*> (context)); + + switch (p) + { + case chunk_one: + case chunk_first: + { + v.clear (); + + // Falling through. + } + case chunk_next: + case chunk_last: + { + v += QString::fromUtf8(static_cast<char*> (b), + static_cast<int> (s)); + break; + } + } + + return true; + } + + static bool + param_callback (const void* context, + ub4* position_context, + const void** b, + ub4* s, + chunk_position* p, + void* temp_buffer, + ub4 capacity) + { + const QByteArray& v (static_cast<const QString*> (context)->toUtf8 ()); + + *s = static_cast<ub4> (v.size ()); + + if (*position_context == 0) + { + if (*s <= capacity) + *p = chunk_one; + else + { + *s = capacity; + *p = chunk_first; + } + } + else + { + *s -= *position_context; + + if (*s <= capacity) + *p = chunk_last; + else + { + *s = capacity; + *p = chunk_next; + } + } + + std::memcpy (temp_buffer, v.constData () + *position_context, *s); + *b = temp_buffer; + *position_context += *s; + + return true; + } + }; + + template <> + struct default_value_traits<QString, id_clob>: qstring_lob_value_traits + { + }; + + template <> + struct default_value_traits<QString, id_nclob>: qstring_lob_value_traits + { + }; + + template <> + struct default_type_traits<QString> + { + static const database_type_id db_type_id = id_string; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_ORACLE_QSTRING_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/oracle/quuid-traits.hxx b/libodb-qt/odb/qt/basic/oracle/quuid-traits.hxx new file mode 100644 index 0000000..5f8041e --- /dev/null +++ b/libodb-qt/odb/qt/basic/oracle/quuid-traits.hxx @@ -0,0 +1,70 @@ +// file : odb/qt/basic/oracle/uuid-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_ORACLE_UUID_TRAITS_HXX +#define ODB_QT_BASIC_ORACLE_UUID_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cassert> + +#include <QtCore/QUuid> + +#include <odb/oracle/traits.hxx> + +namespace odb +{ + namespace oracle + { + template <> + struct default_value_traits<QUuid, id_raw> + { + public: + typedef QUuid value_type; + typedef value_type query_type; + typedef char* image_type; + + static void + set_value (value_type& v, const char* b, std::size_t n, bool is_null) + { + if (!is_null) + { + assert (n == 16); + std::memcpy (&v.data1, b, 16); + } + else + v = QUuid (); + } + + static void + set_image (char* b, + std::size_t c, + std::size_t& n, + bool& is_null, + const value_type& v) + { + // If we can, store nil as NULL. Otherwise, store it as a value. + // + is_null = is_null && v.isNull (); + + if (!is_null) + { + n = 16; + assert (c >= n); + std::memcpy (b, &v.data1, n); + } + } + }; + + template <> + struct default_type_traits<QUuid> + { + static const database_type_id db_type_id = id_raw; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_ORACLE_UUID_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/pgsql/default-mapping.hxx b/libodb-qt/odb/qt/basic/pgsql/default-mapping.hxx new file mode 100644 index 0000000..13dbeb8 --- /dev/null +++ b/libodb-qt/odb/qt/basic/pgsql/default-mapping.hxx @@ -0,0 +1,27 @@ +// file : odb/qt/basic/pgsql/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_PGSQL_DEFAULT_MAPPING_HXX +#define ODB_QT_BASIC_PGSQL_DEFAULT_MAPPING_HXX + +#include <QtCore/QString> +#include <QtCore/QByteArray> +#include <QtCore/QUuid> + +// Map QString to PostgreSQL TEXT by default. Allow NULL values by default as +// QString provides a null representation. +// +#pragma db value(QString) type("TEXT") null + +// Map QByteArray to PostgreSQL BYTEA by default. Allow NULL values by default +// as QByteArray provides a null representation. +// +#pragma db value(QByteArray) type("BYTEA") null + +// By default map QUuid to PostgreSQL UUID and use NULL to represent null +// UUIDs. If NULL is disabled (e.g., at the member level), then we store +// the null UUID (i.e., all bytes are zero). +// +#pragma db value(QUuid) type("UUID") null + +#endif // ODB_QT_BASIC_PGSQL_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/basic/pgsql/qbyte-array-traits.hxx b/libodb-qt/odb/qt/basic/pgsql/qbyte-array-traits.hxx new file mode 100644 index 0000000..3c3c496 --- /dev/null +++ b/libodb-qt/odb/qt/basic/pgsql/qbyte-array-traits.hxx @@ -0,0 +1,77 @@ +// file : odb/qt/basic/pgsql/qbyte-array-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_PGSQL_QBYTE_ARRAY_TRAITS_HXX +#define ODB_QT_BASIC_PGSQL_QBYTE_ARRAY_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t + +#include <QtCore/QByteArray> + +#include <odb/details/buffer.hxx> +#include <odb/pgsql/traits.hxx> + +namespace odb +{ + namespace pgsql + { + template <> + struct default_value_traits<QByteArray, id_bytea> + { + typedef QByteArray value_type; + typedef QByteArray query_type; + typedef details::buffer image_type; + + static void + set_value (QByteArray& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QByteArray (); + else + { + // Note that we cannot use replace() here since a suitable + // overload was only added in Qt 4.7. + // + v.resize (static_cast<int> (n)); + std::memcpy (v.data (), b.data (), n); + } + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const QByteArray& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + n = static_cast<std::size_t> (v.size ()); + if (n > b.capacity ()) + b.capacity (n); + + std::memcpy (b.data (), v.data (), n); + } + } + }; + + template <> + struct default_type_traits<QByteArray> + { + static const database_type_id db_type_id = id_bytea; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_PGSQL_QBYTE_ARRAY_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/pgsql/qstring-traits.hxx b/libodb-qt/odb/qt/basic/pgsql/qstring-traits.hxx new file mode 100644 index 0000000..f1ab53c --- /dev/null +++ b/libodb-qt/odb/qt/basic/pgsql/qstring-traits.hxx @@ -0,0 +1,74 @@ +// file : odb/qt/basic/pgsql/qstring-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_PGSQL_QSTRING_TRAITS_HXX +#define ODB_QT_BASIC_PGSQL_QSTRING_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t + +#include <QtCore/QString> + +#include <odb/details/buffer.hxx> +#include <odb/pgsql/traits.hxx> + +namespace odb +{ + namespace pgsql + { + template <> + struct default_value_traits <QString, id_string> + { + public: + typedef QString value_type; + typedef QString query_type; + typedef details::buffer image_type; + + static void + set_value (QString& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QString (); + else + v = QString::fromUtf8 (b.data (), static_cast<int> (n)); + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + const QByteArray& a (v.toUtf8 ()); + n = static_cast<std::size_t> (a.size ()); + + if (n > b.capacity ()) + b.capacity (n); + + std::memcpy (b.data (), a.data (), n); + } + } + }; + + template <> + struct default_type_traits<QString> + { + static const database_type_id db_type_id = id_string; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_PGSQL_QSTRING_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/pgsql/quuid-traits.hxx b/libodb-qt/odb/qt/basic/pgsql/quuid-traits.hxx new file mode 100644 index 0000000..5999b7e --- /dev/null +++ b/libodb-qt/odb/qt/basic/pgsql/quuid-traits.hxx @@ -0,0 +1,65 @@ +// file : odb/qt/basic/pgsql/uuid-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_PGSQL_UUID_TRAITS_HXX +#define ODB_QT_BASIC_PGSQL_UUID_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy + +#include <QtCore/QUuid> + +#include <odb/pgsql/traits.hxx> + +namespace odb +{ + namespace pgsql + { + template <> + class default_value_traits<QUuid, id_uuid> + { + public: + typedef QUuid value_type; + typedef value_type query_type; + typedef unsigned char* image_type; + + // PostgreSQL binary UUID representation is big-endian in the RFC 4122, + // section 4.1.2 order. While Qt provides (since 4.8) to/fromRfc4122(), + // they both incur a memory allocation (by QByteArray) which we could + // avoid, if we did it ourselves. + // + + static void + set_value (value_type& v, const unsigned char* i, bool is_null) + { + if (!is_null) + v = QUuid::fromRfc4122 ( + QByteArray (reinterpret_cast<const char*> (i), 16)); + else + v = QUuid (); + } + + static void + set_image (unsigned char* i, bool& is_null, const value_type& v) + { + // If we can, store nil as NULL. Otherwise, store it as a value. + // + is_null = is_null && v.isNull (); + + if (!is_null) + std::memcpy (i, v.toRfc4122 ().constData (), 16); + } + }; + + template <> + struct default_type_traits<QUuid> + { + static const database_type_id db_type_id = id_uuid; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_PGSQL_UUID_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/sqlite/default-mapping.hxx b/libodb-qt/odb/qt/basic/sqlite/default-mapping.hxx new file mode 100644 index 0000000..7d14a6c --- /dev/null +++ b/libodb-qt/odb/qt/basic/sqlite/default-mapping.hxx @@ -0,0 +1,27 @@ +// file : odb/qt/basic/sqlite/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_SQLITE_DEFAULT_MAPPING_HXX +#define ODB_QT_BASIC_SQLITE_DEFAULT_MAPPING_HXX + +#include <QtCore/QString> +#include <QtCore/QByteArray> +#include <QtCore/QUuid> + +// Map QString to SQLite TEXT by default. Allow NULL values by default as +// QString provides a null representation. +// +#pragma db value(QString) type("TEXT") null + +// Map QByteArray to SQLite BLOB by default. Allow NULL values by default as +// QByteArray provides a null representation. +// +#pragma db value(QByteArray) type("BLOB") null + +// By default map QUuid to SQLite BLOB and use NULL to represent null UUIDs. +// If NULL is disabled (e.g., at the member level), then we store the null +// UUID (i.e., all bytes are zero). +// +#pragma db value(QUuid) type("BLOB") null + +#endif // ODB_QT_BASIC_SQLITE_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/basic/sqlite/qbyte-array-traits.hxx b/libodb-qt/odb/qt/basic/sqlite/qbyte-array-traits.hxx new file mode 100644 index 0000000..8a26bb1 --- /dev/null +++ b/libodb-qt/odb/qt/basic/sqlite/qbyte-array-traits.hxx @@ -0,0 +1,77 @@ +// file : odb/qt/basic/sqlite/qbyte-array-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_SQLITE_QBYTE_ARRAY_TRAITS_HXX +#define ODB_QT_BASIC_SQLITE_QBYTE_ARRAY_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t + +#include <QtCore/QByteArray> + +#include <odb/details/buffer.hxx> +#include <odb/sqlite/traits.hxx> + +namespace odb +{ + namespace sqlite + { + template <> + struct default_value_traits<QByteArray, id_blob> + { + typedef QByteArray value_type; + typedef QByteArray query_type; + typedef details::buffer image_type; + + static void + set_value (QByteArray& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QByteArray (); + else + { + // Note that we cannot use replace() here since a suitable + // overload was only added in Qt 4.7. + // + v.resize (static_cast<int> (n)); + std::memcpy (v.data (), b.data (), n); + } + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const QByteArray& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + n = static_cast<std::size_t> (v.size ()); + if (n > b.capacity ()) + b.capacity (n); + + std::memcpy (b.data (), v.data (), n); + } + } + }; + + template <> + struct default_type_traits<QByteArray> + { + static const database_type_id db_type_id = id_blob; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_SQLITE_QBYTE_ARRAY_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/sqlite/qstring-traits.hxx b/libodb-qt/odb/qt/basic/sqlite/qstring-traits.hxx new file mode 100644 index 0000000..30a2136 --- /dev/null +++ b/libodb-qt/odb/qt/basic/sqlite/qstring-traits.hxx @@ -0,0 +1,83 @@ +// file : odb/qt/basic/sqlite/qstring-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_SQLITE_QSTRING_TRAITS_HXX +#define ODB_QT_BASIC_SQLITE_QSTRING_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cstddef> // std::size_t + +#include <QtCore/QString> + +#include <odb/details/buffer.hxx> +#include <odb/sqlite/traits.hxx> + +namespace odb +{ + namespace sqlite + { + template <> + struct image_traits<QString, id_text> + { + typedef details::buffer image_type; + + // Use UTF-16 binding for QString. + // + static const bind::buffer_type bind_value = bind::text16; + }; + + template <> + struct default_value_traits <QString, id_text> + { + public: + typedef QString value_type; + typedef QString query_type; + typedef details::buffer image_type; + + static void + set_value (QString& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + if (is_null) + v = QString (); + else + v.setUtf16 (reinterpret_cast<const ushort*> (b.data ()), + static_cast<int> (n / 2)); // In characters. + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const QString& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + n = static_cast<std::size_t> (v.size ()) * 2; // In bytes. + + if (n > b.capacity ()) + b.capacity (n); + + std::memcpy (b.data (), v.utf16 (), n); + } + } + }; + + template <> + struct default_type_traits<QString> + { + static const database_type_id db_type_id = id_text; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_SQLITE_QSTRING_TRAITS_HXX diff --git a/libodb-qt/odb/qt/basic/sqlite/quuid-traits.hxx b/libodb-qt/odb/qt/basic/sqlite/quuid-traits.hxx new file mode 100644 index 0000000..20d4a94 --- /dev/null +++ b/libodb-qt/odb/qt/basic/sqlite/quuid-traits.hxx @@ -0,0 +1,74 @@ +// file : odb/qt/basic/sqlite/uuid-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_BASIC_SQLITE_UUID_TRAITS_HXX +#define ODB_QT_BASIC_SQLITE_UUID_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <cstring> // std::memcpy +#include <cassert> + +#include <QtCore/QUuid> + +#include <odb/sqlite/traits.hxx> + +namespace odb +{ + namespace sqlite + { + template <> + struct default_value_traits<QUuid, id_blob> + { + typedef QUuid value_type; + typedef value_type query_type; + typedef details::buffer image_type; + + static void + set_value (value_type& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + if (!is_null) + { + assert (n == 16); + std::memcpy (&v.data1, b.data (), 16); + } + else + v = QUuid (); + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const value_type& v) + { + // If we can, store nil as NULL. Otherwise, store it as a value. + // + is_null = is_null && v.isNull (); + + if (!is_null) + { + n = 16; + + if (n > b.capacity ()) + b.capacity (n); + + std::memcpy (b.data (), &v.data1, n); + } + } + }; + + template <> + struct default_type_traits<QUuid> + { + static const database_type_id db_type_id = id_blob; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_BASIC_SQLITE_UUID_TRAITS_HXX diff --git a/libodb-qt/odb/qt/buildfile b/libodb-qt/odb/qt/buildfile new file mode 100644 index 0000000..63e6c95 --- /dev/null +++ b/libodb-qt/odb/qt/buildfile @@ -0,0 +1,93 @@ +# file : odb/qt/buildfile +# license : GNU GPL v2; see accompanying LICENSE file + +../ +{ + define options: file + options{*}: extension = options + + # Install into the odb/qt/ subdirectory of, say, /usr/include/ + # recreating subdirectories. + # + {hxx ixx txx options}{*}: + { + install = include/odb/ + install.subdirs = true + } + + qt/ + { + import int_libs = libodb%lib{odb} + imp_libs = + + lib{odb-qt}: {hxx ixx txx cxx}{** -version-build2} {hxx}{version-build2} \ + details/build2/{h}{*} \ + options{**} ../options{qt} \ + $imp_libs $int_libs + + # Include the generated version header into the distribution (so that we + # don't pick up an installed one) and don't remove it when cleaning in src + # (so that clean results in a state identical to distributed). + # + hxx{version-build2}: in{version-build2} $src_root/manifest + hxx{version-build2}: + { + dist = true + clean = ($src_root != $out_root) + } + + # Build options. + # + cxx.poptions =+ "-I$out_root" "-I$src_root" -DLIBODB_QT_BUILD2 + + obja{*}: cxx.poptions += -DLIBODB_QT_STATIC_BUILD + objs{*}: cxx.poptions += -DLIBODB_QT_SHARED_BUILD + + # Export options. + # + lib{odb-qt}: + { + cxx.export.poptions = "-I$out_root" "-I$src_root" -DLIBODB_QT_BUILD2 + cxx.export.libs = $int_libs + } + + liba{odb-qt}: cxx.export.poptions += -DLIBODB_QT_STATIC + libs{odb-qt}: cxx.export.poptions += -DLIBODB_QT_SHARED + + # For pre-releases use the complete version to make sure they cannot be + # used in place of another pre-release or the final version. See the + # version module for details on the version.* variable values. + # + if $version.pre_release + lib{odb-qt}: bin.lib.version = @"-$version.project_id" + else + lib{odb-qt}: bin.lib.version = @"-$version.major.$version.minor" + + # Installation tweaks. + # + install_include = [dir_path] include/odb/qt/ + + # We want these to be picked up whether LIBODB_QT_BUILD2 is defined or + # not. + # + hxx{version}@./: install = false + hxx{version-build2}: install = $install_include/version.hxx + hxx{version-build2-stub}@./: install = $install_include/version-build2.hxx + + details/build2/ + { + h{*}: install = false + + if ($cxx.target.system == 'win32-msvc') + { + h{config-vc}@./: install = $install_include/details/ + h{config-vc-stub}@./: install = $install_include/details/build2/config-vc.h + } + else + { + h{config}@./: install = $install_include/details/ + h{config-stub}@./: install = $install_include/details/build2/config.h + } + } + } +} diff --git a/libodb-qt/odb/qt/containers.options b/libodb-qt/odb/qt/containers.options new file mode 100644 index 0000000..337b064 --- /dev/null +++ b/libodb-qt/odb/qt/containers.options @@ -0,0 +1,18 @@ +# file : odb/qt/containers.options +# licences : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +--odb-epilogue '#include <odb/qt/containers/qhash-traits.hxx>' +--odb-epilogue '#include <odb/qt/containers/qlist-traits.hxx>' +--odb-epilogue '#include <odb/qt/containers/qlinked-list-traits.hxx>' +--odb-epilogue '#include <odb/qt/containers/qmap-traits.hxx>' +--odb-epilogue '#include <odb/qt/containers/qset-traits.hxx>' +--odb-epilogue '#include <odb/qt/containers/qvector-traits.hxx>' + +--hxx-prologue '#include <odb/qt/containers/qhash-traits.hxx>' +--hxx-prologue '#include <odb/qt/containers/qlist-traits.hxx>' +--hxx-prologue '#include <odb/qt/containers/qlinked-list-traits.hxx>' +--hxx-prologue '#include <odb/qt/containers/qmap-traits.hxx>' +--hxx-prologue '#include <odb/qt/containers/qset-traits.hxx>' +--hxx-prologue '#include <odb/qt/containers/qvector-traits.hxx>' diff --git a/libodb-qt/odb/qt/containers/list-iterator.hxx b/libodb-qt/odb/qt/containers/list-iterator.hxx new file mode 100644 index 0000000..67f56fd --- /dev/null +++ b/libodb-qt/odb/qt/containers/list-iterator.hxx @@ -0,0 +1,30 @@ +// file : odb/qt/containers/list-iterator.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINERS_LIST_ITERATOR_HXX +#define ODB_QT_CONTAINERS_LIST_ITERATOR_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QListIterator> + +#include <odb/qt/list.hxx> + +// Java-style QListIterator-like iterator. You can also use the +// QListIterator directly (but not QMutableListIterator). +// +template <typename T> +class QOdbListIterator: public QListIterator<T> +{ +public: + QOdbListIterator (const QOdbList<T>& c): QListIterator<T> (c) {} + QOdbListIterator& operator=(const QOdbList<T>& c) + { + static_cast<QListIterator<T>&> (*this) = c; + return *this; + } +}; + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINERS_LIST_ITERATOR_HXX diff --git a/libodb-qt/odb/qt/containers/list-traits.hxx b/libodb-qt/odb/qt/containers/list-traits.hxx new file mode 100644 index 0000000..5a3ee38 --- /dev/null +++ b/libodb-qt/odb/qt/containers/list-traits.hxx @@ -0,0 +1,107 @@ +// file : odb/qt/containers/list-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINERS_LIST_TRAITS_HXX +#define ODB_QT_CONTAINERS_LIST_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <odb/vector-impl.hxx> +#include <odb/container-traits.hxx> +#include <odb/transaction.hxx> + +#include <odb/qt/containers/list.hxx> + +namespace odb +{ + template <typename V> + class access::container_traits<QOdbList<V> > + { + public: + static const container_kind kind = ck_ordered; + static const bool smart = true; + + typedef QOdbList<V> container_type; + + typedef V value_type; + typedef typename container_type::size_type index_type; + + typedef smart_ordered_functions<index_type, value_type> functions; + typedef ordered_functions<index_type, value_type> dumb_functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + for (index_type i (0), n (c.size ()); i < n; ++i) + f.insert (i, c[i]); + + // Now that this container is persistent, start tracking changes. + // + c._start (); + } + + static void + load (container_type& c, bool more, const functions& f) + { + // Stop tracking changes. + // + c._stop (); + + // Load. + // + c.clear (); + while (more) + { + index_type dummy; + c.append (value_type ()); + more = f.select (dummy, c.modify_back ()); + } + + // Start tracking changes. + // + c._start (); + } + + static bool + changed (const container_type&); + + static void + update (const container_type&, const functions&); + + static void + erase (const container_type* c, const functions& f) + { + f.delete_ (0); + + // Stop tracking changes. + // + if (c != 0) + c->_stop (); + } + + // Version of load() for dumb functions. Used to support + // inverse members of the container type. The implementation + // is identical to the smart one except we don't turn off/on + // change tracking. + // + static void + load (container_type& c, bool more, const dumb_functions& f) + { + c.clear (); + + while (more) + { + index_type dummy; + c.append (value_type ()); + more = f.select (dummy, c.modify_back ()); + } + } + }; +} + +#include <odb/qt/containers/list-traits.txx> + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINERS_LIST_TRAITS_HXX diff --git a/libodb-qt/odb/qt/containers/list-traits.txx b/libodb-qt/odb/qt/containers/list-traits.txx new file mode 100644 index 0000000..105fc2a --- /dev/null +++ b/libodb-qt/odb/qt/containers/list-traits.txx @@ -0,0 +1,101 @@ +// file : odb/qt/containers/list-traits.txx +// license : GNU GPL v2; see accompanying LICENSE file + +namespace odb +{ + template <typename V> + bool access::container_traits<QOdbList<V> >:: + changed (const container_type& c) + { + // Because modifications can cancel each other (e.g., push and pop), + // it is tricky to keep track of whether there are any changes in + // the container. Instead, we are just going to examine each element + // just like update(). + // + + // We should either be tracking or summarily changed. + // + if (c._tracking ()) + { + const vector_impl& impl (c._impl ()); + + for (std::size_t i (0), n (impl.size ()); i < n; ++i) + { + if (impl.state (i) != vector_impl::state_unchanged) + return true; + } + } + else + return true; + + return false; + } + + template <typename V> + void access::container_traits<QOdbList<V> >:: + update (const container_type& c, const functions& f) + { + bool u (false); // Updated flag. + + if (c._tracking ()) + { + const vector_impl& impl (c._impl ()); + + for (std::size_t i (0), n (impl.size ()); i < n; ++i) + { + vector_impl::element_state_type s (impl.state (i)); + index_type ii (static_cast<index_type> (i)); + + switch (s) + { + case vector_impl::state_unchanged: + { + break; + } + case vector_impl::state_inserted: + { + f.insert (ii, c[ii]); + u = u || true; + break; + } + case vector_impl::state_updated: + { + f.update (ii, c[ii]); + u = u || true; + break; + } + case vector_impl::state_erased: + { + f.delete_ (ii); // Delete from i onwards. + u = u || true; + break; + } + } + + // We delete all trailing elements in one go. + // + if (s == vector_impl::state_erased) + break; + } + } + else + { + // Fall back to delete all/insert all. + // + f.delete_ (0); + + for (index_type i (0), n (c.size ()); i < n; ++i) + f.insert (i, c[i]); + + u = true; + } + + // Arm the rollback callback and (re)start change tracking. + // + if (u) + { + c._arm (transaction::current ()); + c._start (); + } + } +} diff --git a/libodb-qt/odb/qt/containers/list.hxx b/libodb-qt/odb/qt/containers/list.hxx new file mode 100644 index 0000000..143deed --- /dev/null +++ b/libodb-qt/odb/qt/containers/list.hxx @@ -0,0 +1,433 @@ +// file : odb/qt/containers/list.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINERS_LIST_HXX +#define ODB_QT_CONTAINERS_LIST_HXX + +#include <odb/pre.hxx> +#include <odb/details/config.hxx> // ODB_CXX11 + +#include <QtCore/QtGlobal> // QT_VERSION +#include <QtCore/QList> + +#ifdef ODB_CXX11 +# include <utility> // std::move +# if defined(ODB_CXX11_INITIALIZER_LIST) && \ + defined(Q_COMPILER_INITIALIZER_LISTS) +# include <initializer_list> +# endif +#endif + +#include <odb/vector-impl.hxx> + +// A QList-like container that keeps track of changes. +// +// Note that the style and order of definitions is (mostly) as +// appears in the qlist.h Qt header (except for some cleanups, +// such as superfluous inline use). +// +template <typename L> +class QOdbListIteratorImpl; + +template <typename T> +class QOdbList: public odb::vector_base +{ +public: + typedef QList<T> base_list_type; + typedef typename base_list_type::iterator base_iterator_type; + + QOdbList() {} + QOdbList(const QOdbList &x): vector_base (x), l_ (x.l_) {} + // ~QOdbList(); + QOdbList &operator=(const QOdbList &l); + +#if QT_VERSION >= 0x040800 + void swap(QOdbList &other); +#endif + +#ifdef ODB_CXX11 + QOdbList(QOdbList &&x) noexcept + : vector_base (std::move (x)), l_ (std::move (x.l_)) {} + + // Note: noexcept is not specified since it can throw while reallocating + // impl_. + // + QOdbList &operator=(QOdbList &&other); + +#if defined(ODB_CXX11_INITIALIZER_LIST) && \ + defined(Q_COMPILER_INITIALIZER_LISTS) + QOdbList(std::initializer_list<T> il): l_ (il) {} +#endif +#endif + + // Implicit conversion. + // + bool operator==(const QList<T> &x) const {return l_ == x;} + bool operator!=(const QList<T> &x) const {return l_ != x;} + + int size() const {return l_.size ();} + void detach() {l_.detach ();} + void detachShared() {l_.detachShared ();} + bool isDetached() const {return l_.isDetached ();} + void setSharable(bool sharable) {l_.setSharable (sharable);} + // Implicit conversion. + bool isSharedWith(const QList<T> &x) const {return l_.isSharedWith (x);} + bool isEmpty() const {return l_.isEmpty ();} + void clear(); + + const T &at(int i) const {return l_.at (i);} + const T &operator[](int i) const {return l_[i];} + //T &operator[](int i); + T &modify (int i); + + void reserve(int size); + void append(const T &t); + void append(const QList<T> &t); // Implicit conversion. + void prepend(const T &t); + void insert(int i, const T &t); + void replace(int i, const T &t); + void removeAt(int i); + int removeAll(const T &t); + bool removeOne(const T &t); + T takeAt(int i); + T takeFirst(); + T takeLast(); + void move(int from, int to); + void swap(int i, int j); + + int indexOf(const T &t, int from = 0) const {return l_.indexOf (t, from);} + int lastIndexOf(const T &t, int from = -1) const + {return l_.lastIndexOf (t, from);} + bool contains(const T &t) const {return l_.contains (t);} + int count(const T &t) const {return l_.count (t);} + + typedef QOdbListIteratorImpl<QOdbList> iterator; + typedef typename base_list_type::const_iterator const_iterator; + + // stl style + iterator begin() {return iterator (this, l_.begin ());} + const_iterator begin() const {return l_.begin ();} + const_iterator cbegin() const {return l_.cbegin ();} + const_iterator constBegin() const {return l_.constBegin ();} + iterator end() {return iterator (this, l_.end ());} + const_iterator end() const {return l_.end ();} + const_iterator cend() const {return l_.cend ();} + const_iterator constEnd() const {return l_.constEnd ();} + + // Return QList iterators. The begin() functions mark all + // the elements as modified. + // + base_iterator_type mbegin (); + base_iterator_type modifyBegin () {return mbegin ();} + base_iterator_type mend () {return l_.end ();} + base_iterator_type modifyEnd () {return mend ();} + + iterator insert(iterator before, const T &t); + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + + // more Qt + typedef iterator Iterator; + typedef const_iterator ConstIterator; + + int count() const {return l_.count ();} + int length() const {return l_.length ();} + //T& first(); + T& modifyFirst(); + const T& first() const {return l_.first ();} + //T& last(); + T& modifyLast(); + const T& last() const {return l_.last ();} + void removeFirst(); + void removeLast(); + bool startsWith(const T &t) const {return l_.startsWith (t);} + bool endsWith(const T &t) const {return l_.endsWith (t);} + QList<T> mid(int pos, int length = -1) const {return l_.mid (pos, length);} + + T value(int i) const {return l_.value (i);} + T value(int i, const T &defValue) const {return l_.value (i, defValue);} + + // stl compatibility + void push_back(const T &t) {append(t);} + void push_front(const T &t) {prepend(t);} + //T& front(); + T& modify_front() {return modifyFirst ();} + const T& front() const {return l_.front ();} + //T& back(); + T& modify_back() {return modifyLast ();} + const T& back() const {return l_.back ();} + void pop_front() {removeFirst();} + void pop_back() {removeLast();} + bool empty() const {return l_.empty ();} + + typedef int size_type; + typedef T value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef typename base_list_type::difference_type difference_type; + + // comfort + // Implicit conversion. + QOdbList &operator+=(const QList<T> &l) {append (l); return *this;} + QOdbList operator+(const QList<T> &l) const + {QOdbList r (*this); r.append (l); return r;} + QOdbList &operator+=(const T &t) {append (t); return *this;} + QOdbList &operator<< (const T &t) {append (t); return *this;} + QOdbList &operator<<(const QList<T> &l) {append (l); return *this;} + + QVector<T> toVector() const {return l_.toVector ();} + QSet<T> toSet() const {return l_.toSet ();} + + static QOdbList fromVector(const QVector<T> &v) + {return base_list_type::fromVector (v);} + static QOdbList fromSet(const QSet<T> &s) + {return base_list_type::fromSet (s);} + + static QOdbList fromStdList(const std::list<T> &l) + {return base_list_type::fromStdList (l);} + std::list<T> toStdList() const {return l_.toStdList ();} + + // Interfacing with the base list. + // + QOdbList (const base_list_type& x): l_ (x) {} + QOdbList& operator= (const base_list_type&); + operator const base_list_type& () const {return l_;} + base_list_type& base () {return l_;} + const base_list_type& base () const {return l_;} + +#ifdef ODB_CXX11 + QOdbList (base_list_type&& x): l_ (std::move (x)) {} + QOdbList& operator= (base_list_type&&); +#endif + + // Change tracking (the rest comes from vector_base). + // +public: + void _start () const {impl_.start (l_.size ());} + +private: + base_list_type l_; +}; + +template <typename L> +class QOdbListIteratorImpl +{ +public: + typedef L list_type; + typedef typename list_type::base_iterator_type base_iterator_type; + typedef typename list_type::const_iterator const_iterator_type; + + typedef typename base_iterator_type::iterator_category iterator_category; + typedef typename base_iterator_type::difference_type difference_type; + typedef typename base_iterator_type::value_type value_type; + typedef typename base_iterator_type::pointer pointer; + typedef typename base_iterator_type::reference reference; + + typedef typename list_type::size_type size_type; + typedef typename list_type::const_reference const_reference; + typedef typename list_type::const_pointer const_pointer; + + QOdbListIteratorImpl (): l_ (0), i_ () {} + QOdbListIteratorImpl (list_type* l, const base_iterator_type& i) + : l_ (l), i_ (i) {} + +#ifndef QT_STRICT_ITERATORS + operator const_iterator_type () const {return i_;} +#endif + base_iterator_type base () const {return i_;} + list_type* list () const {return l_;} + + // Note: const_{reference,pointer}. + // + const_reference operator* () const {return *i_;} + const_pointer operator-> () const {return i_.operator -> ();} + const_reference operator[] (difference_type n) const {return i_[n];} + + // Modifiers. + // + reference modify () const; + reference modify (difference_type n) const; + + QOdbListIteratorImpl& operator++ () {++i_; return *this;} + QOdbListIteratorImpl operator++ (int) + {return QOdbListIteratorImpl (l_, i_++);} + QOdbListIteratorImpl& operator-- () {--i_; return *this;} + QOdbListIteratorImpl operator-- (int) + {return QOdbListIteratorImpl (l_, i_--);} + + QOdbListIteratorImpl operator+ (int n) const + {return QOdbListIteratorImpl (l_, i_ + n);} + QOdbListIteratorImpl& operator+= (int n) {i_ += n; return *this;} + QOdbListIteratorImpl operator- (int n) const + {return QOdbListIteratorImpl (l_, i_ - n);} + QOdbListIteratorImpl& operator-= (int n) {i_ -= n; return *this;} + +private: + list_type* l_; + base_iterator_type i_; +}; + +// operator== +// +template <typename L> +inline bool +operator== (const QOdbListIteratorImpl<L>& x, const QOdbListIteratorImpl<L>& y) +{return x.base () == y.base ();} + +#ifndef QT_STRICT_ITERATORS +template <typename L> +inline bool +operator== (const QOdbListIteratorImpl<L>& x, + const typename QOdbListIteratorImpl<L>::const_iterator_type& y) +{return x.base () == y;} + +template <typename L> +inline bool +operator== (const typename QOdbListIteratorImpl<L>::const_iterator_type& x, + const QOdbListIteratorImpl<L>& y) +{return x == y.base ();} +#endif + +// operator< +// +template <typename L> +inline bool +operator< (const QOdbListIteratorImpl<L>& x, const QOdbListIteratorImpl<L>& y) +{return x.base () < y.base ();} + +#ifndef QT_STRICT_ITERATORS +template <typename L> +inline bool +operator< (const QOdbListIteratorImpl<L>& x, + const typename QOdbListIteratorImpl<L>::const_iterator_type& y) +{return x.base () < y;} + +template <typename L> +inline bool +operator< (const typename QOdbListIteratorImpl<L>::const_iterator_type& x, + const QOdbListIteratorImpl<L>& y) +{return x < y.base ();} +#endif + +// operator!= +// +template <typename L> +inline bool +operator!= (const QOdbListIteratorImpl<L>& x, const QOdbListIteratorImpl<L>& y) +{return x.base () != y.base ();} + +#ifndef QT_STRICT_ITERATORS +template <typename L> +inline bool +operator!= (const QOdbListIteratorImpl<L>& x, + const typename QOdbListIteratorImpl<L>::const_iterator_type& y) +{return x.base () != y;} + +template <typename L> +inline bool +operator!= (const typename QOdbListIteratorImpl<L>::const_iterator_type& x, + const QOdbListIteratorImpl<L>& y) +{return x != y.base ();} +#endif + +// operator> +// +template <typename L> +inline bool +operator> (const QOdbListIteratorImpl<L>& x, const QOdbListIteratorImpl<L>& y) +{return x.base () > y.base ();} + +#ifndef QT_STRICT_ITERATORS +template <typename L> +inline bool +operator> (const QOdbListIteratorImpl<L>& x, + const typename QOdbListIteratorImpl<L>::const_iterator_type& y) +{return x.base () > y;} + +template <typename L> +inline bool +operator> (const typename QOdbListIteratorImpl<L>::const_iterator_type& x, + const QOdbListIteratorImpl<L>& y) +{return x > y.base ();} +#endif + +// operator>= +// +template <typename L> +inline bool +operator>= (const QOdbListIteratorImpl<L>& x, const QOdbListIteratorImpl<L>& y) +{return x.base () >= y.base ();} + +#ifndef QT_STRICT_ITERATORS +template <typename L> +inline bool +operator>= (const QOdbListIteratorImpl<L>& x, + const typename QOdbListIteratorImpl<L>::const_iterator_type& y) +{return x.base () >= y;} + +template <typename L> +inline bool +operator>= (const typename QOdbListIteratorImpl<L>::const_iterator_type& x, + const QOdbListIteratorImpl<L>& y) +{return x >= y.base ();} +#endif + +// operator<= +// +template <typename L> +inline bool +operator<= (const QOdbListIteratorImpl<L>& x, const QOdbListIteratorImpl<L>& y) +{return x.base () <= y.base ();} + +#ifndef QT_STRICT_ITERATORS +template <typename L> +inline bool +operator<= (const QOdbListIteratorImpl<L>& x, + const typename QOdbListIteratorImpl<L>::const_iterator_type& y) +{return x.base () <= y;} + +template <typename L> +inline bool +operator<= (const typename QOdbListIteratorImpl<L>::const_iterator_type& x, + const QOdbListIteratorImpl<L>& y) +{return x <= y.base ();} +#endif + +// operator- +// +template <typename L> +inline typename QOdbListIteratorImpl<L>::difference_type +operator-(const QOdbListIteratorImpl<L>& x, const QOdbListIteratorImpl<L>& y) +{return x.base () - y.base ();} + +#ifndef QT_STRICT_ITERATORS +template <typename L> +inline typename QOdbListIteratorImpl<L>::difference_type +operator-(const QOdbListIteratorImpl<L>& x, + const typename QOdbListIteratorImpl<L>::const_iterator_type& y) +{return x.base () - y;} + +template <typename L> +inline typename QOdbListIteratorImpl<L>::difference_type +operator-(const typename QOdbListIteratorImpl<L>::const_iterator_type& x, + const QOdbListIteratorImpl<L>& y) +{return x - y.base ();} +#endif + +// operator+ +// +template <typename L> +inline QOdbListIteratorImpl<L> +operator+(typename QOdbListIteratorImpl<L>::difference_type n, + const QOdbListIteratorImpl<L>& x) +{return QOdbListIteratorImpl<L> (x.list (), n + x.base ());} + +#include <odb/qt/containers/list.ixx> + +#include <odb/qt/containers/list-traits.hxx> + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINERS_LIST_HXX diff --git a/libodb-qt/odb/qt/containers/list.ixx b/libodb-qt/odb/qt/containers/list.ixx new file mode 100644 index 0000000..d9d37b6 --- /dev/null +++ b/libodb-qt/odb/qt/containers/list.ixx @@ -0,0 +1,318 @@ +// file : odb/qt/containers/list.ixx +// license : GNU GPL v2; see accompanying LICENSE file + +// +// QOdbList +// + +template <typename T> +inline QOdbList<T>& QOdbList<T>:: +operator= (const QOdbList<T>& x) +{ + l_ = x.l_; + if (_tracking ()) + impl_.assign (static_cast<std::size_t> (l_.size ())); + return *this; +} + +template <typename T> +inline QOdbList<T>& QOdbList<T>:: +operator= (const base_list_type& x) +{ + l_ = x; + if (_tracking ()) + impl_.assign (static_cast<std::size_t> (l_.size ())); + return *this; +} + +#ifdef ODB_CXX11 +template <typename T> +inline QOdbList<T>& QOdbList<T>:: +operator= (QOdbList&& x) +{ + l_ = std::move (x.l_); + if (_tracking ()) + impl_.assign (static_cast<std::size_t> (l_.size ())); + return *this; +} + +template <typename T> +inline QOdbList<T>& QOdbList<T>:: +operator= (base_list_type&& x) +{ + l_ = std::move (x); + if (_tracking ()) + impl_.assign (static_cast<std::size_t> (l_.size ())); + return *this; +} +#endif + +#if QT_VERSION >= 0x040800 +template <typename T> +inline void QOdbList<T>:: +swap (QOdbList<T>& x) +{ + l_.swap (x.l_); + vector_base::swap (x); +} +#endif + +template <typename T> +inline void QOdbList<T>:: +clear() +{ + l_.clear (); + if (_tracking ()) + impl_.clear (); +} + +template <typename T> +inline T& QOdbList<T>:: +modify (int i) +{ + T& r (l_[i]); + if (_tracking ()) + impl_.modify (static_cast<std::size_t> (i)); + return r; +} + +template <typename T> +inline void QOdbList<T>:: +reserve (int n) +{ + l_.reserve (n); + if (_tracking ()) + impl_.reserve (static_cast<std::size_t> (n)); +} + +template <typename T> +inline void QOdbList<T>:: +append (const T& x) +{ + l_.append (x); + if (_tracking ()) + impl_.push_back (); +} + +template <typename T> +inline void QOdbList<T>:: +append (const QList<T>& x) +{ + l_.append (x); + if (_tracking ()) + impl_.push_back (static_cast<std::size_t> (x.size ())); +} + +template <typename T> +inline void QOdbList<T>:: +prepend (const T& x) +{ + l_.prepend (x); + if (_tracking ()) + impl_.insert (0); +} + +template <typename T> +inline void QOdbList<T>:: +insert (int i, const T& x) +{ + l_.insert (i, x); + if (_tracking ()) + impl_.insert (static_cast<std::size_t> (i)); +} + +template <typename T> +inline void QOdbList<T>:: +replace (int i, const T& x) +{ + l_.insert (i, x); + if (_tracking ()) + impl_.modify (static_cast<std::size_t> (i)); +} + +template <typename T> +inline void QOdbList<T>:: +removeAt (int i) +{ + l_.removeAt (i); + if (_tracking ()) + impl_.erase (static_cast<std::size_t> (i)); +} + +template <typename T> +inline int QOdbList<T>:: +removeAll (const T& x) +{ + // We have to re-implement this one ourselves since we need to + // know the indexes of the removed elements. + // + int r (0); + for (int i (l_.indexOf (x)); i != -1; i = l_.indexOf (x, i)) + { + removeAt (i); + r++; + } + return r; +} + +template <typename T> +inline bool QOdbList<T>:: +removeOne (const T& x) +{ + // We have to re-implement this one ourselves since we need to + // know the index of the removed element. + // + int i (l_.indexOf (x)); + if (i != -1) + removeAt (i); + return i != -1; +} + +template <typename T> +inline T QOdbList<T>:: +takeAt (int i) +{ + if (_tracking ()) + impl_.erase (static_cast<std::size_t> (i)); + return l_.takeAt (i); +} + +template <typename T> +inline T QOdbList<T>:: +takeFirst () +{ + if (_tracking ()) + impl_.erase (0); + return l_.takeFirst (); +} + +template <typename T> +inline T QOdbList<T>:: +takeLast () +{ + if (_tracking ()) + impl_.pop_back (); + return l_.takeLast (); +} + +template <typename T> +inline void QOdbList<T>:: +move (int from, int to) +{ + l_.move (from, to); + if (_tracking ()) + { + impl_.erase (static_cast<std::size_t> (from)); + impl_.insert (static_cast<std::size_t> (to)); + } +} + +template <typename T> +inline void QOdbList<T>:: +swap (int i, int j) +{ + l_.swap (i, j); + if (_tracking ()) + { + impl_.modify (static_cast<std::size_t> (i)); + impl_.modify (static_cast<std::size_t> (j)); + } +} + +template <typename T> +inline typename QOdbList<T>::base_iterator_type QOdbList<T>:: +mbegin () +{ + if (_tracking ()) + impl_.modify (0, static_cast<std::size_t> (l_.size ())); + return l_.begin (); +} + +template <typename T> +inline typename QOdbList<T>::iterator QOdbList<T>:: +insert (iterator p, const T& x) +{ + if (_tracking ()) + impl_.insert (static_cast<std::size_t> (p.base () - l_.begin ())); + return iterator (this, l_.insert (p.base (), x)); +} + +template <typename T> +inline typename QOdbList<T>::iterator QOdbList<T>:: +erase (iterator p) +{ + if (_tracking ()) + impl_.erase (static_cast<std::size_t> (p.base () - l_.begin ())); + return iterator (this, l_.erase (p.base ())); +} + +template <typename T> +inline typename QOdbList<T>::iterator QOdbList<T>:: +erase (iterator f, iterator l) +{ + if (_tracking ()) + impl_.erase (static_cast<std::size_t> (f.base () - l_.begin ()), + static_cast<std::size_t> (l - f)); + return iterator (this, l_.erase (f.base (), l.base ())); +} + +template <typename T> +inline T& QOdbList<T>:: +modifyFirst () +{ + T& r (l_.first ()); + if (_tracking ()) + impl_.modify (0); + return r; +} + +template <typename T> +inline T& QOdbList<T>:: +modifyLast () +{ + T& r (l_.last ()); + if (_tracking ()) + impl_.modify (static_cast<std::size_t> (l_.size () - 1)); + return r; +} + +template <typename T> +inline void QOdbList<T>:: +removeFirst () +{ + l_.removeFirst (); + if (_tracking ()) + impl_.erase (0); +} + +template <typename T> +inline void QOdbList<T>:: +removeLast () +{ + l_.removeLast (); + if (_tracking ()) + impl_.pop_back (); +} + +// +// QOdbListIteratorImpl +// + +template <typename L> +inline typename QOdbListIteratorImpl<L>::reference QOdbListIteratorImpl<L>:: +modify () const +{ + if (l_->_tracking ()) + l_->_impl ().modify (static_cast<std::size_t> (i_ - l_->base ().begin ())); + return *i_; +} + +template <typename L> +inline typename QOdbListIteratorImpl<L>::reference QOdbListIteratorImpl<L>:: +modify (difference_type n) const +{ + if (l_->_tracking ()) + l_->_impl ().modify ( + static_cast<std::size_t> (i_ - l_->base ().begin () + n)); + return i_[n]; +} diff --git a/libodb-qt/odb/qt/containers/mutable-list-iterator.hxx b/libodb-qt/odb/qt/containers/mutable-list-iterator.hxx new file mode 100644 index 0000000..271633a --- /dev/null +++ b/libodb-qt/odb/qt/containers/mutable-list-iterator.hxx @@ -0,0 +1,110 @@ +// file : odb/qt/containers/mutable-list-iterator.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINERS_MUTABLE_LIST_ITERATOR_HXX +#define ODB_QT_CONTAINERS_MUTABLE_LIST_ITERATOR_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QMutableListIterator> + +#include <odb/qt/list.hxx> + +// Java-style QMutableListIterator-like iterator. The implementation +// is based on what's found in qiterator.h. +// +template <typename T> +class QMutableOdbListIterator +{ +public: + QMutableOdbListIterator(QOdbList<T> &x) + : c (&x) + { + c->setSharable(false); + i = c->begin(); + n = c->end(); + } + + ~QMutableOdbListIterator() {c->setSharable(true);} + + QMutableOdbListIterator &operator=(QOdbList<T> &x) + { + c->setSharable(true); + c = &x; + c->setSharable(false); + i = c->begin(); + n = c->end(); + return *this; + } + + void toFront() {i = c->begin(); n = c->end();} + void toBack() {i = c->end(); n = i;} + bool hasNext() const {return c->constEnd() != const_iterator(i.base ());} + bool hasPrevious() const + { + return c->constBegin() != const_iterator(i.base ()); + } + + bool findNext(const T &t) + { + while (c->constEnd() != const_iterator((n = i).base ())) + if (*i++ == t) + return true; + return false; + } + + bool findPrevious(const T &t) + { + while (c->constBegin() != const_iterator(i.base ())) + if (*(n = --i) == t) + return true; + + n = c->end(); + return false; + } + + T &next() {n = i++; return n.modify ();} + T &peekNext() const {return i.modify ();} + T &previous() {n = --i; return n.modify ();} + T &peekPrevious() const {iterator p (i); return (--p).modify ();} + + void remove() + { + if (c->constEnd() != const_iterator(n.base ())) + { + i = c->erase (n); + n = c->end(); + } + } + + void setValue(const T &t) const + { + if (c->constEnd() != const_iterator(n.base ())) + n.modify () = t; + } + + T &value() + { + Q_ASSERT(c->constEnd() != const_iterator(n.base ())); + return n.modify (); + } + + const T &value() const + { + Q_ASSERT(c->constEnd() != const_iterator(n.base ())); + return *n; + } + + void insert(const T &t) {n = i = c->insert(i, t); ++i;} + +private: + typedef typename QOdbList<T>::iterator iterator; + typedef typename QOdbList<T>::const_iterator const_iterator; + + QOdbList<T>* c; + iterator i, n; +}; + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINERS_MUTABLE_LIST_ITERATOR_HXX diff --git a/libodb-qt/odb/qt/containers/qhash-traits.hxx b/libodb-qt/odb/qt/containers/qhash-traits.hxx new file mode 100644 index 0000000..9f42d37 --- /dev/null +++ b/libodb-qt/odb/qt/containers/qhash-traits.hxx @@ -0,0 +1,129 @@ +// file : odb/qt/containers/qhash-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINER_QHASH_TRAITS_HXX +#define ODB_QT_CONTAINER_QHASH_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QHash> +#include <QtCore/QMultiHash> + +#include <odb/container-traits.hxx> + +namespace odb +{ + template <typename Key, typename T> + class access::container_traits<QHash<Key, T> > + { + public: + static const container_kind kind = ck_map; + static const bool smart = false; + + typedef QHash<Key, T> container_type; + typedef Key key_type; + typedef T value_type; + + typedef map_functions<key_type, value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (i.key (), i.value ()); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + key_type k; + value_type v; + more = f.select (k, v); + c.insert (k, v); // @@ Use std::move in C++11. + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_ (); + + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (i.key (), i.value ()); + } + + static void + erase (const functions& f) + { + f.delete_ (); + } + }; + + // @@ QMultiHash guarantees elements to be stored in reverse order of + // insertion. The current implementation of the generated code does + // not guarantee this. + // + template <typename Key, typename T> + class access::container_traits<QMultiHash<Key, T> > + { + public: + static const container_kind kind = ck_multimap; + static const bool smart = false; + + typedef QMultiHash<Key, T> container_type; + typedef Key key_type; + typedef T value_type; + + typedef map_functions<key_type, value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (i.key (), i.value ()); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + key_type k; + value_type v; + more = f.select (k, v); + c.insert (k, v); //@@ Use std::move in C++11. + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_ (); + + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (i.key (), i.value ()); + } + + static void + erase (const functions& f) + { + f.delete_ (); + } + }; +} + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINER_QHASH_TRAITS_HXX diff --git a/libodb-qt/odb/qt/containers/qlinked-list-traits.hxx b/libodb-qt/odb/qt/containers/qlinked-list-traits.hxx new file mode 100644 index 0000000..3bfc9e9 --- /dev/null +++ b/libodb-qt/odb/qt/containers/qlinked-list-traits.hxx @@ -0,0 +1,82 @@ +// file : odb/qt/containers/qlinked-list-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINER_QLINKED_LIST_TRAITS_HXX +#define ODB_QT_CONTAINER_QLINKED_LIST_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QtGlobal> // QT_VERSION + +// QLinkedList is deprecated since Qt5 5.15 and in Qt6 it has been moved to a +// separate library. +// +#if (QT_VERSION < 0x050F00) || ODB_QT_FORCE_QLINKEDLIST + +#include <QtCore/QLinkedList> + +#include <odb/container-traits.hxx> + +namespace odb +{ + template <typename T> + class access::container_traits<QLinkedList<T> > + { + public: + static const container_kind kind = ck_ordered; + static const bool smart = false; + + typedef QLinkedList<T> container_type; + + typedef T value_type; + typedef typename container_type::size_type index_type; + + typedef ordered_functions<index_type, value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + index_type i (0); + for (typename container_type::const_iterator j (c.begin ()), + e (c.end ()); j != e; ++j) + f.insert (i++, *j); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + index_type dummy; + c.append (value_type ()); + more = f.select (dummy, c.back ()); + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_ (); + + index_type i (0); + for (typename container_type::const_iterator j (c.begin ()), + e (c.end ()); j != e; ++j) + f.insert (i++, *j); + } + + static void + erase (const functions& f) + { + f.delete_ (); + } + }; +} + +#endif + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINER_QLINKED_LIST_TRAITS_HXX diff --git a/libodb-qt/odb/qt/containers/qlist-traits.hxx b/libodb-qt/odb/qt/containers/qlist-traits.hxx new file mode 100644 index 0000000..572d02a --- /dev/null +++ b/libodb-qt/odb/qt/containers/qlist-traits.hxx @@ -0,0 +1,72 @@ +// file : odb/qt/containers/qlist-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINER_QLIST_TRAITS_HXX +#define ODB_QT_CONTAINER_QLIST_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QList> + +#include <odb/container-traits.hxx> + +namespace odb +{ + template <typename T> + class access::container_traits<QList<T> > + { + public: + static const container_kind kind = ck_ordered; + static const bool smart = false; + + typedef QList<T> container_type; + + typedef T value_type; + typedef typename container_type::size_type index_type; + + typedef ordered_functions<index_type, value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + // Index based access is just as fast as iterator based access for + // QList. + // + for (index_type i (0), n (c.size ()); i < n; ++i) + f.insert (i, c[i]); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + index_type dummy; + c.append (value_type ()); + more = f.select (dummy, c.back ()); + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_ (); + + for (index_type i (0), n (c.size ()); i < n; ++i) + f.insert (i, c[i]); + } + + static void + erase (const functions& f) + { + f.delete_ (); + } + }; +} + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINER_QLIST_TRAITS_HXX diff --git a/libodb-qt/odb/qt/containers/qmap-traits.hxx b/libodb-qt/odb/qt/containers/qmap-traits.hxx new file mode 100644 index 0000000..5f13b29 --- /dev/null +++ b/libodb-qt/odb/qt/containers/qmap-traits.hxx @@ -0,0 +1,130 @@ +// file : odb/qt/containers/qmap-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINER_QMAP_TRAITS_HXX +#define ODB_QT_CONTAINER_QMAP_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QMap> +#include <QtCore/QMultiMap> + +#include <odb/container-traits.hxx> + +namespace odb +{ + template <typename Key, typename T> + class access::container_traits<QMap<Key, T> > + { + public: + static const container_kind kind = ck_map; + static const bool smart = false; + + typedef QMap<Key, T> container_type; + + typedef Key key_type; + typedef T value_type; + + typedef map_functions<key_type, value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (i.key (), i.value ()); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + key_type k; + value_type v; + more = f.select (k, v); + c.insert (k, v); //@@ Use std::move in C++11. + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_ (); + + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (i.key (), i.value ()); + } + + static void + erase (const functions& f) + { + f.delete_ (); + } + }; + // @@ QMultiMap guarantees elements to be stored in reverse order of + // insertion. The current implementation of the generated code does + // not guarantee this. + // + template <typename Key, typename T> + class access::container_traits<QMultiMap<Key, T> > + { + public: + static const container_kind kind = ck_multimap; + static const bool smart = false; + + typedef QMultiMap<Key, T> container_type; + + typedef Key key_type; + typedef T value_type; + + typedef map_functions<key_type, value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (i.key (), i.value ()); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + key_type k; + value_type v; + more = f.select (k, v); + c.insert (k, v); //@@ Use std::move in C++11. + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_ (); + + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (i.key (), i.value ()); + } + + static void + erase (const functions& f) + { + f.delete_ (); + } + }; +} + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINER_QMAP_TRAITS_HXX diff --git a/libodb-qt/odb/qt/containers/qset-traits.hxx b/libodb-qt/odb/qt/containers/qset-traits.hxx new file mode 100644 index 0000000..fbea8b7 --- /dev/null +++ b/libodb-qt/odb/qt/containers/qset-traits.hxx @@ -0,0 +1,69 @@ +// file : odb/qt/containers/qset-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINER_QSET_TRAITS_HXX +#define ODB_QT_CONTAINER_QSET_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QSet> + +#include <odb/container-traits.hxx> + +namespace odb +{ + template <typename T> + class access::container_traits<QSet<T> > + { + public: + static const container_kind kind = ck_set; + static const bool smart = false; + + typedef QSet<T> container_type; + typedef T value_type; + + typedef set_functions<value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (*i); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + value_type v; + more = f.select (v); + c.insert (v); //@@ Use std::move in C++11. + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_ (); + + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert (*i); + } + + static void + erase (const functions& f) + { + f.delete_ (); + } + }; +} + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINER_QSET_TRAITS_HXX diff --git a/libodb-qt/odb/qt/containers/qvector-traits.hxx b/libodb-qt/odb/qt/containers/qvector-traits.hxx new file mode 100644 index 0000000..516475d --- /dev/null +++ b/libodb-qt/odb/qt/containers/qvector-traits.hxx @@ -0,0 +1,82 @@ +// file : odb/qt/containers/qvector-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_CONTAINER_QVECTOR_TRAITS_HXX +#define ODB_QT_CONTAINER_QVECTOR_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QtGlobal> // QT_VERSION + +// In Qt 6 QVector is an alias for QList. +// +#if QT_VERSION >= 0x060000 +#include <odb/qt/containers/qlist-traits.hxx> +#else + +#include <QtCore/QVector> + +#include <odb/container-traits.hxx> + +namespace odb +{ + template <typename T> + class access::container_traits<QVector<T> > + { + public: + static const container_kind kind = ck_ordered; + static const bool smart = false; + + typedef QVector<T> container_type; + + typedef T value_type; + typedef typename container_type::size_type index_type; + + typedef ordered_functions<index_type, value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + // Index based access is just as fast as iterator based access for + // QVector. + // + for (index_type i (0), n (c.size ()); i < n; ++i) + f.insert (i, c[i]); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + index_type dummy; + c.append (value_type ()); + more = f.select (dummy, c.back ()); + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_ (); + + for (index_type i (0), n (c.size ()); i < n; ++i) + f.insert (i, c[i]); + } + + static void + erase (const functions& f) + { + f.delete_ (); + } + }; +} + +#endif + +#include <odb/post.hxx> + +#endif // ODB_QT_CONTAINER_QVECTOR_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time.options b/libodb-qt/odb/qt/date-time.options new file mode 100644 index 0000000..d199649 --- /dev/null +++ b/libodb-qt/odb/qt/date-time.options @@ -0,0 +1,4 @@ +# file : odb/qt/date-time.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/date-time/date-time diff --git a/libodb-qt/odb/qt/date-time/date-time-common.options b/libodb-qt/odb/qt/date-time/date-time-common.options new file mode 100644 index 0000000..d813259 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/date-time-common.options @@ -0,0 +1,4 @@ +# file : odb/qt/date-time/date-time-common.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version diff --git a/libodb-qt/odb/qt/date-time/date-time-mssql.options b/libodb-qt/odb/qt/date-time/date-time-mssql.options new file mode 100644 index 0000000..7e35b4d --- /dev/null +++ b/libodb-qt/odb/qt/date-time/date-time-mssql.options @@ -0,0 +1,13 @@ +# file : odb/qt/date-time/date-time-mssql.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/date-time/mssql/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/date-time/mssql/qdate-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/mssql/qtime-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/mssql/qdate-time-traits.hxx>' diff --git a/libodb-qt/odb/qt/date-time/date-time-mysql.options b/libodb-qt/odb/qt/date-time/date-time-mysql.options new file mode 100644 index 0000000..fdbb364 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/date-time-mysql.options @@ -0,0 +1,13 @@ +# file : odb/qt/date-time/date-time-mysql.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/date-time/mysql/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/date-time/mysql/qdate-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/mysql/qtime-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/mysql/qdate-time-traits.hxx>' diff --git a/libodb-qt/odb/qt/date-time/date-time-oracle.options b/libodb-qt/odb/qt/date-time/date-time-oracle.options new file mode 100644 index 0000000..c339ce3 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/date-time-oracle.options @@ -0,0 +1,13 @@ +# file : odb/qt/date-time/date-time-oracle.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/date-time/oracle/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/date-time/oracle/qdate-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/oracle/qtime-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/oracle/qdate-time-traits.hxx>' diff --git a/libodb-qt/odb/qt/date-time/date-time-pgsql.options b/libodb-qt/odb/qt/date-time/date-time-pgsql.options new file mode 100644 index 0000000..9d80d48 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/date-time-pgsql.options @@ -0,0 +1,13 @@ +# file : odb/qt/date-time/date-time-pgsql.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/date-time/pgsql/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/date-time/pgsql/qdate-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/pgsql/qtime-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/pgsql/qdate-time-traits.hxx>' diff --git a/libodb-qt/odb/qt/date-time/date-time-sqlite.options b/libodb-qt/odb/qt/date-time/date-time-sqlite.options new file mode 100644 index 0000000..8eb1110 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/date-time-sqlite.options @@ -0,0 +1,13 @@ +# file : odb/qt/date-time/date-time-sqlite.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Include the default mapping in prologue instead of epilogue to +# allow the user to override the default mapping. +# +--odb-prologue '#include <odb/qt/date-time/sqlite/default-mapping.hxx>' + +--hxx-prologue '#include <odb/qt/date-time/sqlite/qdate-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/sqlite/qtime-traits.hxx>' +--hxx-prologue '#include <odb/qt/date-time/sqlite/qdate-time-traits.hxx>' diff --git a/libodb-qt/odb/qt/date-time/exceptions.cxx b/libodb-qt/odb/qt/date-time/exceptions.cxx new file mode 100644 index 0000000..48f0540 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/exceptions.cxx @@ -0,0 +1,25 @@ +// file : odb/qt/date-time/exceptions.cxx +// license : GNU GPL v2; see accompanying LICENSE file + +#include <odb/qt/date-time/exceptions.hxx> + +namespace odb +{ + namespace qt + { + namespace date_time + { + const char* value_out_of_range:: + what () const ODB_NOTHROW_NOEXCEPT + { + return "date/time value out of range"; + } + + value_out_of_range* value_out_of_range:: + clone () const + { + return new value_out_of_range (*this); + } + } + } +} diff --git a/libodb-qt/odb/qt/date-time/exceptions.hxx b/libodb-qt/odb/qt/date-time/exceptions.hxx new file mode 100644 index 0000000..7a73be2 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/exceptions.hxx @@ -0,0 +1,34 @@ +// file : odb/qt/date-time/exceptions.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_EXCEPTIONS_HXX +#define ODB_QT_DATE_TIME_EXCEPTIONS_HXX + +#include <odb/pre.hxx> + +#include <odb/details/config.hxx> // ODB_NOTHROW_NOEXCEPT + +#include <odb/qt/exception.hxx> +#include <odb/qt/details/export.hxx> + +namespace odb +{ + namespace qt + { + namespace date_time + { + struct LIBODB_QT_EXPORT value_out_of_range: exception + { + virtual const char* + what () const ODB_NOTHROW_NOEXCEPT; + + virtual value_out_of_range* + clone () const; + }; + } + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_EXCEPTIONS_HXX diff --git a/libodb-qt/odb/qt/date-time/mssql/default-mapping.hxx b/libodb-qt/odb/qt/date-time/mssql/default-mapping.hxx new file mode 100644 index 0000000..a8acb6b --- /dev/null +++ b/libodb-qt/odb/qt/date-time/mssql/default-mapping.hxx @@ -0,0 +1,31 @@ +// file : odb/qt/date-time/mssql/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_MSSQL_DEFAULT_MAPPING_HXX +#define ODB_QT_DATE_TIME_MSSQL_DEFAULT_MAPPING_HXX + +#include <QtCore/QDate> +#include <QtCore/QTime> +#include <QtCore/QDateTime> + +// By default map QDate to SQL Server DATE (available only since SQL +// Server 2008). QDate provides a null representation so allow NULL +// values by default. +// +#pragma db value(QDate) type("DATE") null + +// By default map QTime to SQL Server TIME(3) (available only since SQL +// Server 2008). QTime can only represent clock times with a maximum +// precision of milliseconds. QTime provides a null representation so +// allow NULL values by default. +// +#pragma db value(QTime) type("TIME(3)") null + +// By default map QDateTime to SQL Server DATETIME2(3) (available only +// since SQL Server 2008). QDateTime can only represent clock times with +// a maximum precision of milliseconds. QDateTime provides a null +// representation so allow NULL values by default. +// +#pragma db value(QDateTime) type("DATETIME2(3)") null + +#endif // ODB_QT_DATE_TIME_MSSQL_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/date-time/mssql/qdate-time-traits.hxx b/libodb-qt/odb/qt/date-time/mssql/qdate-time-traits.hxx new file mode 100644 index 0000000..5fd8a98 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/mssql/qdate-time-traits.hxx @@ -0,0 +1,104 @@ +// file : odb/qt/date-time/mssql/qdate-time-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_MSSQL_QDATETIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_MSSQL_QDATETIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QDateTime> + +#include <odb/mssql/traits.hxx> + +namespace odb +{ + namespace mssql + { + template <> + struct default_value_traits<QDateTime, id_datetime> + { + typedef QDateTime value_type; + typedef QDateTime query_type; + typedef datetime image_type; + + static void + set_value (QDateTime& v, const datetime& i, bool is_null) + { + if (is_null) + // Default constructor creates a null QDateTime. + // + v = QDateTime (); + else + v = QDateTime (QDate (i.year, + i.month, + i.day), + QTime (i.hour, + i.minute, + i.second, + static_cast<int> (i.fraction / 1000000))); + } + + static void + set_image (datetime& i, + unsigned short s, + bool& is_null, + const QDateTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + const QDate& d (v.date ()); + const QTime& t (v.time ()); + + is_null = false; + i.year = static_cast<SQLSMALLINT> (d.year ()); + i.month = static_cast<SQLUSMALLINT> (d.month ()); + i.day = static_cast<SQLUSMALLINT> (d.day ()); + i.hour = static_cast<SQLUSMALLINT> (t.hour ()); + i.minute = static_cast<SQLUSMALLINT> (t.minute ()); + + // Scale value 8 indicates we are dealing with SMALLDATETIME + // which has the minutes precision. + // + if (s != 8) + { + i.second = static_cast<SQLUSMALLINT> (t.second ()); + + const unsigned int divider[8] = + { + 1000000000, + 100000000, + 10000000, + 1000000, + 100000, + 10000, + 1000, + 100 + }; + + unsigned int ns (static_cast<unsigned int> (t.msec ()) * 1000000); + i.fraction = static_cast<SQLUINTEGER> (ns - ns % divider[s]); + } + else + { + i.second = 0; + i.fraction = 0; + } + } + } + }; + + template <> + struct default_type_traits<QDateTime> + { + static const database_type_id db_type_od = id_datetime; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_MSSQL_QDATETIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/mssql/qdate-traits.hxx b/libodb-qt/odb/qt/date-time/mssql/qdate-traits.hxx new file mode 100644 index 0000000..caa5d3c --- /dev/null +++ b/libodb-qt/odb/qt/date-time/mssql/qdate-traits.hxx @@ -0,0 +1,63 @@ +// file : odb/qt/date-time/mssql/qdate-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_MSSQL_QDATE_TRAITS_HXX +#define ODB_QT_DATE_TIME_MSSQL_QDATE_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QDate> + +#include <odb/mssql/traits.hxx> + +#include <odb/qt/date-time/exceptions.hxx> + +namespace odb +{ + namespace mssql + { + template <> + struct default_value_traits<QDate, id_date> + { + typedef QDate value_type; + typedef QDate query_type; + typedef date image_type; + + static void + set_value (QDate& v, const date& i, bool is_null) + { + if (is_null) + // A null QDate value is equivalent to an invalid QDate value. + // Set v to an invalid date to represent null. + // + v.setDate (0, 0, 0); + else + v.setDate (i.year, i.month, i.day); + } + + static void + set_image (date& i, bool& is_null, const QDate& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + i.year = static_cast<SQLSMALLINT> (v.year ()); + i.month = static_cast<SQLUSMALLINT> (v.month ()); + i.day = static_cast<SQLUSMALLINT> (v.day ()); + } + } + }; + + template <> + struct default_type_traits<QDate> + { + static const database_type_id db_type_id = id_date; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_MSSQL_QDATE_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/mssql/qtime-traits.hxx b/libodb-qt/odb/qt/date-time/mssql/qtime-traits.hxx new file mode 100644 index 0000000..88fbf41 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/mssql/qtime-traits.hxx @@ -0,0 +1,80 @@ +// file : odb/qt/date-time/mssql/qtime-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_MSSQL_QTIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_MSSQL_QTIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QTime> + +#include <odb/mssql/traits.hxx> + +namespace odb +{ + namespace mssql + { + template <> + struct default_value_traits<QTime, id_time> + { + typedef QTime value_type; + typedef QTime query_type; + typedef time image_type; + + static void + set_value (QTime& v, const time& i, bool is_null) + { + if (is_null) + // A null QTime value is equivalent to an invalid QTime value. + // Set v to an invalid time to represent null (hour value of + // a valid time must be in the range 0-23). + // + v.setHMS (24, 0, 0); + else + v.setHMS (i.hour, + i.minute, + i.second, + static_cast<int> (i.fraction / 1000000)); + } + + static void + set_image (time& i, unsigned short s, bool& is_null, const QTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + i.hour = static_cast<SQLUSMALLINT> (v.hour ()); + i.minute = static_cast<SQLUSMALLINT> (v.minute ()); + i.second = static_cast<SQLUSMALLINT> (v.second ()); + + const unsigned int divider[8] = + { + 1000000000, + 100000000, + 10000000, + 1000000, + 100000, + 10000, + 1000, + 100 + }; + + unsigned int ns (static_cast<unsigned int> (v.msec ()) * 1000000); + i.fraction = static_cast<SQLUINTEGER> (ns - ns % divider[s]); + } + } + }; + + template <> + struct default_type_traits<QTime> + { + static const database_type_id db_type_id = id_time; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_MSSQL_QTIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/mysql/default-mapping.hxx b/libodb-qt/odb/qt/date-time/mysql/default-mapping.hxx new file mode 100644 index 0000000..a88c507 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/mysql/default-mapping.hxx @@ -0,0 +1,26 @@ +// file : odb/qt/date-time/mysql/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_MYSQL_DEFAULT_MAPPING_HXX +#define ODB_QT_DATE_TIME_MYSQL_DEFAULT_MAPPING_HXX + +#include <QtCore/QDate> +#include <QtCore/QTime> +#include <QtCore/QDateTime> + +// Map QDate to MySQL DATE by default. QDate provides a null +// representation so allow NULL values by default. +// +#pragma db value(QDate) type("DATE") null + +// Map QTime to MySQL TIME by default. QTime provides a null +// representation so allow NULL values by default. +// +#pragma db value(QTime) type("TIME") null + +// Map QDateTime to MySQL DATETIME by default. QDateTime provides a null +// representation so allow NULL values by default. +// +#pragma db value(QDateTime) type("DATETIME") null + +#endif // ODB_QT_DATE_TIME_MYSQL_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/date-time/mysql/qdate-time-traits.hxx b/libodb-qt/odb/qt/date-time/mysql/qdate-time-traits.hxx new file mode 100644 index 0000000..92279eb --- /dev/null +++ b/libodb-qt/odb/qt/date-time/mysql/qdate-time-traits.hxx @@ -0,0 +1,135 @@ +// file : odb/qt/date-time/mysql/qdate-time-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_MYSQL_QDATETIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_MYSQL_QDATETIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QDateTime> + +#include <odb/mysql/traits.hxx> + +namespace odb +{ + namespace mysql + { + template <> + struct default_value_traits<QDateTime, id_datetime> + { + typedef QDateTime value_type; + typedef QDateTime query_type; + typedef MYSQL_TIME image_type; + + static void + set_value (QDateTime& v, const MYSQL_TIME& i, bool is_null) + { + if (is_null) + // Default constructor creates a null QDateTime. + // + v = QDateTime (); + else + // Since MySQL 5.6.4, the microseconds part is no longer ignored. + // + v = QDateTime (QDate (static_cast<int> (i.year), + static_cast<int> (i.month), + static_cast<int> (i.day)), + QTime (static_cast<int> (i.hour), + static_cast<int> (i.minute), + static_cast<int> (i.second), + static_cast<int> (i.second_part / 1000))); + } + + static void + set_image (MYSQL_TIME& i, bool& is_null, const QDateTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + if ((v < QDateTime (QDate (1000, 1, 1))) || + (v >= QDateTime (QDate (10000, 1, 1)))) + throw odb::qt::date_time::value_out_of_range (); + + is_null = false; + i.neg = false; + + const QDate& d (v.date ()); + i.year = static_cast<unsigned int> (d.year ()); + i.month = static_cast<unsigned int> (d.month ()); + i.day = static_cast<unsigned int> (d.day ()); + + const QTime& t (v.time ()); + i.hour = static_cast<unsigned int> (t.hour ()); + i.minute = static_cast<unsigned int> (t.minute ()); + i.second = static_cast<unsigned int> (t.second ()); + i.second_part = static_cast<unsigned long> (t.msec ()) * 1000; + } + } + }; + + template <> + struct default_value_traits<QDateTime, id_timestamp> + { + typedef QDateTime value_type; + typedef QDateTime query_type; + typedef MYSQL_TIME image_type; + + static void + set_value (QDateTime& v, const MYSQL_TIME& i, bool is_null) + { + if (is_null) + // Default constructor creates a null QDateTime. + // + v = QDateTime (); + else + // Since MySQL 5.6.4, the microseconds part is no longer ignored. + // + v = QDateTime (QDate (static_cast<int> (i.year), + static_cast<int> (i.month), + static_cast<int> (i.day)), + QTime (static_cast<int> (i.hour), + static_cast<int> (i.minute), + static_cast<int> (i.second), + static_cast<int> (i.second_part / 1000))); + } + + static void + set_image (MYSQL_TIME& i, bool& is_null, const QDateTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + if ((v <= QDateTime (QDate (1970, 1, 1))) || + (v > QDateTime (QDate (2038, 1, 19), QTime (3, 14, 7)))) + throw odb::qt::date_time::value_out_of_range (); + + is_null = false; + i.neg = false; + + const QDate& d (v.date ()); + i.year = static_cast<unsigned int> (d.year ()); + i.month = static_cast<unsigned int> (d.month ()); + i.day = static_cast<unsigned int> (d.day ()); + + const QTime& t (v.time ()); + i.hour = static_cast<unsigned int> (t.hour ()); + i.minute = static_cast<unsigned int> (t.minute ()); + i.second = static_cast<unsigned int> (t.second ()); + i.second_part = static_cast<unsigned long> (t.msec ()) * 1000; + } + } + }; + + template <> + struct default_type_traits<QDateTime> + { + static const database_type_id db_type_od = id_datetime; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_MYSQL_QDATETIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/mysql/qdate-traits.hxx b/libodb-qt/odb/qt/date-time/mysql/qdate-traits.hxx new file mode 100644 index 0000000..12a00ec --- /dev/null +++ b/libodb-qt/odb/qt/date-time/mysql/qdate-traits.hxx @@ -0,0 +1,73 @@ +// file : odb/qt/date-time/mysql/qdate-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_MYSQL_QDATE_TRAITS_HXX +#define ODB_QT_DATE_TIME_MYSQL_QDATE_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QDate> + +#include <odb/mysql/traits.hxx> +#include <odb/qt/date-time/exceptions.hxx> + +namespace odb +{ + namespace mysql + { + template <> + struct default_value_traits<QDate, id_date> + { + typedef QDate value_type; + typedef QDate query_type; + typedef MYSQL_TIME image_type; + + static void + set_value (QDate& v, const MYSQL_TIME& i, bool is_null) + { + if (is_null) + // A null QDate value is equivalent to an invalid QDate value. + // Set v to an invalid date to represent null. + // + v.setDate (0, 0, 0); + else + v.setDate (static_cast<int> (i.year), + static_cast<int> (i.month), + static_cast<int> (i.day)); + } + + static void + set_image (MYSQL_TIME& i, bool& is_null, const QDate& v) + { + if (v.isNull ()) + is_null = true; + else if ((v < QDate (1000, 1, 1)) || (v > QDate (9999, 12, 31))) + throw odb::qt::date_time::value_out_of_range (); + else + { + is_null = false; + i.neg = false; + + i.year = static_cast<unsigned int> (v.year ()); + i.month = static_cast<unsigned int> (v.month ()); + i.day = static_cast<unsigned int> (v.day ()); + + i.hour = 0; + i.minute = 0; + i.second = 0; + i.second_part = 0; + } + } + }; + + template <> + struct default_type_traits<QDate> + { + static const database_type_id db_type_id = id_date; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_MYSQL_QDATE_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/mysql/qtime-traits.hxx b/libodb-qt/odb/qt/date-time/mysql/qtime-traits.hxx new file mode 100644 index 0000000..c96e13f --- /dev/null +++ b/libodb-qt/odb/qt/date-time/mysql/qtime-traits.hxx @@ -0,0 +1,74 @@ +// file : odb/qt/date-time/mysql/qtime-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_MYSQL_QTIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_MYSQL_QTIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QTime> + +#include <odb/mysql/traits.hxx> + +namespace odb +{ + namespace mysql + { + template <> + struct default_value_traits<QTime, id_time> + { + typedef QTime value_type; + typedef QTime query_type; + typedef MYSQL_TIME image_type; + + static void + set_value (QTime& v, const MYSQL_TIME& i, bool is_null) + { + if (is_null) + // A null QTime value is equivalent to an invalid QTime value. + // Set v to an invalid time to represent null (hour value of + // a valid time must be in the range 0-23). + // + v.setHMS (24, 0, 0); + else + // Since MySQL 5.6.4, the microseconds part is no longer ignored. + // + v.setHMS (static_cast<int> (i.hour), + static_cast<int> (i.minute), + static_cast<int> (i.second), + static_cast<int> (i.second_part / 1000)); + } + + static void + set_image (MYSQL_TIME& i, bool& is_null, const QTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + i.neg = false; + + i.year = 0; + i.month = 0; + i.day = 0; + + i.hour = static_cast<unsigned int> (v.hour ()); + i.minute = static_cast<unsigned int> (v.minute ()); + i.second = static_cast<unsigned int> (v.second ()); + i.second_part = static_cast<unsigned long> (v.msec ()) * 1000; + } + } + }; + + template <> + struct default_type_traits<QTime> + { + static const database_type_id db_type_id = id_time; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_MYSQL_QTIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/oracle/default-mapping.hxx b/libodb-qt/odb/qt/date-time/oracle/default-mapping.hxx new file mode 100644 index 0000000..32a733a --- /dev/null +++ b/libodb-qt/odb/qt/date-time/oracle/default-mapping.hxx @@ -0,0 +1,29 @@ +// file : odb/qt/date-time/oracle/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_ORACLE_DEFAULT_MAPPING_HXX +#define ODB_QT_DATE_TIME_ORACLE_DEFAULT_MAPPING_HXX + +#include <QtCore/QDate> +#include <QtCore/QTime> +#include <QtCore/QDateTime> + +// Map QDate to Oracle DATE by default. QDate provides a null representation +// so allow NULL values by default. +// +#pragma db value(QDate) type("DATE") null + +// Map QTime to Oracle INTERVAL DAY(0) TO SECOND(3) by default. QTime can +// only represent clock times with a maximum precision of milliseconds. +// QTime provides a null representation so allow NULL values by default. +// +#pragma db value(QTime) type("INTERVAL DAY(0) TO SECOND(3)") null + +// Map QDateTime to Oracle TIMESTAMP(3) by default. QDateTime can only +// represent clock times with a maximum precision of milliseconds. +// QDateTime provides a null representation so allow NULL values by +// default. +// +#pragma db value(QDateTime) type("TIMESTAMP(3)") null + +#endif // ODB_QT_DATE_TIME_ORACLE_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/date-time/oracle/qdate-time-traits.hxx b/libodb-qt/odb/qt/date-time/oracle/qdate-time-traits.hxx new file mode 100644 index 0000000..ba90075 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/oracle/qdate-time-traits.hxx @@ -0,0 +1,136 @@ +// file : odb/qt/date-time/oracle/qdate-time-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_ORACLE_QDATETIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_ORACLE_QDATETIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QDateTime> + +#include <odb/oracle/traits.hxx> +#include <odb/oracle/details/date.hxx> + +namespace odb +{ + namespace oracle + { + template <> + struct default_value_traits<QDateTime, id_timestamp> + { + typedef QDateTime value_type; + typedef QDateTime query_type; + typedef datetime image_type; + + static void + set_value (QDateTime& v, const datetime& i, bool is_null) + { + if (is_null) + // Default constructor creates a null QDateTime. + // + v = QDateTime (); + else + { + sb2 y (0); + ub1 m (0), d (0), h (0), minute (0), s (0); + ub4 ns (0); + i.get (y, m, d, h, minute, s, ns); + + v = QDateTime (QDate (static_cast<int> (y), + static_cast<int> (m), + static_cast<int> (d)), + QTime (static_cast<int> (h), + static_cast<int> (minute), + static_cast<int> (s), + static_cast<int> (ns / 1000000))); + } + } + + static void + set_image (datetime& i, bool& is_null, const QDateTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + const QDate& d (v.date ()); + const QTime& t (v.time ()); + + i.set (static_cast<sb2> (d.year ()), + static_cast<ub1> (d.month ()), + static_cast<ub1> (d.day ()), + static_cast<ub1> (t.hour ()), + static_cast<ub1> (t.minute ()), + static_cast<ub1> (t.second ()), + static_cast<ub4> (t.msec () * 1000000)); + } + } + }; + + template <> + struct default_value_traits<QDateTime, id_date> + { + typedef QDateTime value_type; + typedef QDateTime query_type; + typedef char* image_type; + + static void + set_value (QDateTime& v, const char* b, bool is_null) + { + if (is_null) + // Default constructor creates a null QDateTime. + // + v = QDateTime (); + else + { + short y; + unsigned char m, d, h, minute, s; + + details::get_date (b, y, m, d, h, minute, s); + + v = QDateTime (QDate (static_cast<int> (y), + static_cast<int> (m), + static_cast<int> (d)), + QTime (static_cast<int> (h), + static_cast<int> (minute), + static_cast<int> (s), + 0)); + } + } + + static void + set_image (char* b, bool& is_null, const QDateTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + const QDate& d (v.date ()); + const QTime& t (v.time ()); + + details::set_date (b, + static_cast<short> (d.year ()), + static_cast<unsigned char> (d.month ()), + static_cast<unsigned char> (d.day ()), + static_cast<unsigned char> (t.hour ()), + static_cast<unsigned char> (t.minute ()), + static_cast<unsigned char> (t.second ())); + } + } + }; + + template <> + struct default_type_traits<QDateTime> + { + static const database_type_id db_type_od = id_timestamp; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_ORACLE_QDATETIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/oracle/qdate-traits.hxx b/libodb-qt/odb/qt/date-time/oracle/qdate-traits.hxx new file mode 100644 index 0000000..f293e2d --- /dev/null +++ b/libodb-qt/odb/qt/date-time/oracle/qdate-traits.hxx @@ -0,0 +1,76 @@ +// file : odb/qt/date-time/oracle/qdate-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_ORACLE_QDATE_TRAITS_HXX +#define ODB_QT_DATE_TIME_ORACLE_QDATE_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QDate> + +#include <odb/oracle/traits.hxx> + +#include <odb/oracle/details/date.hxx> + +#include <odb/qt/date-time/exceptions.hxx> + +namespace odb +{ + namespace oracle + { + template <> + struct default_value_traits<QDate, id_date> + { + typedef QDate value_type; + typedef QDate query_type; + typedef char* image_type; + + static void + set_value (QDate& v, const char* b, bool is_null) + { + if (is_null) + // A null QDate value is equivalent to an invalid QDate value. + // Set v to an invalid date to represent null. + // + v.setDate (0, 0, 0); + else + { + short y (0); + unsigned char m (0), d (0), h (0), minute (0), s (0); + details::get_date (b, y, m, d, h, minute, s); + + v.setDate (y, m, d); + } + } + + static void + set_image (char* b, bool& is_null, const QDate& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + details::set_date (b, + static_cast<short> (v.year ()), + static_cast<unsigned char> (v.month ()), + static_cast<unsigned char> (v.day ()), + 0, + 0, + 0); + } + } + }; + + template <> + struct default_type_traits<QDate> + { + static const database_type_id db_type_id = id_date; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_ORACLE_QDATE_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/oracle/qtime-traits.hxx b/libodb-qt/odb/qt/date-time/oracle/qtime-traits.hxx new file mode 100644 index 0000000..0d9aff4 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/oracle/qtime-traits.hxx @@ -0,0 +1,66 @@ +// file : odb/qt/date-time/oracle/qtime-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_ORACLE_QTIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_ORACLE_QTIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QTime> + +#include <odb/oracle/traits.hxx> + +namespace odb +{ + namespace oracle + { + template <> + struct default_value_traits<QTime, id_interval_ds> + { + typedef QTime value_type; + typedef QTime query_type; + typedef interval_ds image_type; + + static void + set_value (QTime& v, const interval_ds& i, bool is_null) + { + if (is_null) + // A null QTime value is equivalent to an invalid QTime value. + // Set v to an invalid time to represent null (hour value of + // a valid time must be in the range 0-23). + // + v.setHMS (24, 0, 0); + else + { + sb4 d (0), h (0), m (0), s (0), ns (0); + i.get (d, h, m, s, ns); + + v.setHMS (h, m, s, ns / 1000000); + } + } + + static void + set_image (interval_ds& i, bool& is_null, const QTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + i.set (0, v.hour (), v.minute (), v.second (), v.msec () * 1000000); + } + } + }; + + template <> + struct default_type_traits<QTime> + { + static const database_type_id db_type_id = id_interval_ds; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_ORACLE_QTIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/pgsql/default-mapping.hxx b/libodb-qt/odb/qt/date-time/pgsql/default-mapping.hxx new file mode 100644 index 0000000..cd3b1b5 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/pgsql/default-mapping.hxx @@ -0,0 +1,26 @@ +// file : odb/qt/date-time/pgsql/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_PGSQL_DEFAULT_MAPPING_HXX +#define ODB_QT_DATE_TIME_PGSQL_DEFAULT_MAPPING_HXX + +#include <QtCore/QDate> +#include <QtCore/QTime> +#include <QtCore/QDateTime> + +// Map QDate to PostgreSQL DATE by default. QDate provides a null +// representation so allow NULL values by default. +// +#pragma db value(QDate) type("DATE") null + +// Map QTime to PostgreSQL TIME by default. QTime provides a null +// representation so allow NULL values by default. +// +#pragma db value(QTime) type("TIME") null + +// Map QDateTime to PostgreSQL TIMESTAMP by default. QDateTime provides a null +// representation so allow NULL values by default. +// +#pragma db value(QDateTime) type("TIMESTAMP") null + +#endif // ODB_QT_DATE_TIME_PGSQL_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/date-time/pgsql/qdate-time-traits.hxx b/libodb-qt/odb/qt/date-time/pgsql/qdate-time-traits.hxx new file mode 100644 index 0000000..a9fe757 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/pgsql/qdate-time-traits.hxx @@ -0,0 +1,70 @@ +// file : odb/qt/date-time/pgsql/qdatetime-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_PGSQL_QDATETIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_PGSQL_QDATETIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QDateTime> + +#include <odb/pgsql/traits.hxx> + +namespace odb +{ + namespace pgsql + { + // Implementation of mapping between QDateTime and PostgreSQL TIMESTAMP. + // TIMESTAMP values are stored as micro-seconds since the PostgreSQL + // epoch 2000-01-01. + // + template <> + struct default_value_traits<QDateTime, id_timestamp> + { + typedef details::endian_traits endian_traits; + + typedef QDateTime value_type; + typedef QDateTime query_type; + typedef long long image_type; + + static void + set_value (QDateTime& v, long long i, bool is_null) + { + if (is_null) + // Default constructor creates a null QDateTime. + // + v = QDateTime (); + else + { + const QDateTime pg_epoch (QDate (2000, 1, 1), QTime (0, 0, 0)); + v = pg_epoch.addMSecs ( + static_cast <qint64> (endian_traits::ntoh (i) / 1000LL)); + } + } + + static void + set_image (long long& i, bool& is_null, const QDateTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + const QDateTime pg_epoch (QDate (2000, 1, 1), QTime (0, 0, 0)); + i = endian_traits::hton ( + static_cast<long long> (pg_epoch.msecsTo (v)) * 1000LL); + } + } + }; + + template <> + struct default_type_traits<QDateTime> + { + static const database_type_id db_type_id = id_timestamp; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_PGSQL_QDATETIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/pgsql/qdate-traits.hxx b/libodb-qt/odb/qt/date-time/pgsql/qdate-traits.hxx new file mode 100644 index 0000000..b7cc7d4 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/pgsql/qdate-traits.hxx @@ -0,0 +1,70 @@ +// file : odb/qt/date-time/pgsql/qdate-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_PGSQL_QDATE_TRAITS_HXX +#define ODB_QT_DATE_TIME_PGSQL_QDATE_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QDate> + +#include <odb/pgsql/traits.hxx> + +namespace odb +{ + namespace pgsql + { + // Implementation of the mapping between QDate and PostgreSQL DATE. The + // DATE values are stored as days since the PostgreSQL epoch 2000-01-01. + // + template <> + struct default_value_traits<QDate, id_date> + { + typedef details::endian_traits endian_traits; + + typedef QDate value_type; + typedef QDate query_type; + typedef int image_type; + + static void + set_value (QDate& v, int i, bool is_null) + { + if (is_null) + // A null QDate value is equivalent to an invalid QDate value. + // Set v to an invalid date to represent null. + // + v.setDate (0, 0, 0); + else + { + const QDate pg_epoch (2000, 1, 1); + v = pg_epoch.addDays (endian_traits::ntoh (i)); + } + } + + static void + set_image (int& i, bool& is_null, const QDate& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + const QDate pg_epoch (2000, 1, 1); + // In Qt5 daysTo() returns qint64. + // + i = endian_traits::hton (static_cast<int> (pg_epoch.daysTo (v))); + } + } + }; + + template <> + struct default_type_traits<QDate> + { + static const database_type_id db_type_id = id_date; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_PGSQL_QDATE_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/pgsql/qtime-traits.hxx b/libodb-qt/odb/qt/date-time/pgsql/qtime-traits.hxx new file mode 100644 index 0000000..86a594b --- /dev/null +++ b/libodb-qt/odb/qt/date-time/pgsql/qtime-traits.hxx @@ -0,0 +1,73 @@ +// file : odb/qt/date-time/pgsql/qtime-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_PGSQL_QTIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_PGSQL_QTIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QTime> + +#include <odb/pgsql/traits.hxx> + +namespace odb +{ + namespace pgsql + { + // Implementation of the mapping between QTime and PostgreSQL TIME. The + // TIME values are stored as micro-seconds since 00:00:00. + // + template <> + struct default_value_traits<QTime, id_time> + { + typedef details::endian_traits endian_traits; + + typedef QTime value_type; + typedef QTime query_type; + typedef long long image_type; + + static void + set_value (QTime& v, long long i, bool is_null) + { + if (is_null) + // A null QTime value is equivalent to an invalid QTime value. + // Set v to an invalid time to represent null (hour value of + // a valid time must be in the range 0-23). + // + v.setHMS (24, 0, 0); + else + { + const QTime base (0, 0, 0); + + v = base.addMSecs ( + static_cast<int> (endian_traits::ntoh (i) / 1000)); + } + } + + static void + set_image (long long& i, bool& is_null, const QTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + const QTime base (0, 0, 0); + + i = endian_traits::hton ( + static_cast<long long> (base.msecsTo (v)) * 1000); + } + } + }; + + template <> + struct default_type_traits<QTime> + { + static const database_type_id db_type_id = id_time; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_PGSQL_QTIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/sqlite/default-mapping.hxx b/libodb-qt/odb/qt/date-time/sqlite/default-mapping.hxx new file mode 100644 index 0000000..a150ca9 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/sqlite/default-mapping.hxx @@ -0,0 +1,26 @@ +// file : odb/qt/date-time/sqlite/default-mapping.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_SQLITE_DEFAULT_MAPPING_HXX +#define ODB_QT_DATE_TIME_SQLITE_DEFAULT_MAPPING_HXX + +#include <QtCore/QDate> +#include <QtCore/QTime> +#include <QtCore/QDateTime> + +// Map QDate to SQLite TEXT by default. QDate provides a null representation +// so allow NULL values by default. +// +#pragma db value(QDate) type("TEXT") null + +// Map QTime to SQLite TEXT by default. QTime provides a null representation +// so allow NULL values by default. +// +#pragma db value(QTime) type("TEXT") null + +// Map QDateTime to SQLite TEXT by default. QDateTime provides a null +// representation so allow NULL values by default. +// +#pragma db value(QDateTime) type("TEXT") null + +#endif // ODB_QT_DATE_TIME_SQLITE_DEFAULT_MAPPING_HXX diff --git a/libodb-qt/odb/qt/date-time/sqlite/qdate-time-traits.hxx b/libodb-qt/odb/qt/date-time/sqlite/qdate-time-traits.hxx new file mode 100644 index 0000000..db561fc --- /dev/null +++ b/libodb-qt/odb/qt/date-time/sqlite/qdate-time-traits.hxx @@ -0,0 +1,138 @@ +// file : odb/qt/date-time/sqlite/qdatetime-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_SQLITE_QDATETIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_SQLITE_QDATETIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <string> +#include <cstddef> // std::size_t +#include <cstring> // std::memcpy + +#include <QtCore/QtGlobal> // QT_VERSION + +#include <QtCore/QDateTime> + +#include <odb/details/buffer.hxx> +#include <odb/sqlite/traits.hxx> +#include <odb/qt/date-time/exceptions.hxx> + +namespace odb +{ + namespace sqlite + { + template <> + struct default_value_traits<QDateTime, id_text> + { + typedef QDateTime value_type; + typedef QDateTime query_type; + typedef details::buffer image_type; + + static void + set_value (QDateTime& v, + const details::buffer& i, + std::size_t n, + bool is_null) + { + if (is_null) + // Default constructor creates a null QDateTime. + // + v = QDateTime (); + else + v = QDateTime::fromString ( + QString::fromLatin1 (i.data (), static_cast<int> (n)), + "yyyy-MM-ddTHH:mm:ss.zzz"); + } + + static void + set_image (details::buffer& i, + std::size_t& n, + bool& is_null, + const QDateTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + // Cannot use toStdString() here since Qt could have been + // configured without the STL compatibility support. + // + std::string s ( + v.toString ("yyyy-MM-ddTHH:mm:ss.zzz").toLatin1 ().constData ()); + + n = s.size (); + if (n > i.capacity ()) + i.capacity (n); + + std::memcpy (i.data (), s.data (), n); + } + } + }; + + // Implementation of mapping between QDateTime and SQLite INTEGER. + // The integer value represents UNIX time. + // + template <> + struct default_value_traits<QDateTime, id_integer> + { + typedef QDateTime value_type; + typedef QDateTime query_type; + typedef long long image_type; + + static void + set_value (QDateTime& v, long long i, bool is_null) + { + if (is_null) + // Default constructor creates a null QDateTime. + // + v = QDateTime (); + else + { + v.setTimeSpec (Qt::UTC); + + // *Time_t() functions are deprecated in favor of *SecsSinceEpoch(). + // +#if QT_VERSION < 0x060000 + v.setTime_t (static_cast<uint> (i)); +#else + v.setSecsSinceEpoch (static_cast<qint64> (i)); +#endif + } + } + + static void + set_image (long long& i, bool& is_null, const QDateTime& v) + { + if (v.isNull ()) + is_null = true; + else if (v < QDateTime (QDate (1970, 1, 1), + QTime (0, 0, 0), + Qt::UTC)) + throw odb::qt::date_time::value_out_of_range (); + else + { + is_null = false; + +#if QT_VERSION < 0x060000 + i = static_cast<long long> (v.toTime_t ()); +#else + i = static_cast<long long> (v.toSecsSinceEpoch ()); +#endif + } + } + }; + + template <> + struct default_type_traits<QDateTime> + { + static const database_type_id db_type_id = id_text; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_SQLITE_QDATETIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/sqlite/qdate-traits.hxx b/libodb-qt/odb/qt/date-time/sqlite/qdate-traits.hxx new file mode 100644 index 0000000..52721b7 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/sqlite/qdate-traits.hxx @@ -0,0 +1,141 @@ +// file : odb/qt/date-time/sqlite/qdate-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_SQLITE_QDATE_TRAITS_HXX +#define ODB_QT_DATE_TIME_SQLITE_QDATE_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <string> +#include <cstddef> // std::size_t +#include <cstring> // std::memcpy + +#include <QtCore/QtGlobal> // QT_VERSION + +#include <QtCore/QDate> +#include <QtCore/QDateTime> + +#include <odb/details/buffer.hxx> +#include <odb/sqlite/traits.hxx> +#include <odb/qt/date-time/exceptions.hxx> + +namespace odb +{ + namespace sqlite + { + template <> + struct default_value_traits<QDate, id_text> + { + typedef QDate value_type; + typedef QDate query_type; + typedef details::buffer image_type; + + static void + set_value (QDate& v, + const details::buffer& i, + std::size_t n, + bool is_null) + { + if (is_null) + // A null QDate value is equivalent to an invalid QDate value. + // Set v to an invalid date to represent null. + // + v.setDate (0, 0, 0); + else + v = QDate::fromString ( + QString::fromLatin1 (i.data (), static_cast<int> (n)), + "yyyy-MM-dd"); + } + + static void + set_image (details::buffer& i, + std::size_t& n, + bool& is_null, + const QDate& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + // Cannot use toStdString() here since Qt could have been + // configured without the STL compatibility support. + // + std::string s (v.toString ("yyyy-MM-dd").toLatin1 ().constData ()); + + n = s.size (); + if (n > i.capacity ()) + i.capacity (n); + + std::memcpy (i.data (), s.data (), n); + } + } + }; + + // Implementation of the mapping between QDate and SQLite INTEGER. The + // integer value represents UNIX time. + // + template <> + struct default_value_traits<QDate, id_integer> + { + typedef QDate value_type; + typedef QDate query_type; + typedef long long image_type; + + static void + set_value (QDate& v, long long i, bool is_null) + { + if (is_null) + // A null QDate value is equivalent to an invalid QDate value. + // Set v to an invalid date to represent null. + // + v.setDate (0, 0, 0); + else + { + QDateTime dt; + dt.setTimeSpec (Qt::UTC); + + // *Time_t() functions are deprecated in favor of *SecsSinceEpoch(). + // +#if QT_VERSION < 0x060000 + dt.setTime_t (static_cast<uint> (i)); +#else + dt.setSecsSinceEpoch (static_cast<qint64> (i)); +#endif + v = dt.date (); + } + } + + static void + set_image (long long& i, bool& is_null, const QDate& v) + { + if (v.isNull ()) + is_null = true; + else if (v < QDate (1970, 1, 1)) + throw odb::qt::date_time::value_out_of_range (); + else + { + is_null = false; + const QDateTime dt (v, QTime (0, 0, 0), Qt::UTC); + +#if QT_VERSION < 0x060000 + i = static_cast<long long> (dt.toTime_t ()); +#else + i = static_cast<long long> (dt.toSecsSinceEpoch ()); +#endif + } + } + }; + + template <> + struct default_type_traits<QDate> + { + static const database_type_id db_type_id = id_text; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_SQLITE_QDATE_TRAITS_HXX diff --git a/libodb-qt/odb/qt/date-time/sqlite/qtime-traits.hxx b/libodb-qt/odb/qt/date-time/sqlite/qtime-traits.hxx new file mode 100644 index 0000000..dd86399 --- /dev/null +++ b/libodb-qt/odb/qt/date-time/sqlite/qtime-traits.hxx @@ -0,0 +1,120 @@ +// file : odb/qt/date-time/sqlite/qtime-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DATE_TIME_SQLITE_QTIME_TRAITS_HXX +#define ODB_QT_DATE_TIME_SQLITE_QTIME_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <string> +#include <cstddef> // std::size_t +#include <cstring> // std::memcpy + +#include <QtCore/QTime> + +#include <odb/details/buffer.hxx> +#include <odb/sqlite/traits.hxx> + +namespace odb +{ + namespace sqlite + { + template <> + struct default_value_traits<QTime, id_text> + { + typedef QTime value_type; + typedef QTime query_type; + typedef details::buffer image_type; + + static void + set_value (QTime& v, + const details::buffer& i, + std::size_t n, + bool is_null) + { + if (is_null) + // A null QTime value is equivalent to an invalid QTime value. + // Set v to an invalid time to represent null (hour value of + // a valid time must be in the range 0-23). + // + v.setHMS (24, 0, 0); + else + v = QTime::fromString ( + QString::fromLatin1 (i.data (), static_cast<int> (n)), + "HH:mm:ss.zzz"); + } + + static void + set_image (details::buffer& i, + std::size_t& n, + bool& is_null, + const QTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + + // Cannot use toStdString() here since Qt could have been + // configured without the STL compatibility support. + // + std::string s ( + v.toString ("HH:mm:ss.zzz").toLatin1 ().constData ()); + + n = s.size (); + if (n > i.capacity ()) + i.capacity (n); + + std::memcpy (i.data (), s.data (), n); + } + } + }; + + // Implementation of mapping between QTime and SQLite INTEGER. The + // integer value represents seconds since midnight. + // + template <> + struct default_value_traits<QTime, id_integer> + { + typedef QTime value_type; + typedef QTime query_type; + typedef long long image_type; + + static void + set_value (QTime& v, long long i, bool is_null) + { + if (is_null) + // A null QTime value is equivalent to an invalid QTime value. + // Set v to an invalid time to represent null (hour value of + // a valid time must be in the range 0-23). + // + v.setHMS (24, 0, 0); + else + v = QTime (0, 0, 0).addSecs (static_cast<int> (i)); + } + + static void + set_image (long long& i, bool& is_null, const QTime& v) + { + if (v.isNull ()) + is_null = true; + else + { + is_null = false; + i = static_cast<long long> (QTime (0, 0, 0).secsTo (v)); + } + } + }; + + template <> + struct default_type_traits<QTime> + { + static const database_type_id db_type_id = id_text; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_DATE_TIME_SQLITE_QTIME_TRAITS_HXX diff --git a/libodb-qt/odb/qt/details/build2/config-stub.h b/libodb-qt/odb/qt/details/build2/config-stub.h new file mode 100644 index 0000000..fbb2971 --- /dev/null +++ b/libodb-qt/odb/qt/details/build2/config-stub.h @@ -0,0 +1,5 @@ +/* file : odb/qt/details/build2/config-stub.h + * license : GNU GPL v2; see accompanying LICENSE file + */ + +#include <odb/qt/details/config.h> diff --git a/libodb-qt/odb/qt/details/build2/config-vc-stub.h b/libodb-qt/odb/qt/details/build2/config-vc-stub.h new file mode 100644 index 0000000..e6a412d --- /dev/null +++ b/libodb-qt/odb/qt/details/build2/config-vc-stub.h @@ -0,0 +1,5 @@ +/* file : odb/qt/details/build2/config-vc-stub.h + * license : GNU GPL v2; see accompanying LICENSE file + */ + +#include <odb/qt/details/config-vc.h> diff --git a/libodb-qt/odb/qt/details/build2/config-vc.h b/libodb-qt/odb/qt/details/build2/config-vc.h new file mode 100644 index 0000000..36113ce --- /dev/null +++ b/libodb-qt/odb/qt/details/build2/config-vc.h @@ -0,0 +1,15 @@ +/* file : odb/qt/details/build2/config-vc.h + * license : GNU GPL v2; see accompanying LICENSE file + */ + +/* Configuration file for Windows/VC++ for the build2 build. */ + +#ifndef ODB_QT_DETAILS_CONFIG_VC_H +#define ODB_QT_DETAILS_CONFIG_VC_H + +/* Define LIBODB_QT_BUILD2 for the installed case. */ +#ifndef LIBODB_QT_BUILD2 +# define LIBODB_QT_BUILD2 +#endif + +#endif /* ODB_QT_DETAILS_CONFIG_VC_H */ diff --git a/libodb-qt/odb/qt/details/build2/config.h b/libodb-qt/odb/qt/details/build2/config.h new file mode 100644 index 0000000..12d168f --- /dev/null +++ b/libodb-qt/odb/qt/details/build2/config.h @@ -0,0 +1,17 @@ +/* file : odb/qt/details/build2/config.h + * license : GNU GPL v2; see accompanying LICENSE file + */ + +/* Static configuration file for the build2 build. The installed case + (when LIBODB_QT_BUILD2 is not necessarily defined) is the only + reason we have it. */ + +#ifndef ODB_QT_DETAILS_CONFIG_H +#define ODB_QT_DETAILS_CONFIG_H + +/* Define LIBODB_QT_BUILD2 for the installed case. */ +#ifndef LIBODB_QT_BUILD2 +# define LIBODB_QT_BUILD2 +#endif + +#endif /* ODB_QT_DETAILS_CONFIG_H */ diff --git a/libodb-qt/odb/qt/details/config-vc.h b/libodb-qt/odb/qt/details/config-vc.h new file mode 100644 index 0000000..6718a07 --- /dev/null +++ b/libodb-qt/odb/qt/details/config-vc.h @@ -0,0 +1,5 @@ +/* file : odb/qt/details/config-vc.h + * license : GNU GPL v2; see accompanying LICENSE file + */ + +/* Dummy configuration file for Windows/VC++. */ diff --git a/libodb-qt/odb/qt/details/config.h.in b/libodb-qt/odb/qt/details/config.h.in new file mode 100644 index 0000000..a0c3989 --- /dev/null +++ b/libodb-qt/odb/qt/details/config.h.in @@ -0,0 +1,12 @@ +/* file : odb/qt/details/config.h.in + * license : GNU GPL v2; see accompanying LICENSE file + */ + +/* This file is automatically processed by configure. */ + +#ifndef ODB_QT_DETAILS_CONFIG_H +#define ODB_QT_DETAILS_CONFIG_H + +#undef LIBODB_QT_STATIC_LIB + +#endif /* ODB_QT_DETAILS_CONFIG_H */ diff --git a/libodb-qt/odb/qt/details/config.hxx b/libodb-qt/odb/qt/details/config.hxx new file mode 100644 index 0000000..9077380 --- /dev/null +++ b/libodb-qt/odb/qt/details/config.hxx @@ -0,0 +1,38 @@ +// file : odb/qt/details/config.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DETAILS_CONFIG_HXX +#define ODB_QT_DETAILS_CONFIG_HXX + +// no pre + +// Qt5 may complain if we are building without -fPIC. Instead of asking the +// user to pass one of these options to the ODB compiler (which can, BTW, be +// done with -x -fPIC, for example, if one is not using the Qt profile), we +// are going to define __PIC__ ourselves just to silence Qt. We also want to +// try to minimize this to cases where it is actually necessary. To achieve +// this, we need to include the Qt config file without including <QtGlobal>, +// which is where the test for PIE is. While newer versions of Qt (from 4.7) +// have <QtConfig>, to support older versions we will include qconfig.h +// directly. This file appears to be present in all the versions starting with +// Qt 4.0. +// +#ifdef ODB_COMPILER +# if defined(__ELF__) && !defined(__PIC__) +# include <QtCore/qconfig.h> // QT_REDUCE_RELOCATIONS +# ifdef QT_REDUCE_RELOCATIONS +# define __PIC__ +# endif +# endif +# define LIBODB_QT_STATIC_LIB +#elif !defined(LIBODB_QT_BUILD2) +# ifdef _MSC_VER +# include <odb/qt/details/config-vc.h> +# else +# include <odb/qt/details/config.h> +# endif +#endif + +// no post + +#endif // ODB_QT_DETAILS_CONFIG_HXX diff --git a/libodb-qt/odb/qt/details/export.hxx b/libodb-qt/odb/qt/details/export.hxx new file mode 100644 index 0000000..4c0097f --- /dev/null +++ b/libodb-qt/odb/qt/details/export.hxx @@ -0,0 +1,78 @@ +// file : odb/qt/details/export.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_DETAILS_EXPORT_HXX +#define ODB_QT_DETAILS_EXPORT_HXX + +#include <odb/pre.hxx> + +#include <odb/qt/details/config.hxx> + +// Normally we don't export class templates (but do complete specializations), +// inline functions, and classes with only inline member functions. Exporting +// classes that inherit from non-exported/imported bases (e.g., std::string) +// will end up badly. The only known workarounds are to not inherit or to not +// export. Also, MinGW GCC doesn't like seeing non-exported function being +// used before their inline definition. The workaround is to reorder code. In +// the end it's all trial and error. + +#ifdef LIBODB_QT_BUILD2 + +#if defined(LIBODB_QT_STATIC) // Using static. +# define LIBODB_QT_EXPORT +#elif defined(LIBODB_QT_STATIC_BUILD) // Building static. +# define LIBODB_QT_EXPORT +#elif defined(LIBODB_QT_SHARED) // Using shared. +# ifdef _WIN32 +# define LIBODB_QT_EXPORT __declspec(dllimport) +# else +# define LIBODB_QT_EXPORT +# endif +#elif defined(LIBODB_QT_SHARED_BUILD) // Building shared. +# ifdef _WIN32 +# define LIBODB_QT_EXPORT __declspec(dllexport) +# else +# define LIBODB_QT_EXPORT +# endif +#else +// If none of the above macros are defined, then we assume we are being used +// by some third-party build system that cannot/doesn't signal the library +// type. Note that this fallback works for both static and shared but in case +// of shared will be sub-optimal compared to having dllimport. +// +# define LIBODB_QT_EXPORT // Using static or shared. +#endif + +#else // LIBODB_QT_BUILD2 + +#ifdef LIBODB_QT_STATIC_LIB +# define LIBODB_QT_EXPORT +#else +# ifdef _WIN32 +# ifdef _MSC_VER +# ifdef LIBODB_QT_DYNAMIC_LIB +# define LIBODB_QT_EXPORT __declspec(dllexport) +# else +# define LIBODB_QT_EXPORT __declspec(dllimport) +# endif +# else +# ifdef LIBODB_QT_DYNAMIC_LIB +# ifdef DLL_EXPORT +# define LIBODB_QT_EXPORT __declspec(dllexport) +# else +# define LIBODB_QT_EXPORT +# endif +# else +# define LIBODB_QT_EXPORT __declspec(dllimport) +# endif +# endif +# else +# define LIBODB_QT_EXPORT +# endif +#endif + +#endif // LIBODB_QT_BUILD2 + +#include <odb/post.hxx> + +#endif // ODB_QT_DETAILS_EXPORT_HXX diff --git a/libodb-qt/odb/qt/exception.hxx b/libodb-qt/odb/qt/exception.hxx new file mode 100644 index 0000000..44646d5 --- /dev/null +++ b/libodb-qt/odb/qt/exception.hxx @@ -0,0 +1,28 @@ +// file : odb/qt/exception.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_EXCEPTION_HXX +#define ODB_QT_EXCEPTION_HXX + +#include <odb/pre.hxx> + +#include <odb/exceptions.hxx> + +#include <odb/details/config.hxx> // ODB_NOTHROW_NOEXCEPT +#include <odb/qt/details/export.hxx> + +namespace odb +{ + namespace qt + { + struct LIBODB_QT_EXPORT exception: odb::exception + { + virtual const char* + what () const ODB_NOTHROW_NOEXCEPT = 0; + }; + } +} + +#include <odb/post.hxx> + +#endif // ODB_QT_EXCEPTION_HXX diff --git a/libodb-qt/odb/qt/lazy-ptr.hxx b/libodb-qt/odb/qt/lazy-ptr.hxx new file mode 100644 index 0000000..6e5a3e0 --- /dev/null +++ b/libodb-qt/odb/qt/lazy-ptr.hxx @@ -0,0 +1,9 @@ +// file : odb/qt/lazy-ptr.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_LAZY_PTR_HXX +#define ODB_QT_LAZY_PTR_HXX + +#include <odb/qt/smart-ptr/lazy-ptr.hxx> + +#endif // ODB_QT_LAZY_PTR_HXX diff --git a/libodb-qt/odb/qt/list-iterator.hxx b/libodb-qt/odb/qt/list-iterator.hxx new file mode 100644 index 0000000..bb8b20c --- /dev/null +++ b/libodb-qt/odb/qt/list-iterator.hxx @@ -0,0 +1,9 @@ +// file : odb/qt/list-iterator.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_LIST_ITERATOR_HXX +#define ODB_QT_LIST_ITERATOR_HXX + +#include <odb/qt/containers/list-iterator.hxx> + +#endif // ODB_QT_LIST_ITERATOR_HXX diff --git a/libodb-qt/odb/qt/list.hxx b/libodb-qt/odb/qt/list.hxx new file mode 100644 index 0000000..7918ef6 --- /dev/null +++ b/libodb-qt/odb/qt/list.hxx @@ -0,0 +1,9 @@ +// file : odb/qt/list.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_LIST_HXX +#define ODB_QT_LIST_HXX + +#include <odb/qt/containers/list.hxx> + +#endif // ODB_QT_LIST_HXX diff --git a/libodb-qt/odb/qt/mutable-list-iterator.hxx b/libodb-qt/odb/qt/mutable-list-iterator.hxx new file mode 100644 index 0000000..045ae99 --- /dev/null +++ b/libodb-qt/odb/qt/mutable-list-iterator.hxx @@ -0,0 +1,9 @@ +// file : odb/qt/mutable-list-iterator.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_MUTABLE_LIST_ITERATOR_HXX +#define ODB_QT_MUTABLE_LIST_ITERATOR_HXX + +#include <odb/qt/containers/mutable-list-iterator.hxx> + +#endif // ODB_QT_MUTABLE_LIST_ITERATOR_HXX diff --git a/libodb-qt/odb/qt/smart-ptr.options b/libodb-qt/odb/qt/smart-ptr.options new file mode 100644 index 0000000..b95b39b --- /dev/null +++ b/libodb-qt/odb/qt/smart-ptr.options @@ -0,0 +1,19 @@ +# file : odb/qt/smart-ptr.options +# license : GNU GPL v2; see accompanying LICENSE file + +--profile qt/version + +# Make QSharedPointer the default object pointer. +# +--hxx-prologue '#include <QtCore/QSharedPointer>' +--default-pointer QSharedPointer + +# Include pointer traits. +# +--odb-epilogue '#include <odb/qt/smart-ptr/pointer-traits.hxx>' +--hxx-prologue '#include <odb/qt/smart-ptr/pointer-traits.hxx>' + +# Include wrapper traits. +# +--odb-epilogue '#include <odb/qt/smart-ptr/wrapper-traits.hxx>' +--hxx-prologue '#include <odb/qt/smart-ptr/wrapper-traits.hxx>' diff --git a/libodb-qt/odb/qt/smart-ptr/lazy-pointer-traits.hxx b/libodb-qt/odb/qt/smart-ptr/lazy-pointer-traits.hxx new file mode 100644 index 0000000..6c7aa38 --- /dev/null +++ b/libodb-qt/odb/qt/smart-ptr/lazy-pointer-traits.hxx @@ -0,0 +1,61 @@ +// file : odb/qt/smart-ptr/lazy-pointer-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_SMART_PTR_LAZY_POINTER_TRAITS_HXX +#define ODB_QT_SMART_PTR_LAZY_POINTER_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <odb/pointer-traits.hxx> +#include <odb/qt/smart-ptr/lazy-ptr.hxx> + +namespace odb +{ + template <typename T> + class pointer_traits<QLazySharedPointer<T> > + { + public: + static const pointer_kind kind = pk_shared; + static const bool lazy = true; + + typedef T element_type; + typedef QLazySharedPointer<element_type> pointer_type; + typedef QSharedPointer<element_type> eager_pointer_type; + + static bool + null_ptr (const pointer_type& p) + { + return !p; + } + + template <class O /* = T */> + static typename object_traits<O>::id_type + object_id (const pointer_type& p) + { + return p.template objectId<O> (); + } + }; + + template <typename T> + class pointer_traits<QLazyWeakPointer<T> > + { + public: + static const pointer_kind kind = pk_weak; + static const bool lazy = true; + + typedef T element_type; + typedef QLazyWeakPointer<element_type> pointer_type; + typedef QLazySharedPointer<element_type> strong_pointer_type; + typedef QWeakPointer<element_type> eager_pointer_type; + + static strong_pointer_type + lock (const pointer_type& p) + { + return p.toStrongRef (); + } + }; +} + +#include <odb/post.hxx> + +#endif // ODB_QT_SMART_PTR_LAZY_POINTER_TRAITS_HXX diff --git a/libodb-qt/odb/qt/smart-ptr/lazy-ptr.hxx b/libodb-qt/odb/qt/smart-ptr/lazy-ptr.hxx new file mode 100644 index 0000000..865e355 --- /dev/null +++ b/libodb-qt/odb/qt/smart-ptr/lazy-ptr.hxx @@ -0,0 +1,442 @@ +// file : odb/qt/smart-ptr/lazy-ptr.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_SMART_PTR_LAZY_PTR_HXX +#define ODB_QT_SMART_PTR_LAZY_PTR_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QSharedPointer> +#include <QtCore/QWeakPointer> +#include <QtCore/QGlobalStatic> + +#include <odb/forward.hxx> // odb::database +#include <odb/traits.hxx> +#include <odb/lazy-ptr-impl.hxx> +#include <odb/details/config.hxx> // ODB_CXX11 + +template <class T> +class QLazyWeakPointer; + +// +// QLazySharedPointer declaration. +// + +template <class T> +class QLazySharedPointer +{ + // The standard QSharedPointer interface. + // +public: + // These typedefs are inherited by QSharedPointer indirectly from + // QtSharedPointer::Basic<T> + // + typedef T Type; + typedef T element_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef qptrdiff difference_type; + + QLazySharedPointer (); + + explicit + QLazySharedPointer (T*); + + template <class Deleter> + QLazySharedPointer (T*, Deleter); + + QLazySharedPointer (const QLazySharedPointer&); + + template <class X> + QLazySharedPointer (const QLazySharedPointer<X>&); + + template <class X> + QLazySharedPointer (const QLazyWeakPointer<X>&); + + ~QLazySharedPointer (); + + QLazySharedPointer& + operator= (const QLazySharedPointer&); + + template <class X> + QLazySharedPointer& + operator= (const QLazySharedPointer<X>&); + + template <class X> + QLazySharedPointer& + operator= (const QLazyWeakPointer<X>&); + + typedef QSharedPointer<T> QLazySharedPointer<T>::*unspecified_bool_type; + operator unspecified_bool_type () const + { + return isNull () ? 0 : &QLazySharedPointer::p_; + } + + bool + operator! () const; + + T& + operator* () const; + + T* + operator-> () const; + + void + swap (QLazySharedPointer&); + + bool + isNull () const; + + T* + data () const; + + QLazyWeakPointer<T> + toWeakRef () const; + + void + clear (); + + template <class X> + QLazySharedPointer<X> + staticCast () const; + + template <class X> + QLazySharedPointer<X> + dynamicCast () const; + + template <class X> + QLazySharedPointer<X> + constCast () const; + + // Initialization and assignment from QSharedPointer and QWeakPointer. + // +public: + template <class X> + QLazySharedPointer (const QSharedPointer<X>&); + + template <class X> + explicit + QLazySharedPointer (const QWeakPointer<X>&); + + template <class X> + QLazySharedPointer& + operator= (const QSharedPointer<X>&); + + template <class X> + QLazySharedPointer& + operator= (const QWeakPointer<X>&); + + // Lazy loading interface. + // +public: + typedef odb::database database_type; + + // isNull() loaded() + // + // true true NULL pointer to transient object + // false true valid pointer to persistent object + // true false unloaded pointer to persistent object + // false false valid pointer to transient object + // + bool + loaded () const; + + QSharedPointer<T> + load () const; + + // Unload the pointer. For transient objects this function is + // equivalent to clear(). + // + void unload () const; + + // Get the underlying eager pointer. If this is an unloaded pointer + // to a persistent object, then the returned pointer will be NULL. + // + QSharedPointer<T> + getEager () const; + + template <class DB, class ID> + QLazySharedPointer (DB&, const ID&); + + template <class DB> + QLazySharedPointer (DB&, T*); + + template <class DB, class Deleter> + QLazySharedPointer (DB&, T*, Deleter); + + template <class DB, class X> + QLazySharedPointer (DB&, const QSharedPointer<X>&); + + template <class DB, class X> + QLazySharedPointer (DB&, const QWeakPointer<X>&); + +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT + template <class O = T> +#else + template <class O /* = T */> +#endif + typename odb::object_traits<O>::id_type + objectId () const; + + database_type& + database () const; + + // Helpers. + // +public: + template <class X> + bool + equal (const QLazySharedPointer<X>&) const; + +private: + template <class X> friend class QLazySharedPointer; + template <class X> friend class QLazyWeakPointer; + + // For QLazyWeakPointer::toStrongRef(). + // + QLazySharedPointer (const QSharedPointer<T>& p, + const odb::lazy_ptr_impl<T>& i) + : p_ (p), i_ (i) {} + +private: + mutable QSharedPointer<T> p_; + mutable odb::lazy_ptr_impl<T> i_; +}; + +// +// QLazySharedPointer related non-members. +// + +template <class T, class X> +QLazySharedPointer<X> +qSharedPointerCast (const QLazySharedPointer<T>&); + +template <class T, class X> +QLazySharedPointer<X> +qSharedPointerConstCast (const QLazySharedPointer<T>&); + +template <class T, class X> +QLazySharedPointer<X> +qSharedPointerDynamicCast (const QLazySharedPointer<T>&); + +template <class T, class X> +bool +operator== (const QLazySharedPointer<T>&, const QLazySharedPointer<X>&); + +template <class T, class X> +bool +operator!= (const QLazySharedPointer<T>&, const QLazySharedPointer<T>&); + +// +// QLazyWeakPointer declaration +// + +template <class T> +class QLazyWeakPointer +{ + // The standard QWeakPointer interface + // +public: + typedef T element_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef qptrdiff difference_type; + + QLazyWeakPointer (); + + QLazyWeakPointer (const QLazyWeakPointer&); + + template <class X> + QLazyWeakPointer (const QLazyWeakPointer<X>&); + + template <class X> + QLazyWeakPointer (const QLazySharedPointer<X>&); + + ~QLazyWeakPointer (); + + QLazyWeakPointer& + operator= (const QLazyWeakPointer&); + + template <class X> + QLazyWeakPointer& + operator= (const QLazyWeakPointer<X>&); + + template <class X> + QLazyWeakPointer& + operator= (const QLazySharedPointer<X>&); + + typedef QWeakPointer<T> QLazyWeakPointer<T>::*unspecified_bool_type; + operator unspecified_bool_type () const + { + return isNull () ? 0 : &QLazyWeakPointer<T>::p_; + } + + bool + operator! () const; + +#ifdef QWEAKPOINTER_ENABLE_ARROW + T* + operator-> () const; +#endif + + void + clear (); + + T* + data () const; + + bool + isNull () const; + + QLazySharedPointer<T> + toStrongRef () const; + + // Initialization/assignment from QSharedPointer and QWeakPointer. + // +public: + template <class X> + QLazyWeakPointer (const QWeakPointer<X>&); + + template <class X> + QLazyWeakPointer (const QSharedPointer<X>&); + + template <class X> + QLazyWeakPointer& + operator= (const QWeakPointer<X>&); + + template <class X> + QLazyWeakPointer& + operator= (const QSharedPointer<X>&); + + // Lazy loading interface. + // +public: + typedef odb::database database_type; + + // toStrongRef().isNull() loaded() + // + // true true expired pointer to transient object + // false true valid pointer to persistent object + // true false expired pointer to persistent object + // false false valid pointer to transient object + // + bool + loaded () const; + + // Create a strong reference using toStrongRef() and load. + // + QSharedPointer<T> + load () const; + + // Unload the pointer. For transient objects this function is equivalent + // to clear(). + // + void + unload () const; + + // Get the underlying eager pointer. If this is an unloaded pointer + // to a persistent object, then the returned pointer will be NULL. + // + QWeakPointer<T> + getEager () const; + + template <class DB, class ID> + QLazyWeakPointer (DB&, const ID&); + + template <class DB, class X> + QLazyWeakPointer (DB&, const QSharedPointer<X>&); + + template <class DB, class X> + QLazyWeakPointer (DB&, const QWeakPointer<X>&); + + // The objectId() function can only be called when the object is persistent, + // or: toStrongRef().isNull() XOR loaded() (can use != for XOR). + // +#ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT + template <class O = T> +#else + template <class O /* = T */> +#endif + typename odb::object_traits<O>::id_type + objectId () const; + + database_type& + database () const; + + // Helpers. + // +public: + template <class X> + bool + equal (const QLazyWeakPointer<X>&) const; + + template <class X> + bool + equal (const QLazySharedPointer<X>&) const; + +private: + template <class X> friend class QLazySharedPointer; + template <class X> friend class QLazyWeakPointer; + + mutable QWeakPointer<T> p_; + mutable odb::lazy_ptr_impl<T> i_; +}; + +// +// QLazyWeakPointer related non-members. +// + +template <class T, class X> +QLazySharedPointer<X> +qSharedPointerCast (const QLazyWeakPointer<T>&); + +template <class T, class X> +QLazySharedPointer<X> +qSharedPointerConstCast (const QLazyWeakPointer<T>&); + +template <class T, class X> +QLazySharedPointer<X> +qSharedPointerDynamicCast (const QLazyWeakPointer<T>&); + +template <class T, class X> +QLazyWeakPointer<X> +qWeakPointerCast (const QLazyWeakPointer<T>&); + +template <class T, class X> +bool +operator== (const QLazyWeakPointer<T>&, const QLazyWeakPointer<X>&); + +template <class T, class X> +bool +operator== (const QLazyWeakPointer<T>&, const QLazySharedPointer<X>&); + +template <class T, class X> +bool +operator== (const QLazySharedPointer<T>&, const QLazyWeakPointer<X>&); + +template <class T, class X> +bool +operator!= (const QLazyWeakPointer<T>&, const QLazyWeakPointer<X>&); + +template <class T, class X> +bool +operator!= (const QLazyWeakPointer<T>&, const QLazySharedPointer<X>&); + +template <class T, class X> +bool +operator!= (const QLazySharedPointer<T>&, const QLazyWeakPointer<X>&); + +#include <odb/qt/smart-ptr/lazy-ptr.ixx> +#include <odb/qt/smart-ptr/lazy-ptr.txx> + +#include <odb/qt/smart-ptr/lazy-pointer-traits.hxx> + +#include <odb/post.hxx> + +#endif // ODB_QT_SMART_PTR_LAZY_PTR_HXX diff --git a/libodb-qt/odb/qt/smart-ptr/lazy-ptr.ixx b/libodb-qt/odb/qt/smart-ptr/lazy-ptr.ixx new file mode 100644 index 0000000..b9e6de8 --- /dev/null +++ b/libodb-qt/odb/qt/smart-ptr/lazy-ptr.ixx @@ -0,0 +1,626 @@ +// file : odb/qt/smart-ptr/lazy-ptr.ixx +// license : GNU GPL v2; see accompanying LICENSE file + +// +// QLazySharedPointer definition. +// + +template <class T> +inline QLazySharedPointer<T>:: +QLazySharedPointer () {} + +template <class T> +inline QLazySharedPointer<T>:: +QLazySharedPointer (T* p): p_ (p) {} + +template <class T> +template <class Deleter> +inline QLazySharedPointer<T>:: +QLazySharedPointer (T* p, Deleter d): p_ (p, d) {} + +template <class T> +inline QLazySharedPointer<T>:: +QLazySharedPointer (const QLazySharedPointer& r): p_ (r.p_), i_ (r.i_) {} + +template <class T> +template <class X> +inline QLazySharedPointer<T>:: +QLazySharedPointer (const QLazySharedPointer<X>& r): p_ (r.p_), i_ (r.i_) {} + +template <class T> +template <class X> +inline QLazySharedPointer<T>:: +QLazySharedPointer (const QLazyWeakPointer<X>& r): p_ (r.p_), i_ (r.i_) {} + +template <class T> +inline QLazySharedPointer<T>:: +~QLazySharedPointer () {} + +template <class T> +inline QLazySharedPointer<T>& QLazySharedPointer<T>:: +operator= (const QLazySharedPointer& r) +{ + p_ = r.p_; + i_ = r.i_; + return *this; +} + +template <class T> +template <class X> +inline QLazySharedPointer<T>& QLazySharedPointer<T>:: +operator= (const QLazySharedPointer<X>& r) +{ + p_ = r.p_; + i_ = r.i_; + return *this; +} + +template <class T> +template <class X> +inline QLazySharedPointer<T>& QLazySharedPointer<T>:: +operator= (const QLazyWeakPointer<X>& r) +{ + p_ = r.p_; + i_ = r.i_; + return *this; +} + +template <class T> +inline bool QLazySharedPointer<T>:: +operator! () const +{ + return isNull (); +} + +template <class T> +inline T& QLazySharedPointer<T>:: +operator* () const +{ + return *p_; +} + +template <class T> +inline T* QLazySharedPointer<T>:: +operator-> () const +{ + return p_.operator-> (); +} + +template <class T> +inline void QLazySharedPointer<T>:: +swap (QLazySharedPointer& x) +{ + p_.swap (x.p_); + i_.swap (x.i_); +} + +template <class T> +inline bool QLazySharedPointer<T>:: +isNull () const +{ + return !(p_ || i_); +} + +template <class T> +inline T* QLazySharedPointer<T>:: +data () const +{ + return p_.data (); +} + +template <class T> +inline QLazyWeakPointer<T> QLazySharedPointer<T>:: +toWeakRef () const +{ + return QLazyWeakPointer<T> (*this); +} + +template <class T> +inline void QLazySharedPointer<T>:: +clear () +{ + p_.clear (); + i_.reset (); +} + +template <class T> +template <class X> +inline QLazySharedPointer<X> QLazySharedPointer<T>:: +staticCast () const +{ + QLazySharedPointer c (p_.template staticCast<X> ()); + c.i_ = i_; + return c; +} + +template <class T> +template <class X> +inline QLazySharedPointer<X> QLazySharedPointer<T>:: +dynamicCast () const +{ + QLazySharedPointer<X> c (p_.template dynamicCast<X> ()); + + if (c) + c.i_ = i_; + + return c; +} + +template <class T> +template <class X> +inline QLazySharedPointer<X> QLazySharedPointer<T>:: +constCast () const +{ + QLazySharedPointer<X> c (p_.template constCast<X> ()); + c.i_ = i_; + return c; +} + +template <class T> +template <class Y> +inline QLazySharedPointer<T>:: +QLazySharedPointer (const QSharedPointer<Y>& r): p_ (r) {} + +template <class T> +template <class Y> +inline QLazySharedPointer<T>:: +QLazySharedPointer (const QWeakPointer<Y>& r): p_ (r) {} + +template <class T> +template <class X> +inline QLazySharedPointer<T>& QLazySharedPointer<T>:: +operator= (const QSharedPointer<X>& r) +{ + p_ = r; + i_.reset (); + return *this; +} + +template <class T> +template <class X> +inline QLazySharedPointer<T>& QLazySharedPointer<T>:: +operator= (const QWeakPointer<X>& r) +{ + p_ = r; + i_.reset (); + return *this; +} + +template <class T> +inline bool QLazySharedPointer<T>:: +loaded () const +{ + bool i (i_); + return !p_ != i; // !p_ XOR i_ +} + +template <class T> +inline QLazySharedPointer<T> QLazyWeakPointer<T>:: +toStrongRef () const +{ + return QLazySharedPointer<T> (p_.toStrongRef (), i_); +} + +template <class T> +inline QSharedPointer<T> QLazySharedPointer<T>:: +load () const +{ + if (!p_ && i_) + p_ = i_.template load<T> (true); // Reset id. + + return p_; +} + +template <class T> +inline void QLazySharedPointer<T>:: +unload () const +{ + typedef typename odb::object_traits<T>::object_type object_type; + + if (p_) + { + if (i_.database () != 0) + i_.reset_id (odb::object_traits<object_type>::id (*p_)); + + p_.clear (); + } +} + +template <class T> +inline QSharedPointer<T> QLazySharedPointer<T>:: +getEager () const +{ + return p_; +} + +template <class T> +template <class DB, class ID> +inline QLazySharedPointer<T>:: +QLazySharedPointer (DB& db, const ID& id): i_ (db, id) {} + +template <class T> +template <class DB> +inline QLazySharedPointer<T>:: +QLazySharedPointer (DB& db, T* p) + : p_ (p) +{ + if (p_) + i_.reset_db (db); +} + +template <class T> +template <class DB, class Deleter> +inline QLazySharedPointer<T>:: +QLazySharedPointer (DB& db, T* p, Deleter d) + : p_ (p, d) +{ + if (p_) + i_.reset_db (db); +} + +template <class T> +template <class DB, class Y> +inline QLazySharedPointer<T>:: +QLazySharedPointer (DB& db, const QSharedPointer<Y>& r) + : p_ (r) +{ + if (p_) + i_.reset_db (db); +} + +template <class T> +template <class DB, class Y> +inline QLazySharedPointer<T>:: +QLazySharedPointer (DB& db, const QWeakPointer<Y>& r) + : p_ (r) +{ + if (p_) + i_.reset_db (db); +} + +template <class T> +inline typename QLazySharedPointer<T>::database_type& QLazySharedPointer<T>:: +database () const +{ + return *i_.database (); +} + +template <class T> +template <class O> +inline typename odb::object_traits<O>::id_type QLazySharedPointer<T>:: +objectId () const +{ + typedef typename odb::object_traits<T>::object_type object_type; + + return p_ + ? odb::object_traits<object_type>::id (*p_) + : i_.template object_id<O> (); +} + +// +// QLazySharedPointer related non-member function definitions. +// + +template <class T, class X> +inline QLazySharedPointer<X> +qSharedPointerCast (const QLazySharedPointer<T>& r) +{ + return r.template staticCast<X> (); +} + +template <class T, class X> +inline QLazySharedPointer<X> +qSharedPointerConstCast (const QLazySharedPointer<T>& r) +{ + return r.template constCast<X> (); +} + +template <class T, class X> +inline QLazySharedPointer<X> +qSharedPointerDynamicCast (const QLazySharedPointer<T>& r) +{ + return r.template dynamicCast<X> (); +} + +template <class T, class X> +inline bool +operator== (const QLazySharedPointer<T>& a, const QLazySharedPointer<X>& b) +{ + return a.equal (b); +} + +template <class T, class X> +inline bool +operator!= (const QLazySharedPointer<T>& a, const QLazySharedPointer<X>& b) +{ + return !a.equal (b); +} + +// +// QLazyWeakPointer definition. +// + +template <class T> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer () {} + + +template <class T> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer (const QLazyWeakPointer& r): p_ (r.p_), i_ (r.i_) {} + +template <class T> +template <class X> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer (const QLazyWeakPointer<X>& r): p_ (r.p_), i_ (r.i_) {} + +template <class T> +template <class X> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer (const QLazySharedPointer<X>& r): p_ (r.p_), i_ (r.i_) {} + +template <class T> +inline QLazyWeakPointer<T>:: +~QLazyWeakPointer () {} + +template <class T> +inline QLazyWeakPointer<T>& QLazyWeakPointer<T>:: +operator= (const QLazyWeakPointer& r) +{ + p_ = r.p_; + i_ = r.i_; + return *this; +} + +template <class T> +template <class X> +inline QLazyWeakPointer<T>& QLazyWeakPointer<T>:: +operator= (const QLazyWeakPointer<X>& r) +{ + p_ = r.p_; + i_ = r.i_; + return *this; +} + +template <class T> +template <class X> +inline QLazyWeakPointer<T>& QLazyWeakPointer<T>:: +operator= (const QLazySharedPointer<X>& r) +{ + p_ = r.p_; + i_ = r.i_; + return *this; +} + +template <class T> +inline bool QLazyWeakPointer<T>:: +operator! () const +{ + return isNull (); +} + +#ifdef QWEAKPOINTER_ENABLE_ARROW +template <class T> +inline T* QLazyWeakPointer<T>:: +operator-> () const +{ + return p_.operator-> (); +} +#endif + +template <class T> +inline void QLazyWeakPointer<T>:: +clear () +{ + p_.clear (); + i_.reset (); +} + +template <class T> +inline T* QLazyWeakPointer<T>:: +data () const +{ + return p_.data (); +} + +template <class T> +inline bool QLazyWeakPointer<T>:: +isNull () const +{ + return !(p_ || i_); +} + +template <class T> +template <class X> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer (const QWeakPointer<X>& r): p_ (r) {} + +template <class T> +template <class X> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer (const QSharedPointer<X>& r): p_ (r) {} + +template <class T> +template <class X> +inline QLazyWeakPointer<T>& QLazyWeakPointer<T>:: +operator= (const QWeakPointer<X>& r) +{ + p_ = r; + i_.reset (); + return *this; +} + +template <class T> +template <class X> +inline QLazyWeakPointer<T>& QLazyWeakPointer<T>:: +operator= (const QSharedPointer<X>& r) +{ + p_ = r; + i_.reset (); + return *this; +} + +template <class T> +inline bool QLazyWeakPointer<T>:: +loaded () const +{ + bool i (i_); + return p_.toStrongRef ().isNull () != i; // expired () XOR i_ +} + +template <class T> +inline QSharedPointer<T> QLazyWeakPointer<T>:: +load () const +{ + QSharedPointer<T> r (p_.toStrongRef ()); + + if (!r && i_) + { + r = i_.template load<T> (false); // Keep id. + p_ = r; + } + + return r; +} + +template <class T> +inline void QLazyWeakPointer<T>:: +unload () const +{ + // With weak pointer we always keep i_ up to date. + // + p_.clear (); +} + +template <class T> +inline QWeakPointer<T> QLazyWeakPointer<T>:: +getEager () const +{ + return p_; +} + +template <class T> +template <class DB, class ID> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer (DB& db, const ID& id): i_ (db, id) {} + +template <class T> +template <class DB, class X> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer (DB& db, const QSharedPointer<X>& r) + : p_ (r) +{ + typedef typename odb::object_traits<T>::object_type object_type; + + if (r) + i_.reset (db, odb::object_traits<object_type>::id (*r)); +} + +template <class T> +template <class DB, class X> +inline QLazyWeakPointer<T>:: +QLazyWeakPointer (DB& db, const QWeakPointer<X>& r) + : p_ (r) +{ + typedef typename odb::object_traits<T>::object_type object_type; + + QSharedPointer<T> sp (p_.toStrongRef ()); + + if (sp) + i_.reset (db, odb::object_traits<object_type>::id (*sp)); +} + +template <class T> +template <class O /* = T */> +inline typename odb::object_traits<O>::id_type QLazyWeakPointer<T>:: +objectId () const +{ + typedef typename odb::object_traits<T>::object_type object_type; + + QSharedPointer<T> sp (p_.toStrongRef ()); + + return sp + ? odb::object_traits<object_type>::id (*sp) + : i_.template object_id<O> (); +} + +template <class T> +inline typename QLazyWeakPointer<T>::database_type& QLazyWeakPointer<T>:: +database () const +{ + return *i_.database (); +} + +// +// QLazyWeakPointer related non-member functions. +// + +template <class T, class X> +inline QLazySharedPointer<X> +qSharedPointerCast (const QLazyWeakPointer<T>& r) +{ + return QLazySharedPointer<T> (r).template staticCast<X> (); +} + +template <class T, class X> +inline QLazySharedPointer<X> +qSharedPointerConstCast (const QLazyWeakPointer<T>& r) +{ + return QLazySharedPointer<T> (r).template constCast<X> (); +} + +template <class T, class X> +inline QLazySharedPointer<X> +qSharedPointerDynamicCast (const QLazyWeakPointer<T>& r) +{ + return QLazySharedPointer<T> (r).template dynamicCast<X> (); +} + +template <class T, class X> +inline QLazyWeakPointer<X> +qWeakPointerCast (const QLazyWeakPointer<T>& r) +{ + return QLazySharedPointer<T> (r).template staticCast<X> ().toWeakRef (); +} + +template <class T, class X> +inline bool +operator== (const QLazyWeakPointer<T>& t, const QLazyWeakPointer<X>& x) +{ + return t.equal (x); +} + +template <class T, class X> +inline bool +operator== (const QLazyWeakPointer<T>& t, const QLazySharedPointer<X>& x) +{ + return t.equal (x); +} + +template <class T, class X> +inline bool +operator== (const QLazySharedPointer<T>& t, const QLazyWeakPointer<X>& x) +{ + return x.equal (t); +} + +template <class T, class X> +inline bool +operator!= (const QLazyWeakPointer<T>& t, const QLazyWeakPointer<X>& x) +{ + return !t.equal (x); +} + +template <class T, class X> +inline bool +operator!= (const QLazyWeakPointer<T>& t, const QLazySharedPointer<X>& x) +{ + return !t.equal (x); +} + +template <class T, class X> +inline bool +operator!= (const QLazySharedPointer<T>& t, const QLazyWeakPointer<X>& x) +{ + return !x.equal (t); +} diff --git a/libodb-qt/odb/qt/smart-ptr/lazy-ptr.txx b/libodb-qt/odb/qt/smart-ptr/lazy-ptr.txx new file mode 100644 index 0000000..0ae038a --- /dev/null +++ b/libodb-qt/odb/qt/smart-ptr/lazy-ptr.txx @@ -0,0 +1,74 @@ +// file : odb/qt/smart-ptr/lazy-ptr.txx +// license : GNU GPL v2; see accompanying LICENSE file + +template <class T> +template <class X> +bool QLazySharedPointer<T>:: +equal (const QLazySharedPointer<X>& r) const +{ + bool t1 (!p_ == loaded ()); + bool t2 (!r.p_ == r.loaded ()); + + // If both are transient, then compare the underlying pointers. + // + if (t1 && t2) + return p_ == r.p_; + + // If one is transient and the other is persistent, then compare + // the underlying pointers but only if they are non NULL. Note + // that an unloaded persistent object is always unequal to a + // transient object. + // + if (t1 || t2) + return p_ == r.p_ && p_; + + // If both objects are persistent, then we compare databases and + // object ids. + // + typedef typename odb::object_traits<T>::object_type object_type1; + typedef typename odb::object_traits<X>::object_type object_type2; + + return i_.database () == r.i_.database () && + objectId<object_type1> () == r.template objectId<object_type2> (); +} + +// +// QLazyWeakPointer +// + +template <class T> +template <class X> +bool QLazyWeakPointer<T>:: +equal (const QLazyWeakPointer<X>& r) const +{ + if (isNull () && r.isNull ()) + return true; + + QLazySharedPointer<T> sp1 (toStrongRef ()); + QLazySharedPointer<T> sp2 (r.toStrongRef ()); + + // If either one has expired, they are not equal. + // + if (!sp1 || !sp2) + return false; + + return sp1.equal (sp2); +} + +template <class T> +template <class X> +bool QLazyWeakPointer<T>:: +equal (const QLazySharedPointer<X>& r) const +{ + if (isNull () && r.isNull ()) + return true; + + QLazySharedPointer<T> sp (toStrongRef ()); + + // If the weak pointer has expired, they are not equal. + // + if (!sp) + return false; + + return r.equal (sp); +} diff --git a/libodb-qt/odb/qt/smart-ptr/pointer-traits.hxx b/libodb-qt/odb/qt/smart-ptr/pointer-traits.hxx new file mode 100644 index 0000000..f5cbc39 --- /dev/null +++ b/libodb-qt/odb/qt/smart-ptr/pointer-traits.hxx @@ -0,0 +1,110 @@ +// file : odb/qt/smart-ptr/pointer-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_SMART_PTR_POINTER_TRAITS_HXX +#define ODB_QT_SMART_PTR_POINTER_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QSharedPointer> +#include <QtCore/QWeakPointer> + +#include <odb/pointer-traits.hxx> +#include <odb/details/meta/remove-const.hxx> + +namespace odb +{ + // Specialization for QSharedPointer. + // + template <typename T> + class pointer_traits<QSharedPointer<T> > + { + public: + static const pointer_kind kind = pk_shared; + static const bool lazy = false; + + typedef T element_type; + typedef QSharedPointer<element_type> pointer_type; + typedef QSharedPointer<const element_type> const_pointer_type; + typedef typename odb::details::meta::remove_const<element_type>::result + unrestricted_element_type; + typedef QSharedPointer<unrestricted_element_type> + unrestricted_pointer_type; + typedef smart_ptr_guard<pointer_type> guard; + + static element_type* + get_ptr (const pointer_type& p) + { + return p.data (); + } + + static element_type& + get_ref (const pointer_type& p) + { + return *p; + } + + static bool + null_ptr (const pointer_type& p) + { + return !p; + } + + static unrestricted_pointer_type + const_pointer_cast (const pointer_type& p) + { + return qSharedPointerConstCast<unrestricted_element_type> (p); + } + + template <typename T1> + static QSharedPointer<T1> + static_pointer_cast (const pointer_type& p) + { + return qSharedPointerCast<T1> (p); + } + + template <typename T1> + static QSharedPointer<T1> + dynamic_pointer_cast (const pointer_type& p) + { + return qSharedPointerDynamicCast<T1> (p); + } + + public: + static void* + allocate (std::size_t n) + { + return operator new (n); + } + + static void + free (void* p) + { + operator delete (p); + } + }; + + // Specialization for QWeakPointer. + // + template <typename T> + class pointer_traits<QWeakPointer<T> > + { + public: + static const pointer_kind kind = pk_weak; + static const bool lazy = false; + + typedef T element_type; + typedef QWeakPointer<element_type> pointer_type; + typedef QSharedPointer<element_type> strong_pointer_type; + + static strong_pointer_type + lock (const pointer_type& p) + { + return p.toStrongRef (); + } + }; +} + +#include <odb/post.hxx> + +#endif // ODB_QT_SMART_PTR_POINTER_TRAITS_HXX diff --git a/libodb-qt/odb/qt/smart-ptr/wrapper-traits.hxx b/libodb-qt/odb/qt/smart-ptr/wrapper-traits.hxx new file mode 100644 index 0000000..dc6cb02 --- /dev/null +++ b/libodb-qt/odb/qt/smart-ptr/wrapper-traits.hxx @@ -0,0 +1,64 @@ +// file : odb/qt/smart-ptr/wrapper-traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_QT_SMART_PTR_WRAPPER_TRAITS_HXX +#define ODB_QT_SMART_PTR_WRAPPER_TRAITS_HXX + +#include <odb/pre.hxx> + +#include <QtCore/QSharedPointer> + +#include <odb/wrapper-traits.hxx> + +namespace odb +{ + // Specialization for QSharedPointer. + // + template <typename T> + class wrapper_traits< QSharedPointer<T> > + { + public: + typedef T wrapped_type; + typedef QSharedPointer<T> wrapper_type; + + // T can be const. + // + typedef + typename odb::details::meta::remove_const<T>::result + unrestricted_wrapped_type; + + static const bool null_handler = true; + static const bool null_default = false; + + static bool + get_null (const wrapper_type& p) + { + return p.isNull (); + } + + static void + set_null (wrapper_type& p) + { + p.clear (); + } + + static const wrapped_type& + get_ref (const wrapper_type& p) + { + return *p; + } + + static wrapped_type& + set_ref (wrapper_type& p) + { + if (p.isNull ()) + p = wrapper_type (new unrestricted_wrapped_type); + + return const_cast<unrestricted_wrapped_type&> (*p); + } + }; +} + +#include <odb/post.hxx> + +#endif // ODB_QT_SMART_PTR_WRAPPER_TRAITS_HXX diff --git a/libodb-qt/odb/qt/version-build2-stub.hxx b/libodb-qt/odb/qt/version-build2-stub.hxx new file mode 100644 index 0000000..b00d1de --- /dev/null +++ b/libodb-qt/odb/qt/version-build2-stub.hxx @@ -0,0 +1,4 @@ +// file : odb/qt/version-build2-stub.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#include <odb/qt/version.hxx> diff --git a/libodb-qt/odb/qt/version-build2.hxx b/libodb-qt/odb/qt/version-build2.hxx new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/libodb-qt/odb/qt/version-build2.hxx diff --git a/libodb-qt/odb/qt/version-build2.hxx.in b/libodb-qt/odb/qt/version-build2.hxx.in new file mode 100644 index 0000000..51f1191 --- /dev/null +++ b/libodb-qt/odb/qt/version-build2.hxx.in @@ -0,0 +1,46 @@ +// file : odb/qt/version-build2.hxx.in +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef LIBODB_QT_VERSION // Note: using the version macro itself. + +// @@ TODO: need to derive automatically (it is also hardcoded in *.options). +// +#define ODB_QT_VERSION 2047600 + +// The numeric version format is AAAAABBBBBCCCCCDDDE where: +// +// AAAAA - major version number +// BBBBB - minor version number +// CCCCC - bugfix version number +// DDD - alpha / beta (DDD + 500) version number +// E - final (0) / snapshot (1) +// +// When DDDE is not 0, 1 is subtracted from AAAAABBBBBCCCCC. For example: +// +// Version AAAAABBBBBCCCCCDDDE +// +// 0.1.0 0000000001000000000 +// 0.1.2 0000000001000020000 +// 1.2.3 0000100002000030000 +// 2.2.0-a.1 0000200001999990010 +// 3.0.0-b.2 0000299999999995020 +// 2.2.0-a.1.z 0000200001999990011 +// +#define LIBODB_QT_VERSION $libodb_qt.version.project_number$ULL +#define LIBODB_QT_VERSION_STR "$libodb_qt.version.project$" +#define LIBODB_QT_VERSION_ID "$libodb_qt.version.project_id$" + +#define LIBODB_QT_VERSION_MAJOR $libodb_qt.version.major$ +#define LIBODB_QT_VERSION_MINOR $libodb_qt.version.minor$ +#define LIBODB_QT_VERSION_PATCH $libodb_qt.version.patch$ + +#define LIBODB_QT_PRE_RELEASE $libodb_qt.version.pre_release$ + +#define LIBODB_QT_SNAPSHOT $libodb_qt.version.snapshot_sn$ULL +#define LIBODB_QT_SNAPSHOT_ID "$libodb_qt.version.snapshot_id$" + +#include <odb/version.hxx> + +$libodb.check(LIBODB_VERSION, LIBODB_SNAPSHOT)$ + +#endif // LIBODB_QT_VERSION diff --git a/libodb-qt/odb/qt/version.hxx b/libodb-qt/odb/qt/version.hxx new file mode 100644 index 0000000..4f9510a --- /dev/null +++ b/libodb-qt/odb/qt/version.hxx @@ -0,0 +1,55 @@ +// file : odb/qt/version.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifdef LIBODB_QT_BUILD2 +# include <odb/qt/version-build2.hxx> +#else + +#ifndef ODB_QT_VERSION_HXX +#define ODB_QT_VERSION_HXX + +#include <odb/pre.hxx> + +#include <odb/version.hxx> + +// Version format is AABBCCDD where +// +// AA - major version number +// BB - minor version number +// CC - bugfix version number +// DD - alpha / beta (DD + 50) version number +// +// When DD is not 00, 1 is subtracted from AABBCC. For example: +// +// Version AABBCCDD +// 2.0.0 02000000 +// 2.1.0 02010000 +// 2.1.1 02010100 +// 2.2.0.a1 02019901 +// 3.0.0.b2 02999952 +// + +// Check that we have compatible ODB version. +// +#if ODB_VERSION != 20476 +# error incompatible odb interface version detected +#endif + +// ODB Qt interface version: odb interface version plus the Qt interface +// version. +// +#define ODB_QT_VERSION 2047600 +#define ODB_QT_VERSION_STR "2.5.0-b.26" + +// libodb-qt version: odb interface version plus the bugfix version. Note +// that LIBODB_QT_VERSION is always greater or equal to ODB_QT_VERSION +// since if the Qt interface virsion is incremented then the bugfix version +// must be incremented as well. +// +#define LIBODB_QT_VERSION 2049976 +#define LIBODB_QT_VERSION_STR "2.5.0-b.26" + +#include <odb/post.hxx> + +#endif // ODB_QT_VERSION_HXX +#endif // LIBODB_QT_BUILD2 diff --git a/libodb-qt/odb/qt/version.options b/libodb-qt/odb/qt/version.options new file mode 100644 index 0000000..0fef537 --- /dev/null +++ b/libodb-qt/odb/qt/version.options @@ -0,0 +1,16 @@ +# file : odb/qt/version.options +# license : GNU GPL v2; see accompanying LICENSE file + +# Include the config file first so that it can do its thing before we +# include any Qt headers. +# +--odb-prologue '#include <odb/qt/details/config.hxx>' + +# Make sure the options files as seen by the ODB compiler and header +# files as seen by the C++ compiler have the same Qt interface version. +# +--hxx-prologue '#include <odb/qt/version.hxx>' + +--hxx-prologue '#if ODB_QT_VERSION != 2047600 // 2.5.0-b.26' +--hxx-prologue '# error ODB and C++ compilers see different libodb-qt interface versions' +--hxx-prologue '#endif' |