ephemeral 1.3.0 → 2.3.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f06df215d34c0b7b86bc1097de53f4c9fdd524ab
4
+ data.tar.gz: 269b9359462a464c70be5c35df2b8a88cf94d3eb
5
+ SHA512:
6
+ metadata.gz: dd05de0085dea751196f01b31dd724a68bf97a2bb0e9b20f0ce274b97e07a03f2feee9c2b0671aea6af8fc3a8d21453b49fc79d686151d0b06b4bfdf2e696dd4
7
+ data.tar.gz: dabdfd17688254f4af1d5fa586adb6f2db4647e7b404640245b9665a2681a80c6f0609efec84e58e71bd94425fe27c1f4d20fde8cfe4919133e4f1e85b453950
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile.lock CHANGED
@@ -1,30 +1,69 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activesupport (3.2.7)
5
- i18n (~> 0.6)
6
- multi_json (~> 1.0)
7
- diff-lcs (1.1.3)
8
- git (1.2.5)
9
- i18n (0.6.0)
10
- jeweler (1.8.4)
4
+ activesupport (4.1.4)
5
+ i18n (~> 0.6, >= 0.6.9)
6
+ json (~> 1.7, >= 1.7.7)
7
+ minitest (~> 5.1)
8
+ thread_safe (~> 0.1)
9
+ tzinfo (~> 1.1)
10
+ addressable (2.3.6)
11
+ builder (3.2.2)
12
+ diff-lcs (1.2.5)
13
+ faraday (0.8.9)
14
+ multipart-post (~> 1.2.0)
15
+ git (1.2.7)
16
+ github_api (0.10.1)
17
+ addressable
18
+ faraday (~> 0.8.1)
19
+ hashie (>= 1.2)
20
+ multi_json (~> 1.4)
21
+ nokogiri (~> 1.5.2)
22
+ oauth2
23
+ hashie (3.2.0)
24
+ highline (1.6.21)
25
+ i18n (0.6.11)
26
+ jeweler (1.8.8)
27
+ builder
11
28
  bundler (~> 1.0)
12
29
  git (>= 1.2.5)
30
+ github_api (= 0.10.1)
31
+ highline (>= 1.6.15)
32
+ nokogiri (= 1.5.10)
13
33
  rake
14
34
  rdoc
15
- json (1.7.4)
16
- multi_json (1.3.6)
17
- rake (0.9.2.2)
18
- rdoc (3.12)
35
+ json (1.8.1)
36
+ jwt (1.0.0)
37
+ minitest (5.4.0)
38
+ multi_json (1.10.1)
39
+ multi_xml (0.5.5)
40
+ multipart-post (1.2.0)
41
+ nokogiri (1.5.10)
42
+ oauth2 (1.0.0)
43
+ faraday (>= 0.8, < 0.10)
44
+ jwt (~> 1.0)
45
+ multi_json (~> 1.3)
46
+ multi_xml (~> 0.5)
47
+ rack (~> 1.2)
48
+ rack (1.5.2)
49
+ rake (10.3.2)
50
+ rdoc (3.12.2)
19
51
  json (~> 1.4)
20
- rspec (2.11.0)
21
- rspec-core (~> 2.11.0)
22
- rspec-expectations (~> 2.11.0)
23
- rspec-mocks (~> 2.11.0)
24
- rspec-core (2.11.1)
25
- rspec-expectations (2.11.2)
26
- diff-lcs (~> 1.1.3)
27
- rspec-mocks (2.11.2)
52
+ rspec (3.0.0)
53
+ rspec-core (~> 3.0.0)
54
+ rspec-expectations (~> 3.0.0)
55
+ rspec-mocks (~> 3.0.0)
56
+ rspec-core (3.0.2)
57
+ rspec-support (~> 3.0.0)
58
+ rspec-expectations (3.0.2)
59
+ diff-lcs (>= 1.2.0, < 2.0)
60
+ rspec-support (~> 3.0.0)
61
+ rspec-mocks (3.0.2)
62
+ rspec-support (~> 3.0.0)
63
+ rspec-support (3.0.2)
64
+ thread_safe (0.3.4)
65
+ tzinfo (1.2.1)
66
+ thread_safe (~> 0.1)
28
67
 
29
68
  PLATFORMS
30
69
  ruby
data/README.md CHANGED
@@ -1,9 +1,7 @@
1
1
  ephemeral
2
2
  =========
3
3
 
4
- Ephemeral was created at Trunk Club to bring ORM-like functionality to non-persisted objects. The anticipated use case is for an application that consumes an API and materializes one or more collections of objects from a JSON response or XML response.
5
-
6
- Please note that Ephemeral is currently in beta and is probably not ready for production use.
4
+ Ephemeral brings ORM-like functionality to non-persisted objects. The anticipated use case is for an application that consumes an API and materializes one or more collections of objects from a JSON response or XML response. Another frequent use involves providing relations and scopes to POROs (plain old Ruby objects).
7
5
 
