lib/og/store.rb in og-0.31.0 vs lib/og/store.rb in og-0.40.0
- old
+ new
@@ -1,163 +1,166 @@
module Og
-# A Store is responsible for the peristance of the ObjectGraph.
+# A Store is a backend of Og used to persist objects. An
+# adapter specializes the Store. For example the SQL Store
+# has the MySQL, PostgreSQL, Sqlite3 etc adapters as
+# specializations.
class Store
- # Options.
+ attr_accessor :ogmanager
- attr_accessor :options
-
- # Transaction nesting.
-
- attr_accessor :transaction_nesting
-
- # :section: Store methods.
-
- # Return the store for the given name.
-
- def self.for_name(name)
- Logger.info "Og uses the #{name.to_s.capitalize} store."
- # gmosx: to keep RDoc happy.
- require('og/store/' + name.to_s)
- return Og.const_get("#{name.to_s.capitalize}Store")
- end
-
- # Creates a store.
-
- def self.create(options)
- end
-
- # Destroys a store.
-
- def self.destroy(options)
- end
-
- # :section: Misc methods.
-
# Create a session to the store.
+ #
+ # === Default options
+ #
+ # * :evolve_schema => :warn
- def initialize(options)
- @options = options
+ def initialize options
+ @options = {
+ :evolve_schema => :warn
+ }.merge(options)
@transaction_nesting = 0
end
# Close the session to the store.
def close
+ raise 'Not implemented'
end
-
+
# Enchants a class.
def enchant(klass, manager)
- # gmosx, FIXME:
- # ARGH, have to update this!
- #
- # klass.class.send(:define_method, :index) do |arg|
- # meta :index, arg
- # end
-
- pk = klass.primary_key.symbol
-
+ pk = klass.primary_key
klass.module_eval %{
+
+ # A managed object is considered saved if it has
+ # a valid primary key.
+
def saved?
- return #{klass.primary_key.symbol}
+ return #{pk}
end
+ # The inverse of saved.
+
def unsaved?
- return !#{klass.primary_key.symbol}
+ return !#{pk}
end
# Evaluate an alias for the primary key.
alias_method :pk, :#{pk}
alias_method :pk=, :#{pk}=
-
- def self.pk_symbol
- :#{klass.primary_key.symbol}
- end
}
-
end
-
+
# :section: Lifecycle methods.
# Loads an object from the store using the primary key.
def load(pk, klass)
+ raise 'Not implemented'
end
+ alias_method :exist?, :load
# Reloads an object from the store.
def reload(obj)
+ raise 'Not implemented'
end
# Save an object to store. Insert if this is a new object or
- # update if this is already inserted in the database.
+ # update if this is already inserted in the database. Checks
+ # if the object is valid before saving. Returns false if the
+ # object is invalid and populates obj.errors.
def save(obj, options = nil)
return false unless obj.valid?
if obj.saved?
- obj.og_update(self, options)
+ update_count = obj.og_update(self, options)
else
- obj.og_insert(self)
+ update_count = 1 if obj.og_insert(self)
end
+
+ # Save building collections if any.
+ obj.save_building_collections
+
+ return update_count
end
alias_method :<<, :save
alias_method :validate_and_save, :save
+ # Force the persistence of an Object. Ignore any validation
+ # and/or other errors.
+
def force_save!(obj, options)
if obj.saved?
- obj.og_update(self, options)
+ obj.og_update self, options
else
- obj.og_insert(self)
+ obj.og_insert self
end
end
# Insert an object in the store.
def insert(obj)
- obj.og_insert(self)
+ obj.og_insert self
end
# Update an object in the store.
- def update(obj, options = nil)
- obj.og_update(self, options)
+ def update obj, options = nil
+ obj.og_update self, options
end
- # Update selected properties of an object or class of
+ # Update selected attributes of an object or class of
# objects.
-
- def update_properties(obj_or_class, props, options = nil)
+
+ def update_attributes target, *attributes
+ update(target, :only => attributes)
end
- alias_method :pupdate, :update_properties
- alias_method :update_property, :update_properties
+ alias_method :aupdate, :update_attributes
+ alias_method :update_attribute, :update_attributes
# Permanently delete an object from the store.
def delete(obj_or_pk, klass = nil, cascade = true)
- unless obj_or_pk.is_a?(EntityMixin)
- # create a dummy instance to keep the og_delete
+ unless obj_or_pk.is_a? EntityMixin
+ # create an instance to keep the og_delete
# method as an instance method like the other lifecycle
- # methods.
- klass.allocate.og_delete(self, obj_or_pk, cascade)
+ # methods. This even allows to call og_delete aspects
+ # that use instance variable (for example, sophisticated
+ # cache sweepers).
+ #
+ # gmosx: the following is not enough!
+ # obj = klass.allocate
+ # obj.pk = obj_or_pk
+ obj = klass[obj_or_pk]
+ obj.og_delete(self, cascade)
else
- obj_or_pk.og_delete(self, nil, cascade)
+ obj_or_pk.og_delete(self, cascade)
end
end
+ # Delete all instances of the given class.
+
+ def delete_all(klass)
+ raise 'Not implemented'
+ end
+
# Perform a query.
def find(klass, options)
+ raise 'Not implemented'
end
# Count the results returned by the query.
def count(options)
+ raise 'Not implemented'
end
# :section: Transaction methods.
# Start a new transaction.
@@ -189,32 +192,23 @@
def transaction(&block)
begin
start
yield(self)
commit
- rescue => ex
+ rescue Object => ex
rollback
raise ex
end
end
private
- def eval_og_insert(klass)
+ #--
+ # A helper for inserting advices in the precompiled methods.
+ #++
+
+ def insert_advices where, target, klass, advices # :nodoc: all
+ Aspects.gen_advice_code(target, klass.send(advices), where) if klass.respond_to?(advices)
end
-
- def eval_og_update(klass)
- end
-
- def eval_og_read(klass)
- end
-
- def eval_og_delete(klass)
- end
-
- def eval_og_create_schema(klass)
- end
end
end
-
-# * George Moschovitis <gm@navel.gr>