Skip to content

Commit

Permalink
Merge pull request #1355 from fnc12/bigfux/fk-with-inheritance
Browse files Browse the repository at this point in the history
added column_pointer support to fk
  • Loading branch information
fnc12 authored Nov 9, 2024
2 parents 2ce3dcf + 9a7a760 commit cf82e1e
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
6 changes: 6 additions & 0 deletions dev/constraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "error_code.h"
#include "table_type_of.h"
#include "type_printer.h"
#include "column_pointer.h"

namespace sqlite_orm {

Expand Down Expand Up @@ -375,6 +376,11 @@ namespace sqlite_orm {
foreign_key_t<std::tuple<Cs...>, std::tuple<Rs...>> references(Rs... refs) {
return {std::move(this->columns), {std::forward<Rs>(refs)...}};
}

template<class T, class... Rs>
foreign_key_t<std::tuple<Cs...>, std::tuple<internal::column_pointer<T, Rs>...>> references(Rs... refs) {
return {std::move(this->columns), {sqlite_orm::column<T>(refs)...}};
}
};
#endif

Expand Down
7 changes: 7 additions & 0 deletions include/sqlite_orm/sqlite_orm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3191,6 +3191,8 @@ namespace sqlite_orm {

// #include "type_printer.h"

// #include "column_pointer.h"

namespace sqlite_orm {

namespace internal {
Expand Down Expand Up @@ -3549,6 +3551,11 @@ namespace sqlite_orm {
foreign_key_t<std::tuple<Cs...>, std::tuple<Rs...>> references(Rs... refs) {
return {std::move(this->columns), {std::forward<Rs>(refs)...}};
}

template<class T, class... Rs>
foreign_key_t<std::tuple<Cs...>, std::tuple<internal::column_pointer<T, Rs>...>> references(Rs... refs) {
return {std::move(this->columns), {sqlite_orm::column<T>(refs)...}};
}
};
#endif

Expand Down
80 changes: 80 additions & 0 deletions tests/constraints/foreign_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,84 @@ TEST_CASE("Foreign key 2") {

storage.update(t2);
}

TEST_CASE("Foreign key with inheritance") {
struct Person {
int id;
std::string name;
int age;
};

// Define derived class Student
struct Student : public Person {
std::string school_name;

Student(int id, std::string name, int age, std::string school_name) :
Person{id, std::move(name), age}, school_name(std::move(school_name)) {}
};

// Define derived class Teacher
struct Teacher : public Person {
std::string subject;
double salary;

Teacher(int id, std::string name, int age, std::string subject, double salary) :
Person{id, std::move(name), age}, subject(subject), salary(salary) {}
};

// Define Classroom class referencing Teacher and Student
struct Classroom {
int id;
int teacher_id; // Foreign key referencing Teacher
int student_id; // Foreign key referencing Student
std::string room_name;
};

auto storage =
make_storage("",

// Define the Person table as a base, though it is not used directly
make_table<Person>("persons",
make_column("id", &Person::id, primary_key().autoincrement()),
make_column("name", &Person::name),
make_column("age", &Person::age)),

// Define the Student table with foreign key inheritance
make_table<Student>("students",
make_column("id", &Student::id, primary_key()),
make_column("name", &Student::name),
make_column("age", &Student::age),
make_column("school_name", &Student::school_name)),

// Define the Teacher table with foreign key inheritance
make_table<Teacher>("teachers",
make_column("id", &Teacher::id, primary_key()),
make_column("name", &Teacher::name),
make_column("age", &Teacher::age),
make_column("subject", &Teacher::subject),
make_column("salary", &Teacher::salary)),

// Define the Classroom table with foreign keys to Teacher and Student
make_table<Classroom>("classrooms",
make_column("id", &Classroom::id, primary_key().autoincrement()),
make_column("teacher_id", &Classroom::teacher_id),
make_column("student_id", &Classroom::student_id),
make_column("room_name", &Classroom::room_name),
foreign_key(&Classroom::teacher_id).references<Teacher>(&Teacher::id),
foreign_key(&Classroom::student_id).references<Student>(&Student::id)));
// Sync schema (create tables)
storage.sync_schema();

// Create and insert a Teacher record
Teacher teacher{0, "Mr. Smith", 45, "Mathematics", 55000.00};
int teacher_id = storage.insert(teacher);

// Create and insert a Student record
Student student = {0, "Alice", 20, "High School"};
int student_id = storage.insert(student);

// Create and insert a Classroom record with foreign keys
Classroom classroom = {0, teacher_id, student_id, "Room A"};
storage.insert(classroom);
}
#endif

0 comments on commit cf82e1e

Please sign in to comment.