-
-
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
base: dev
Are you sure you want to change the base?
Conversation
The if-condition used for filtering primary key columns must be the same at run-time as at compile-time.
... to the mapped object type, avoiding hard to read error messages later.
Up until this commit, the functions were referred to as "composite PK functions", although this actually always meant "table PK functions", regardless of whether they were single or composite primary keys defined at the table level.
* Improved understanding through legibility.
For proper type safety `storage_t<>::insert()` needs to return an `sqlite3_int64` instead of an `int`. This is the best way to correct the problem. Usually, compilers just accept narrowing type conversions, the nicest thing that can happen is a warning message, the worst is an error depending on compiler flags. The programmer has to handle the rest and it is the best thing to do anyway.
* Check column definition up front when making the column. * Renamed internal traits. * Removed unit test file `is_column_with_insertable_primary_key.cpp`. It became superfluous during the course of development in the past years. Column constraints are checked elsewhere already, and it is now only a duplicate of `is_primary_key_insertable.cpp`.
SQLite documentation clearly states that an auto-incrementable primary key column must be a 64-bit signed integer type.
337084c to
93a23fe
Compare
This approach keeps the previous way if all composite primary key columns have a default value, yet still enables inserting records if the table has composite primary key columns with only some or no default values.
* WITHOUT ROWID is only available since SQLite 3.8.2. * FTS5: consider that it can be explicitly enabled with `SQLITE_ORM_ENABLE_FTS5`. * Auxiliary virtual table columns are only available since SQLite 3.24.0. * Hidden virtual table columns have no version attached.
728b390 to
4007b1a
Compare
Only types that can represent a 64-bit signed integer - either integral or custom types - have the required properties to be an alias for the rowid and can cover the whole value range of it.
4007b1a to
0886bd5
Compare
| } | ||
|
|
||
| /** | ||
| * Checks whether contraints contain specified class template. |
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
| 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 |
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: g[u]arantee
| constexpr size_t nTablePrimaryKeyColumns = | ||
| nested_tuple_size_for_t<columns_tuple_t, elements_type, pk_index_sequence>::value; | ||
|
|
||
| static_assert(nTablePrimaryKeyColumns > 0, "Tabel primary key definition must contain one column"); |
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: Table not Tabel
|
|
||
| template<class O, class... Cols> | ||
| int insert(const O& o, columns_t<Cols...> cols) { | ||
| int64 insert(const O& o, columns_t<Cols...> cols) { |
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.
on man, it will produce a lot of warnings. I'd leave it like this just like it is done in Java (where almost all integer operations are handles by simple ints) for simplicity and if somebody wants to get more precise int64 result one can use last_insert_rowid() instead or use a prepared statement of insert. I mean this function int insert is a real legacy and I'd leave its signature like this just like the below one's
|
|
||
| struct DeptMaster { | ||
| int deptId = 0; | ||
| sqlite_orm::int64 deptId = 0; |
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.
what happens to this example if we skip this change?
| REQUIRE(get<1>(statement) == userPointers.end()); | ||
| storage.execute(statement); | ||
| } | ||
| SECTION("references") { |
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 type of sections is a really good shot
| primary_key(&A::getAddress, &A::getType, &A::getIndex))); | ||
| storage.sync_schema(); | ||
| storage.replace(A(1, 1, 0, std::make_shared<double>(55.5))); | ||
| storage.insert(A(1, 1, 0, std::make_shared<double>(55.5))); |
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 is a really good bug fix
Improvements:
Other improvements:
make_table().getquery statement.INTEGER.Fixes