| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- using Invercargill.DataStructures;
- using InvercargillSql.Dialects;
- using InvercargillSql.Orm.Projections;
- namespace InvercargillSql.Orm {
-
- /**
- * Registry for entity mappers and projection definitions.
- *
- * TypeRegistry centralizes the registration and lookup of entity mappers
- * and projection definitions, allowing them to be shared across multiple
- * OrmSession instances if needed.
- *
- * Example usage:
- * {{{
- * var registry = new TypeRegistry();
- * registry.register_entity<User>(user_mapper);
- * registry.register_projection<UserSummary>(user_summary_definition);
- *
- * var session = new OrmSession(connection, dialect, registry);
- * }}}
- */
- public class TypeRegistry : Object, TypeProvider {
- private Dictionary<Type, EntityMapper> _mappers;
- private Dictionary<Type, ProjectionDefinition> _projection_registry;
-
- /**
- * Creates a new TypeRegistry instance.
- */
- public TypeRegistry() {
- _mappers = new Dictionary<Type, EntityMapper>();
- _projection_registry = new Dictionary<Type, ProjectionDefinition>();
- }
-
- /**
- * Registers an entity mapper for type T.
- *
- * @param mapper The entity mapper to register
- */
- public void register_entity<T>(EntityMapper<T> mapper) {
- _mappers.set(typeof(T), mapper);
- }
-
- /**
- * Registers an entity mapper with schema introspection for type T.
- *
- * This method introspects the database schema to discover primary keys,
- * auto-increment columns, and other metadata.
- *
- * @param table_name The database table name
- * @param connection The database connection for schema introspection
- * @param dialect The SQL dialect for schema introspection
- * @param build_action A function that configures the EntityMapperBuilder
- * @throws SqlError if schema introspection fails
- */
- public void register_with_schema<T>(
- string table_name,
- Connection connection,
- SqlDialect dialect,
- owned GLib.Func<EntityMapperBuilder<T>> build_action
- ) throws SqlError {
- var builder = new EntityMapperBuilder<T>();
- builder.table(table_name);
- build_action(builder);
-
- // Introspect schema and apply to mapper
- var schema = dialect.introspect_schema(connection, table_name);
- var mapper = builder.build_with_schema(schema);
-
- _mappers.set(typeof(T), mapper);
- }
-
- /**
- * Registers an entity mapper by Type.
- *
- * This is a non-generic version for advanced scenarios.
- *
- * @param type The entity type
- * @param mapper The entity mapper to register
- */
- public void register_entity_for_type(Type type, EntityMapper mapper) {
- _mappers.set(type, mapper);
- }
-
- /**
- * Gets the entity mapper for type T.
- *
- * @return The EntityMapper<T> for type T
- * @throws SqlError if no mapper is registered for type T
- */
- public EntityMapper<T> get_mapper<T>() throws SqlError {
- var mapper = _mappers.get_or_default(typeof(T)) as EntityMapper<T>;
- if (mapper == null) {
- throw new SqlError.GENERAL_ERROR("Entity type not registered: " + typeof(T).name());
- }
- return mapper;
- }
-
- /**
- * Gets the entity mapper for a type.
- *
- * This is a non-generic version that returns the base EntityMapper type.
- *
- * @param type The entity type to look up
- * @return The EntityMapper for the type, or null if not registered
- */
- public EntityMapper? get_mapper_for_type(Type type) {
- return _mappers.get_or_default(type);
- }
-
- /**
- * Checks if an entity mapper is registered for type T.
- *
- * @return true if a mapper is registered, false otherwise
- */
- public bool has_mapper<T>() {
- return _mappers.has(typeof(T));
- }
-
- /**
- * Checks if an entity mapper is registered for a type.
- *
- * @param type The entity type to check
- * @return true if a mapper is registered, false otherwise
- */
- public bool has_mapper_for_type(Type type) {
- return _mappers.has(type);
- }
-
- /**
- * Registers a projection definition for type T.
- *
- * @param definition The projection definition to register
- */
- public void register_projection<TProjection>(ProjectionDefinition definition) {
- _projection_registry.set(typeof(TProjection), definition);
- }
-
- /**
- * Registers a projection definition by Type.
- *
- * This is a non-generic version for advanced scenarios.
- *
- * @param type The projection type
- * @param definition The projection definition to register
- */
- public void register_projection_for_type(Type type, ProjectionDefinition definition) {
- _projection_registry.set(type, definition);
- }
-
- /**
- * Gets the projection definition for type T.
- *
- * @return The ProjectionDefinition for the type, or null if not registered
- */
- public ProjectionDefinition? get_projection<TProjection>() {
- return _projection_registry.get_or_default(typeof(TProjection));
- }
-
- /**
- * Gets the projection definition by type.
- *
- * @param type The projection type to look up
- * @return The ProjectionDefinition for the type, or null if not registered
- */
- public ProjectionDefinition? get_projection_for_type(Type type) {
- return _projection_registry.get_or_default(type);
- }
-
- /**
- * Checks if a projection is registered for type T.
- *
- * @return true if a projection is registered, false otherwise
- */
- public bool has_projection<T>() {
- return _projection_registry.has(typeof(T));
- }
-
- /**
- * Checks if a projection is registered for a type.
- *
- * @param type The projection type to check
- * @return true if a projection is registered, false otherwise
- */
- public bool has_projection_for_type(Type type) {
- return _projection_registry.has(type);
- }
- }
- }
|