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 /example/tutorial_ec.cpp | |
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 'example/tutorial_ec.cpp')
-rw-r--r-- | example/tutorial_ec.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/example/tutorial_ec.cpp b/example/tutorial_ec.cpp new file mode 100644 index 0000000..2c6af7f --- /dev/null +++ b/example/tutorial_ec.cpp @@ -0,0 +1,197 @@ +// +// 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.hpp> +#include <boost/describe/class.hpp> + +#include <iostream> + +using namespace boost; + +// tag::query_t[] +struct users { std::string name; std::int64_t age; }; +BOOST_DESCRIBE_STRUCT(users, (), (name, age)); +// end::query_t[] + +int main(int /*argc*/, char */*argv*/[]) +{ + system::error_code ec; + sqlite::error_info ei; + + sqlite::connection conn; + +#if defined(SQLITE_EXAMPLE_USE_DB) + // tag::conn_path[] + conn.connect("./my_db.db", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, ec); + // end::conn_path[] +#else + // tag::conn_mem[] + conn.connect(sqlite::in_memory, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, ec); + // end::conn_mem[] +#endif + + if (ec) + goto error; + + // tag::execute[] + conn.execute(R"( + CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + age INTEGER NOT NULL); + INSERT INTO users(name, age) VALUES('Alice', 30); + INSERT INTO users(name, age) VALUES('Bob', 25); + )", ec, ei); + // end::execute[] + + if (ec) + goto error; + +{ + // tag::query1[] + sqlite::resultset q = conn.query("SELECT name, age FROM users ORDER BY id ASC;", ec, ei); + if (ec) + goto error; + // end::query1[] + + // tag::query2[] + assert(q.current()[0].get_text() == "Alice"); + assert(q.read_next(ec, ei)); // true if it's the last row! + if (ec) + goto error; + assert(q.current()[0].get_text() == "Bob"); + // end::query2[] +} + + // tag::query3[] + for (const auto & t : + conn.query<std::tuple<sqlite::string_view, std::int64_t>>("SELECT name, age FROM users;", ec, ei)) + std::cout << "User " << std::get<0>(t) << " is " << std::get<1>(t) << " old." << std::endl; + + if (ec) + goto error; + + // end::query3[] + + // tag::query4[] + for (const auto & a : conn.query<users>("SELECT age, name FROM users;", ec, ei)) + std::cout << "User " << a.name << " is " << a.age << " old." << std::endl; + if (ec) + goto error; + // end::query4[] + + // tag::query_strict[] + { + auto r = conn.query<users>("SELECT age, name FROM users;", ec, ei).strict(); + while (r.read_next(ec, ei) && !ec) + { + // because this is strict, it takes ec & ei for conversion errors. + const auto & a = r.current(ec, ei); + if (ec) + break; + std::cout << "User " << a.name << " is " << a.age << " old." << std::endl; + } + } + if (ec) + goto error; + + // end::query_strict[] + + + // tag::statement_insert[] + + { + auto p = conn.prepare("insert into users (name, age) values (?1, ?2), (?3, ?4)", ec, ei); + if (!ec) + std::move(p).execute({"Paul", 31, "Mark", 51}, ec, ei); + if (ec) + goto error; + } + // end::statement_insert[] + + + // tag::statement_multi_insert[] + { + conn.execute("BEGIN TRANSACTION;", ec, ei); + if (ec) + goto error; + sqlite::transaction t{conn, sqlite::transaction::adopt_transaction}; // use a transaction to speed this up + + auto st = conn.prepare(R"(insert into users ("name", age) values ($name, $age))", ec, ei); + if (!ec) + st.execute({{"name", "Allen"}, {"age", 43}}, ec, ei); + if (!ec) + st.execute({{"name", "Tom"}, {"age", 84}}, ec, ei); + if (!ec) + t.commit(ec, ei); + + if (ec) + goto error; + } + + + // end::statement_multi_insert[] + + // tag::to_upper[] + sqlite::create_scalar_function( + conn, + "to_upper", + [](sqlite::context<>, // <1> + boost::span<sqlite::value, 1u> val // <2> + ) -> sqlite::result<std::string> + { + if (val[0].type() != sqlite::value_type::text) + return sqlite::error(SQLITE_MISUSE, "Value must be string"); // <2> + auto txt = val[0].get_text(); + std::string res; + res.resize(txt.size()); + std::transform(txt.begin(), txt.end(), res.begin(), [](char c){return std::toupper(c);}); + return res; + }, + sqlite::deterministic // <3> + , ec, ei); + if (ec) + goto error; + { + auto qu = conn.query("SELECT to_upper(name) FROM users WHERE name == 'Alice';", ec, ei); + if (ec) goto error; + assert(qu.current()[0].get_text() == "ALICE"); + } + // end::to_upper[] + + + // tag::oldest[] + struct retirees + { + std::int64_t retirement_age; + std::int64_t count = 0u; + retirees(std::size_t retirement_age) + : retirement_age(retirement_age) {} + + void step(span<sqlite::value, 1> args) noexcept // no possible errors, no result needed + { + if (args[0].get_int() >= retirement_age) + count += 1; + } + std::int64_t final() noexcept { return count; } + }; + sqlite::create_aggregate_function<retirees>(conn, "retirees", std::make_tuple(65), {}, ec, ei); + if (ec) goto error; + + { + auto q = conn.query("select retirees(age) from users;", ec, ei); + if (ec) goto error; + std::cout << "The amount of retirees is " << q.current()[0].get_text() << std::endl; + } + // end::oldest[] + + return 0; + + error: + fprintf(stderr, "sqlite failure: %s - %s\n", ec.message().c_str(), ei.message().c_str()); + return EXIT_FAILURE; +}
\ No newline at end of file |