diff --git a/docs/flatten.md b/docs/flatten.md new file mode 100644 index 0000000..308cc92 --- /dev/null +++ b/docs/flatten.md @@ -0,0 +1,84 @@ +# `sqlgen::Flatten` + +The `sqlgen::Flatten` class provides a way to compose database tables by embedding one struct within another, while maintaining a flat database schema. It's particularly useful for creating normalized database structures while keeping a clean C++ interface. + +## Usage + +### Basic Definition + +Define nested structures and use `Flatten` to compose them: + +```cpp +struct Person { + sqlgen::PrimaryKey id; + std::string first_name; + std::string last_name; + int age; +}; + +struct Employee { + static constexpr const char* tablename = "EMPLOYEES"; + + sqlgen::Flatten person; + float salary; +}; +``` + +This generates a flat SQL schema where the `Person` fields are directly embedded in the `EMPLOYEES` table: + +```sql +CREATE TABLE IF NOT EXISTS "EMPLOYEES"( + "id" INTEGER NOT NULL, + "first_name" TEXT NOT NULL, + "last_name" TEXT NOT NULL, + "age" INTEGER NOT NULL, + "salary" REAL NOT NULL, + PRIMARY KEY("id") +); +``` + +### Assignment and Access + +Assign values to flattened fields: + +```cpp +const auto employee = Employee{ + .person = Person{ + .id = 1, + .first_name = "Homer", + .last_name = "Simpson", + .age = 45 + }, + .salary = 60000.0 +}; +``` + +Access the nested fields directly: + +```cpp +// Access nested fields +employee.person().first_name; // "Homer" +employee.person().age; // 45 +employee.salary; // 60000.0 +``` + +### Reading and Writing + +Use `Flatten` with `sqlgen::read` and `sqlgen::write` operations: + +```cpp +const auto conn = sqlgen::sqlite::connect(); + +// Write flattened data +sqlgen::write(conn, std::vector{employee}); + +// Read flattened data +const auto employees = sqlgen::read>(conn).value(); +``` + +## Notes + +- `Flatten` is implemented as an alias to `rfl::Flatten`, leveraging the reflection capabilities of reflect-cpp +- The flattened fields are stored directly in the parent table, maintaining a normalized database structure +- When using `Flatten`, the nested struct's fields are treated as if they were direct fields of the parent struct +- Primary keys and other SQL constraints from nested structs are preserved in the generated schema