Created
September 15, 2012 14:44
-
-
Save davybrion/3728289 to your computer and use it in GitHub Desktop.
code snippets for "Using NHibernate To Persist And Query Ruby Objects" post, part III
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ObjectFactory | |
def self.create_from_nhibernate_hash(hashtable) | |
entity_name = hashtable[NHibernator::TYPE_KEY_NAME.to_clr_string] | |
entity = const_get(entity_name.to_sym).new | |
entity.hydrate_from hashtable | |
entity | |
end | |
def self.create_proxy_from_nhibernate_hash(hashtable, entity_name, id) | |
proxy = const_get("#{entity_name}Proxy".to_sym).new | |
proxy.hydrate_from hashtable, id | |
proxy | |
end | |
def self.create_multiple_from_nhibernate_list(list) | |
entities = [] | |
# TODO: differentiate between proxies and normal entities in the list | |
list.each { |hash| entities << create_from_nhibernate_hash(hash) } | |
entities | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TYPE_KEY_NAME = "$type$" | |
def self.each_writeable_accessor_of(klass, &block) | |
setters = klass.public_instance_methods(true).select { |name| name =~ /\w=$/ } | |
setters.each { |setter| yield setter } | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def self.initialize(session_factory) | |
all_class_metadata = session_factory.get_all_class_metadata | |
all_class_metadata.keys.each do |key| | |
metadata = all_class_metadata[key] | |
realclass = Object::const_get(key) | |
realclass.send :include, NHibernator | |
create_proxy_class_for realclass, metadata.identifier_property_name | |
end | |
end | |
def self.create_proxy_class_for(klass, identifier_name) | |
proxyclass = Class.new(klass) | |
Object::const_set "#{klass.name}Proxy", proxyclass | |
proxyclass.class_eval do | |
define_method identifier_name do | |
@id | |
end | |
def hydrate_from(hashtable, id) | |
@nhibernate_values = hashtable | |
@id = id | |
end | |
end | |
each_writeable_accessor_of(klass) do |setter| | |
proxyclass.class_eval do | |
define_method setter do |value| | |
# execute the getter to force NH's lazy proxymap to fetch the data | |
send setter.to_s.chop | |
super value | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def self.include(base) | |
# everything you do within this method will be executed whenever | |
# this module is included in a class... the base parameter is | |
# the class that included the module | |
# ... | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
each_writeable_accessor_of(base) do |setter| | |
getter = setter.to_s.chop | |
base.class_eval do | |
undef_method getter | |
undef_method setter | |
define_method getter do | |
return nil if @nhibernate_values.nil? | |
value = @nhibernate_values[getter.to_clr_string] | |
return value unless value.is_a? System::Collections::IEnumerable | |
# TODO: cache the WrappedList instance | |
WrappedList.new(value) | |
end | |
define_method setter do |value| | |
@nhibernate_values = System::Collections::Hashtable.new if @nhibernate_values.nil? | |
@nhibernate_values[setter.to_s.chop.to_clr_string] = value | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
base.send :include, System::Collections::IDictionary |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
base.class_eval do | |
def nhibernate_values | |
@nhibernate_values | |
end | |
def hydrate_from(hashtable) | |
@nhibernate_values = hashtable | |
referenced_entities = Hash.new | |
hashtable.keys.each do |key| | |
value = hashtable[key.to_clr_string] | |
if value.is_a? System::Collections::IDictionary | |
if value.is_a? System::Collections::Hashtable | |
referenced_entity = ObjectFactory.create_from_nhibernate_hash(value) | |
else | |
type = value.hibernate_lazy_initializer.entity_name | |
id = value.hibernate_lazy_initializer.identifier | |
referenced_entity = ObjectFactory.create_proxy_from_nhibernate_hash(value, type, id) | |
end | |
referenced_entities[key] = referenced_entity | |
end | |
end | |
referenced_entities.keys.each { |key| send "#{key}=", referenced_entities[key] } | |
end | |
def Equals(other) | |
self == other | |
end | |
def GetHashCode | |
hash | |
end | |
def ==(other) | |
return false if other.nil? | |
return @nhibernate_values.Equals(other) if other.is_a? System::Collections::IDictionary | |
return false unless other.respond_to? :nhibernate_values | |
other.nhibernate_values.Equals(@nhibernate_values) | |
end | |
def hash | |
@nhibernate_values.GetHashCode() | |
end | |
def [](key) | |
self.send key | |
end | |
def []=(key, value) | |
self.send "#{key}=", value | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class WrappedList | |
include System::Collections::IList | |
def initialize(list) | |
@list = list | |
end | |
def each(&block) | |
@list.each do |item| | |
if item.respond_to? :nhibernate_values | |
yield item | |
else | |
yield ObjectFactory.create_from_nhibernate_hash(item) | |
end | |
end | |
end | |
def GetEnumerator | |
WrappedListEnumerator.new(self) | |
end | |
def add(item) | |
@list.add item | |
end | |
def clear | |
@list.clear | |
end | |
def contains(item) | |
@list.contains item | |
end | |
def count | |
@list.count | |
end | |
def remove(item) | |
original_count = count | |
if item.respond_to? :nhibernate_values | |
@list.remove item.nhibernate_values | |
else | |
@list.remove item | |
end | |
original_count != count | |
end | |
def is_read_only | |
@list.is_read_only | |
end | |
def index_of(item) | |
@list.index_of item | |
end | |
def insert(index, item) | |
@list.insert index, item | |
end | |
def remove_at(index) | |
@list.remove_at index | |
end | |
def [](index) | |
item = @list[index] | |
return item if item.respond_to? :nhibernate_values | |
ObjectFactory.create_from_nhibernate_hash(item) | |
end | |
def []=(index, item) | |
@list[index] = item | |
end | |
def Equals(other) | |
self == other | |
end | |
def GetHashCode | |
hash | |
end | |
def ==(other) | |
return false if other.nil? | |
@list.Equals(other) | |
end | |
def hash | |
GetHashCode | |
end | |
end | |
class WrappedListEnumerator | |
include System::Collections::IEnumerator | |
def initialize(wrappedlist) | |
@wrappedlist = wrappedlist | |
reset | |
end | |
def reset | |
@current_index = -1 | |
end | |
def current | |
@wrappedlist[@current_index] | |
end | |
def move_next | |
@current_index += 1 | |
return false if @current_index >= @wrappedlist.count | |
true | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment