大更新

This commit is contained in:
2026-08-08 19:16:58 +08:00
parent d289f8d6e2
commit ae5dc3eb46
178 changed files with 69427 additions and 525 deletions
@@ -328,9 +328,18 @@ private:
const auto view = describe_table_view<T>();
const std::string order_by = query.order_by.empty() ? view.default_order_by : query.order_by;
const std::string order_dir = query.order_by.empty() ? view.default_order_dir : query.order_dir.empty() ? "asc" : query.order_dir;
if(order_by.empty() || !is_sortable_field(order_by)) {
if(order_by.empty()) {
return;
}
if(!is_sortable_field(order_by)) {
if(!query.order_by.empty()) {
throw std::invalid_argument("table query field is not sortable: " + order_by);
}
return;
}
if(order_dir != "asc" && order_dir != "desc") {
throw std::invalid_argument("table order direction must be asc or desc");
}
const bool descending = order_dir == "desc";
std::stable_sort(entries.begin(), entries.end(), [&](const Entry* left, const Entry* right) {
int comparison{};
@@ -191,6 +191,13 @@ inline void validate_composition_slot_contracts(const Composition_View& view, co
validate_composition_view(view);
std::vector<std::string> slots;
collect_composition_slots(view.body, slots);
for(std::size_t index = 0; index < slots.size(); ++index) {
for(std::size_t other = index + 1; other < slots.size(); ++other) {
if(slots[index] == slots[other]) {
throw std::invalid_argument("duplicate composition slot reference: " + slots[index]);
}
}
}
for(const auto& slot_name : slots) {
const auto iterator = std::find_if(contracts.begin(), contracts.end(), [&](const Composition_Slot_Contract& contract) {
return contract.name == slot_name;