# Todo - move `prepare_*` methods from `dialect` to `query_compiler` - add `insert_query_builder` and `update_update_builder` (returning multiple statements) - finish fetch eager many-to-many relations - implement lazy loading - implement polymorphic class hierarchies - finish `database` (schema_repository) class (move add/drop from `session` to `schema`) - implement a flag class for enumerations - PK generator 1. Introduce execute_result 2. Add `abstract_pk_generator` class 3. Add `identity_pk_generator` class 4. Add `sequence_pk_generator` class 5. Add `table_pk_generator` class 6. Add `manual_pk_generator` class 7. Extend `session::insert` logic to use pk generator 8. Add generator to `schema_node` or `table` class when attaching type ```cpp struct abstract_pk_generator { virtual ~abstract_pk_generator() = default; virtual int64_t next_id() = 0; virtual std::vector next_ids(int count) = 0; }; struct sequence_pk_generator : abstract_pk_generator { explicit sequence_pk_generator(const std::string& sequence_name) : query_(query::query::select().nextval(sequence_name)) {} int64_t next_id(sql::executor& exec) override { return query_.fetch_value(exec); } std::vector next_ids(int count) override; private: query::fetchable_query query_; }; struct table_pk_generator : abstract_pk_generator { explicit table_pk_generator(const std::string& table_name); int64_t next_id() override; std::vector next_ids(int count) override; private: std::string table_name_; }; ``` __Proposal for polymorphic classes:__ object_ptr::as does the following checks; 1. The requested type has a super class 2. Super class has a discriminator column defined 3. Super class has a discriminator value defined 4. Discriminator value is mapped to the requested type If all checks succeed, the requested is fetched from the database. ```cpp schema.attach("payloads", make_polymorph("type")); schema.attach("id_list_payloads", {"IdPayload"}); schema.attach("id_payloads", {"IdListPayload"}); //schema.attach("id_list_payloads", make_polymorph_type("IdPayload")); //schema.attach("id_payloads", make_polymorph_type("IdListPayload")); object::object_ptr payload; auto result = payload.as(); if (result.is_ok()) { const auto& is_payload = result.value(); // Use requested type id_payload->id = 1; } payload.is_polymorphic(); payload.is_polymorphic_type(); ```