ephemeral 1.3.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: []