summaryrefslogtreecommitdiff
path: root/subprojects/boost-sqlite/src
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/boost-sqlite/src')
-rw-r--r--subprojects/boost-sqlite/src/backup.cpp61
-rw-r--r--subprojects/boost-sqlite/src/blob.cpp94
-rw-r--r--subprojects/boost-sqlite/src/connection.cpp158
-rw-r--r--subprojects/boost-sqlite/src/detail/exception.cpp46
-rw-r--r--subprojects/boost-sqlite/src/error.cpp83
-rw-r--r--subprojects/boost-sqlite/src/ext.cpp14
-rw-r--r--subprojects/boost-sqlite/src/field.cpp39
-rw-r--r--subprojects/boost-sqlite/src/meta_data.cpp83
-rw-r--r--subprojects/boost-sqlite/src/resultset.cpp61
-rw-r--r--subprojects/boost-sqlite/src/row.cpp24
-rw-r--r--subprojects/boost-sqlite/src/value.cpp39
11 files changed, 702 insertions, 0 deletions
diff --git a/subprojects/boost-sqlite/src/backup.cpp b/subprojects/boost-sqlite/src/backup.cpp
new file mode 100644
index 0000000..76099b1
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/blob.cpp b/subprojects/boost-sqlite/src/blob.cpp
new file mode 100644
index 0000000..397d85b
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/connection.cpp b/subprojects/boost-sqlite/src/connection.cpp
new file mode 100644
index 0000000..1ac0ae7
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/detail/exception.cpp b/subprojects/boost-sqlite/src/detail/exception.cpp
new file mode 100644
index 0000000..e360f38
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/error.cpp b/subprojects/boost-sqlite/src/error.cpp
new file mode 100644
index 0000000..9344fbe
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/ext.cpp b/subprojects/boost-sqlite/src/ext.cpp
new file mode 100644
index 0000000..0152994
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/field.cpp b/subprojects/boost-sqlite/src/field.cpp
new file mode 100644
index 0000000..7ff433f
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/meta_data.cpp b/subprojects/boost-sqlite/src/meta_data.cpp
new file mode 100644
index 0000000..c16bf27
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/resultset.cpp b/subprojects/boost-sqlite/src/resultset.cpp
new file mode 100644
index 0000000..9528a2a
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/row.cpp b/subprojects/boost-sqlite/src/row.cpp
new file mode 100644
index 0000000..a674e9c
--- /dev/null
+++ b/subprojects/boost-sqlite/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/subprojects/boost-sqlite/src/value.cpp b/subprojects/boost-sqlite/src/value.cpp
new file mode 100644
index 0000000..4ad5294
--- /dev/null
+++ b/subprojects/boost-sqlite/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
+