A Manager manages Models. Each Manager is attched to a single Store. Multiple Managers can exist in the same Og application.
- close_store
- dump
- export
- get_store
- import
- init_store
- initialize_store
- load
- manage
- manage_class
- manage_classes
- manageable?
- manageable_classes
- managed?
- managed?
- managed_classes
- managed_classes
- managers
- new
- post_setup
- put_store
- resolve_polymorphic
- unmanage_class
- unmanage_classes
- with_store
| [RW] | cache | The managed object cache. This cache is optional. When used it improves object lookups. |
| [RW] | models | The collection of Models (managed classes) managed by this manager. |
| [RW] | name | The name of this manager. Useful in the multiple managers scenario. |
| [RW] | options | The configuration options. |
| [RW] | store | The store used for persistence. This is a virtual field when running in thread_safe mode. |
Is the given class managed by any manager?
[ show source ]
# File lib/og/manager.rb, line 289
289: def managed?(klass)
290: self.managers.any? { |m| m.managed? klass }
291: end
Remove the classes managed by all managers.
[ show source ]
# File lib/og/manager.rb, line 295
295: def managed_classes
296: managed = self.managers.collect {|m| m.managed_classes}
297: managed.flatten
298: end
Return all managers defined in this application.
[ show source ]
# File lib/og/manager.rb, line 281
281: def managers
282: managers = []
283: ObjectSpace.each_object(self) { |o| managers << o }
284: return managers
285: end
Initialize the manager.
Options
:store, :adapter = the adapter/store to use as backend.
[ show source ]
# File lib/og/manager.rb, line 46
46: def initialize(options)
47: @options = options
48: @name = options[:name]
49: @models = []
50:
51: @store_class = Adapter.for_name(options[:adapter] || options[:store])
52: @store_class.allocate.destroy_db(options) if Og.destroy_schema || options[:destroy]
53:
54: init_store()
55: end
Used when changing thread_safe mode
[ show source ]
# File lib/og/manager.rb, line 79
79: def close_store
80: unless @pool
81: @store.close
82: else
83: @pool.each { |s| s.close }
84: @pool.clear
85: end
86: @pool = nil
87: end
Dump Og managed objects to the filesystem.
[ show source ]
# File lib/og/dump.rb, line 14
14: def dump(options = {})
15: classes = options[:classes] || options[:class] || manageable_classes
16: basedir = options[:basedir] || 'ogdump'
17:
18: FileUtils.makedirs(basedir)
19:
20: for c in [ classes ].flatten
21: Logger.info "Dumping class '#{c}'"
22: all = c.all.map { |obj| obj.properties_to_hash }
23: File.open("#{basedir}/#{c}.yml", 'w') { |f| f << all.to_yaml }
24: end
25: end
Alias for #dump
Get a store from the pool. The pool is thread safe and blocks if it is empty.
[ show source ]
# File lib/og/manager.rb, line 92
92: def get_store
93: if @pool
94: @pool.pop
95: else
96: @store
97: end
98: end
Alias for #load
Alias for #initialize_store
Initialize a store.
[ show source ]
# File lib/og/manager.rb, line 59
59: def initialize_store
60: if @pool
61: close_store
62: end
63:
64: if Og.thread_safe
65: @pool = Pool.new
66: (options[:connection_count] || 5).times do
67: @pool << @store_class.new(@options)
68: @pool.last.ogmanager = self
69: end
70: else
71: @store = @store_class.new(@options)
72: @store.ogmanager = self
73: end
74: end
Load Og managed objects from the filesystem. This method can apply optional transformation rules in order to evolve a schema.
[ show source ]
# File lib/og/dump.rb, line 31
31: def load(options = {})
32: classes = options[:classes] || manageable_classes
33: basedir = options[:basedir] || 'ogdump'
34: rules = options[:rules] || rules[:evolution] || {}
35:
36: classes.each { |c| c.destroy if managed?(c) }
37: unmanage_classes(classes)
38: manage_classes
39:
40: for f in Dir["#{basedir}/*.yml"]
41: all = YAML.load(File.read(f))
42:
43: unless all.empty?
44: klass = f.split(/\/|\./)[1]
45:
46: Logger.info "Loading class '#{klass}'"
47:
48: if krules = rules[klass.to_sym]
49: if krules[:self]
50: # Class name changed.
51: Logger.info "Renaming class '#{klass}' to '#{krules[:self]}'"
52: klass = krules[:self]
53: end
54:
55: Logger.info "Evolution transformation will be applied!"
56: end
57:
58: klass = constant(klass)
59:
60: for h in all
61: obj = klass.allocate
62: obj.assign_with(h)
63: if krules
64: krules.each do |old, new|
65: obj.instance_variable_set "@#{new}", h[old]
66: end
67: end
68: obj.insert
69: end
70: end
71: end
72: end
Manage a class. Injects Og related functionality to the class.
[ show source ]
# File lib/og/manager.rb, line 126
126: def manage(klass)
127: return if managed?(klass) or (!manageable?(klass))
128:
129: # Check if the class has a :text key.
130:
131: for a in klass.serializable_attributes
132: if klass.ann(a, :key)
133: klass.ann(:self, :text_key => a)
134: break
135: end
136: end
137:
138: # DON'T DO THIS!!!
139: #--
140: # gmosx: this is used though, dont remove without recoding
141: # some stuff.
142: #++
143:
144: klass.module_eval %{
145: def ==(other)
146: other.instance_of?(#{klass}) ? @#{klass.primary_key} == other.#{klass.primary_key} : false
147: end
148: }
149:
150: klass.class.send(:attr_accessor, :ogmanager)
151: klass.instance_variable_set '@ogmanager', self
152:
153: # FIXME: move somewhere else.
154:
155: klass.define_force_methods
156:
157: Relation.enchant(klass)
158:
159: # ensure that the superclass is managed before the
160: # subclass.
161:
162: manage(klass.superclass) if manageable?(klass.superclass)
163:
164: # Perform store related enchanting.
165:
166: with_store do |s|
167: s.enchant(klass, self)
168: end
169:
170: # Call special class enchanting code.
171:
172: klass.enchant if klass.respond_to?(:enchant)
173: @models.push(klass).uniq!
174: end
Alias for #manage_classes
Manage a collection of classes.
[ show source ]
# File lib/og/manager.rb, line 220
220: def manage_classes(*classes)
221: classes.flatten!
222: classes.compact!
223:
224: mc = self.class.managed_classes
225:
226: classes = manageable_classes.flatten if classes.empty?
227: classes = classes.reject { |c| mc.member?(c) || !manageable?(c) }
228:
229: sc = @store_class.allocate
230:
231: classes.each { |c| sc.force_primary_key(c) }
232: classes.each { |c| Relation.resolve_targets(c) }
233: classes.each { |c| Relation.resolve_polymorphic_markers(c) }
234:
235: # The polymorpic resolution step creates more manageable classes.
236:
237: classes += classes.map {|c| Relation.resolve_polymorphic_relations(c) }
238:
239: classes.flatten!
240:
241: classes = classes.reject { |c| !c or self.class.managed?(c) }
242:
243: Logger.debug "Og manageable classes: #{classes.inspect}" if $DBG
244:
245: classes.each { |c| Relation.resolve_targets(c) }
246: classes.each { |c| Relation.resolve_names(c) }
247: classes.each { |c| manage(c) }
248: end
Is this class manageable by Og?
Unmanageable classes include classes:
- without serializable attributes
- explicitly marked as Unmanageable (is Og::Unamanageable)
- are polymorphic_parents (ie thay are used to spawn polymorphic relations)
[ show source ]
# File lib/og/manager.rb, line 183
183: def manageable?(klass)
184: (klass.respond_to?(:serializable_attributes)) and
185: (!klass.serializable_attributes.empty?) and
186: (!Og.unmanageable_classes.include?(klass)) and
187: (!klass.polymorphic_parent?)
188: end
Use Ruby’s advanced reflection features to find all manageable classes. Managable are all classes that define Properties.
[ show source ]
# File lib/og/manager.rb, line 206
206: def manageable_classes
207: classes = []
208:
209: ObjectSpace.each_object(Class) do |c|
210: if manageable?(c)
211: classes << c
212: end
213: end
214:
215: return classes
216: end
Is the class managed by Og?
[ show source ]
# File lib/og/manager.rb, line 192
192: def managed?(klass)
193: @models.include?(klass)
194: end
Returns an array containing all classes managed by this manager.
[ show source ]
# File lib/og/manager.rb, line 198
198: def managed_classes
199: @models
200: end
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.
[ show source ]
# File lib/og/manager.rb, line 271
271: def post_setup
272: with_store do |s|
273: s.post_setup if s.respond_to?(:post_setup)
274: end
275: end
Return a store to the pool.
[ show source ]
# File lib/og/manager.rb, line 102
102: def put_store(store)
103: if @pool and store
104: @pool.push(store)
105: end
106: end
Resolve polymorphic relations.
[ show source ]
# File lib/og/manager.rb, line 119
119: def resolve_polymorphic(klass)
120: Relations.resolve_polymorphic(klass)
121: end
Alias for #unmanage_classes
Do not manage the given classes.
[ show source ]
# File lib/og/manager.rb, line 253
253: def unmanage_classes(*classes)
254: classes = manageable_classes.flatten if classes.empty?
255:
256: for c in classes
257: @models.delete(c)
258: end
259: end
Safely work with (multithreaded) stores.
[ show source ]
# File lib/og/manager.rb, line 110
110: def with_store
111: store = get_store
112: return yield(store)
113: ensure
114: put_store(store)
115: end