-
-
Notifications
You must be signed in to change notification settings - Fork 341
Correcting ordinary insert statement for tables with composite primary keys #1468
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
Open
trueqbit
wants to merge
21
commits into
dev
Choose a base branch
from
fix/insert-without-rowid
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
10ce490
Fixed handling composite primary key columns for tables without rowid
trueqbit 0706a7b
Unit tests for insertions into tables without rowid and compound PKs
trueqbit 64bfce4
Check up front whether type of range to insert or replace is convertible
trueqbit f1f81fa
Removed the period after static assert messages, according to the pre…
trueqbit 871b134
Unit test for serializing for insert statements involving a primary key
trueqbit dac555b
Moved cpp guard that enables testing projected range insertions
trueqbit 9d93093
Same compiler warning options for GNU as for Clang for unit tests
trueqbit df79495
Renamed functions dealing with the table primary key
trueqbit 2534b1b
Omit only single primary key columns in insert statements
trueqbit d359eb4
Renamed auxiliary function testing whether a primary key contains a c…
trueqbit ebae237
Addressed a compiler error that occurred with msvc 141
trueqbit 0de1671
Validate primary key requirements up front
trueqbit aeb72b5
Improved filter for excluding columns during serialization
trueqbit 030d0e7
Returned the properly typed last inserted rowid
trueqbit dcc213f
Improved column primary key checks
trueqbit 93a23fe
Deprecated types other than 64-bit signed integer for autoincrement PKs
trueqbit 9e65e40
Ordinary insert statement skips primary key columns with a default value
trueqbit 9eaf678
Fixed pre-C++23 if constexpr expression
trueqbit 4791366
Corrected CPP guards for some SQLite features
trueqbit ae205d2
Taking into account that the rowid key might represented by a custom …
trueqbit 0886bd5
Deprecated types other than 64-bit signed integer for single-column PKs
trueqbit File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,19 @@ | ||
| #pragma once | ||
|
|
||
| #include <sqlite3.h> // sqlite_int64 | ||
| #ifndef SQLITE_ORM_IMPORT_STD_MODULE | ||
| #include <tuple> // std::tuple | ||
| #include <string> // std::string | ||
| #include <memory> // std::unique_ptr | ||
| #include <type_traits> // std::is_same, std::is_member_object_pointer | ||
| #include <type_traits> // std::enable_if, std::is_same, std::is_member_object_pointer, std::is_signed | ||
| #include <utility> // std::move | ||
| #endif | ||
|
|
||
| #include "../functional/cxx_type_traits_polyfill.h" | ||
| #include "../tuple_helper/tuple_traits.h" | ||
| #include "../tuple_helper/tuple_filter.h" | ||
| #include "../type_traits.h" | ||
| #include "../member_traits/member_traits.h" | ||
| #include "../type_traits.h" | ||
| #include "../type_is_nullable.h" | ||
| #include "../constraints.h" | ||
|
|
||
|
|
@@ -84,6 +85,14 @@ namespace sqlite_orm { | |
| return tuple_has<constraints_type, Trait>::value; | ||
| } | ||
|
|
||
| /** | ||
| * Checks whether contraints contain specified class template. | ||
| */ | ||
| template<template<class...> class Primary> | ||
| constexpr static bool is_template() { | ||
| return tuple_has_template<constraints_type, Primary>::value; | ||
| } | ||
|
|
||
| /** | ||
| * Simplified interface for `DEFAULT` constraint | ||
| * @return string representation of default value if it exists otherwise nullptr | ||
|
|
@@ -165,19 +174,65 @@ namespace sqlite_orm { | |
| field_type_t, | ||
| filter_tuple_sequence_t<Elements, mpl::disjunction_fn<is_column, is_hidden_column>::template fn>>; | ||
|
|
||
| #if SQLITE_VERSION_NUMBER >= 3031000 | ||
| // Custom type: programmer's responsibility to garantee data integrity in the value range of a 64-bit signed integer | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo: g[u]arantee |
||
| template<class F, class SFINAE = void> | ||
| struct check_pkcol { | ||
| static constexpr void validate_column_primary_key_with_autoincrement() {} | ||
| }; | ||
|
|
||
| // For integer types: further checks | ||
| template<class F> | ||
| struct check_pkcol<F, std::enable_if_t<std::is_integral<F>::value>> { | ||
| // For 64-bit signed integer type: valid | ||
| template<class X = F, | ||
| std::enable_if_t<sizeof(X) == sizeof(sqlite_int64) && | ||
| std::is_signed<X>::value == std::is_signed<sqlite_int64>::value, | ||
| bool> = true> | ||
| static constexpr void validate_column_primary_key_with_autoincrement() {} | ||
|
|
||
| // [Deprecation notice] For integral types other than 64-bit signed integer, AUTOINCREMENT is deprecated on PRIMARY KEY columns | ||
| // and will be turned into a static_assert failure in v1.11 | ||
| template<class X = F, | ||
| std::enable_if_t<sizeof(X) != sizeof(sqlite_int64) || | ||
| std::is_signed<X>::value != std::is_signed<sqlite_int64>::value, | ||
| bool> = true> | ||
| [[deprecated( | ||
| R"(Use a 64-bit signed integer for AUTOINCREMENT on an INTEGER PRIMARY KEY as an alias for the "rowid" key)")]] static constexpr void | ||
| validate_column_primary_key_with_autoincrement() {} | ||
| }; | ||
|
|
||
| // For non-integer types: static_assert failure | ||
| template<class F> | ||
| struct check_pkcol<F, std::enable_if_t<!std::is_base_of<integer_printer, type_printer<F>>::value>> { | ||
| static constexpr void validate_column_primary_key_with_autoincrement() { | ||
| static_assert( | ||
| polyfill::always_false_v<F>, | ||
| R"(AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY as an alias for the "rowid" key)"); | ||
| } | ||
| }; | ||
|
|
||
| template<class G, class... Op> | ||
| constexpr void validate_column_definition() { | ||
| using constraints_type = std::tuple<Op...>; | ||
|
|
||
| static_assert(polyfill::conjunction_v<is_column_constraint<Op>...>, "Incorrect column constraints"); | ||
|
|
||
| if constexpr (tuple_has_template<constraints_type, primary_key_with_autoincrement>::value) { | ||
| check_pkcol<member_field_type_t<G>>::validate_column_primary_key_with_autoincrement(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Factory function for a column definition from a member object pointer for hidden virtual table columns. | ||
| */ | ||
| template<class M, class... Op, satisfies<std::is_member_object_pointer, M> = true> | ||
| hidden_column<M, empty_setter, Op...> make_hidden_column(std::string name, M memberPointer, Op... constraints) { | ||
| static_assert(polyfill::conjunction_v<is_column_constraint<Op>...>, "Incorrect constraints pack"); | ||
| static_assert(polyfill::conjunction_v<is_column_constraint<Op>...>, "Incorrect column constraints"); | ||
|
|
||
| // attention: do not use `std::make_tuple()` for constructing the tuple member `[[no_unique_address]] column_constraints::constraints`, | ||
| // as this will lead to UB with Clang on MinGW! | ||
| return {std::move(name), memberPointer, {}, std::tuple<Op...>{std::move(constraints)...}}; | ||
| } | ||
| #endif | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -188,7 +243,7 @@ SQLITE_ORM_EXPORT namespace sqlite_orm { | |
| template<class M, class... Op, internal::satisfies<std::is_member_object_pointer, M> = true> | ||
| internal::column_t<M, internal::empty_setter, Op...> | ||
| make_column(std::string name, M memberPointer, Op... constraints) { | ||
| static_assert(polyfill::conjunction_v<internal::is_column_constraint<Op>...>, "Incorrect constraints pack"); | ||
| internal::validate_column_definition<M, Op...>(); | ||
|
|
||
| // attention: do not use `std::make_tuple()` for constructing the tuple member `[[no_unique_address]] column_constraints::constraints`, | ||
| // as this will lead to UB with Clang on MinGW! | ||
|
|
@@ -206,7 +261,7 @@ SQLITE_ORM_EXPORT namespace sqlite_orm { | |
| internal::column_t<G, S, Op...> make_column(std::string name, S setter, G getter, Op... constraints) { | ||
| static_assert(std::is_same<internal::setter_field_type_t<S>, internal::getter_field_type_t<G>>::value, | ||
| "Getter and setter must get and set same data type"); | ||
| static_assert(polyfill::conjunction_v<internal::is_column_constraint<Op>...>, "Incorrect constraints pack"); | ||
| internal::validate_column_definition<G, Op...>(); | ||
|
|
||
| // attention: do not use `std::make_tuple()` for constructing the tuple member `[[no_unique_address]] column_constraints::constraints`, | ||
| // as this will lead to UB with Clang on MinGW! | ||
|
|
@@ -224,7 +279,7 @@ SQLITE_ORM_EXPORT namespace sqlite_orm { | |
| internal::column_t<G, S, Op...> make_column(std::string name, G getter, S setter, Op... constraints) { | ||
| static_assert(std::is_same<internal::setter_field_type_t<S>, internal::getter_field_type_t<G>>::value, | ||
| "Getter and setter must get and set same data type"); | ||
| static_assert(polyfill::conjunction_v<internal::is_column_constraint<Op>...>, "Incorrect constraints pack"); | ||
| internal::validate_column_definition<G, Op...>(); | ||
|
|
||
| // attention: do not use `std::make_tuple()` for constructing the tuple member `[[no_unique_address]] column_constraints::constraints`, | ||
| // as this will lead to UB with Clang on MinGW! | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
typo: con[s]traints