summaryrefslogtreecommitdiff
path: root/example/ordered_map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'example/ordered_map.cpp')
-rw-r--r--example/ordered_map.cpp304
1 files changed, 0 insertions, 304 deletions
diff --git a/example/ordered_map.cpp b/example/ordered_map.cpp
deleted file mode 100644
index 26a285b..0000000
--- a/example/ordered_map.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-//
-// 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/container/flat_map.hpp>
-#include <iostream>
-
-using namespace boost;
-
-// this examples shows how to expose an ordered map as a vtable.
-
-// tag::cursor[]
-struct ordered_map_cursor final : sqlite::vtab::cursor<sqlite::string_view> // <1>
-{
- container::flat_map<std::string, std::string> &data;
- ordered_map_cursor(container::flat_map<std::string, std::string> &data) : data(data) {}
- bool inverse = false;
-
- using const_iterator = typename container::flat_map<std::string, std::string>::const_iterator;
- const_iterator begin{data.begin()}, end{data.end()}; // <2>
-
- sqlite::result<void> next() override { if (inverse) end--; else begin++; return {};} // <3>
-
- sqlite::result<sqlite3_int64> row_id() override
- {
- return {system::in_place_error, SQLITE_MISUSE, // <4>
- "this shouldn't be called, we're omitting the row id"};
- }
- sqlite::result<sqlite::string_view> column(int i, bool /*nochange*/) override // <5>
- {
- auto & elem = inverse ? *std::prev(end) : *begin;
-
- if (i == 0)
- return elem.first;
- else
- return elem.second;
- }
- // end::cursor[]
- //tag::filter[]
- sqlite::result<void> filter(int idx, const char * idxStr, span<sqlite::value> values) override
- {
- if (idx != 0) // <1>
- inverse = true;
-
- for (auto i = 0u; i < values.size(); i ++)
- {
- auto txt = values[i].get_text();
- switch (idxStr[i])
- {
- case SQLITE_INDEX_CONSTRAINT_EQ: // <2>
- {
- auto nw = data.equal_range(txt);
- if (nw.first > begin)
- begin = nw.first;
- if (nw.second < end)
- end = nw.second;
- }
-
- break;
- case SQLITE_INDEX_CONSTRAINT_GT: // <3>
- {
- auto new_begin = data.find(txt);
- new_begin ++;
- if (new_begin > begin)
- begin = new_begin;
- }
- break;
- case SQLITE_INDEX_CONSTRAINT_GE: // <3>
- {
- auto new_begin = data.find(txt);
- if (new_begin > begin)
- begin = new_begin;
- }
- break;
- case SQLITE_INDEX_CONSTRAINT_LE: // <4>
- {
- auto new_end = data.find(txt);
- new_end++;
- if (new_end < end)
- end = new_end;
-
- }
- break;
- case SQLITE_INDEX_CONSTRAINT_LT: // <4>
- {
- auto new_end = data.find(txt);
- if (new_end < end)
- end = new_end;
- }
- break;
- }
-
- }
- return {};
- }
- //end::filter[]
- // tag::cursor[]
- bool eof() noexcept override // <6>
- {
- return begin == end;
- }
-};
-// end::cursor[]
-
-
-// tag::table[]
-struct map_impl final
- : sqlite::vtab::table<ordered_map_cursor>,
- sqlite::vtab::modifiable // <1>
-
-{
- container::flat_map<std::string, std::string> &data;
- map_impl(container::flat_map<std::string, std::string> &data) : data(data) {}
-
- const char * declaration() override // <2>
- {
- return R"(
- create table my_map(
- name text primary key unique not null,
- data text) WITHOUT ROWID;)";
- }
-
-
- sqlite::result<cursor_type> open() override // <3>
- {
- return cursor_type{data};
- }
-
- sqlite::result<void> delete_(sqlite::value key) override // <4>
- {
- data.erase(key.get_text());
- return {};
- }
- sqlite::result<sqlite_int64> insert(sqlite::value /*key*/, span<sqlite::value> values,
- int /*on_conflict*/) override // <5>
- {
- data.emplace(values[0].get_text(), values[1].get_text());
- return 0;
- }
-
- sqlite::result<sqlite_int64> update(sqlite::value old_key, sqlite::value new_key,
- span<sqlite::value> values,
- int /*on_conflict*/) override // <6>
- {
- if (new_key.get_int() != old_key.get_int())
- data.erase(old_key.get_text());
- data.insert_or_assign(values[0].get_text(), values[1].get_text());
- return 0;
- }
-
- // end::table[]
- // tag::best_index[]
- sqlite::result<void> best_index(sqlite::vtab::index_info & info) override
- {
- // we're using the index to encode the mode, because it's simple enough.
- // more complex application should use it as an index like intended
-
- int idx = 0;
- sqlite::unique_ptr<char[]> str; // <1>
- if (info.constraints().size() > 0)
- {
- const auto sz = info.constraints().size()+1;
- str.reset(static_cast<char*>(sqlite3_malloc(sz)));
- std::memset(str.get(), '\0', sz);
- }
- else
- return {};
-
- for (auto i = 0u; i < info.constraints().size(); i++)
- {
- if ((idx & SQLITE_INDEX_CONSTRAINT_EQ) != 0)
- break;
- auto ct = info.constraints()[i];
- if (ct.iColumn == 0
- && ct.usable != 0) // aye, that's us
- {
- switch (ct.op) //<2>
- {
- // we'll stick to these
- case SQLITE_INDEX_CONSTRAINT_EQ: BOOST_FALLTHROUGH;
- case SQLITE_INDEX_CONSTRAINT_GT: BOOST_FALLTHROUGH;
- case SQLITE_INDEX_CONSTRAINT_GE: BOOST_FALLTHROUGH;
- case SQLITE_INDEX_CONSTRAINT_LE: BOOST_FALLTHROUGH;
- case SQLITE_INDEX_CONSTRAINT_LT:
- str[idx] = ct.op;
- info.usage()[i].argvIndex = ++idx; // use it -> value in this position in `filter`.
- info.usage()[i].omit = 1; // tell sqlite that we're sure enough, so sqlite doesn't check
- break;
- default:
- break;
- }
- }
- }
-
-
- if (info.order_by().size() == 1 && info.order_by()[0].iColumn == 0)
- {
- idx |= info.order_by()[0].desc; // <3>
- info.set_already_ordered(); // <4>
- }
-
- // <5>
- info.set_index(idx);
- if (str)
- info.set_index_string(str.release(), true);
-
- return {};
- }
- // end::best_index[]
- // tag::table[]
-};
-
-// end::table[]
-
-// tag::module[]
-struct ordered_map_module final : sqlite::vtab::eponymous_module<map_impl>
-{
- container::flat_map<std::string, std::string> data;
- template<typename ... Args>
- ordered_map_module(Args && ...args) : data(std::forward<Args>(args)...) {}
-
- sqlite::result<map_impl> connect(
- sqlite::connection /*conn*/, int /*argc*/, const char * const */*argv*/)
- {
- return map_impl{data};
- }
-};
-// end::module[]
-
-
-
-std::initializer_list<std::pair<std::string, std::string>> init_data = {
- {"atomic", "1.53.0"},
- {"chrono", "1.47.0"},
- {"container", "1.48.0"},
- {"context", "1.51.0"},
- {"contract", "1.67.0"},
- {"coroutine", "1.53.0"},
- {"date_time", "1.29.0"},
- {"exception", "1.36.0"},
- {"fiber", "1.62.0"},
- {"filesystem", "1.30.0"},
- {"graph", "1.18.0"},
- {"graph_parallel", "1.40.0"},
- {"headers", "1.00.0"},
- {"iostreams", "1.33.0"},
- {"json", "1.75.0"},
- {"locale", "1.48.0"},
- {"log", "1.54.0"},
- {"math", "1.23.0"},
- {"mpi", "1.35.0"},
- {"nowide", "1.73.0"},
- {"program_options", "1.32.0"},
- {"python", "1.19.0"},
- {"random", "1.15.0"},
- {"regex", "1.18.0"},
- {"serialization", "1.32.0"},
- {"stacktrace", "1.65.0"},
- {"system", "1.35.0"},
- {"test", "1.21.0"},
- {"thread", "1.25.0"},
- {"timer", "1.9.0"},
- {"type_erasure", "1.54.0"},
- {"url", "1.81.0"},
- {"wave", "1.33.0"}
-};
-
-void print(std::ostream & os, sqlite::resultset rw)
-{
- os << "[";
- for (auto & r : rw)
- os << r.at(0).get_text() << ", ";
- os << "]" << std::endl;
-}
-
-int main (int /*argc*/, char * /*argv*/[])
-{
- sqlite::connection conn{":memory:"};
-
- // tag::module[]
- ordered_map_module & m = sqlite::create_module(conn, "my_map", ordered_map_module(init_data));
- // end::module[]
- boost::ignore_unused(m);
-
- print(std::cout, conn.query("select * from my_map order by name desc;"));
- print(std::cout, conn.query("select * from my_map where name = 'url';"));
- print(std::cout, conn.query("select * from my_map where name < 'url' and name >= 'system' ;"));
- print(std::cout, conn.query("select * from my_map where name > 'json';"));
- print(std::cout, conn.query("select * from my_map where name >= 'json';"));
- print(std::cout, conn.query("select * from my_map where name < 'json';"));
- print(std::cout, conn.query("select * from my_map where name == 'json' order by name asc;"));
- print(std::cout, conn.query("select * from my_map where name == 'json' order by name desc;"));
-
- print(std::cout, conn.query("select * from my_map where name < 'url' and name >= 'system' order by name desc;"));
- print(std::cout, conn.query("select * from my_map where data == '1.81.0';"));
-
- conn.query("delete from my_map where data == '1.81.0';");
-
- return 0;
-} \ No newline at end of file