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
-
#close_store ⇒ Object
used when changing thread_safe mode.
-
#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.
- #initialize_store ⇒ Object (also: #init_store)
-
#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?.
-
#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.
61 62 63 64 65 66 67 68 69 |
# File 'lib/og/manager.rb', line 61 def initialize() @options = @entities = {} @store_class = Store.for_name([:store]) @store_class.destroy() if [:destroy] @store_class.destroy_tables() if [:destroy_tables] init_store end |
Instance Attribute Details
#cache ⇒ Object
The managed object cache. This cache is optional. When used it improves object lookups.
59 60 61 |
# File 'lib/og/manager.rb', line 59 def cache @cache end |
#entities ⇒ Object
The collection of Entities (managed classes) managed by this manager.
54 55 56 |
# File 'lib/og/manager.rb', line 54 def entities @entities end |
#options ⇒ Object
The configuration options.
44 45 46 |
# File 'lib/og/manager.rb', line 44 def @options end |
#store=(value) ⇒ Object
The store used for persistence. This is a virtual field when running in thread_safe mode.
49 50 51 |
# File 'lib/og/manager.rb', line 49 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 |
.managed_classes ⇒ Object
23 24 25 26 |
# File 'lib/og/manager.rb', line 23 def self.managed_classes managed = self.managers.collect {|m| m.managed_classes} managed.flatten 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 } return managers end |
Instance Method Details
#close_store ⇒ Object
used when changing thread_safe mode
89 90 91 92 93 94 95 96 97 |
# File 'lib/og/manager.rb', line 89 def close_store if @pool.empty? @store.close else @pool.each { |s| s.close } @pool.clear end @pool = nil end |
#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.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/og/manager.rb', line 101 def get_store if @pool thread = Thread.current unless st = thread[:og_store] and st.is_a?(@store_class) if 0 == @pool.size() initialize_store() end st = @pool.pop() thread[:og_store] = st end return st else return @store end end |
#initialize_store ⇒ Object Also known as: init_store
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/og/manager.rb', line 71 def initialize_store if @pool close_store end if Og.thread_safe @pool = Pool.new ([:connection_count] || 5).times do @pool << @store_class.new(@options) end else @store = @store_class.new(@options) 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.
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/og/manager.rb', line 142 def manage(klass) return if managed?(klass) or Og.unmanageable_classes.include?(klass) 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.
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/og/manager.rb', line 218 def manage_classes(*classes) classes = manageable_classes.flatten # if classes.empty? FIXME! classes = classes.reject { |c| self.class.managed?(c) } 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! classes = classes.reject { |c| self.class.managed?(c) } 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?
Unmanageable classes include classes:
-
without properties
-
explicitly marked as Unmanageable (is Og::Unamanageable)
-
are polymorphic_parents (ie thay are used to spawn polymorphic relations)
182 183 184 |
# File 'lib/og/manager.rb', line 182 def manageable?(klass) klass.respond_to?(:properties) and (!klass.properties.empty?) and (!Og.unmanageable_classes.include?(klass)) and (!klass.polymorphic_parent?) end |
#manageable_classes ⇒ Object
Use Ruby’s advanced reflection features to find all manageable classes. Managable are all classes that define Properties.
203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/og/manager.rb', line 203 def manageable_classes classes = [] # for c in Property.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?
188 189 190 |
# File 'lib/og/manager.rb', line 188 def managed?(klass) @entities.include?(klass) end |
#managed_classes ⇒ Object
Returns an array containing all classes managed by this manager.
195 196 197 |
# File 'lib/og/manager.rb', line 195 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.
257 258 259 |
# File 'lib/og/manager.rb', line 257 def post_setup store.post_setup if store.respond_to?(:post_setup) end |
#put_store ⇒ Object
Return a store to the pool.
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/og/manager.rb', line 123 def put_store if @pool 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.
136 137 138 |
# File 'lib/og/manager.rb', line 136 def resolve_polymorphic(klass) Relations.resolve_polymorphic(klass) end |
#unmanage_classes(*classes) ⇒ Object Also known as: unmanage_class
239 240 241 242 243 244 245 |
# File 'lib/og/manager.rb', line 239 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 |