8
6
  Example the First
9
7
  =================
@@ -19,7 +17,8 @@ Let's say that we have an API server that stores information about the invention
19
17
  scope :telegraphy, {:category => 'Telegraphy'}
20
18
  scope :electrical, {:category => 'Electrical'}
21
19
  scope :mechanical, {:category => 'Mechanical'}
22
- scope :stolen {:stolen_by_edison => true }
20
+ scope :stolen, {:stolen_by_edison => true }
21
+ scope :by_name, lambda{|name| where :name => name}
23
22
 
24
23
  def initialize(args={})
25
24
  # Marshal object based on your API
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.0
1
+ 2.3.0
data/ephemeral.gemspec CHANGED
@@ -2,14 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: ephemeral 2.3.0 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
8
  s.name = "ephemeral"
8
- s.version = "1.3.0"
9
+ s.version = "2.3.0"
9
10
 
10
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
11
13
  s.authors = ["Corey Ehmke"]
12
- s.date = "2013-09-23"
14
+ s.date = "2014-07-10"
13
15
  s.description = "Ephemeral lets you define one-to-many relationships between in-memory objects, with ORM-like support for where clauses and chainable scopes."
14
16
  s.email = "corey@idolhands.com"
15
17
  s.extra_rdoc_files = [
@@ -17,6 +19,7 @@ Gem::Specification.new do |s|
17
19
  "README.md"
18
20
  ]
19
21
  s.files = [
22
+ ".rspec",
20
23
  "Gemfile",
21
24
  "Gemfile.lock",
22
25
  "LICENSE.txt",
@@ -32,12 +35,11 @@ Gem::Specification.new do |s|
32
35
  ]
33
36
  s.homepage = "http://github.com/Bantik/ephemeral"
34
37
  s.licenses = ["MIT"]
35
- s.require_paths = ["lib"]
36
- s.rubygems_version = "1.8.24"
38
+ s.rubygems_version = "2.2.2"
37
39
  s.summary = "Ephemeral is an ODM for in-memory collections of objects."
38
40
 
39
41
  if s.respond_to? :specification_version then
40
- s.specification_version = 3
42
+ s.specification_version = 4
41
43
 
42
44
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
45
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
@@ -9,6 +9,7 @@ module Ephemeral
9
9
  base.extend ClassMethods
10
10
  base.send(:attr_accessor, :relations)
11
11
  base.send(:attr_writer, :collections)
12
+ base.send(:class_variable_set, "@@objects", [])
12
13
  end
13
14
 
14
15
  def collections
@@ -17,6 +18,14 @@ module Ephemeral
17
18
 
18
19
  module ClassMethods
19
20
 
21
+ def new(*args, &block)
22
+ object = allocate
23
+ object.send(:initialize, *args, &block)
24
+ objects = class_variable_get("@@objects")
25
+ class_variable_set("@@objects", [objects, object].flatten)
26
+ object
27
+ end
28
+
20
29
  def collects(name=nil, args={})
21
30
  return @@collections unless name
22
31
  class_name = args[:class_name] || name.to_s.classify
@@ -25,9 +34,9 @@ module Ephemeral
25
34
 
26
35
  self.send :define_method, name do
27
36
  self.collections[class_name] ||= Ephemeral::Collection.new(class_name)
28
- return [] if self.collections[class_name].empty?
29
- self.collections[class_name]
37
+ self.collections[class_name]#.objects
30
38
  end
39
+
31
40
  self.send :define_method, "#{name}=" do |objects|
32
41
  self.collections[class_name] = Ephemeral::Collection.new(class_name, objects)
33
42
  end
@@ -52,7 +61,47 @@ module Ephemeral
52
61
  end
53
62
 
54
63
  def scopes
55
- @@scopes ||= {}
64
+ begin
65
+ return @@scopes if @@scopes
66
+ rescue
67
+ @@scopes = {}
68
+ attach_scopes
69
+ ensure
70
+ return @@scopes
71
+ end
72
+ end
73
+
74
+ def collections
75
+ @@collections ||= {}
76
+ end
77
+
78
+ def objects
79
+ class_variable_get("@@objects")
80
+ end
81
+
82
+ def attach_scopes
83
+ scopes.each do |k, v|
84
+ if v.is_a?(Proc)
85
+ define_singleton_method(k, v)
86
+ else
87
+ define_singleton_method k, lambda { self.execute_scope(k)}
88
+ end
89
+ end
90
+ end
91
+
92
+ def method_missing(method_name, *arguments, &block)
93
+ scope = scopes[method_name]
94
+ super if scope.nil?
95
+ if scope.is_a?(Proc)
96
+ scope.call(arguments)
97
+ else
98
+ execute_scope(method_name)
99
+ end
100
+ end
101
+
102
+ def execute_scope(method=nil)
103
+ results = scopes[method].inject([]) {|a, (k, v)| a << self.objects.select {|o| o.send(k) == v } }.flatten
104
+ Ephemeral::Collection.new(self.name, results)
56
105
  end
57
106
 
58
107
  end
@@ -6,9 +6,15 @@ module Ephemeral
6
6
 
7
7
  attr_accessor :objects, :klass
8
8
 
9
+ def self.respond_to?(method_sym, include_private = false)
10
+ if Collection.new(method_sym).match? || Collection.new.eval(klass).scopes[method_name]
11
+ true
12
+ end
13
+ end
14
+
9
15
  def initialize(klass, objects=[])
10
- self.klass = eval(klass)
11
- self.klass.scopes.each{ |k, v| define_singleton_method k, lambda { self.execute_scope(k)} }
16
+ self.klass = klass
17
+ attach_scopes
12
18
  self.objects = self.materialize(objects)
13
19
  self
14
20
  end
@@ -22,9 +28,8 @@ module Ephemeral
22
28
  end
23
29
 
24
30
  def where(args={})
25
- return [] unless self.objects
26
- results = args.inject([]) {|a, (k, v)| a << self.objects.select {|o| o.send(k) == v} }
27
- results = results.flatten.select {|r| results.flatten.count(r) == results.count }.uniq
31
+ results = args.inject([]) {|a, (k, v)| a << self.objects.select {|o| o.send(k) == v} }.flatten
32
+ Ephemeral::Collection.new(self.klass, results)
28
33
  end
29
34
 
30
35
  def last
@@ -33,19 +38,47 @@ module Ephemeral
33
38
 
34
39
  def materialize(objects_array=[])
35
40
  return [] unless objects_array
36
- return objects_array if objects_array.first.class == self.klass
37
- objects_array.map{|t| self.klass.new(t) }
41
+ return objects_array if objects_array && objects_array.first.class.name == self.klass
42
+ objects_array.map{|t| eval(self.klass).new(t) }
38
43
  end
39
44
 
40
- def execute_scope(method)
41
- return Ephemeral::Collection.new(self.klass.name) unless self.objects
42
- results = self.klass.scopes[method].inject([]) {|a, (k, v)| a << self.objects.select {|o| o.send(k) == v } }
43
- results = results.flatten.select {|r| results.flatten.count(r) == results.count }.uniq
44
- Ephemeral::Collection.new(self.klass.name, results)
45
+ def execute_scope(method=nil)
46
+ results = eval(self.klass).scopes[method].inject([]) {|a, (k, v)| a << self.objects.select {|o| o.send(k) == v } }.flatten
47
+ Ephemeral::Collection.new(self.klass, results)
45
48
  end
46
49
 
47
50
  def << (objekts)
48
- self.objects += objekts
51
+ self.objects << objekts
52
+ self.objects.flatten!
53
+ end
54
+
55
+ def marshal_dump
56
+ [@klass, @objects]
57
+ end
58
+
59
+ def marshal_load(array=[])
60
+ @klass, @objects = array
61
+ attach_scopes
62
+ end
63
+
64
+ def attach_scopes
65
+ eval(self.klass).scopes.each do |k, v|
66
+ if v.is_a?(Proc)
67
+ define_singleton_method(k, v)
68
+ else
69
+ define_singleton_method k, lambda { self.execute_scope(k)}
70
+ end
71
+ end
72
+ end
73
+
74
+ def method_missing(method_name, *arguments, &block)
75
+ scope = eval(self.klass).scopes[method_name]
76
+ super if scope.nil?
77
+ if scope.is_a?(Proc)
78
+ scope.call(arguments)
79
+ else
80
+ execute_scope(method_name)
81
+ end
49
82
  end
50
83
 
51
84
  end
@@ -5,15 +5,15 @@ module Ephemeral
5
5
  attr_accessor :object, :klass
6
6
 
7
7
  def initialize(klass, object=nil)
8
- self.klass = eval(klass)
8
+ self.klass = klass
9
9
  self.object = self.materialize(object)
10
10
  self
11
11
  end
12
12
 
13
13
  def materialize(object=nil)
14
14
  return nil unless object
15
- return object if object.is_a? self.klass
16
- self.klass.new(object)
15
+ return object if object.class.name == self.klass
16
+ eval(self.klass).new(object)
17
17
  end
18
18
 
19
19
  end
@@ -6,6 +6,7 @@ class Rarity
6
6
  scope :foos, {:name => 'foo'}
7
7
  scope :paychecks, {:name => 'Paychecks'}
8
8
  scope :threes, {:item_count => 3}
9
+ scope :by_name, lambda{|name| where :name => name}
9
10
  def initialize(args={}); args.each{|k,v| self.send("#{k}=", v)}; end
