Module: Familia::DataType::Connection
- Includes:
- Connection::Behavior
- Included in:
- Familia::DataType
- Defined in:
- lib/familia/data_type/connection.rb
Overview
Connection - Instance-level connection and key generation methods
This module provides instance methods for database connection resolution and Redis key generation for DataType objects. It includes shared connection behavior from Familia::Connection::Behavior, enabling transaction and pipeline support for both parent-owned and standalone DataType objects.
Key features:
- Database connection resolution with Chain of Responsibility pattern
- Redis key generation based on parent context
- Direct database access for advanced operations
- Transaction support (MULTI/EXEC) for atomic operations
- Pipeline support for batched command execution
- Parent delegation for owned DataType objects
- Standalone connection management for independent DataType objects
Connection Chain Priority:
- FiberTransactionHandler - Active transaction context
- FiberConnectionHandler - Fiber-local connections
- ProviderConnectionHandler - User-defined connection provider
- ParentDelegationHandler - Delegate to parent object (primary for owned DataTypes)
- StandaloneConnectionHandler - Independent DataType connection
Instance Method Summary collapse
-
#dbclient(uri = nil) ⇒ Redis
Retrieves a Database connection using the Chain of Responsibility pattern.
-
#dbkey ⇒ String
Produces the full dbkey for this object.
-
#direct_access {|Redis, String| ... } ⇒ Object
Provides a structured way to "gear down" to run db commands that are not implemented in our DataType classes since we intentionally don't have a method_missing method.
-
#uri ⇒ URI?
Returns the effective URI this DataType will use for connections.
Methods included from Connection::Behavior
#connect, #create_dbclient, #multi, #normalize_uri, #pipeline, #pipelined, #transaction, #uri=, #url, #url=
Instance Method Details
#dbclient(uri = nil) ⇒ Redis
Retrieves a Database connection using the Chain of Responsibility pattern
Implements connection resolution optimized for DataType usage patterns:
- Fast path check for active transaction context
- Full connection chain for comprehensive resolution
- Parent delegation as primary behavior for owned DataTypes
- Standalone connection handling for independent DataTypes
Note: We don't cache the connection chain in an instance variable because DataType objects are frozen for thread safety. Building the chain is cheap (just creating handler objects), and the actual connection resolution work is done by the handlers themselves.
102 103 104 105 106 107 108 |
# File 'lib/familia/data_type/connection.rb', line 102 def dbclient(uri = nil) # Fast path for transaction context (highest priority) return Fiber[:familia_transaction] if Fiber[:familia_transaction] # Build connection chain (not cached due to frozen objects) build_connection_chain.handle(uri) end |
#dbkey ⇒ String
Produces the full dbkey for this object.
This method determines the appropriate dbkey based on the context of the DataType object:
- If a hardcoded key is set in the options, it returns that key.
- For instance-level DataType objects, it uses the parent instance's dbkey method.
- For class-level DataType objects, it uses the parent class's dbkey method.
- For standalone DataType objects, it uses the keystring as the full dbkey.
For class-level DataType objects (parent_class? == true):
- The suffix is optional and used to differentiate between different types of objects.
- If no suffix is provided, the class's default suffix is used (via the self.suffix method).
- If a nil suffix is explicitly passed, it won't appear in the resulting dbkey.
- Passing nil as the suffix is how class-level DataType objects are created without the global default 'object' suffix.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/familia/data_type/connection.rb', line 140 def dbkey # Return the hardcoded key if it's set. This is useful for # support legacy keys that aren't derived in the same way. return opts[:dbkey] if opts[:dbkey] if parent_instance? # This is an instance-level datatype object so the parent instance's # dbkey method is defined in Familia::Horreum::InstanceMethods. parent.dbkey(keystring) elsif parent_class? # This is a class-level datatype object so the parent class' dbkey # method is defined in Familia::Horreum::DefinitionMethods. parent.dbkey(keystring, nil) else # This is a standalone DataType object where it's keystring # is the full database key (dbkey). keystring end end |
#direct_access {|Redis, String| ... } ⇒ Object
Provides a structured way to "gear down" to run db commands that are not implemented in our DataType classes since we intentionally don't have a method_missing method.
Enhanced to work seamlessly with transactions and pipelines. When called within a transaction or pipeline context, uses that connection automatically.
183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/familia/data_type/connection.rb', line 183 def direct_access if Fiber[:familia_transaction] # Already in transaction, use that connection yield(Fiber[:familia_transaction], dbkey) elsif Fiber[:familia_pipeline] # Already in pipeline, use that connection yield(Fiber[:familia_pipeline], dbkey) else yield(dbclient, dbkey) end end |
#uri ⇒ URI?
Returns the effective URI this DataType will use for connections
For parent-owned DataTypes, delegates to parent's URI. For standalone DataTypes with logical_database option, constructs URI with that database. For standalone DataTypes without options, returns global Familia.uri. Explicit @uri assignment (via uri=) takes precedence.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/familia/data_type/connection.rb', line 61 def uri return @uri if defined?(@uri) && @uri return parent.uri if parent && parent.respond_to?(:uri) # Check opts[:logical_database] first, then parent's logical_database db_num = opts[:logical_database] db_num ||= parent.logical_database if parent && parent.respond_to?(:logical_database) if db_num # Create a new URI with the database number but without custom port # This ensures consistent URI representation (e.g., redis://host/db not redis://host:port/db) base_uri = Familia.uri URI.parse("redis://#{base_uri.host}/#{db_num}") else Familia.uri end end |