Class: PgGraph::Reflector
- Inherits:
-
Object
- Object
- PgGraph::Reflector
- Defined in:
- lib/pg_graph/reflector.rb
Constant Summary collapse
- REFLECTIONS_SCHEMA =
"public"
- REFLECTIONS_TABLE =
"reflections"
Class Method Summary collapse
- .default_reflections ⇒ Object
- .default_reflections=(reflections) ⇒ Object
- .load_file(file, default_reflections: Reflector.default_reflections) ⇒ Object
- .load_table(conn, schema = nil, table = nil, default_reflections: Reflector.default_reflections) ⇒ Object
- .load_yaml(yaml_array, default_reflections: Reflector.default_reflections) ⇒ Object
Instance Method Summary collapse
-
#add(*reflections) ⇒ Object
New reflections are inserted as a block at the head of the list of reflections.
- #dup ⇒ Object
-
#empty? ⇒ Boolean
Return true if the Reflector has no reflections.
-
#initialize(reflections = [], default_reflections: Reflector.default_reflections) ⇒ Reflector
constructor
A new instance of Reflector.
- #multi?(uid) ⇒ Boolean
-
#reflections ⇒ Object
Reflections ordered from most-specific to least-specific and newest to oldest.
- #save_table(conn, schema = nil, table = nil) ⇒ Object
-
#that(uid, unique, multi = false, table: nil) ⇒ Object
Find ‘that’ field name for the given UID by searching through reflections for a match.
-
#this(uid) ⇒ Object
Find ‘that’ field name for the given UID by searching through reflections for a match.
- #to_yaml ⇒ Object
Constructor Details
#initialize(reflections = [], default_reflections: Reflector.default_reflections) ⇒ Reflector
Returns a new instance of Reflector.
115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/pg_graph/reflector.rb', line 115 def initialize(reflections = [], default_reflections: Reflector.default_reflections) constrain reflections, [Reflection] # @reflection maps from number of reflection components to list of reflections. The # keys are initially created in descending to ensure that #values return # lists of components sorted from most to least specific. New reflections # are inserted at the beginning of the lists to make it possible to # override ealier reflections @reflections = {} (1..4).to_a.reverse.each { |components| @reflections[components] = [] } add(default_reflections || []) add(reflections) end |
Class Method Details
.default_reflections ⇒ Object
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/pg_graph/reflector.rb', line 222 def self.default_reflections @default_reflections ||= begin initializers = [ {"match"=>"/parent_id/", "that"=>"child"}, {"match"=>"/child_id/", "that"=>"parent"}, {"match"=>"/parent_(\\w+)_id/", "that"=>"child_$1"}, {"match"=>"/child_(\\w+)_id/", "that"=>"parent_$1"}, {"match"=>"kind", "this"=>"kind", "that"=>"$$"}, {"match"=>"/(\\w+)_kind/", "this"=>"$1", "that"=>"$$"}, {"match"=>"/(\\w+)_by_id/", "this"=>"$1_by", "that"=>"$1_$$", pluralize: true}, {"match"=>"/(\\w+)_id/", "this"=>"$1", "that"=>"$$", multi: false}, {"match"=>"/(\\w+)_id/", "this"=>"$1", "that"=>"$1_of", multi: true, pluralize: false}, {"match"=>"/(\\w+)/", "this"=>"$1", "that"=>"$$"}, # Kind fields w/o explicit 'kind' ] initializers.map { |initializer| Reflection.load_yaml initializer.merge(default_reflection: true) } end end |
.default_reflections=(reflections) ⇒ Object
242 243 244 |
# File 'lib/pg_graph/reflector.rb', line 242 def self.default_reflections=(reflections) @default_reflections = reflections end |
.load_file(file, default_reflections: Reflector.default_reflections) ⇒ Object
184 185 186 |
# File 'lib/pg_graph/reflector.rb', line 184 def self.load_file(file, default_reflections: Reflector.default_reflections) load_yaml YAML.load(IO.read(file)), default_reflections: default_reflections end |
.load_table(conn, schema = nil, table = nil, default_reflections: Reflector.default_reflections) ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/pg_graph/reflector.rb', line 188 def self.load_table(conn, schema = nil, table = nil, default_reflections: Reflector.default_reflections) schema ||= REFLECTIONS_SCHEMA table ||= REFLECTIONS_TABLE if conn.schema.exist?(schema) && conn.schema.exist_table?(schema, table) yaml = conn.structs(%( select match, this, that, multi, pluralize, false as "default_reflection" from #{schema}.#{table} order by ordinal )).map(&:to_h) else yaml = {} end load_yaml yaml, default_reflections: default_reflections end |
.load_yaml(yaml_array, default_reflections: Reflector.default_reflections) ⇒ Object
179 180 181 182 |
# File 'lib/pg_graph/reflector.rb', line 179 def self.load_yaml(yaml_array, default_reflections: Reflector.default_reflections) reflections = yaml_array.map { |hash| Reflection.load_yaml(hash) } Reflector.new(reflections, default_reflections: default_reflections) end |
Instance Method Details
#add(*reflections) ⇒ Object
New reflections are inserted as a block at the head of the list of reflections
137 138 139 140 141 142 143 |
# File 'lib/pg_graph/reflector.rb', line 137 def add(*reflections) @reflection_list = nil # reverse makes it possible to use #insert but keep order: Array(reflections).flatten.reverse.each { |reflection| @reflections[reflection.components].insert(0, reflection) } end |
#dup ⇒ Object
128 |
# File 'lib/pg_graph/reflector.rb', line 128 def dup() Reflector.new(reflections.dup) end |
#empty? ⇒ Boolean
Return true if the Reflector has no reflections
131 132 133 |
# File 'lib/pg_graph/reflector.rb', line 131 def empty?() @reflection_list ? reflections.empty? : !@reflections.values.all?(:empty?) end |
#multi?(uid) ⇒ Boolean
171 172 173 |
# File 'lib/pg_graph/reflector.rb', line 171 def multi?(uid) reflection = reflections.find { |reflection| reflection.re.match(uid) }&.multi == false end |
#reflections ⇒ Object
Reflections ordered from most-specific to least-specific and newest to oldest
110 111 112 113 |
# File 'lib/pg_graph/reflector.rb', line 110 def reflections() # assumes @reflection keys are created in descending order @reflection_list ||= @reflections.values.flatten end |
#save_table(conn, schema = nil, table = nil) ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/pg_graph/reflector.rb', line 203 def save_table(conn, schema = nil, table = nil) schema ||= REFLECTIONS_SCHEMA table ||= REFLECTIONS_TABLE self.class.ensure_table(conn, schema, table) values = reflections.select { |r| !r.default_reflection }.map.with_index { |reflection, i| values = "(" + Reflection::METHODS.map { |m| v = reflection.send(m) v.nil? ? "null" : "'#{v}'" }.join(", ") + ", #{i})" }.join(",\n") conn.exec %( insert into #{schema}.#{table} (match, this, that, multi, pluralize, default_reflection, ordinal) values #{values} ) end |
#that(uid, unique, multi = false, table: nil) ⇒ Object
Find ‘that’ field name for the given UID by searching through reflections for a match. The name is pluralized if the matcher returns true or if the matcher returns nil and unique is false. The :table option can be used to override the table name in ‘$$’ rules. This is used in N:M and M:M relations. Returns false if the :that property is set to false in the reflections file. Returns nil if no match was found or if a matching reflection has #continue equal to false
160 161 162 163 164 165 166 167 168 169 |
# File 'lib/pg_graph/reflector.rb', line 160 def that(uid, unique, multi = false, table: nil) constrain uid, String if (name, pluralize = do_match(uid, :that, multi, table: table)) if pluralize.nil? && !unique || pluralize PgGraph.inflector.pluralize(name) else name end end end |
#this(uid) ⇒ Object
Find ‘that’ field name for the given UID by searching through reflections for a match. Returns nil if no match was found or if a matching reflection has #continue equal to false
148 149 150 151 |
# File 'lib/pg_graph/reflector.rb', line 148 def this(uid) constrain uid, String do_match(uid, :this)&.first end |
#to_yaml ⇒ Object
175 176 177 |
# File 'lib/pg_graph/reflector.rb', line 175 def to_yaml reflections.map { |reflection| reflection.to_yaml } end |