10
11
  end
11
12
 
@@ -44,24 +45,24 @@ describe Ephemeral do
44
45
  context 'collections' do
45
46
 
46
47
  it 'defines a collection' do
47
- Collector.collects[:rarities].klass.should == Rarity
48
- Collector.collects[:antiques].klass.should == Antique
48
+ Collector.collects[:rarities].klass.should == 'Rarity'
49
+ Collector.collects[:antiques].klass.should == 'Antique'
49
50
  end
50
51
 
51
52
  it 'accepts a class name' do
52
- Collector.collects[:junk].klass.should == NotCollectible
53
+ Collector.collects[:junk].klass.should == 'NotCollectible'
53
54
  end
54
55
 
55
56
  it 'creates a setter' do
56
- Collector.new.respond_to?(:rarities=).should be_true
57
+ Collector.new.respond_to?(:rarities=).should be_truthy
57
58
  end
58
59
 
59
60
  it 'creates a getter' do
60
- Collector.new.respond_to?(:rarities).should be_true
61
+ Collector.new.respond_to?(:rarities).should be_truthy
61
62
  end
62
63
 
63
64
  it 'registers a scope' do
64
- Rarity.scopes.include?(:foos).should be_true
65
+ Rarity.scopes.include?(:by_name).should be_truthy
65
66
  end
66
67
 
67
68
  end
@@ -69,7 +70,7 @@ describe Ephemeral do
69
70
  context 'relations' do
70
71
 
71
72
  it 'defines a relation' do
72
- Antique.new(:picker => {:name => 'Frank Fritz'}).picker.is_a?(Picker).should be_true
73
+ Antique.new(:picker => {:name => 'Frank Fritz'}).picker.is_a?(Picker).should be_truthy
73
74
  end
74
75
 
75
76
  end
@@ -127,10 +128,6 @@ describe Ephemeral do
127
128
 
128
129
  end
129
130
 
130
- it 'initializes with an empty array' do
131
- Collector.new.rarities.should == []
132
- end
133
-
134
131
  it 'performs a where' do
135
132
  @collector.rarities.where(:name => 'Paychecks').should_not be_blank
136
133
  @collector.antiques.where(:name => 'Trading Cards').should_not be_blank
@@ -150,6 +147,10 @@ describe Ephemeral do
150
147
  @collector.rarities.paychecks.threes.count.should == 1
151
148
  end
152
149
 
150
+ it 'handle lambda scopes' do
151
+ @collector.rarities.by_name('Paychecks').count.should == 2
152
+ end
153
+
153
154
  end
154
155
 
155
156
  end
metadata CHANGED
@@ -1,94 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ephemeral
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
5
- prerelease:
4
+ version: 2.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Corey Ehmke
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-09-23 00:00:00.000000000 Z
11
+ date: 2014-07-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rdoc
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: '3.12'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: '3.12'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: bundler
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rspec
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - ">="
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - ">="
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: jeweler
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ~>
73
+ - - "~>"
84
74
  - !ruby/object:Gem::Version
85
75
  version: 1.8.4
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ~>
80
+ - - "~>"
92
81
  - !ruby/object:Gem::Version
93
82
  version: 1.8.4
94
83
  description: Ephemeral lets you define one-to-many relationships between in-memory
@@ -100,6 +89,7 @@ extra_rdoc_files:
100
89
  - LICENSE.txt
101
90
  - README.md
102
91
  files:
92
+ - ".rspec"
103
93
  - Gemfile
104
94
  - Gemfile.lock
105
95
  - LICENSE.txt
@@ -115,29 +105,25 @@ files:
115
105
  homepage: http://github.com/Bantik/ephemeral
116
106
  licenses:
117
107
  - MIT
108
+ metadata: {}
118
109
  post_install_message:
119
110
  rdoc_options: []
120
111
  require_paths:
121
112
  - lib
122
113
  required_ruby_version: !ruby/object:Gem::Requirement
123
- none: false
124
114
  requirements:
125
- - - ! '>='
115
+ - - ">="
126
116
  - !ruby/object:Gem::Version
127
117
  version: '0'
128
- segments:
129
- - 0
130
- hash: 1892452542155194633
131
118
  required_rubygems_version: !ruby/object:Gem::Requirement
132
- none: false
133
119
  requirements:
134
- - - ! '>='
120
+ - - ">="
135
121
  - !ruby/object:Gem::Version
136
122
  version: '0'
137
123
  requirements: []
138
124
  rubyforge_project:
139
- rubygems_version: 1.8.24
125
+ rubygems_version: 2.2.2
140
126
  signing_key:
141
- specification_version: 3
127
+ specification_version: 4
142
128
  summary: Ephemeral is an ODM for in-memory collections of objects.
143
129
  test_files: []