Class: DagMe::Configuration
- Inherits:
-
Object
- Object
- DagMe::Configuration
- Defined in:
- lib/dag_me/configuration.rb
Constant Summary collapse
- MAINTAIN_MODES =
%i[postgresql_closure recursive_cte].freeze
Instance Attribute Summary collapse
-
#edge_table ⇒ Object
readonly
Returns the value of attribute edge_table.
-
#maintain ⇒ Object
readonly
Returns the value of attribute maintain.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#paths_table ⇒ Object
readonly
Returns the value of attribute paths_table.
-
#prefix ⇒ Object
readonly
Returns the value of attribute prefix.
-
#schema ⇒ Object
readonly
Returns the value of attribute schema.
-
#scope_columns ⇒ Object
readonly
Returns the value of attribute scope_columns.
Instance Method Summary collapse
- #adapter ⇒ Object
-
#association_name(base) ⇒ Object
children / power_children, dag_child_edges / power_dag_child_edges, ...
- #closure? ⇒ Boolean
- #composite_pk? ⇒ Boolean
-
#default? ⇒ Boolean
The unnamed dag from a bare
dag_mecall. - #edge_child_columns ⇒ Object
- #edge_class ⇒ Object
-
#edge_class_name ⇒ Object
Task::DagEdge for the default dag, Relay::PowerDagEdge for dag_me :power.
-
#edge_parent_columns ⇒ Object
Graph column names, one per pk column.
-
#function_ref(suffix) ⇒ Object
Schema-qualified reference for a generated function ("ai.skill_dag_lock").
-
#initialize(model:, name: nil, maintain: :postgresql_closure, scope: nil, prefix: nil, edge_table: nil, paths_table: nil) ⇒ Configuration
constructor
A new instance of Configuration.
-
#node_pk_columns ⇒ Object
Node identity as an ordered column list.
- #node_pk_type(column) ⇒ Object
- #node_table ⇒ Object
- #paths_ancestor_columns ⇒ Object
- #paths_class ⇒ Object
- #paths_class_name ⇒ Object
- #paths_descendant_columns ⇒ Object
-
#qualify(identifier) ⇒ Object
"skill_dag_edges" -> "ai.skill_dag_edges" when the node table lives in a named schema; identity otherwise.
- #scope_column_type(column) ⇒ Object
-
#trigger_name(suffix) ⇒ Object
Trigger names are plain identifiers; placement comes from ON
.
Constructor Details
#initialize(model:, name: nil, maintain: :postgresql_closure, scope: nil, prefix: nil, edge_table: nil, paths_table: nil) ⇒ Configuration
Returns a new instance of Configuration.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
# File 'lib/dag_me/configuration.rb', line 9 def initialize(model:, name: nil, maintain: :postgresql_closure, scope: nil, prefix: nil, edge_table: nil, paths_table: nil) unless MAINTAIN_MODES.include?(maintain) raise ArgumentError, "maintain must be one of #{MAINTAIN_MODES.inspect}, got #{maintain.inspect}" end @model = model @name = name&.to_sym @maintain = maintain @scope_columns = Array(scope).map(&:to_sym).freeze # Schema-qualified node tables ("ai.skills") keep the prefix a plain # identifier - trigger and temp-table names cannot carry a schema - and # place generated tables and functions in the node table's schema. @schema, base_table = split_schema(model.table_name) # A custom prefix keeps generated identifiers under PostgreSQL's 63-byte # limit when the derived one (long table names) would silently truncate. @prefix = prefix&.to_s || [base_table.singularize, @name, 'dag'].compact.join('_') validate_prefix! @edge_table = edge_table || qualify("#{@prefix}_edges") @paths_table = paths_table || qualify("#{@prefix}_paths") # Ivar peek keeps class load DB-free; composite keys must be declared # before the macro. Array === because AR seeds a BasicObject sentinel. @composite_pk = model.instance_variable_defined?(:@primary_key) && Array === model.instance_variable_get(:@primary_key) # rubocop:disable Style/CaseEquality end
Instance Attribute Details
#edge_table ⇒ Object (readonly)
Returns the value of attribute edge_table.
7 8 9
# File 'lib/dag_me/configuration.rb', line 7 def edge_table @edge_table end
#maintain ⇒ Object (readonly)
Returns the value of attribute maintain.
7 8 9
# File 'lib/dag_me/configuration.rb', line 7 def maintain @maintain end
#model ⇒ Object (readonly)
Returns the value of attribute model.
7 8 9
# File 'lib/dag_me/configuration.rb', line 7 def model @model end
#name ⇒ Object (readonly)
Returns the value of attribute name.
7 8 9
# File 'lib/dag_me/configuration.rb', line 7 def name @name end
#paths_table ⇒ Object (readonly)
Returns the value of attribute paths_table.
7 8 9
# File 'lib/dag_me/configuration.rb', line 7 def paths_table @paths_table end
#prefix ⇒ Object (readonly)
Returns the value of attribute prefix.
7 8 9
# File 'lib/dag_me/configuration.rb', line 7 def prefix @prefix end
#schema ⇒ Object (readonly)
Returns the value of attribute schema.
7 8 9
# File 'lib/dag_me/configuration.rb', line 7 def schema @schema end
#scope_columns ⇒ Object (readonly)
Returns the value of attribute scope_columns.
7 8 9
# File 'lib/dag_me/configuration.rb', line 7 def scope_columns @scope_columns end
Instance Method Details
#adapter ⇒ Object
134 135 136 137 138 139 140
# File 'lib/dag_me/configuration.rb', line 134 def adapter @adapter ||= if closure? Adapters::PostgresqlClosure.new(self) else Adapters::RecursiveCte.new(self) end end
#association_name(base) ⇒ Object
children / power_children, dag_child_edges / power_dag_child_edges, ...
80 81 82
# File 'lib/dag_me/configuration.rb', line 80 def association_name(base) default? ? base.to_sym : :"#{name}_#{base}" end
#closure? ⇒ Boolean
35 36 37
# File 'lib/dag_me/configuration.rb', line 35 def closure? maintain == :postgresql_closure end
#composite_pk? ⇒ Boolean
84 85 86
# File 'lib/dag_me/configuration.rb', line 84 def composite_pk? @composite_pk end
#default? ⇒ Boolean
The unnamed dag from a bare
dag_mecall. Named dags come fromdag_me :powerand get name-prefixed tables, constants, and associations so several graphs can coexist on one model.58 59 60
# File 'lib/dag_me/configuration.rb', line 58 def default? name.nil? end
#edge_child_columns ⇒ Object
114 115 116
# File 'lib/dag_me/configuration.rb', line 114 def edge_child_columns @edge_child_columns ||= role_columns('child') end
#edge_class ⇒ Object
71 72 73
# File 'lib/dag_me/configuration.rb', line 71 def edge_class model.const_get(edge_class_name) end
#edge_class_name ⇒ Object
Task::DagEdge for the default dag, Relay::PowerDagEdge for dag_me :power.
63 64 65
# File 'lib/dag_me/configuration.rb', line 63 def edge_class_name default? ? 'DagEdge' : "#{name.to_s.camelize}DagEdge" end
#edge_parent_columns ⇒ Object
Graph column names, one per pk column. Single-key models keep the classic parent_id / child_id / ancestor_id / descendant_id regardless of the pk's actual name; composite keys suffix each key column.
110 111 112
# File 'lib/dag_me/configuration.rb', line 110 def edge_parent_columns @edge_parent_columns ||= role_columns('parent') end
#function_ref(suffix) ⇒ Object
Schema-qualified reference for a generated function ("ai.skill_dag_lock").
46 47 48
# File 'lib/dag_me/configuration.rb', line 46 def function_ref(suffix) qualify("#{prefix}_#{suffix}") end
#node_pk_columns ⇒ Object
Node identity as an ordered column list. Single-key models yield one column and everything downstream degenerates to the classic layout.
94 95 96 97 98 99 100 101 102 103 104 105
# File 'lib/dag_me/configuration.rb', line 94 def node_pk_columns @node_pk_columns ||= if composite_pk? model.primary_key.map(&:to_s).freeze else pk = model.primary_key if pk.is_a?(Array) raise ArgumentError, "#{model.name}: declare `self.primary_key = [...]` before calling dag_me" end [pk.to_s].freeze end end
#node_pk_type(column) ⇒ Object
126 127 128
# File 'lib/dag_me/configuration.rb', line 126 def node_pk_type(column) model.columns_hash.fetch(column.to_s).sql_type end
#node_table ⇒ Object
88 89 90
# File 'lib/dag_me/configuration.rb', line 88 def node_table model.table_name end
#paths_ancestor_columns ⇒ Object
118 119 120
# File 'lib/dag_me/configuration.rb', line 118 def paths_ancestor_columns @paths_ancestor_columns ||= role_columns('ancestor') end
#paths_class ⇒ Object
75 76 77
# File 'lib/dag_me/configuration.rb', line 75 def paths_class model.const_get(paths_class_name) end
#paths_class_name ⇒ Object
67 68 69
# File 'lib/dag_me/configuration.rb', line 67 def paths_class_name default? ? 'DagPath' : "#{name.to_s.camelize}DagPath" end
#paths_descendant_columns ⇒ Object
122 123 124
# File 'lib/dag_me/configuration.rb', line 122 def paths_descendant_columns @paths_descendant_columns ||= role_columns('descendant') end
#qualify(identifier) ⇒ Object
"skill_dag_edges" -> "ai.skill_dag_edges" when the node table lives in a named schema; identity otherwise.
41 42 43
# File 'lib/dag_me/configuration.rb', line 41 def qualify(identifier) schema ? "#{schema}.#{identifier}" : identifier end
#scope_column_type(column) ⇒ Object
130 131 132
# File 'lib/dag_me/configuration.rb', line 130 def scope_column_type(column) model.columns_hash.fetch(column.to_s).sql_type end
#trigger_name(suffix) ⇒ Object
Trigger names are plain identifiers; placement comes from ON
.
51 52 53
# File 'lib/dag_me/configuration.rb', line 51 def trigger_name(suffix) "#{prefix}_#{suffix}" end