Skip to content

Adopt fcpp::vector in the public Database API#39

Open
jkalias wants to merge 4 commits into
mainfrom
claude/open-issues-list-60jh6y
Open

Adopt fcpp::vector in the public Database API#39
jkalias wants to merge 4 commits into
mainfrom
claude/open-issues-list-60jh6y

Conversation

@jkalias

@jkalias jkalias commented Jul 19, 2026

Copy link
Copy Markdown
Owner

What & why

Extends the functional_cpp integration (which already provides fcpp::optional_t for nullable
fields) so that query results and batch operations use fcpp::vector<T> instead of
std::vector<T>. Callers can now chain functional operations directly on a fetched result — e.g.
db->FetchAll<Person>().filter(...).map<std::wstring>(...) — without wrapping it themselves.

Scope

Only the public Database template API changes:

  • FetchAll<T>() and Fetch<T>(const QueryPredicateBase*) now return fcpp::vector<T>.
  • Batch Save/SaveAutoIncrement/Update now take fcpp::vector<T>, with thin std::vector
    forwarding overloads kept
    so existing call sites keep compiling. The overloads copy into an
    fcpp::vector and forward; the SaveAutoIncrement wrapper writes the assigned ids back into the
    caller's std::vector.
  • The private FetchRecords hydration loop builds the result with insert_back(std::move(model)),
    preserving the no-extra-copy fetch path.

Internal plumbing (Bindings, GetValues, query/predicate classes, Reflection::member_metadata,
StringUtilities::Join) stays on std::vector — it's implementation detail and gains nothing from
the functional API.

Source-breaking change (documented)

The changed return types break callers that bind a result to std::vector<T> explicitly, since
there is no implicit conversion back. auto call sites, range-for, indexing, and size() are
unaffected. The README's "Working with query results" section documents the migration, including
that fcpp::vector::operator[] is bounds-checked and calls std::abort() on out-of-range access
instead of being UB.

Tests

  • All existing tests pass unchanged (they use auto/indexing/size()), confirming the container
    swap is behavior-preserving.
  • New tests/functional_vector_test.cc proves the migration's point: chaining filter + map and
    all_of/any_of on a fetch result; range-for/indexing parity; batch Save/Update/
    SaveAutoIncrement accepting an fcpp::vector with id write-back; and the std::vector
    compatibility overloads (including id write-back through the SaveAutoIncrement wrapper).

Verification

Full suite green in C++11, C++17, and C++20 (91 tests each: 84 existing + 7 new).

Notes

  • No *_parallel methods or anything behind PARALLEL_ALGORITHM_AVAILABLE are used, so the code is
    standard-agnostic.
  • Records/reflection macros are untouched; fcpp::vector is not used in struct field declarations.
  • The C++11 minimum, the functional_cpp tag, and the CMake wiring are unchanged.

claude added 3 commits July 19, 2026 19:29
FetchAll, Fetch(predicate) and the private FetchRecords hydration loop now
return fcpp::vector<T> instead of std::vector<T>, so callers can chain
functional operations (filter/map/all_of/...) directly on a query result.
The hydration loop builds the result with insert_back(std::move(model)),
keeping the no-extra-copy fetch path.

The batch Save/SaveAutoIncrement/Update methods now take fcpp::vector<T>,
with thin std::vector overloads kept for source compatibility: they copy
into an fcpp::vector and forward, and the SaveAutoIncrement wrapper writes
the generated ids back into the caller's std::vector.

Internal plumbing (bindings, query classes, reflection metadata) stays on
std::vector; only the public template API changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YLXHcZjrnrdhRZAgqDh6kd
Covers the point of the migration: chaining filter + map and all_of/any_of
directly on a fetch result, range-for/indexing parity with std::vector, and
that batch Save/Update/SaveAutoIncrement accept an fcpp::vector with ids
written back. Also verifies the std::vector compatibility overloads still
work, including id write-back through the SaveAutoIncrement wrapper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YLXHcZjrnrdhRZAgqDh6kd
Adds a "Working with query results" section showing a filter/map chain, notes
that batch writes accept an fcpp::vector, and adds a migration note: auto call
sites are unaffected, explicit std::vector bindings need iterator construction,
and indexing is bounds-checked (aborts instead of UB). Updates the one example
that bound a fetch result to std::vector, and lists functional_cpp as a
dependency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YLXHcZjrnrdhRZAgqDh6kd

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9c288909a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread include/database.h Outdated
The std::vector compatibility wrapper copied into an fcpp::vector, ran the
whole batch, then copied ids back at the end. Because each insert commits
independently, a later row throwing would skip the end copy-back and leave
the caller's std::vector without ids for rows that already committed.

Save each record through the single-record overload instead, writing every
id back as soon as its row is inserted - restoring the pre-fcpp::vector
partial-success behavior and dropping the container copy.

Addresses a Codex review comment on PR #39.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YLXHcZjrnrdhRZAgqDh6kd
@jkalias

jkalias commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 22fe6fce96

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants