ohm-identity_map 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZThmYTc5ODlhMDVkOTVjNGUwOWE0NTJmNDhjZGVjZWI1ZjM5ZDBiZQ==
5
+ data.tar.gz: !binary |-
6
+ MDMxZjc2YjAyOTE0YzE3YzhiNjA3NTA0ODE5ODc4OWI5NTE5NzJhMA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NDFmNDA4ZWM1N2I4ODM1NTlkY2U5MTNlMjQ3MDEyYzFlZDVjYzYwZmZjNTkx
10
+ YWQ2NjA3NGIyNDc2MWY1MjhiNjRkNWZmYmJmYzE0NGUwMzAwZDhiZTRmM2Zj
11
+ OTYzYmNjNmM5NjYxMDczMTBjOWZiNzFhNzA5NjNhYTU4ZWJiMzQ=
12
+ data.tar.gz: !binary |-
13
+ YjMxMWFiMjRjZWMwNzRhNGUzOGJmNWNiZGQxMWY2MzlmNzYwMzdhNTFmNTMy
14
+ NzYyZjJhMzNiYTNmMzVhN2I5ZGFmNDhlY2QzNDdhNzBlZWRlZWEzN2M5ZWRj
15
+ MmYzMmNhZGQxYjgxZTc5Yjk2ZTM5YWU2YTU0Y2MyZDU0Zjc4NTU=
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /.gs
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ Ohm::IdentityMap
2
+ ================
3
+
4
+ Provides a basic identity map for [Ohm][1].
5
+
6
+ Usage
7
+ -----
8
+
9
+ require "ohm/identity_map"
10
+
11
+ # By default, no identity map is used.
12
+
13
+ Post[1].object_id == Post[1].object_id
14
+ # => false
15
+
16
+ # Enable the identity map for the duration of a block.
17
+
18
+ Ohm::Model.identity_map do
19
+ Post[1].object_id == Post[1].object_id
20
+ end
21
+ # => true
22
+
23
+ Web
24
+ ---
25
+
26
+ It's easy to create a Rack middleware to enable the identity map for the
27
+ duration of the request/response cycle. (Such middleware may be included in
28
+ this library in the future, once we test this behavior in production.)
29
+
30
+ class OhmIdentityMapMiddleware
31
+ def initialize(app)
32
+ @app = app
33
+ end
34
+
35
+ def call(env)
36
+ Ohm::Model.identity_map { @app.call(env) }
37
+ end
38
+ end
39
+
40
+ # config.ru or any Rack::Builder
41
+ use OhmIdentityMapMiddleware
42
+
43
+ Known issues
44
+ ------------
45
+
46
+ Currently not handling updates and deletes.
47
+
48
+ License
49
+ -------
50
+
51
+ See `UNLICENSE`. With love, from [Educabilia](http://educabilia.com).
52
+
53
+ [1]: https://github.com/soveran/ohm
data/UNLICENSE ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
@@ -0,0 +1,57 @@
1
+ require "ohm"
2
+
3
+ module Ohm::IdentityMap
4
+ VERSION = "0.1.0"
5
+
6
+ def self.included(model)
7
+ model.extend(Macros)
8
+
9
+ class << model
10
+ alias original_loader []
11
+
12
+ def [](id)
13
+ if map = Thread.current[:_ohm_identity_map]
14
+ map.fetch(id) { map[id] = original_loader(id) }
15
+ else
16
+ original_loader(id)
17
+ end
18
+ end
19
+
20
+ alias original_fetch fetch
21
+
22
+ def fetch(ids)
23
+ if map = Thread.current[:_ohm_identity_map]
24
+ missing_ids, missing_indices = [], []
25
+
26
+ mapped = ids.map.with_index do |id, index|
27
+ map.fetch(id) do
28
+ missing_ids << id
29
+ missing_indices << index
30
+ nil
31
+ end
32
+ end
33
+
34
+ original_fetch(missing_ids).each.with_index do |instance, index|
35
+ mapped[missing_indices[index]] = instance
36
+ map.store(missing_ids[index], instance)
37
+ end
38
+
39
+ mapped
40
+ else
41
+ original_fetch(ids)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ module Macros
48
+ def identity_map
49
+ Thread.current[:_ohm_identity_map] = {}
50
+ yield
51
+ ensure
52
+ Thread.current[:_ohm_identity_map] = nil
53
+ end
54
+ end
55
+ end
56
+
57
+ Ohm::Model.send(:include, Ohm::IdentityMap)
@@ -0,0 +1,16 @@
1
+ require File.expand_path("lib/ohm/identity_map", File.dirname(__FILE__))
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "ohm-identity_map"
5
+ s.version = Ohm::IdentityMap::VERSION
6
+ s.summary = "Basic identity map for Ohm."
7
+ s.authors = ["Educabilia", "Damian Janowski"]
8
+ s.email = ["opensource@educabilia.com", "djanowski@dimaion.com"]
9
+ s.homepage = "https://github.com/educabilia/ohm-identity_map"
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = `git ls-files -- {test}/*`.split("\n")
13
+
14
+ s.add_development_dependency "ohm"
15
+ s.add_development_dependency "cutest"
16
+ end
data/rakefile ADDED
@@ -0,0 +1,7 @@
1
+ task :test do
2
+ require "cutest"
3
+
4
+ Cutest.run(Dir["test/**/*_test.rb"])
5
+ end
6
+
7
+ task :default => :test
@@ -0,0 +1,54 @@
1
+ require_relative "prelude"
2
+
3
+ class Post < Ohm::Model
4
+ attribute :title
5
+ end
6
+
7
+ class Comment < Ohm::Model
8
+ attribute :body
9
+
10
+ reference :post, :Post
11
+ end
12
+
13
+ scope do
14
+ setup do
15
+ post = Post.create(title: "How to create an Identity Map in Ruby")
16
+
17
+ Comment.create(post_id: post.id, body: "Great article!")
18
+ Comment.create(post_id: post.id, body: "Not so great...")
19
+ end
20
+
21
+ test "Model#[] - identity map disabled" do
22
+ assert Comment[1].object_id != Comment[1].object_id
23
+ end
24
+
25
+ test "Model#[] - identity map enabled" do
26
+ comments = Ohm::Model.identity_map do
27
+ [Comment[1], Comment[1]]
28
+ end
29
+
30
+ assert_equal 1, comments.map(&:object_id).uniq.size
31
+
32
+ assert Comment[1].object_id != Comment[1].object_id
33
+ end
34
+
35
+ test "Model#fetch - identity map disabled" do
36
+ comments = Comment.fetch([1, 2])
37
+
38
+ assert_equal 2, comments.map(&:object_id).uniq.size
39
+ end
40
+
41
+ test "Model#fetch - identity map enabled" do
42
+ comments = Ohm::Model.identity_map { Comment.fetch([1]) + Comment.fetch([1]) }
43
+
44
+ assert_equal 1, comments.map(&:object_id).uniq.size
45
+
46
+ comments = Ohm::Model.identity_map { Comment.fetch([1]) + Comment.fetch([2]) }
47
+
48
+ assert_equal 2, comments.map(&:object_id).uniq.size
49
+
50
+ comments = Ohm::Model.identity_map { Comment.fetch([1]) + Comment.fetch([1, 2]) }
51
+
52
+ assert_equal 2, comments.map(&:object_id).uniq.size
53
+ end
54
+ end
data/test/prelude.rb ADDED
@@ -0,0 +1,11 @@
1
+ ENV["REDIS_URL"] = "redis://localhost:6379/15"
2
+
3
+ require "cutest"
4
+
5
+ $VERBOSE = 1
6
+
7
+ require_relative "../lib/ohm/identity_map"
8
+
9
+ prepare do
10
+ Ohm.flush
11
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ohm-identity_map
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Educabilia
8
+ - Damian Janowski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ohm
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: cutest
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ description:
43
+ email:
44
+ - opensource@educabilia.com
45
+ - djanowski@dimaion.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - .gitignore
51
+ - README.md
52
+ - UNLICENSE
53
+ - lib/ohm/identity_map.rb
54
+ - ohm-identity_map.gemspec
55
+ - rakefile
56
+ - test/identity_map_test.rb
57
+ - test/prelude.rb
58
+ homepage: https://github.com/educabilia/ohm-identity_map
59
+ licenses: []
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.0.0
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: Basic identity map for Ohm.
81
+ test_files: []