mongo_light 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,36 @@
1
+ require 'mongo'
2
+
3
+ module MongoLight
4
+ module Connection
5
+
6
+ def self.setup(connection, database_name)
7
+ @@connection = connection
8
+ @@database = @@connection.db(database_name)
9
+ handle_passenger_forking
10
+ end
11
+
12
+ def self.connection
13
+ @@connection
14
+ end
15
+
16
+ def self.database
17
+ @@database
18
+ end
19
+
20
+ def self.collections
21
+ @@database.collections
22
+ end
23
+
24
+ def self.[](collection_name)
25
+ @@database.collection(collection_name)
26
+ end
27
+
28
+ def self.handle_passenger_forking
29
+ if defined?(PhusionPassenger)
30
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
31
+ @@connection.connect if forked
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,75 @@
1
+ module MongoLight
2
+ module Document
3
+ extend ActiveSupport::Concern
4
+ include EmbeddedDocument
5
+
6
+ module ClassMethods
7
+ def collection
8
+ Connection[self.to_s.tableize]
9
+ end
10
+ def find_by_id(id)
11
+ real_id = Id.from_string(id)
12
+ return nil if real_id.nil?
13
+
14
+ found = collection.find_one(real_id)
15
+ found.nil? ? nil : self.new(unmap(found))
16
+ end
17
+ def find_one(selector = {})
18
+ found = collection.find_one(map(selector))
19
+ found.nil? ? nil : self.new(unmap(found))
20
+ end
21
+ def find(selector={}, opts={}, collection = nil)
22
+ raw = opts.delete(:raw) || false
23
+ opts[:transformer] = Proc.new{|data| raw ? unmap(data, raw) : self.new(unmap(data)) }
24
+ c = collection || self.collection
25
+ c.find(map(selector), map_options(opts))
26
+ end
27
+ def remove(selector={}, collection = nil)
28
+ c = collection || self.collection
29
+ c.remove(map(selector))
30
+ end
31
+ def update(selector, document, options = {}, collection = nil)
32
+ c = collection || self.collection
33
+ c.update(map(selector), map(document), options)
34
+ end
35
+ def count(selector={}, collection = nil)
36
+ c = collection || self.collection
37
+ c.find(map(selector)).count
38
+ end
39
+ end
40
+ module InstanceMethods
41
+ def initialize(attributes = {})
42
+ attributes[:_id] = Id.new unless attributes.include?('_id') || attributes.include?(:_id)
43
+ @attributes = attributes
44
+ attributes.each do |k,v|
45
+ send("#{k}=", v) unless k == :_id || k == '_id'
46
+ end
47
+ end
48
+ def eql?(other)
49
+ other.is_a?(self.class) && id == other.id
50
+ end
51
+ alias :== :eql?
52
+ def hash
53
+ id.hash
54
+ end
55
+ def id
56
+ @attributes[:_id] || @attributes['_id']
57
+ end
58
+ def id=(value)
59
+ @attributes[:_id] = value
60
+ end
61
+ def ==(other)
62
+ other.class == self.class && id == other.id
63
+ end
64
+ def collection
65
+ self.class.collection
66
+ end
67
+ def save
68
+ collection.save(self.class.map(@attributes))
69
+ end
70
+ def save!
71
+ collection.save(self.class.map(@attributes), {:safe => true})
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,75 @@
1
+ module MongoLight
2
+ module EmbeddedDocument
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def mongo_accessor(map)
7
+ @map = map
8
+ @unmap = {}
9
+ map.each do |k,v|
10
+ define_method(k) { @attributes[k] }
11
+ define_method("#{k}=") {|value| @attributes[k] = value }
12
+ if v.is_a?(Hash)
13
+ @unmap[v[:field].to_s] = {:prop => k, :class => v[:class]}
14
+ else
15
+ @unmap[v.to_s] = k
16
+ end
17
+ end
18
+ end
19
+ def map(raw)
20
+ return {} if raw.blank? || !raw.is_a?(Hash)
21
+ hash = {}
22
+ raw.each do |key, value|
23
+ if value.is_a?(EmbeddedDocument)
24
+ v = value.class.map(value.attributes)
25
+ elsif value.is_a?(Hash)
26
+ v = map(value)
27
+ else
28
+ v = value
29
+ end
30
+ hash[map_key(key.to_sym)] = v
31
+ end
32
+ return hash
33
+ end
34
+ def map_options(options)
35
+ options[:fields] = map(options[:fields]) if options.include?(:fields)
36
+ options[:sort][0] = map_key(options[:sort][0]) if options.include?(:sort)
37
+ options
38
+ end
39
+ def unmap(data, raw = false)
40
+ return {} if data.blank? || !data.is_a?(Hash)
41
+ hash = {}
42
+ data.each do |key, value|
43
+ if @unmap[key].is_a?(Hash)
44
+ real_key = @unmap[key][:prop]
45
+ c = @unmap[key][:class]
46
+ v = raw ? c.unmap(value) : c.new(c.unmap(value))
47
+ else
48
+ real_key = key == '_id' ? :_id : @unmap[key]
49
+ v = value
50
+ end
51
+ hash[real_key] = v
52
+ end
53
+ hash
54
+ end
55
+ def map_key(key)
56
+ return key unless @map.include?(key)
57
+ @map[key].is_a?(Hash) ? @map[key][:field] : @map[key]
58
+ end
59
+ end
60
+ module InstanceMethods
61
+ def initialize(attributes = {})
62
+ @attributes = attributes
63
+ attributes.each do |k,v|
64
+ send("#{k}=", v)
65
+ end
66
+ end
67
+ def [](name)
68
+ @attributes[name]
69
+ end
70
+ def attributes
71
+ @attributes
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,17 @@
1
+ module MongoLight
2
+ module Id
3
+ def self.new
4
+ BSON::ObjectId.new
5
+ end
6
+ def self.valid?(id)
7
+ return false if id.blank? || id.class == Fixnum
8
+ return true if id.class == BSON::ObjectId
9
+ BSON::ObjectId.legal?(id)
10
+ end
11
+ def self.from_string(id)
12
+ return nil unless Id.valid?(id)
13
+ return id if id.class == BSON::ObjectId
14
+ BSON::ObjectId.from_string(id)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module MongoLight
2
+ Version = '0.0.1'
3
+ end
@@ -0,0 +1,4 @@
1
+ require 'mongo_light/id'
2
+ require 'mongo_light/connection'
3
+ require 'mongo_light/embedded_document'
4
+ require 'mongo_light/document'
data/license ADDED
@@ -0,0 +1,14 @@
1
+ This file is part of MongoLight.
2
+
3
+ MongoLight is free software: you can redistribute it and/or modify
4
+ it under the terms of the GNU General Public License as published by
5
+ the Free Software Foundation, either version 3 of the License, or
6
+ (at your option) any later version.
7
+
8
+ MongoLight is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ GNU General Public License for more details.
12
+
13
+ You should have received a copy of the GNU General Public License
14
+ along with MongoLight. If not, see <http://www.gnu.org/licenses/>.
data/readme.markdown ADDED
@@ -0,0 +1,68 @@
1
+ # MongoLight #
2
+ MongoLight is a lightweight object-relational mapper for Rails and MongoDB. It is **not** ActiveRecord compatible. Rather, the primary purpose is to be a thin wrapper around the excellent core [MongoDB driver](https://github.com/mongodb/mongo-ruby-driver).
3
+
4
+ The only Rails dependency is on ActiveSupport::Concern.
5
+
6
+ The wrapper fits a specific use-case (mine).
7
+
8
+ ## Setup ##
9
+ During initialization (such as in an initializer), call `MongoLight::Connection.setup`, supplying 2 parameters. The first is a MongoDB connection (that you get from the core driver). The second parameter is the database name. For example:
10
+
11
+ MongoLight::Connection.setup(Mongo::Connection.new, 'test')
12
+
13
+ This'll automatically handle Passenger forking issues (if Passenger is running).
14
+
15
+ ## Documents ##
16
+ To define a document include `MongoLight::Document` and define your properties using the `mongo_accessor` method:
17
+
18
+ class User
19
+ include MongoLight::Document
20
+ mongo_accessor({:name => :name, password => :pw, :email => :e})
21
+ end
22
+
23
+ Within your code, you can access the `name`, `password` and `email` properties. However, internally, MongoDB will store the fields as `name`, `pw` and `e` (document databases store the field names with each document, this can save a lot of space (we saved 25%)).
24
+
25
+ ## Document Manipulation ##
26
+ Most of what you can do on a MongoDB collection (again, the Ruby driver), you can do on a MongoLight document:
27
+
28
+ #string ids which are valid BsonIds will automatically get converted
29
+ User.find_by_id(some_id)
30
+ User.find_one(hash_selector)
31
+ User.find(selector, options)
32
+ User.remove(selector)
33
+ User.update(selector, new_document, options)
34
+
35
+ In addition to any options which the ruby driver supports, the `find` method can be passed ``{:raw => true}` which'll cause a hash to be returned rather than a mapped object.
36
+
37
+ Instances can be saved via `save` or `save!` (safe mode).
38
+
39
+ New instances can be created by passing a hash into the constructor:
40
+
41
+ User.new({:name => 'goku', :password => 'over 9000!!!'})
42
+
43
+ Finally, you can always access the underlying `collection` from a class or object (`User.collection` or `user.collection`).
44
+
45
+ ## Embedded Documents ##
46
+ Embedded documents are supported. First, define an embedded document using `include MongoLight::EmbeddedDocument` and the same `mongo_accessor` method:
47
+
48
+ class Comment
49
+ include MongoLight::EmbeddedDocument
50
+ mongo_accessor({:title => :t, description => :d})
51
+ end
52
+
53
+ Next, use the following fancy syntax for your root document:
54
+
55
+ class User
56
+ include MongoLight::Document
57
+ mongo_accessor({:name => :name, password => :pw, :email => :e, :comments => {:field => :c, :class => Comment}})
58
+ end
59
+
60
+ Again, this'll make `comments` accessible on your objects, but store it within the `c` field.
61
+
62
+ Please note that aliasing completely fails when querying embedded documents - you need to use the shortened name:
63
+
64
+ User.find({:name => 'blah', 'c.t' => 'blah2}) #yes, it sucks
65
+
66
+
67
+
68
+
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongo_light
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Karl Seguin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-27 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description:
17
+ email:
18
+ - karlseguin@gmail.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - lib/mongo_light/connection.rb
27
+ - lib/mongo_light/document.rb
28
+ - lib/mongo_light/embedded_document.rb
29
+ - lib/mongo_light/id.rb
30
+ - lib/mongo_light/version.rb
31
+ - lib/mongo_light.rb
32
+ - license
33
+ - readme.markdown
34
+ homepage: http://github.com/karlseguib/MongoLight
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.5
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: A Lightweight ORM for Rails and MongoDB
61
+ test_files: []
62
+