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.
- data/.gitignore +2 -0
- data/Gemfile +11 -0
- data/Rakefile +16 -0
- data/VERSION +1 -0
- data/examples/eg.helper.rb +21 -0
- data/examples/loading.eg.rb +75 -0
- data/lib/peace_love.rb +23 -0
- data/lib/peace_love/collection.rb +47 -0
- data/lib/peace_love/cursor.rb +31 -0
- data/lib/peace_love/document.rb +83 -0
- data/peace_love.gemspec +51 -0
- metadata +86 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -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
|
data/lib/peace_love.rb
ADDED
@@ -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
|
data/peace_love.gemspec
ADDED
@@ -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
|