peace_love 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ .*.sw?
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source :rubygems
2
+
3
+ gem 'angry_hash', '0.0.5'
4
+ gem 'mongo'
5
+ gem 'bson_ext'
6
+
7
+ group :test do
8
+ gem 'exemplor'
9
+ end
10
+
11
+ # vim: ft=ruby
@@ -0,0 +1,16 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "peace_love"
5
+ gemspec.summary = "Peace, Love and Mongo."
6
+ gemspec.description = "A simple mixin layer for enhancing hashes retrieved from MongoDB. It eschews the normal 'mapping' compulsion of mongo libraries."
7
+ gemspec.email = "lachie@smartbomb.com.au"
8
+ gemspec.homepage = "http://github.com/lachie/peace_love"
9
+ gemspec.authors = ["Lachie Cox"]
10
+
11
+ gemspec.add_dependency("mongo", ['~>1.0.0'])
12
+ end
13
+ rescue LoadError
14
+ puts "Jeweler not available. Install it with: gem install jeweler"
15
+ end
16
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup(:test,:default)
4
+ require 'exemplor'
5
+
6
+ require 'pp'
7
+
8
+ require 'pathname'
9
+ here = Pathname(__FILE__).dirname
10
+ $LOAD_PATH << here << (here+'../lib')
11
+
12
+ class Object
13
+ def tapp(tag=nil)
14
+ print "#{tag}=" if tag
15
+ pp self
16
+ self
17
+ end
18
+ end
19
+
20
+ require 'mongo'
21
+ $db = Mongo::Connection.new.db('sample-db')
@@ -0,0 +1,75 @@
1
+ require 'eg.helper'
2
+ require 'angry_hash'
3
+ require 'peace_love'
4
+
5
+ eg.setup do
6
+ PeaceLove.db = $db
7
+ end
8
+
9
+ module Kind
10
+ def claws; "dainty" end
11
+
12
+ def for_kids?
13
+ fictional? && cartoon?
14
+ end
15
+ end
16
+
17
+ module Bear
18
+ include PeaceLove::Doc
19
+ sub_doc :kind, Kind
20
+ sub_col :lovers, Bear
21
+
22
+ def claws; "woah" end
23
+ def liver
24
+ super.upcase
25
+ end
26
+ end
27
+
28
+ eg 'loading object' do
29
+ $db['bears'].remove()
30
+ $db['bears'].insert(:name => 'yogi', :liver => 'pure', :kind => {:fictional => true, :cartoon => true})
31
+
32
+ PeaceLove['bears'].mixin = Bear
33
+ yogi = PeaceLove['bears'].find_one(:name => 'yogi')
34
+ Show(yogi.claws)
35
+ Show(yogi.name)
36
+
37
+ Assert(yogi.liver == 'PURE')
38
+ Show(yogi.kind.for_kids?)
39
+ end
40
+
41
+ eg 'wrapping the cursor' do
42
+ $db['bears'].remove()
43
+ $db['bears'].insert(:name => 'yogi' , :liver => 'pure', :kind => {:fictional => true, :cartoon => true})
44
+ $db['bears'].insert(:name => 'humphrey', :liver => 'cihrrotic', :kind => {:fictional => true, :cartoon => false})
45
+
46
+ PeaceLove['bears'].find.each {|b|
47
+ Show(b)
48
+ Show(b.liver)
49
+ }
50
+ end
51
+
52
+ eg 'sub collection' do
53
+ $db['bears'].remove()
54
+ $db['bears'].insert(:name => 'yogi', :liver => 'pure', :kind => {:fictional => true, :cartoon => true}, :lovers => [
55
+ {:name => 'mrs. yogi', :liver => 'donated'}, {:name => 'yogi paw', :liver => 'jaundiced'}
56
+ ])
57
+
58
+ yogi = PeaceLove['bears'].find_one(:name => 'yogi')
59
+
60
+ Show(yogi.lovers)
61
+ Assert(yogi.lovers[0].liver == 'DONATED')
62
+ Assert(yogi.lovers[1].liver == 'JAUNDICED')
63
+ end
64
+
65
+ eg 'blank doc' do
66
+ PeaceLove['bears'].mixin = Bear
67
+ yogi = PeaceLove['bears'].build
68
+ yogi.claws
69
+ end
70
+
71
+ eg 'saving object' do
72
+ h = AngryHash[ :somesuch => 'second thing' ]
73
+ id = PeaceLove['bears'].insert( h )
74
+ PeaceLove['bears'].find_one(id)
75
+ end
@@ -0,0 +1,23 @@
1
+ require 'mongo'
2
+ require 'angry_hash'
3
+
4
+ module PeaceLove
5
+ end
6
+
7
+ require 'peace_love/document'
8
+ require 'peace_love/collection'
9
+ require 'peace_love/cursor'
10
+
11
+ module PeaceLove
12
+ class << self
13
+ attr_accessor :db
14
+
15
+ def collections
16
+ @collections ||= {}
17
+ end
18
+
19
+ def [](collection_name)
20
+ collections[collection_name.to_s] ||= PeaceLove::Collection.new( db[collection_name] )
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ module PeaceLove
2
+ class Collection
3
+ attr_accessor :mixin
4
+ attr_reader :mongo_collection
5
+
6
+ def initialize(collection)
7
+ @collection = @mongo_collection = collection
8
+ end
9
+
10
+ def build(seed={})
11
+ __wrap( seed )
12
+ end
13
+
14
+ def find_one(*args)
15
+ __wrap( @collection.find_one(*args) )
16
+ end
17
+
18
+ def find(*args,&block)
19
+ if block_given?
20
+ @collection.find(*args) {|cursor| yield __wrap_cursor(cursor)}
21
+ else
22
+ __wrap_cursor(@collection.find(*args))
23
+ end
24
+ end
25
+
26
+ def __wrap_cursor(cursor)
27
+ PeaceLove::Cursor.new(cursor,self)
28
+ end
29
+
30
+ def __wrap(hash)
31
+ hash = __extend( AngryHash[ hash ] )
32
+ hash.extend mixin if mixin
33
+ hash
34
+ end
35
+
36
+ def __extend(hash)
37
+ hash.extend mixin if mixin
38
+ hash
39
+ end
40
+
41
+ (Mongo::Collection.instance_methods - self.instance_methods).each do |name|
42
+ next if name[-1] == ?=
43
+ class_eval "def #{name}(*args,&block); @collection.#{name}(*args,&block) end" unless method_defined?(name)
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,31 @@
1
+ module PeaceLove
2
+ class Cursor
3
+ include Enumerable
4
+
5
+ attr_reader :mongo_cursor
6
+
7
+ def initialize(cursor,collection)
8
+ @collection = collection
9
+ @cursor = @mongo_cursor = cursor
10
+ end
11
+
12
+ def each
13
+ @cursor.each {|doc| yield @collection.__wrap(doc)}
14
+ end
15
+
16
+ def next_document
17
+ @collection.__wrap( @cursor.next_document )
18
+ end
19
+
20
+ def to_a
21
+ @cursor.to_a.map {|doc| @collection.__wrap(doc)}
22
+ end
23
+
24
+ (Mongo::Cursor.instance_methods - self.instance_methods).each do |name|
25
+ next if name[-1] == ?=
26
+ class_eval "def #{name}(*args,&block); @collection.#{name}(*args,&block) end" unless method_defined?(name)
27
+ end
28
+ end
29
+ end
30
+
31
+
@@ -0,0 +1,83 @@
1
+
2
+ module PeaceLove
3
+ module Doc
4
+ class << self
5
+ def included(base)
6
+ base.extend ClassMethods
7
+
8
+ base.module_eval do
9
+ def self.extend_object(obj)
10
+ Doc.mark_extension(obj,self)
11
+ super
12
+ end
13
+ end
14
+ end
15
+
16
+ def object_extensions
17
+ @object_extensions ||= Hash.new {|h,k| h[k] = []}
18
+ end
19
+ def mark_extension(obj,with)
20
+ object_extensions[obj.__id__] << with
21
+ end
22
+
23
+ def mixin_registry
24
+ @mixin_registry ||= Hash.new {|h,k| h[k] = {}}
25
+ end
26
+
27
+ def register_mixin(target_class,field,mod,options)
28
+ mixin_registry[target_class][field.to_s] = [:single, mod, options]
29
+ end
30
+ def register_mixin_array(target_class, field, mod, options)
31
+ mixin_registry[target_class][field.to_s] = [:array, mod, options]
32
+ end
33
+
34
+ def mixin_to(parent_obj,field,obj)
35
+ # XXX - what does having multiple extensions really mean here?
36
+ extensions = object_extensions[parent_obj.__id__]
37
+
38
+ mixins = mixin_registry.values_at(*extensions).map {|m| m[field.to_s]}.compact
39
+
40
+
41
+ mixins.each {|(kind,mod,options)|
42
+ if options.key?(:default) && obj.nil?
43
+ obj = options[:default]
44
+ end
45
+
46
+ # XXX - what happens when obj is nil
47
+
48
+ case kind
49
+ when :single
50
+ obj.extend mod
51
+ when :array
52
+ # XXX - this is ok for now... we really need to typecheck, perhaps wrap in a smart-array
53
+ obj.map! {|elt| elt.extend mod}
54
+ end
55
+ }
56
+
57
+ obj
58
+ end
59
+ end
60
+
61
+ def [](key)
62
+ Doc.mixin_to(self,key,super)
63
+ end
64
+
65
+ module ClassMethods
66
+ def sub_document(field,mod,options={})
67
+ Doc.register_mixin(self,field,mod,options)
68
+ end
69
+ alias_method :sub_doc, :sub_document
70
+
71
+ def sub_collection(field,mod,options={})
72
+ Doc.register_mixin_array(self,field,mod,options)
73
+ end
74
+ alias_method :sub_col, :sub_collection
75
+
76
+ def build(seed={})
77
+ doc = AngryHash[ seed ]
78
+ doc.extend self
79
+ doc
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,51 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{peace_love}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Lachie Cox"]
12
+ s.date = %q{2010-06-24}
13
+ s.description = %q{A simple mixin layer for enhancing hashes retrieved from MongoDB. It eschews the normal 'mapping' compulsion of mongo libraries.}
14
+ s.email = %q{lachie@smartbomb.com.au}
15
+ s.files = [
16
+ ".gitignore",
17
+ "Gemfile",
18
+ "Rakefile",
19
+ "VERSION",
20
+ "examples/eg.helper.rb",
21
+ "examples/loading.eg.rb",
22
+ "lib/peace_love.rb",
23
+ "lib/peace_love/collection.rb",
24
+ "lib/peace_love/cursor.rb",
25
+ "lib/peace_love/document.rb",
26
+ "peace_love.gemspec"
27
+ ]
28
+ s.homepage = %q{http://github.com/lachie/peace_love}
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.6}
32
+ s.summary = %q{Peace, Love and Mongo.}
33
+ s.test_files = [
34
+ "examples/eg.helper.rb",
35
+ "examples/loading.eg.rb"
36
+ ]
37
+
38
+ if s.respond_to? :specification_version then
39
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<mongo>, ["~> 1.0.0"])
44
+ else
45
+ s.add_dependency(%q<mongo>, ["~> 1.0.0"])
46
+ end
47
+ else
48
+ s.add_dependency(%q<mongo>, ["~> 1.0.0"])
49
+ end
50
+ end
51
+
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: peace_love
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Lachie Cox
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-24 00:00:00 +10:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mongo
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 0
30
+ - 0
31
+ version: 1.0.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: A simple mixin layer for enhancing hashes retrieved from MongoDB. It eschews the normal 'mapping' compulsion of mongo libraries.
35
+ email: lachie@smartbomb.com.au
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files: []
41
+
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - Rakefile
46
+ - VERSION
47
+ - examples/eg.helper.rb
48
+ - examples/loading.eg.rb
49
+ - lib/peace_love.rb
50
+ - lib/peace_love/collection.rb
51
+ - lib/peace_love/cursor.rb
52
+ - lib/peace_love/document.rb
53
+ - peace_love.gemspec
54
+ has_rdoc: true
55
+ homepage: http://github.com/lachie/peace_love
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --charset=UTF-8
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.3.6
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Peace, Love and Mongo.
84
+ test_files:
85
+ - examples/eg.helper.rb
86
+ - examples/loading.eg.rb