-
Notifications
You must be signed in to change notification settings - Fork 679
Add C++ Bindings #3544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add C++ Bindings #3544
Conversation
8a32cdb to
7b372b7
Compare
…_exports to carry defaults
… as exceptions are not available for C++ yet
…r to how Views worked with errors + added a version of IterBuf for C++ to start to reduce allocations
7b372b7 to
fa45b54
Compare
Thanks! Co-authored-by: Ryan <[email protected]> Signed-off-by: Jason Larabie <[email protected]>
jdetter
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments/questions to get started here. There is a lot to review here so I'll do another pass later today.
The main thing I would bring up is that we are referring to this as the "C++ SDK" which I think we should rebrand to the "C++ bindings". My reason is that the other bindings libraries all refer to themselves as bindings, not an SDK. We typically use the nomenclature "SDK" to mean the client SDKs, not the module side bindings.
I fear that if we start referring to this as our C++ SDK this will both confuse users and confuse the LLM training especially if we add a C++ client SDK in the future. If you want feedback from the team on this it might be a good topic to bring up during standup.
Let me know when you're ready for another pass, I'm really excited that this seems like it's working so far and I'm excited for the future with C++26! 🙂
crates/bindings-cpp/QUICKSTART.md
Outdated
|
|
||
| SpacetimeDB C++ uses a unique accessor pattern: | ||
| - `ctx.db[table_name]` - Access table for iteration and basic operations | ||
| - `ctx.db[table_field]` - Access indexed fields for optimized operations (generated symbol named `tableName_fieldName`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a bit weird, shouldn't it be something like this instead:
ctx.db[table_name].table_field
What if 2 tables have the same indexed field name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh yeah this is still confusing, it is ctx.db[table_name_and_field_name] with how the accessors get generated. Maybe I change it to?
- `ctx.db[table]` - Access table for iteration and basic operations, eg. ctx.db[user]
- `ctx.db[table_field]` - Access indexed fields for optimized operations, eg. ctx.db[user_id]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made the change and going to leave this comment open as it might not be good enough yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the goal is to simply clarify how it currently works, my personal preference towards camelCase:
- `ctx.db[tableName]` - Access table for iteration and basic operations, eg. ctx.db[user]
- `ctx.db[tableName_fieldName]` - Access indexed fields for optimized operations, eg. ctx.db[user_id]
This is because it allows it to be clear that we are specifically referring to the name of a given table/field, while also not adding any additional special characters, like underscore, that is present in snake_case. The extra underscore get confusing when those are also used as the table to field delimiters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback I like that and it's in!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is fine with me for now - is this something we can fix with C++26?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% certain to be honest, the proposal for reflection in C++ 26 doesn't have full code injection, it should help with metaprogramming but I need to play with it before I know if I can resolve this completely to make it more in the style of: ctx.db.user.id or ctx.db.user().id().
Co-authored-by: John Detter <[email protected]> Signed-off-by: Jason Larabie <[email protected]>
Co-authored-by: John Detter <[email protected]> Signed-off-by: Jason Larabie <[email protected]>
…abs/SpacetimeDB into jlarabie/bindings-cpp
rekhoff
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM. I very much wish we could use C++26, but given our options, I think the current implementation makes sense. I've reviewed the documentation, skimmed the code, and done some simple local testing. I'd love more eyes on this from core team members, but am happy to sign off approval.
…ter() to return a clean iterator for all use cases Updated delete_all to work with datastore_delete_by_index_scan_point_bsatn and function correctly
|
Quick update - I didn't love the implementation for the iterator on filter() I had a mix of different uses and was going to move the read-write index to use the same pattern as the View/Multicolumn as the version from Arvikasoft was materializing the entire iterator into a vector. I really hate the devex of that pattern though as you have to manually loop through the iterator so I've added a small wrapper to make this more clean to go from: for (auto iter = ctx.db[score_points].filter(range_from(300));
iter != IndexIterator<Score>(); ++iter) {
const auto& score = *iter;
}To: for (const auto& score : ctx.db[score_points].filter(range_from(300)) {
} |
|
@JasonAtClockwork I would take a look at this CI failure, I think it's unlikely that it's a flake because it seems pretty consistent. It might be something introduced by this PR: |
jdetter
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested this at least with the basic quickstart doc and everything seems to be working. I also looked back and did another pass on the comments that I put down - let me know if you need me to take another look at anything.
I have not done a nit-pick review on the code here since there is quite a lot but I have skimmed it and haven't found anything too concerning. I think it would be better to do a UX review when we go through the follow-up docs PRs anyway. Please request my review when those are ready as well.
Thanks Jason, this is great 👍
gefjon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've only looked at the procedure-related stuff in here, but it looks great - much better than I expected, to be honest. Thanks for all your hard work on this!
joshua-spacetime
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The view code looks correct. sender is a method in the 2.0 rust module api. But as I understand it, this is not meant to be 2.0 compliant. Also this does not include the query builder which will be added separately.

Description of Changes
This adds C++ server bindings (/crate/bindings-cpp) to allow writing C++ 20 modules.
API and ABI breaking changes
None
Expected complexity level and risk
2 - Doesn't heavily impact any other areas but is complex macro C++ structure to support a similar developer experience, did have a small impact on init command
Testing