peace_love 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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