diff options
author | John Turner <jturner.usa@gmail.com> | 2025-09-14 00:16:10 -0400 |
---|---|---|
committer | John Turner <jturner.usa@gmail.com> | 2025-09-14 00:16:10 -0400 |
commit | efcea3a80da7c4479d5fe168435ecc9fd06bdc72 (patch) | |
tree | 5cb0177e17b1b00a177f2e830e809f606334571b /src | |
download | sqlite-kv-bench-efcea3a80da7c4479d5fe168435ecc9fd06bdc72.tar.gz |
Squashed 'subprojects/boost-sqlite/' content from commit 3378e35
git-subtree-dir: subprojects/boost-sqlite
git-subtree-split: 3378e353705271e569cf4ba15c467b840a39798c
Diffstat (limited to 'src')
-rw-r--r-- | src/backup.cpp | 61 | ||||
-rw-r--r-- | src/blob.cpp | 94 | ||||
-rw-r--r-- | src/connection.cpp | 158 | ||||
-rw-r--r-- | src/detail/exception.cpp | 46 | ||||
-rw-r--r-- | src/error.cpp | 83 | ||||
-rw-r--r-- | src/ext.cpp | 14 | ||||
-rw-r--r-- | src/field.cpp | 39 | ||||
-rw-r--r-- | src/meta_data.cpp | 83 | ||||
-rw-r--r-- | src/resultset.cpp | 61 | ||||
-rw-r--r-- | src/row.cpp | 24 | ||||
-rw-r--r-- | src/value.cpp | 39 |
11 files changed, 702 insertions, 0 deletions
diff --git a/src/backup.cpp b/src/backup.cpp new file mode 100644 index 0000000..76099b1 --- /dev/null +++ b/src/backup.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + + +#include <boost/sqlite/backup.hpp> +#include <boost/sqlite/connection.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + + +void +backup(connection & source, + connection & target, + cstring_ref source_name, + cstring_ref target_name, + system::error_code & ec, + error_info & ei) +{ + struct del + { + void operator()(sqlite3_backup * bp) + { + sqlite3_backup_finish(bp); + } + }; + + std::unique_ptr<sqlite3_backup, del> bu{ + sqlite3_backup_init(target.handle(), target_name.c_str(), + source.handle(), source_name.c_str())}; + if (bu == nullptr) + { + BOOST_SQLITE_ASSIGN_EC(ec, sqlite3_errcode(target.handle())); + ei.set_message(sqlite3_errmsg(target.handle())); + return ; + } + + const auto res = sqlite3_backup_step(bu.get(), -1); + if (SQLITE_DONE != res) + BOOST_SQLITE_ASSIGN_EC(ec, res); +} + + +void +backup(connection & source, + connection & target, + cstring_ref source_name, + cstring_ref target_name) +{ + system::error_code ec; + error_info ei; + backup(source, target, source_name, target_name, ec, ei); + if (ec) + throw_exception(system::system_error(ec, ei.message())); +} + +BOOST_SQLITE_END_NAMESPACE + diff --git a/src/blob.cpp b/src/blob.cpp new file mode 100644 index 0000000..397d85b --- /dev/null +++ b/src/blob.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + + +#include <boost/sqlite/blob.hpp> +#include <boost/sqlite/connection.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + +blob_handle open_blob(connection & conn, + cstring_ref db, + cstring_ref table, + cstring_ref column, + sqlite3_int64 row, + bool read_only, + system::error_code & ec, + error_info & ei) +{ + sqlite3_blob * bb = nullptr; + blob_handle bh; + + int res = sqlite3_blob_open(conn.handle(), db.c_str(), table.c_str(), column.c_str(), + row, read_only ? 0 : 1, &bb); + if (res != 0) + { + BOOST_SQLITE_ASSIGN_EC(ec, sqlite3_errcode(conn.handle())); + ei.set_message(sqlite3_errmsg(conn.handle())); + } + else + bh = blob_handle(bb); + + return bh; +} + +blob_handle open_blob(connection & conn, + cstring_ref db, + cstring_ref table, + cstring_ref column, + sqlite3_int64 row, + bool read_only) +{ + boost::system::error_code ec; + error_info ei; + auto b = open_blob(conn, db, table, column, row, read_only, ec, ei); + if (ec) + boost::throw_exception(system::system_error(ec, ei.message()), BOOST_CURRENT_LOCATION); + return b; +} + +void blob_handle::reopen(sqlite3_int64 row_id, system::error_code & ec) +{ + int res = sqlite3_blob_reopen(blob_.get(), row_id); + BOOST_SQLITE_ASSIGN_EC(ec, res); +} +void blob_handle::reopen(sqlite3_int64 row_id) +{ + boost::system::error_code ec; + reopen(row_id, ec); + if (ec) + boost::throw_exception(system::system_error(ec), BOOST_CURRENT_LOCATION); +} + +void blob_handle::read_at(void *data, int len, int offset, system::error_code &ec) +{ + int res = sqlite3_blob_read(blob_.get(), data, len, offset); + BOOST_SQLITE_ASSIGN_EC(ec, res); +} +void blob_handle::read_at(void *data, int len, int offset) +{ + boost::system::error_code ec; + read_at(data, len, offset, ec); + if (ec) + boost::throw_exception(system::system_error(ec), BOOST_CURRENT_LOCATION); +} + +void blob_handle::write_at(const void *data, int len, int offset, system::error_code &ec) +{ + int res = sqlite3_blob_write(blob_.get(), data, len, offset); + BOOST_SQLITE_ASSIGN_EC(ec, res); +} +void blob_handle::write_at(const void *data, int len, int offset) +{ + boost::system::error_code ec; + write_at(data, len, offset, ec); + if (ec) + boost::throw_exception(system::system_error(ec), BOOST_CURRENT_LOCATION); +} + +BOOST_SQLITE_END_NAMESPACE + diff --git a/src/connection.cpp b/src/connection.cpp new file mode 100644 index 0000000..1ac0ae7 --- /dev/null +++ b/src/connection.cpp @@ -0,0 +1,158 @@ +// +// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + + +#include <boost/sqlite/connection.hpp> +#include <boost/sqlite/statement.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + + + +void connection::connect(cstring_ref filename, int flags) +{ + system::error_code ec; + connect(filename, flags, ec); + if (ec) + throw_exception(system::system_error(ec, "connect")); +} + +void connection::connect(cstring_ref filename, int flags, system::error_code & ec) +{ + sqlite3 * res; + auto r = sqlite3_open_v2(filename.c_str(), &res, flags, + nullptr); + if (r != SQLITE_OK) + BOOST_SQLITE_ASSIGN_EC(ec, r); + else + { + impl_.reset(res); + impl_.get_deleter().owned_ = true; + } + sqlite3_extended_result_codes(impl_.get(), true); +} + +void connection::close() +{ + system::error_code ec; + error_info ei; + close(ec, ei); + if (ec) + throw_exception(system::system_error(ec, ei.message())); +} + +void connection::close(system::error_code & ec, + error_info & ei) +{ + if (impl_) + { + auto tmp = impl_.release(); + auto cc = sqlite3_close(tmp); + if (SQLITE_OK != cc) + { + impl_.reset(tmp); + BOOST_SQLITE_ASSIGN_EC(ec, cc); + ei.set_message(sqlite3_errmsg(impl_.get())); + } + } +} + + +resultset connection::query( + core::string_view q, + system::error_code & ec, + error_info & ei) +{ + resultset res; + sqlite3_stmt * ss; + const auto cc = sqlite3_prepare_v2(impl_.get(), + q.data(), static_cast<int>(q.size()), + &ss, nullptr); + + if (cc != SQLITE_OK) + { + BOOST_SQLITE_ASSIGN_EC(ec, cc); + ei.set_message(sqlite3_errmsg(impl_.get())); + } + else + { + res.impl_.reset(ss); + if (!ec) + res.read_next(ec, ei); + } + return res; +} + +resultset connection::query(core::string_view q) +{ + system::error_code ec; + error_info ei; + auto tmp = query(q, ec, ei); + if (ec) + throw_exception(system::system_error(ec, ei.message())); + return tmp; +} + +statement connection::prepare( + core::string_view q, + system::error_code & ec, + error_info & ei) +{ + statement res; + sqlite3_stmt * ss; + const auto cc = sqlite3_prepare_v2(impl_.get(), + q.data(), static_cast<int>(q.size()), + &ss, nullptr); + + if (cc != SQLITE_OK) + { + BOOST_SQLITE_ASSIGN_EC(ec, cc); + ei.set_message(sqlite3_errmsg(impl_.get())); + } + else + res.impl_.reset(ss); + return res; +} + +statement connection::prepare(core::string_view q) +{ + system::error_code ec; + error_info ei; + auto tmp = prepare(q, ec, ei); + if (ec) + throw_exception(system::system_error(ec, ei.message())); + return tmp; +} + +void connection::execute( + cstring_ref q, + system::error_code & ec, + error_info & ei) +{ + char * msg = nullptr; + + auto res = sqlite3_exec(impl_.get(), q.c_str(), nullptr, nullptr, &msg); + if (res != SQLITE_OK) + { + BOOST_SQLITE_ASSIGN_EC(ec, res); + if (msg != nullptr) + ei.set_message(msg); + } +} + +void connection::execute(cstring_ref q) +{ + system::error_code ec; + error_info ei; + execute(q, ec, ei); + if (ec) + throw_exception(system::system_error(ec, ei.message())); +} + +BOOST_SQLITE_END_NAMESPACE + + diff --git a/src/detail/exception.cpp b/src/detail/exception.cpp new file mode 100644 index 0000000..e360f38 --- /dev/null +++ b/src/detail/exception.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2023 Klemens D. Morgenstern +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/sqlite/detail/exception.hpp> +#include <boost/system/system_error.hpp> + +#include <stdexcept> + +BOOST_SQLITE_BEGIN_NAMESPACE +namespace detail +{ + +void throw_error_code(const boost::system::error_code & ec, + const boost::source_location & loc) +{ + boost::throw_exception(system::system_error(ec), + ec.has_location() ? ec.location() : loc); +} + +void throw_error_code(const boost::system::error_code & ec, + const error_info & ei, + const boost::source_location & loc) +{ + boost::throw_exception(system::system_error(ec, ei.message()), + ec.has_location() ? ec.location() : loc); +} + +void throw_out_of_range(const char * msg, + const boost::source_location & loc) +{ + boost::throw_exception(std::out_of_range(msg), loc); +} + +void throw_invalid_argument(const char * msg, + const boost::source_location & loc) +{ + { + boost::throw_exception(std::invalid_argument(msg), loc); + } +} + + +} +BOOST_SQLITE_END_NAMESPACE diff --git a/src/error.cpp b/src/error.cpp new file mode 100644 index 0000000..9344fbe --- /dev/null +++ b/src/error.cpp @@ -0,0 +1,83 @@ +// +// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + + +#include <boost/sqlite/detail/config.hpp> +#include <boost/sqlite/error.hpp> +#include <boost/core/detail/string_view.hpp> +#include <algorithm> + +BOOST_SQLITE_BEGIN_NAMESPACE + +struct sqlite_category_t final : system::error_category +{ +#if defined(BOOST_SQLITE_COMPILE_EXTENSION) + sqlite_category_t() : system::error_category(0x7d4c7b49d8a3edull) {} +#else + sqlite_category_t() : system::error_category(0x7d4c7b49d8a3fdull) {} +#endif + + bool failed( int ev ) const noexcept final + { + return ev != SQLITE_OK + && ev != SQLITE_NOTICE + && ev != SQLITE_WARNING + && ev != SQLITE_ROW + && ev != SQLITE_DONE; + } + + std::string message( int ev ) const final + { + return sqlite3_errstr(ev); + } + char const * message( int ev, char * buffer, std::size_t len ) const noexcept final + { + std::snprintf( buffer, len, "%s", sqlite3_errstr( ev ) ); + return buffer; + } + + const char * name() const BOOST_NOEXCEPT override + { + return "sqlite3"; + } + + system::error_condition default_error_condition( int ev ) const noexcept final + { + namespace errc = boost::system::errc; + switch (ev & 0xFF) + { + case SQLITE_OK: return {}; + case SQLITE_PERM: return errc::permission_denied; + case SQLITE_BUSY: return errc::device_or_resource_busy; + case SQLITE_NOMEM: return errc::not_enough_memory; + case SQLITE_INTERRUPT: return errc::interrupted; + case SQLITE_IOERR: return errc::io_error; + } + + return system::error_condition(ev, *this); + } + +}; + + +system::error_category & sqlite_category() +{ + static sqlite_category_t cat; + return cat; +} + +void throw_exception_from_error( error const & e, boost::source_location const & loc ) +{ + boost::throw_exception( + system::system_error(e.code, + sqlite_category(), + e.info.message().c_str()), loc); +} + + +BOOST_SQLITE_END_NAMESPACE + diff --git a/src/ext.cpp b/src/ext.cpp new file mode 100644 index 0000000..0152994 --- /dev/null +++ b/src/ext.cpp @@ -0,0 +1,14 @@ +// +// Copyright (c) 2023 Klemens Morgenstern (klemens.morgenstern@gmx.net) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/sqlite/connection.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + +BOOST_SYMBOL_EXPORT const sqlite3_api_routines *sqlite3_api{nullptr}; + +BOOST_SQLITE_END_NAMESPACE diff --git a/src/field.cpp b/src/field.cpp new file mode 100644 index 0000000..7ff433f --- /dev/null +++ b/src/field.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 2023 Klemens D. Morgenstern +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/sqlite/field.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + +cstring_ref field::get_text() const +{ + const auto ptr = sqlite3_column_text(stm_, col_); + if (ptr == nullptr) + { + if (sqlite3_errcode(sqlite3_db_handle(stm_)) != SQLITE_NOMEM) + return ""; + else + throw_exception(std::bad_alloc(), BOOST_CURRENT_LOCATION); + } + return reinterpret_cast<const char*>(ptr); +} + + +blob_view field::get_blob() const +{ + const auto ptr = sqlite3_column_blob(stm_, col_); + if (ptr == nullptr) + { + if (sqlite3_errcode(sqlite3_db_handle(stm_)) != SQLITE_NOMEM) + return {nullptr, 0u}; + else + throw_exception(std::bad_alloc(), BOOST_CURRENT_LOCATION); + } + const auto sz = sqlite3_column_bytes(stm_, col_); + return blob_view(ptr, sz); +} + +BOOST_SQLITE_END_NAMESPACE + diff --git a/src/meta_data.cpp b/src/meta_data.cpp new file mode 100644 index 0000000..c16bf27 --- /dev/null +++ b/src/meta_data.cpp @@ -0,0 +1,83 @@ +// +// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + + +#include <boost/sqlite/meta_data.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + + + + +auto table_column_meta_data(connection& conn, + cstring_ref db_name, cstring_ref table_name, cstring_ref column_name, + system::error_code & ec, error_info &ei) -> column_meta_data +{ + const char * data_type= "", *collation = ""; + int nn, pk, ai; + + int res = sqlite3_table_column_metadata(conn.handle(), db_name.c_str(), table_name.c_str(), + column_name.c_str(), + &data_type, &collation, &nn, &pk, &ai); + + if (res != SQLITE_OK) + { + BOOST_SQLITE_ASSIGN_EC(ec, res); + ei.set_message(sqlite3_errmsg(conn.handle())); + } + + return {data_type, collation, nn != 0, pk != 0, ai != 0}; +} + + + +auto table_column_meta_data(connection& conn, + cstring_ref table_name, cstring_ref column_name, + system::error_code & ec, error_info &ei) -> column_meta_data +{ + const char * data_type= "", *collation = ""; + int nn, pk, ai; + + int res = sqlite3_table_column_metadata(conn.handle(), nullptr, table_name.c_str(), column_name.c_str(), + &data_type, &collation, &nn, &pk, &ai); + + if (res != SQLITE_OK) + { + BOOST_SQLITE_ASSIGN_EC(ec, res); + ei.set_message(sqlite3_errmsg(conn.handle())); + } + + return {data_type, collation, nn != 0, pk != 0, ai != 0}; +} + + + + +auto table_column_meta_data(connection& conn, + cstring_ref db_name, cstring_ref table_name, cstring_ref column_name) -> column_meta_data +{ + system::error_code ec; + error_info ei; + auto res = table_column_meta_data(conn, db_name, table_name, column_name, ec, ei); + if (ec) + throw_exception(system::system_error(ec, ei.message())); + return res; +} + +auto table_column_meta_data(connection& conn, + cstring_ref table_name, cstring_ref column_name) -> column_meta_data +{ + system::error_code ec; + error_info ei; + auto res = table_column_meta_data(conn, table_name, column_name, ec, ei); + if (ec) + throw_exception(system::system_error(ec, ei.message())); + return res; +} + +BOOST_SQLITE_END_NAMESPACE + diff --git a/src/resultset.cpp b/src/resultset.cpp new file mode 100644 index 0000000..9528a2a --- /dev/null +++ b/src/resultset.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/sqlite/resultset.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + + +bool resultset::read_next( + system::error_code & ec, + error_info & ei) // could also return row* instead! +{ + if (done_) + return false; + auto cc = sqlite3_step(impl_.get()); + if (cc == SQLITE_DONE) + { + done_ = true; + return false; + } + else if (cc != SQLITE_ROW) + { + BOOST_SQLITE_ASSIGN_EC(ec, cc); + ei.set_message(sqlite3_errmsg(sqlite3_db_handle(impl_.get()))); + } + return !done_; +} + +bool resultset::read_next() +{ + system::error_code ec; + error_info ei; + auto tmp = read_next(ec, ei); + if (ec) + throw_exception(system::system_error(ec, ei.message())); + return tmp; +} + +resultset::iterator resultset::iterator::operator++() +{ + if (sentinel_) + return *this; + + auto cc = sqlite3_step(row_.stm_); + if (cc == SQLITE_DONE) + sentinel_ = true; + else if (cc != SQLITE_ROW) + { + system::error_code ec; + BOOST_SQLITE_ASSIGN_EC(ec, cc); + throw_exception(system::system_error(ec, sqlite3_errmsg(sqlite3_db_handle(row_.stm_)))); + } + return *this; +} + +BOOST_SQLITE_END_NAMESPACE + diff --git a/src/row.cpp b/src/row.cpp new file mode 100644 index 0000000..a674e9c --- /dev/null +++ b/src/row.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2023 Klemens D. Morgenstern +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/sqlite/row.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + +field row::at(std::size_t idx) const +{ + if (idx >= size()) + throw_exception(std::out_of_range("column out of range"), BOOST_CURRENT_LOCATION); + else + { + field f; + f.stm_ = stm_; + f.col_ = static_cast<int>(idx); + return f; + } +} + +BOOST_SQLITE_END_NAMESPACE + diff --git a/src/value.cpp b/src/value.cpp new file mode 100644 index 0000000..4ad5294 --- /dev/null +++ b/src/value.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 2023 Klemens D. Morgenstern +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/sqlite/value.hpp> + +BOOST_SQLITE_BEGIN_NAMESPACE + +cstring_ref value::get_text() const +{ + const auto ptr = sqlite3_value_text(value_); + if (ptr == nullptr) + { + if (is_null()) + return ""; + else + throw_exception(std::bad_alloc(), BOOST_CURRENT_LOCATION); + } + return reinterpret_cast<const char*>(ptr); +} + +blob_view value::get_blob() const +{ + const auto ptr = sqlite3_value_blob(value_); + if (ptr == nullptr) + { + if (is_null()) + return {nullptr, 0u}; + else + throw_exception(std::bad_alloc(), BOOST_CURRENT_LOCATION); + } + const auto sz = sqlite3_value_bytes(value_); + return blob_view(ptr, sz); +} + + +BOOST_SQLITE_END_NAMESPACE + |