Skip to content

Commit 93a23fe

Browse files
committed
Deprecated types other than 64-bit signed integer for autoincrement PKs
SQLite documentation clearly states that an auto-incrementable primary key column must be a 64-bit signed integer type.
1 parent dcc213f commit 93a23fe

File tree

28 files changed

+180
-130
lines changed

28 files changed

+180
-130
lines changed

dev/schema/column.h

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#pragma once
22

3+
#include <sqlite3.h> // sqlite_int64
34
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
45
#include <tuple> // std::tuple
56
#include <string> // std::string
67
#include <memory> // std::unique_ptr
7-
#include <type_traits> // std::is_same, std::is_member_object_pointer
8+
#include <type_traits> // std::enable_if, std::is_same, std::is_member_object_pointer, std::is_signed
89
#include <utility> // std::move
910
#endif
1011

@@ -165,22 +166,40 @@ namespace sqlite_orm {
165166
field_type_t,
166167
filter_tuple_sequence_t<Elements, mpl::disjunction_fn<is_column, is_hidden_column>::template fn>>;
167168

169+
// [Deprecation notice] For arithmetic types other than 64-bit signed integer, AUTOINCREMENT is deprecated on PRIMARY KEY columns and will be removed in v1.11
170+
template<class F, class SFINAE = void>
171+
struct check_pkcol {
172+
[[deprecated(
173+
R"(Use a 64-bit signed integer for AUTOINCREMENT on an INTEGER PRIMARY KEY as an alias for the "rowid" key)")]] static constexpr void
174+
validate_column_primary_key_with_autoincrement() {}
175+
};
176+
177+
// For 64-bit signed integer type: valid
178+
template<class F>
179+
struct check_pkcol<F,
180+
std::enable_if_t<sizeof(F) == sizeof(sqlite_int64) &&
181+
std::is_signed<F>::value == std::is_signed<sqlite_int64>::value>> {
182+
static constexpr void validate_column_primary_key_with_autoincrement() {}
183+
};
184+
185+
// For non-integer types: static_assert failure
186+
template<class F>
187+
struct check_pkcol<F, std::enable_if_t<!std::is_base_of<integer_printer, type_printer<F>>::value>> {
188+
static constexpr void validate_column_primary_key_with_autoincrement() {
189+
static_assert(
190+
polyfill::always_false_v<F>,
191+
R"(AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY as an alias for the "rowid" key)");
192+
}
193+
};
194+
168195
template<class G, class... Op>
169196
constexpr void validate_column_definition() {
170197
using constraints_type = std::tuple<Op...>;
171198

172199
static_assert(polyfill::conjunction_v<is_column_constraint<Op>...>, "Incorrect column constraints");
173200

174-
if constexpr (tuple_has<constraints_type, is_primary_key>::value) {
175-
using field_type = member_field_type_t<G>;
176-
using is_pkcol_correct = mpl::invoke_t<
177-
mpl::disjunction<mpl::always<std::is_base_of<integer_printer, type_printer<field_type>>>,
178-
mpl::not_<check_if_has_template<primary_key_with_autoincrement>>>,
179-
constraints_type>;
180-
181-
static_assert(
182-
is_pkcol_correct::value,
183-
R"(AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY as an alias for the "rowid" key)");
201+
if constexpr (tuple_has_template<constraints_type, primary_key_with_autoincrement>::value) {
202+
check_pkcol<member_field_type_t<G>>::validate_column_primary_key_with_autoincrement();
184203
}
185204
}
186205

examples/chrono_binding.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ using std::cout;
138138
using std::endl;
139139

140140
struct Person {
141-
int id;
141+
int64 id;
142142
std::string name;
143143
std::chrono::sys_days birthdate;
144144
};

examples/common_table_expressions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ void depth_or_breadth_first() {
526526

527527
void select_from_subselect() {
528528
struct Employee {
529-
int m_empno;
529+
int64 m_empno;
530530
std::string m_ename;
531531
double m_salary;
532532
std::optional<double> m_commission;

examples/except_intersection.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ using std::cout;
99
using std::endl;
1010

1111
struct DeptMaster {
12-
int deptId = 0;
12+
sqlite_orm::int64 deptId = 0;
1313
std::string deptName;
1414
};
1515

1616
struct EmpMaster {
17-
int empId = 0;
17+
sqlite_orm::int64 empId = 0;
1818
std::string firstName;
1919
std::string lastName;
2020
long salary;

examples/select.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,13 @@ void all_employees() {
127127

128128
void all_artists() {
129129
struct Artist {
130-
int id;
130+
int64 id;
131131
std::string name;
132132
};
133133

134134
struct Album {
135-
int id;
136-
int artist_id;
135+
int64 id;
136+
int64 artist_id;
137137
};
138138

139139
auto storage = make_storage("",
@@ -165,13 +165,13 @@ void all_artists() {
165165

166166
void named_adhoc_structs() {
167167
struct Artist {
168-
int id;
168+
int64 id;
169169
std::string name;
170170
};
171171

172172
struct Album {
173-
int id;
174-
int artist_id;
173+
int64 id;
174+
int64 artist_id;
175175
std::string name;
176176
};
177177

examples/self_join.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ using std::cout;
1515
using std::endl;
1616

1717
struct Employee {
18-
int employeeId;
18+
sqlite_orm::int64 employeeId;
1919
std::string lastName;
2020
std::string firstName;
2121
std::string title;

examples/unique.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ using std::cout;
99
using std::endl;
1010

1111
struct Entry {
12-
int id;
12+
sqlite_orm::int64 id;
1313
std::string uniqueColumn;
1414
std::unique_ptr<std::string> nullableColumn;
1515
};

include/sqlite_orm/sqlite_orm.h

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8917,11 +8917,12 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
89178917

89188918
// #include "schema/column.h"
89198919

8920+
#include <sqlite3.h> // sqlite_int64
89208921
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
89218922
#include <tuple> // std::tuple
89228923
#include <string> // std::string
89238924
#include <memory> // std::unique_ptr
8924-
#include <type_traits> // std::is_same, std::is_member_object_pointer
8925+
#include <type_traits> // std::enable_if, std::is_same, std::is_member_object_pointer, std::is_signed
89258926
#include <utility> // std::move
89268927
#endif
89278928

@@ -9129,22 +9130,40 @@ namespace sqlite_orm {
91299130
field_type_t,
91309131
filter_tuple_sequence_t<Elements, mpl::disjunction_fn<is_column, is_hidden_column>::template fn>>;
91319132

9133+
// [Deprecation notice] For arithmetic types other than 64-bit signed integer, AUTOINCREMENT is deprecated on PRIMARY KEY columns and will be removed in v1.11
9134+
template<class F, class SFINAE = void>
9135+
struct check_pkcol {
9136+
[[deprecated(
9137+
R"(Use a 64-bit signed integer for AUTOINCREMENT on an INTEGER PRIMARY KEY as an alias for the "rowid" key)")]] static constexpr void
9138+
validate_column_primary_key_with_autoincrement() {}
9139+
};
9140+
9141+
// For 64-bit signed integer type: valid
9142+
template<class F>
9143+
struct check_pkcol<F,
9144+
std::enable_if_t<sizeof(F) == sizeof(sqlite_int64) &&
9145+
std::is_signed<F>::value == std::is_signed<sqlite_int64>::value>> {
9146+
static constexpr void validate_column_primary_key_with_autoincrement() {}
9147+
};
9148+
9149+
// For non-integer types: static_assert failure
9150+
template<class F>
9151+
struct check_pkcol<F, std::enable_if_t<!std::is_base_of<integer_printer, type_printer<F>>::value>> {
9152+
static constexpr void validate_column_primary_key_with_autoincrement() {
9153+
static_assert(
9154+
polyfill::always_false_v<F>,
9155+
R"(AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY as an alias for the "rowid" key)");
9156+
}
9157+
};
9158+
91329159
template<class G, class... Op>
91339160
constexpr void validate_column_definition() {
91349161
using constraints_type = std::tuple<Op...>;
91359162

91369163
static_assert(polyfill::conjunction_v<is_column_constraint<Op>...>, "Incorrect column constraints");
91379164

9138-
if constexpr (tuple_has<constraints_type, is_primary_key>::value) {
9139-
using field_type = member_field_type_t<G>;
9140-
using is_pkcol_correct = mpl::invoke_t<
9141-
mpl::disjunction<mpl::always<std::is_base_of<integer_printer, type_printer<field_type>>>,
9142-
mpl::not_<check_if_has_template<primary_key_with_autoincrement>>>,
9143-
constraints_type>;
9144-
9145-
static_assert(
9146-
is_pkcol_correct::value,
9147-
R"(AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY as an alias for the "rowid" key)");
9165+
if constexpr (tuple_has_template<constraints_type, primary_key_with_autoincrement>::value) {
9166+
check_pkcol<member_field_type_t<G>>::validate_column_primary_key_with_autoincrement();
91489167
}
91499168
}
91509169

tests/constraints/foreign_key.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ TEST_CASE("Foreign key 2") {
133133

134134
TEST_CASE("Foreign key with inheritance") {
135135
struct Person {
136-
int id;
136+
int64 id;
137137
std::string name;
138138
int age;
139139
};
@@ -157,9 +157,9 @@ TEST_CASE("Foreign key with inheritance") {
157157

158158
// Define Classroom class referencing Teacher and Student
159159
struct Classroom {
160-
int id;
161-
int teacher_id; // Foreign key referencing Teacher
162-
int student_id; // Foreign key referencing Student
160+
int64 id;
161+
int64 teacher_id; // Foreign key referencing Teacher
162+
int64 student_id; // Foreign key referencing Student
163163
std::string room_name;
164164
};
165165

tests/operators/between.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using namespace sqlite_orm;
55

66
TEST_CASE("Between") {
77
struct Object {
8-
int id = 0;
8+
int64 id = 0;
99
};
1010

1111
auto storage =

0 commit comments

Comments
 (0)