| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- using Invercargill.DataStructures;
- using Invercargill.Mapping;
- namespace InvercargillSql.Orm {
-
- /**
- * Fluent builder for creating EntityMapper instances.
- *
- * This builder provides a type-safe, fluent API for configuring entity mappings.
- * It wraps a PropertyMapperBuilder<T> and adds ORM-specific metadata like
- * column definitions.
- *
- * Schema metadata (primary key, auto-increment, etc.) is discovered through
- * database introspection rather than being configured explicitly.
- *
- * Example usage:
- * {{{
- * var mapper = EntityMapper.build_for<User>(b => b
- * .table("users")
- * .column<int64>("id", u => u.id, (u, v) => u.id = v)
- * .column<string>("name", u => u.name, (u, v) => u.name = v)
- * .column<string>("email", u => u.email, (u, v) => u.email = v));
- * }}}
- */
- public class EntityMapperBuilder<T> : Object {
- private string? _table_name;
- private Vector<ColumnDefinition> _columns;
- private PropertyMapperBuilder<T> _mapper_builder;
-
- /**
- * Creates a new EntityMapperBuilder instance.
- */
- public EntityMapperBuilder() {
- _columns = new Vector<ColumnDefinition>();
- _mapper_builder = new PropertyMapperBuilder<T>();
- }
-
- /**
- * Sets the database table name for this entity.
- *
- * If not called, the entity type name will be used as the table name.
- *
- * @param name The table name in the database
- * @return This builder for method chaining
- */
- public EntityMapperBuilder<T> table(string name) {
- _table_name = name;
- return this;
- }
-
- /**
- * Adds a column mapping for a property.
- *
- * This method configures both the ORM column definition and the underlying
- * PropertyMapper mapping. It returns this EntityMapperBuilder for natural
- * method chaining.
- *
- * @param name The column name in the database
- * @param getter A function to get the property value from an entity
- * @param setter A function to set the property value on an entity
- * @return This builder for method chaining
- *
- * Example:
- * {{{
- * .column<int64>("id", u => u.id, (u, v) => u.id = v)
- * .column<string>("name", u => u.name, (u, v) => u.name = v)
- * }}}
- */
- public EntityMapperBuilder<T> column<TProp>(string name, owned PropertyGetter<T, TProp> getter, owned PropertySetter<T, TProp> setter) {
- var col_def = new ColumnDefinition() {
- name = name,
- column_type = ColumnType.from_gtype(typeof(TProp)) ?? ColumnType.TEXT
- };
- _columns.add(col_def);
-
- // Add to underlying PropertyMapper - transfer ownership of delegates
- var mapping_builder = _mapper_builder.map<TProp>(name, (owned)getter, (owned)setter);
-
- // Configure when_null handler to skip setting (leave property as default)
- // This allows the PropertyMapper to handle null values from the database gracefully
- mapping_builder.when_null((o) => { /* skip - leave property as default */ });
-
- // Configure when_undefined handler to skip setting (leave property as default)
- // This allows the PropertyMapper to handle partial property sets (e.g., back-populating only the PK)
- mapping_builder.when_undefined((o) => { /* skip - leave property as default */ });
-
- return this;
- }
-
- /**
- * Builds and returns the configured EntityMapper.
- *
- * @return A new EntityMapper instance with all configured mappings
- */
- public EntityMapper<T> build() {
- var mapper = new EntityMapper<T>();
- mapper.table_name = _table_name ?? typeof(T).name();
- mapper.property_mapper = _mapper_builder.build();
- mapper.columns = _columns;
- return mapper;
- }
-
- /**
- * Builds the EntityMapper with schema metadata from introspection.
- *
- * This internal method is used by OrmSession.register_with_schema<T>()
- * to apply discovered schema metadata to the mapper.
- *
- * @param schema The introspected table schema
- * @return A new EntityMapper instance with schema metadata applied
- */
- public EntityMapper<T> build_with_schema(TableSchema schema) {
- var mapper = build();
- mapper.table_schema = schema;
- mapper.primary_key_column = schema.primary_key_column;
- return mapper;
- }
- public string peek_table() {
- return _table_name;
- }
- }
- }
|