Class: Og::Manager
- Inherits:
-
Object
- Object
- Og::Manager
- Defined in:
- lib/og/manager.rb,
lib/og/evolution.rb
Overview
A Manager defines the relations between entities, ie objects managed by Og.
Defined Under Namespace
Classes: EntityInfo
Instance Attribute Summary collapse
-
#cache ⇒ Object
The managed object cache.
-
#entities ⇒ Object
The collection of Entities (managed classes) managed by this manager.
-
#options ⇒ Object
The configuration options.
-
#store ⇒ Object
The store used for persistence.
Class Method Summary collapse
Instance Method Summary collapse
-
#dump(options = {}) ⇒ Object
(also: #export)
Dump Og managed objects to the filesystem.
-
#get_store ⇒ Object
(also: #store, #conn)
Get a store from the pool.
-
#initialize(options) ⇒ Manager
constructor
A new instance of Manager.
-
#load(options = {}) ⇒ Object
(also: #import, #evolve)
Load Og managed objects from the filesystem.
-
#manage(klass) ⇒ Object
Manage a class.
-
#manage_classes(*classes) ⇒ Object
(also: #manage_class)
Manage a collection of classes.
-
#manageable?(klass) ⇒ Boolean
Is this class manageable by Og? – FIXME: investigate this (polymorphic/unmanageable).
-
#manageable_classes ⇒ Object
Use Ruby’s advanced reflection features to find all manageable classes.
-
#managed?(klass) ⇒ Boolean
(also: #entity?)
Is the class managed by Og?.
-
#managed_classes ⇒ Object
Returns an array containing all classes managed by this manager.
-
#post_setup ⇒ Object
Allows functionality that requires a store is finalized to be implemented.
-
#put_store ⇒ Object
Return a store to the pool.
-
#resolve_polymorphic(klass) ⇒ Object
Resolve polymorphic relations.
- #unmanage_classes(*classes) ⇒ Object (also: #unmanage_class)
Constructor Details
#initialize(options) ⇒ Manager
Returns a new instance of Manager.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/og/manager.rb', line 56 def initialize() @options = @entities = {} @pool = Pool.new @store_class = Store.for_name([:store]) @store_class.destroy() if [:destroy] @store_class.destroy_tables() if [:destroy_tables] if Og.thread_safe ([:connection_count] || 5).times do @pool << @store_class.new() end else @store = @store_class.new() end end |
Instance Attribute Details
#cache ⇒ Object
The managed object cache. This cache is optional. When used it improves object lookups.
54 55 56 |
# File 'lib/og/manager.rb', line 54 def cache @cache end |
#entities ⇒ Object
The collection of Entities (managed classes) managed by this manager.
49 50 51 |
# File 'lib/og/manager.rb', line 49 def entities @entities end |
#options ⇒ Object
The configuration options.
39 40 41 |
# File 'lib/og/manager.rb', line 39 def @options end |
#store=(value) ⇒ Object
The store used for persistence. This is a virtual field when running in thread_safe mode.
44 45 46 |
# File 'lib/og/manager.rb', line 44 def store=(value) @store = value end |
Class Method Details
.managed?(klass) ⇒ Boolean
19 20 21 |
# File 'lib/og/manager.rb', line 19 def self.managed?(klass) self.managers.any? { |m| m.managed? klass } end |
.managers ⇒ Object
13 14 15 16 17 |
# File 'lib/og/manager.rb', line 13 def self.managers managers = [] ObjectSpace.each_object(self) { |o| managers << o } managers end |
Instance Method Details
#dump(options = {}) ⇒ Object Also known as: export
Dump Og managed objects to the filesystem.
14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/og/evolution.rb', line 14 def dump( = {}) classes = [:classes] || [:class] || manageable_classes basedir = [:basedir] || 'ogdump' FileUtils.makedirs(basedir) for c in [ classes ].flatten Logger.info "Dumping class '#{c}'" all = c.all.map { |obj| obj.properties_to_hash } File.open("#{basedir}/#{c}.yml", 'w') { |f| f << all.to_yaml } end end |
#get_store ⇒ Object Also known as: store, conn
Get a store from the pool.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/og/manager.rb', line 76 def get_store if Og.thread_safe thread = Thread.current unless st = thread[:og_store] and st.is_a?(@store_class) st = @pool.pop() thread[:og_store] = st end return st else return @store end end |
#load(options = {}) ⇒ Object Also known as: import, evolve
Load Og managed objects from the filesystem. This method can apply optional transformation rules in order to evolve a schema.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/og/evolution.rb', line 31 def load( = {}) classes = [:classes] || manageable_classes basedir = [:basedir] || 'ogdump' rules = [:rules] || rules[:evolution] || {} classes.each { |c| c.destroy if managed?(c) } unmanage_classes(classes) manage_classes for f in Dir["#{basedir}/*.yml"] all = YAML.load(File.read(f)) unless all.empty? klass = f.split(/\/|\./)[1] Logger.info "Loading class '#{klass}'" if krules = rules[klass.to_sym] if krules[:self] # Class name changed. Logger.info "Renaming class '#{klass}' to '#{krules[:self]}'" klass = krules[:self] end Logger.info "Evolution transformation will be applied!" end klass = constant(klass) for h in all obj = klass.allocate obj.assign_with(h) if krules krules.each do |old, new| obj.instance_variable_set "@#{new}", h[old] end end obj.insert end end end end |
#manage(klass) ⇒ Object
Manage a class. Converts the class to an Entity.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/og/manager.rb', line 114 def manage(klass) return if managed?(klass) or klass.ancestors.include?(Unmanageable) info = EntityInfo.new(klass) # DON'T DO THIS!!! klass.module_eval %{ def ==(other) other.instance_of?(#{klass}) ? @#{klass.primary_key.symbol} == other.#{klass.primary_key.symbol} : false end } klass.class.send(:attr_accessor, :ogmanager) klass.instance_variable_set '@ogmanager', self Relation.enchant(klass) # ensure that the superclass is managed before the # subclass. manage(klass.superclass) if manageable?(klass.superclass) # FIXME: uggly! store.enchant(klass, self); put_store # Call special class enchanting code. klass.enchant if klass.respond_to?(:enchant) @entities[klass] = info end |
#manage_classes(*classes) ⇒ Object Also known as: manage_class
Manage a collection of classes.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/og/manager.rb', line 187 def manage_classes(*classes) classes = manageable_classes.flatten # if classes.empty? FIXME! classes.each { |c| Relation.resolve_targets(c) } classes.each { |c| Relation.resolve_polymorphic_markers(c) } classes.each { |c| Relation.resolve_polymorphic_relations(c) } # The polymorpic resolution step creates more manageable classes. classes = manageable_classes.flatten # if classes.empty? FIXME! Logger.debug "Og manageable classes: #{classes.inspect}" if $DBG classes.each { |c| Relation.resolve_targets(c) } classes.each { |c| Relation.resolve_names(c) } classes.each { |c| manage(c) } end |
#manageable?(klass) ⇒ Boolean
Is this class manageable by Og? – FIXME: investigate this (polymorphic/unmanageable). ++
152 153 154 |
# File 'lib/og/manager.rb', line 152 def manageable?(klass) klass.respond_to?(:properties) and (!klass.properties.empty?) # and !self.class.managed?(klass) # and klass.ann.self.polymorphic.nil? end |
#manageable_classes ⇒ Object
Use Ruby’s advanced reflection features to find all manageable classes. Managable are all classes that define Properties.
173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/og/manager.rb', line 173 def manageable_classes classes = [] ObjectSpace.each_object(Class) do |c| if manageable?(c) classes << c end end return classes end |
#managed?(klass) ⇒ Boolean Also known as: entity?
Is the class managed by Og?
158 159 160 |
# File 'lib/og/manager.rb', line 158 def managed?(klass) @entities.include?(klass) end |
#managed_classes ⇒ Object
Returns an array containing all classes managed by this manager.
165 166 167 |
# File 'lib/og/manager.rb', line 165 def managed_classes @entities.map {|e| e[0]} end |
#post_setup ⇒ Object
Allows functionality that requires a store is finalized to be implemented. A vastly superior method of constructing foreign key constraints is an example of functionality this provides. Currently only used by the PostgreSQL store. Another good use for this would be an alternate table and field creation routine, which could be much faster, something I intend to do to the PostgreSQL store if nobody has reasons for objecting.
224 225 226 |
# File 'lib/og/manager.rb', line 224 def post_setup store.post_setup if store.respond_to?(:post_setup) end |
#put_store ⇒ Object
Return a store to the pool.
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/og/manager.rb', line 95 def put_store if Og.thread_safe thread = Thread.current if conn = thread[:og_store] thread[:og_store] = nil return @pool.push(conn) end end end |
#resolve_polymorphic(klass) ⇒ Object
Resolve polymorphic relations.
108 109 110 |
# File 'lib/og/manager.rb', line 108 def resolve_polymorphic(klass) Relations.resolve_polymorphic(klass) end |
#unmanage_classes(*classes) ⇒ Object Also known as: unmanage_class
206 207 208 209 210 211 212 |
# File 'lib/og/manager.rb', line 206 def unmanage_classes(*classes) classes = manageable_classes.flatten if classes.empty? for c in classes @entities.delete_if { |k, v| v.klass == c } end end |