This repository has been archived by the owner on Jan 3, 2024. It is now read-only.
forked from fnc12/sqlite_orm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcolumn_names_getter.h
118 lines (104 loc) · 5.33 KB
/
column_names_getter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#pragma once
#include <type_traits> // std::is_base_of
#include <string> // std::string
#include <vector> // std::vector
#include <functional> // std::reference_wrapper
#include <system_error>
#include <utility> // std::move
#include "tuple_helper/tuple_traits.h"
#include "tuple_helper/tuple_iteration.h"
#include "error_code.h"
#include "mapped_type_proxy.h"
#include "alias_traits.h"
#include "select_constraints.h"
#include "storage_lookup.h" // pick_table
#include "serializer_context.h"
#include "util.h"
namespace sqlite_orm {
namespace internal {
template<class T, class DBOs>
std::string serialize(const T&, const serializer_context<DBOs>&);
template<class T, class Ctx>
std::vector<std::string>& collect_table_column_names(std::vector<std::string>& collectedExpressions,
bool definedOrder,
const Ctx& context) {
if(definedOrder) {
auto& table = pick_table<mapped_type_proxy_t<T>>(context.db_objects);
collectedExpressions.reserve(collectedExpressions.size() + table.count_columns_amount());
table.for_each_column([qualified = !context.skip_table_name,
&tableName = table.name,
&collectedExpressions](const column_identifier& column) {
if(is_alias_v<T>) {
collectedExpressions.push_back(quote_identifier(alias_extractor<T>::extract()) + "." +
quote_identifier(column.name));
} else if(qualified) {
collectedExpressions.push_back(quote_identifier(tableName) + "." +
quote_identifier(column.name));
} else {
collectedExpressions.push_back(quote_identifier(column.name));
}
});
} else {
collectedExpressions.reserve(collectedExpressions.size() + 1);
if(is_alias_v<T>) {
collectedExpressions.push_back(quote_identifier(alias_extractor<T>::extract()) + ".*");
} else if(!context.skip_table_name) {
const basic_table& table = pick_table<mapped_type_proxy_t<T>>(context.db_objects);
collectedExpressions.push_back(quote_identifier(table.name) + ".*");
} else {
collectedExpressions.emplace_back("*");
}
}
return collectedExpressions;
}
/** @short Column expression collector.
*/
struct column_names_getter {
/**
* The default implementation simply serializes the passed argument.
*/
template<class E, class Ctx>
std::vector<std::string>& operator()(const E& t, const Ctx& context) {
auto columnExpression = serialize(t, context);
if(columnExpression.empty()) {
throw std::system_error{orm_error_code::column_not_found};
}
collectedExpressions.reserve(collectedExpressions.size() + 1);
collectedExpressions.push_back(std::move(columnExpression));
return collectedExpressions;
}
template<class T, class Ctx>
std::vector<std::string>& operator()(const std::reference_wrapper<T>& expression, const Ctx& context) {
return (*this)(expression.get(), context);
}
template<class T, class Ctx>
std::vector<std::string>& operator()(const asterisk_t<T>& expression, const Ctx& context) {
return collect_table_column_names<T>(collectedExpressions, expression.defined_order, context);
}
template<class T, class Ctx>
std::vector<std::string>& operator()(const object_t<T>& expression, const Ctx& context) {
return collect_table_column_names<T>(collectedExpressions, expression.defined_order, context);
}
template<class... Args, class Ctx>
std::vector<std::string>& operator()(const columns_t<Args...>& cols, const Ctx& context) {
collectedExpressions.reserve(collectedExpressions.size() + cols.count);
iterate_tuple(cols.columns, [this, &context](auto& colExpr) {
(*this)(colExpr, context);
});
// note: `capacity() > size()` can occur in case `asterisk_t<>` does spell out the columns in defined order
if(mpl::instantiate<check_if_tuple_has_template<asterisk_t>,
typename columns_t<Args...>::columns_type>::value &&
collectedExpressions.capacity() > collectedExpressions.size()) {
collectedExpressions.shrink_to_fit();
}
return collectedExpressions;
}
std::vector<std::string> collectedExpressions;
};
template<class T, class Ctx>
std::vector<std::string> get_column_names(const T& t, const Ctx& context) {
column_names_getter serializer;
return serializer(t, context);
}
}
}