Skip to content

Commit

Permalink
fts5 first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneBaldZakharov committed Sep 21, 2023
1 parent 8b2f195 commit b3ced5e
Show file tree
Hide file tree
Showing 33 changed files with 1,027 additions and 145 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ cmake-build-debug/
.idea/

/compile
build
22 changes: 22 additions & 0 deletions dev/ast/match.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

namespace sqlite_orm {
namespace internal {

template<class T, class X>
struct match_t {
using mapped_type = T;
using argument_type = X;

argument_type argument;

match_t(argument_type argument): argument(std::move(argument)) {}
};
}

template<class T, class X>
internal::match_t<T, X> match(X argument) {
return {std::move(argument)};
}

}
27 changes: 24 additions & 3 deletions dev/ast_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "ast/group_by.h"
#include "ast/exists.h"
#include "ast/set.h"
#include "ast/match.h"

namespace sqlite_orm {

Expand Down Expand Up @@ -141,9 +142,19 @@ namespace sqlite_orm {
using node_type = binary_operator<L, R, Ds...>;

template<class C>
void operator()(const node_type& binaryOperator, C& lambda) const {
iterate_ast(binaryOperator.lhs, lambda);
iterate_ast(binaryOperator.rhs, lambda);
void operator()(const node_type& node, C& lambda) const {
iterate_ast(node.lhs, lambda);
iterate_ast(node.rhs, lambda);
}
};

template<class L, class R>
struct ast_iterator<is_equal_with_table_t<L, R>, void> {
using node_type = is_equal_with_table_t<L, R>;

template<class C>
void operator()(const node_type& node, C& lambda) const {
iterate_ast(node.rhs, lambda);
}
};

Expand Down Expand Up @@ -212,6 +223,16 @@ namespace sqlite_orm {
}
};

template<class T, class X>
struct ast_iterator<match_t<T, X>, void> {
using node_type = match_t<T, X>;

template<class L>
void operator()(const node_type& node, L& lambda) const {
iterate_ast(node.argument, lambda);
}
};

template<class T>
struct ast_iterator<into_t<T>, void> {
using node_type = into_t<T>;
Expand Down
4 changes: 2 additions & 2 deletions dev/column_names_getter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ namespace sqlite_orm {

namespace internal {

template<class T, class DBOs>
std::string serialize(const T&, const serializer_context<DBOs>&);
template<class T, class C>
std::string serialize(const T& t, const C& context);

template<class T, class Ctx>
std::vector<std::string>& collect_table_column_names(std::vector<std::string>& collectedExpressions,
Expand Down
15 changes: 15 additions & 0 deletions dev/conditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,16 @@ namespace sqlite_orm {
}
};

template<class L, class R>
struct is_equal_with_table_t: negatable_t {
using left_type = L;
using right_type = R;

right_type rhs;

is_equal_with_table_t(right_type rhs): rhs(std::move(rhs)) {}
};

struct is_not_equal_string {
operator std::string() const {
return "!=";
Expand Down Expand Up @@ -1085,6 +1095,11 @@ namespace sqlite_orm {
return {std::move(l), std::move(r)};
}

template<class L, class R>
internal::is_equal_with_table_t<L, R> is_equal(R rhs) {
return {std::move(rhs)};
}

template<class L, class R>
internal::is_not_equal_t<L, R> is_not_equal(L l, R r) {
return {std::move(l), std::move(r)};
Expand Down
4 changes: 2 additions & 2 deletions dev/default_value_extractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ namespace sqlite_orm {

namespace internal {

template<class T, class DBOs>
std::string serialize(const T&, const serializer_context<DBOs>&);
template<class T, class C>
std::string serialize(const T& t, const C& context);

/**
* Serialize default value of a column's default valu
Expand Down
2 changes: 1 addition & 1 deletion dev/eponymous_vtabs/dbstat.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#endif

#include "../column.h"
#include "../table.h"
#include "../schema/table.h"

namespace sqlite_orm {
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
Expand Down
2 changes: 1 addition & 1 deletion dev/implementations/table_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "../functional/cxx_universal.h" // ::size_t
#include "../type_printer.h"
#include "../column.h"
#include "../table.h"
#include "../schema/table.h"

namespace sqlite_orm {
namespace internal {
Expand Down
8 changes: 7 additions & 1 deletion dev/node_tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
#include "ast/where.h"
#include "ast/into.h"
#include "ast/group_by.h"
#include "ast/match.h"

namespace sqlite_orm {

namespace internal {

template<class T, class SFINAE = void>
Expand Down Expand Up @@ -89,6 +89,9 @@ namespace sqlite_orm {
template<class E>
struct node_tuple<order_by_t<E>, void> : node_tuple<E> {};

template<class L, class R>
struct node_tuple<is_equal_with_table_t<L, R>, void> : node_tuple<R> {};

template<class T>
struct node_tuple<T, match_if<is_binary_condition, T>> {
using node_type = T;
Expand Down Expand Up @@ -158,6 +161,9 @@ namespace sqlite_orm {
template<class T>
struct node_tuple<into_t<T>, void> : node_tuple<void> {};

template<class T, class X>
struct node_tuple<match_t<T, X>, void> : node_tuple<X> {};

template<class... Args>
struct node_tuple<values_t<Args...>, void> {
using type = tuple_cat_t<node_tuple_t<Args>...>;
Expand Down
File renamed without changes.
146 changes: 127 additions & 19 deletions dev/table.h → dev/schema/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,25 +116,6 @@ namespace sqlite_orm {
return result;
}

template<class G, class S>
bool exists_in_composite_primary_key(const column_field<G, S>& column) const {
bool res = false;
this->for_each_primary_key([&column, &res](auto& primaryKey) {
using colrefs_tuple = decltype(primaryKey.columns);
using same_type_index_sequence =
filter_tuple_sequence_t<colrefs_tuple,
check_if_is_type<member_field_type_t<G>>::template fn,
member_field_type_t>;
iterate_tuple(primaryKey.columns, same_type_index_sequence{}, [&res, &column](auto& memberPointer) {
if(compare_any(memberPointer, column.member_pointer) ||
compare_any(memberPointer, column.setter)) {
res = true;
}
});
});
return res;
}

/**
* Call passed lambda with all defined primary keys.
*/
Expand Down Expand Up @@ -284,6 +265,128 @@ namespace sqlite_orm {

template<class O, bool W, class... Cs>
struct is_table<table_t<O, W, Cs...>> : std::true_type {};

template<class M>
struct virtual_table_t: basic_table {
using module_details_type = M;
using object_type = typename module_details_type::object_type;
using elements_type = typename module_details_type::columns_type;

static constexpr bool is_without_rowid_v = false;
using is_without_rowid = polyfill::bool_constant<is_without_rowid_v>;

module_details_type module_details;

virtual_table_t(std::string name, module_details_type module_details):
basic_table{std::move(name)}, module_details{std::move(module_details)} {}

/**
* Call passed lambda with columns not having the specified constraint trait `OpTrait`.
* @param lambda Lambda called for each column.
*/
template<template<class...> class OpTraitFn, class L>
void for_each_column_excluding(L&& lambda) const {
this->module_details.template for_each_column_excluding<OpTraitFn>(lambda);
}

/**
* Call passed lambda with columns not having the specified constraint trait `OpTrait`.
* @param lambda Lambda called for each column.
*/
template<class OpTraitFnCls, class L, satisfies<mpl::is_metafunction_class, OpTraitFnCls> = true>
void for_each_column_excluding(L&& lambda) const {
this->module_details.template for_each_column_excluding<OpTraitFnCls>(lambda);
}

/**
* Call passed lambda with all defined columns.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<class L>
void for_each_column(L&& lambda) const {
this->module_details.for_each_column(lambda);
}
};

template<class T>
struct is_virtual_table : std::false_type {};

template<class M>
struct is_virtual_table<virtual_table_t<M>> : std::true_type {};

template<class T, class... Cs>
struct using_fts5_t {
using object_type = T;
using columns_type = std::tuple<Cs...>;

columns_type columns;

using_fts5_t(columns_type columns): columns(std::move(columns)) {}

/**
* Call passed lambda with columns not having the specified constraint trait `OpTrait`.
* @param lambda Lambda called for each column.
*/
template<template<class...> class OpTraitFn, class L>
void for_each_column_excluding(L&& lambda) const {
iterate_tuple(this->columns, col_index_sequence_excluding<columns_type, OpTraitFn>{}, lambda);
}

/**
* Call passed lambda with columns not having the specified constraint trait `OpTrait`.
* @param lambda Lambda called for each column.
*/
template<class OpTraitFnCls, class L, satisfies<mpl::is_metafunction_class, OpTraitFnCls> = true>
void for_each_column_excluding(L&& lambda) const {
this->for_each_column_excluding<OpTraitFnCls::template fn>(lambda);
}

/**
* Call passed lambda with all defined columns.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<class L>
void for_each_column(L&& lambda) const {
using col_index_sequence = filter_tuple_sequence_t<columns_type, is_column>;
iterate_tuple(this->columns, col_index_sequence{}, lambda);
}
};

template<class O, bool WithoutRowId, class... Cs, class G, class S>
bool exists_in_composite_primary_key(const table_t<O, WithoutRowId, Cs...> &table, const column_field<G, S>& column) {
bool res = false;
table.for_each_primary_key([&column, &res](auto& primaryKey) {
using colrefs_tuple = decltype(primaryKey.columns);
using same_type_index_sequence =
filter_tuple_sequence_t<colrefs_tuple,
check_if_is_type<member_field_type_t<G>>::template fn,
member_field_type_t>;
iterate_tuple(primaryKey.columns, same_type_index_sequence{}, [&res, &column](auto& memberPointer) {
if(compare_any(memberPointer, column.member_pointer) ||
compare_any(memberPointer, column.setter)) {
res = true;
}
});
});
return res;
}

template<class M, class G, class S>
bool exists_in_composite_primary_key(const virtual_table_t<M> &virtualTable, const column_field<G, S>& column) {
return false;
}
}

template<class... Cs, class T = typename std::tuple_element_t<0, std::tuple<Cs...>>::object_type>
internal::using_fts5_t<T, Cs...> using_fts5(Cs... columns) {
SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES(
return {std::make_tuple(std::forward<Cs>(columns)...)});
}

template<class T, class... Cs>
internal::using_fts5_t<T, Cs...> using_fts5(Cs... columns) {
SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES(
return {std::make_tuple(std::forward<Cs>(columns)...)});
}

/**
Expand All @@ -307,4 +410,9 @@ namespace sqlite_orm {
SQLITE_ORM_CLANG_SUPPRESS_MISSING_BRACES(
return {std::move(name), std::make_tuple<Cs...>(std::forward<Cs>(args)...)});
}

template<class M>
internal::virtual_table_t<M> make_virtual_table(std::string name, M module_details) {
return internal::virtual_table_t<M>(std::move(name), std::move(module_details));
}
}
4 changes: 2 additions & 2 deletions dev/triggers.h → dev/schema/triggers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include <string>
#include <tuple>

#include "functional/cxx_universal.h"
#include "optional_container.h"
#include "../functional/cxx_universal.h"
#include "../optional_container.h"

// NOTE Idea : Maybe also implement a custom trigger system to call a c++ callback when a trigger triggers ?
// (Could be implemented with a normal trigger that insert or update an internal table and then retreive
Expand Down
17 changes: 17 additions & 0 deletions dev/serializer_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ namespace sqlite_orm {
serializer_context(const db_objects_type& dbObjects) : db_objects{dbObjects} {}
};

template<class DBOs>
struct serializer_context_with_no_types_and_constraints: serializer_context<DBOs> {
using super = serializer_context<DBOs>;

serializer_context_with_no_types_and_constraints(const super &parentContext): super(parentContext) {}
};

template<class DBOs>
serializer_context_with_no_types_and_constraints<DBOs> make_serializer_context_with_no_types_and_constraints(const serializer_context<DBOs> &parentContext) {
return {parentContext};
}

template<class S>
struct serializer_context_builder {
using storage_type = S;
Expand All @@ -33,6 +45,11 @@ namespace sqlite_orm {
const storage_type& storage;
};

template<class T>
struct no_need_types_and_constraints: std::false_type {};

template<class DBOs>
struct no_need_types_and_constraints<serializer_context_with_no_types_and_constraints<DBOs>>: std::true_type {};
}

}
Loading

0 comments on commit b3ced5e

Please sign in to comment.