mongobijou 0.0.0

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0ed3b84f762515db71a89bd46e061f5ca6e68261
4
+ data.tar.gz: a13e94a1f24bf06699934923b759edbddcdd191e
5
+ SHA512:
6
+ metadata.gz: 63ce469ee675914e24efdd2d620a901f99b6e6dfc354d7e03591985ec0a5b76f90b541eafc501344cb75c3f6e8d9df49e07cf9905e95050bd3c09c7478e2941e
7
+ data.tar.gz: 4efec66cb012f96fbdc0759abc49865669b18f21f72bd1f5f0282ef23dbf712e9c32f9749eef0922c13d1a32f76a09f007f70c25c9dd86f3380c74294fbd0774
@@ -0,0 +1,40 @@
1
+ Dir["#{Dir.pwd}/lib/mongo_bijou/*.rb"].each { |file| require_relative file }
2
+
3
+ # Module to supply class objects with mongodb storage.
4
+ module MongoBijou
5
+ # Returns the value of attribute config_attr.
6
+ attr_accessor :config_attr
7
+
8
+ def self.included(klass)
9
+ klass.extend Murderer
10
+ klass.extend Boaster
11
+ end
12
+
13
+ # Default configuration for object attributes to be saved in db - all.
14
+ def attr_defaults
15
+ @config_attr = crusher.to_hash(self)
16
+ end
17
+
18
+ def db_name=(name)
19
+ Client.instance.db_name = name
20
+ end
21
+
22
+ # Call this method on object to perform saving
23
+ # object with configured attributes.
24
+ def mongo_store
25
+ attr_defaults if config_attr.nil?
26
+ attr = crusher.crush(config_attr)
27
+ client = Client.instance.client[collection_name]
28
+ client.insert_one(attr).inserted_id.to_s
29
+ end
30
+
31
+ private
32
+
33
+ def collection_name
34
+ self.class.to_s.downcase
35
+ end
36
+
37
+ def crusher
38
+ Crusher.new(self)
39
+ end
40
+ end
@@ -0,0 +1,86 @@
1
+ module MongoBijou
2
+ module Boaster
3
+ def find(id)
4
+ doc = find_in_db(id)
5
+ from_doc_to_object(doc)
6
+ end
7
+
8
+ def all
9
+ docs = Client.instance.client[collection_name].find.to_a
10
+ docs.each_with_object([]) do |doc, array|
11
+ array << from_doc_to_object(doc)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def find_in_db(id)
18
+ doc = Client.instance.client[collection_name]
19
+ doc.find(_id: BSON::ObjectId(id)).to_a.first
20
+ end
21
+
22
+ def from_doc_to_object(doc)
23
+ obj_attr = object_attr_retrieve(doc)
24
+ hash = build_class_hash(obj_attr)
25
+ object = drill(hash)
26
+ object.config_attr = Crusher.new(self).to_hash(object)
27
+ object
28
+ end
29
+
30
+ def object_attr_retrieve(hash)
31
+ hash.keep_if { |key, _value| class_name == unmark_class(key) }
32
+ end
33
+
34
+ def drill(hash)
35
+ hash.each do |key, value|
36
+ hash[key] = drill(value) if value.instance_of?(Hash)
37
+ return build_partial(key, value) if class?(key)
38
+ end
39
+ end
40
+
41
+ def class?(value)
42
+ value.is_a? Class
43
+ end
44
+
45
+ def build_partial(klass, hash)
46
+ hash.each_with_object(klass.new) do |(key, value), partial|
47
+ partial.instance_variable_set("@#{key}".to_sym, value)
48
+ end
49
+ end
50
+
51
+ def build_class_hash(hash)
52
+ hash.each_with_object({}) do |(key, value), cpy_hash|
53
+ cpy_key = constantize_if_class(key)
54
+ cpy_hash[cpy_key] = if value.instance_of?(BSON::Document)
55
+ build_class_hash(value)
56
+ else
57
+ value
58
+ end
59
+ end
60
+ end
61
+
62
+ def constantize_if_class(str)
63
+ if marked_as_class?(str)
64
+ Object.const_get(unmark_class(str))
65
+ else
66
+ str
67
+ end
68
+ end
69
+
70
+ def marked_as_class?(str)
71
+ unmark_class(str) != str
72
+ end
73
+
74
+ def unmark_class(str)
75
+ str.gsub(/_class_name/, '')
76
+ end
77
+
78
+ def collection_name
79
+ class_name.downcase
80
+ end
81
+
82
+ def class_name
83
+ to_s
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,23 @@
1
+ require 'singleton'
2
+ require 'mongo'
3
+
4
+ # Module to supply class objects with mongodb storage.
5
+ module MongoBijou
6
+ # MongoDB connector.
7
+ class Client
8
+ include Singleton
9
+ # Returns the value of attribute client.
10
+ attr_reader :client, :db_name
11
+
12
+ # Returns a new instance of MongoClient.
13
+ def initialize
14
+ @db_name = 'default'
15
+ @client = Mongo::Client.new(['127.0.0.1:27017'], database: @db_name)
16
+ end
17
+
18
+ def db_name=(db_name)
19
+ @db_name = db_name
20
+ @client = Mongo::Client.new(['127.0.0.1:27017'], database: @db_name)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,63 @@
1
+ # Module to supply class objects with mongodb storage.
2
+ module MongoBijou
3
+ CORE_TYPES =
4
+ [Fixnum, String, TrueClass, FalseClass, Bignum, Array, Hash, NilClass]
5
+
6
+ # Class able to create deep-nested hash of object's attributes.
7
+ class Crusher
8
+ # Returns a new instance of AttributesFormatter.
9
+ def initialize(object)
10
+ @object = object
11
+ end
12
+
13
+ # Runs #scan_attr(attributes) method and deletes
14
+ # :config_attr from received hash.
15
+ # Then it adds class name, that included module, to formatted hash
16
+ # (necessary when retrieving from database).
17
+ def crush(hash)
18
+ { mark_class(@object) => scan(hash) }
19
+ end
20
+
21
+ # Creates hash of given object's instance variables.
22
+ def to_hash(object)
23
+ object.instance_variables.each_with_object({}) do |attr, hash|
24
+ hash[attr.to_s.delete('@').to_sym] = object.instance_variable_get(attr)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ # Recursion method. It scans attributes to check if attribute:
31
+ # * is a Ruby core type - leave as it is.
32
+ # * is not a Ruby core type - save class name in symbolized form.
33
+ # * has nested attributes - perform another scan.
34
+ def scan(hash)
35
+ hash.each do |key, value|
36
+ next if belongs_to_core? value
37
+ unless nested?(value)
38
+ hash[key] = mark_class(value)
39
+ next
40
+ end
41
+ hash[key] = nested_to_hash(value)
42
+ end
43
+ end
44
+
45
+ def belongs_to_core?(object)
46
+ CORE_TYPES.include? object.class
47
+ end
48
+
49
+ def nested?(object)
50
+ object.instance_variables.any?
51
+ end
52
+
53
+ def mark_class(object)
54
+ (object.class.to_s + '_class_name').to_sym
55
+ end
56
+
57
+ # Symbolize class name and perform another scan
58
+ # with attributes of actual object.
59
+ def nested_to_hash(object)
60
+ { mark_class(object) => scan(to_hash(object)) }
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,21 @@
1
+ module MongoBijou
2
+ module Murderer
3
+ def remove(id)
4
+ Client.instance.client[collection_name].delete_one(_id: id)
5
+ end
6
+
7
+ def drop
8
+ Client.instance.client[collection_name].drop
9
+ end
10
+
11
+ private
12
+
13
+ def collection_name
14
+ class_name.downcase
15
+ end
16
+
17
+ def class_name
18
+ to_s
19
+ end
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongobijou
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Robert Pawlas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Mongo mapper for ruby objects
14
+ email: robspawlas@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/mongo_bijou.rb
20
+ - lib/mongo_bijou/boaster.rb
21
+ - lib/mongo_bijou/client.rb
22
+ - lib/mongo_bijou/crusher.rb
23
+ - lib/mongo_bijou/murderer.rb
24
+ homepage: http://rubygems.org/gems/mongobijou
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.4.8
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: ''
48
+ test_files: []
49
+ has_rdoc: