Skip to content

Commit 19a84fb

Browse files
authored
Merge pull request #1486 from Alvov1/feature/static-assert-get-pk-only
Add static_assert to get*, remove to reject non-pk arguments at compile time
2 parents 237b8e0 + 905edac commit 19a84fb

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

dev/storage.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ namespace sqlite_orm::internal {
392392
*/
393393
template<class O, class... Ids>
394394
void remove(Ids... ids) {
395+
static_assert((internal::is_bindable_v<Ids> && ...), "Only primary key values are accepted as Ids");
395396
this->assert_mapped_type<O>();
396397
auto statement = this->prepare(sqlite_orm::remove<O>(std::forward<Ids>(ids)...));
397398
this->execute(statement);
@@ -535,6 +536,7 @@ namespace sqlite_orm::internal {
535536
*/
536537
template<class O, class... Ids>
537538
O get(Ids... ids) {
539+
static_assert((internal::is_bindable_v<Ids> && ...), "Only primary key values are accepted as Ids");
538540
this->assert_mapped_type<O>();
539541
this->assert_primary_key_type<O>();
540542
auto statement = this->prepare(sqlite_orm::get<O>(std::forward<Ids>(ids)...));
@@ -554,6 +556,7 @@ namespace sqlite_orm::internal {
554556
*/
555557
template<class O, class... Ids>
556558
std::unique_ptr<O> get_pointer(Ids... ids) {
559+
static_assert((internal::is_bindable_v<Ids> && ...), "Only primary key values are accepted as Ids");
557560
this->assert_mapped_type<O>();
558561
this->assert_primary_key_type<O>();
559562
auto statement = this->prepare(sqlite_orm::get_pointer<O>(std::forward<Ids>(ids)...));
@@ -592,6 +595,7 @@ namespace sqlite_orm::internal {
592595
*/
593596
template<class O, class... Ids>
594597
std::optional<O> get_optional(Ids... ids) {
598+
static_assert((internal::is_bindable_v<Ids> && ...), "Only primary key values are accepted as Ids");
595599
this->assert_mapped_type<O>();
596600
this->assert_primary_key_type<O>();
597601
auto statement = this->prepare(sqlite_orm::get_optional<O>(std::forward<Ids>(ids)...));

include/sqlite_orm/sqlite_orm.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25388,6 +25388,7 @@ namespace sqlite_orm::internal {
2538825388
*/
2538925389
template<class O, class... Ids>
2539025390
void remove(Ids... ids) {
25391+
static_assert((internal::is_bindable_v<Ids> && ...), "Only primary key values are accepted as Ids");
2539125392
this->assert_mapped_type<O>();
2539225393
auto statement = this->prepare(sqlite_orm::remove<O>(std::forward<Ids>(ids)...));
2539325394
this->execute(statement);
@@ -25531,6 +25532,7 @@ namespace sqlite_orm::internal {
2553125532
*/
2553225533
template<class O, class... Ids>
2553325534
O get(Ids... ids) {
25535+
static_assert((internal::is_bindable_v<Ids> && ...), "Only primary key values are accepted as Ids");
2553425536
this->assert_mapped_type<O>();
2553525537
this->assert_primary_key_type<O>();
2553625538
auto statement = this->prepare(sqlite_orm::get<O>(std::forward<Ids>(ids)...));
@@ -25550,6 +25552,7 @@ namespace sqlite_orm::internal {
2555025552
*/
2555125553
template<class O, class... Ids>
2555225554
std::unique_ptr<O> get_pointer(Ids... ids) {
25555+
static_assert((internal::is_bindable_v<Ids> && ...), "Only primary key values are accepted as Ids");
2555325556
this->assert_mapped_type<O>();
2555425557
this->assert_primary_key_type<O>();
2555525558
auto statement = this->prepare(sqlite_orm::get_pointer<O>(std::forward<Ids>(ids)...));
@@ -25588,6 +25591,7 @@ namespace sqlite_orm::internal {
2558825591
*/
2558925592
template<class O, class... Ids>
2559025593
std::optional<O> get_optional(Ids... ids) {
25594+
static_assert((internal::is_bindable_v<Ids> && ...), "Only primary key values are accepted as Ids");
2559125595
this->assert_mapped_type<O>();
2559225596
this->assert_primary_key_type<O>();
2559325597
auto statement = this->prepare(sqlite_orm::get_optional<O>(std::forward<Ids>(ids)...));

tests/static_tests/get_pk_ids.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <sqlite_orm/sqlite_orm.h>
2+
#include <catch2/catch_all.hpp>
3+
4+
#include <type_traits> // std::is_same
5+
#include <memory> // std::unique_ptr, std::shared_ptr
6+
#include <string> // std::string
7+
#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED
8+
#include <optional> // std::optional
9+
#endif
10+
11+
using namespace sqlite_orm;
12+
13+
TEST_CASE("get* and remove accept bindable pk types") {
14+
struct User {
15+
int id = 0;
16+
std::string name;
17+
};
18+
19+
using Storage = decltype(make_storage(
20+
"",
21+
make_table("users", make_column("id", &User::id, primary_key()), make_column("name", &User::name))));
22+
23+
STATIC_REQUIRE(std::is_same_v<decltype(std::declval<Storage>().get<User>(std::declval<int>())), User>);
24+
25+
STATIC_REQUIRE(std::is_same_v<decltype(std::declval<Storage>().get_pointer<User>(std::declval<int>())),
26+
std::unique_ptr<User>>);
27+
28+
STATIC_REQUIRE(std::is_same_v<decltype(std::declval<Storage>().get_no_throw<User>(std::declval<int>())),
29+
std::shared_ptr<User>>);
30+
31+
#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED
32+
STATIC_REQUIRE(
33+
std::is_same_v<decltype(std::declval<Storage>().get_optional<User>(std::declval<int>())), std::optional<User>>);
34+
#endif
35+
36+
STATIC_REQUIRE(std::is_same_v<decltype(std::declval<Storage>().remove<User>(std::declval<int>())), void>);
37+
}

0 commit comments

Comments
 (0)