ssdb-attr 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42862ff9c47b1a76de97dad8d083f9f600f59899
4
- data.tar.gz: 29d3a85d0b87e99d2b392d571a705c8c0bf31b9b
3
+ metadata.gz: 3d0a8577ee7cc342983ced7c743a36fb4bf06a99
4
+ data.tar.gz: c202f59301160470540f18f6fd8bfb7a6c346d97
5
5
  SHA512:
6
- metadata.gz: 015184c70c5f94521c89f9e25f7a6d3c1d4c695b96ffbc70d239b8a706ccd87b968cf7f0240af359066eed9c86983fae5d5c3db20c7f6a0b8d86e605cf3bea65
7
- data.tar.gz: bcf2ca89d68a6fe73ff897b8300e825ac2de3973c08a85a270e64a89ea8d22239304167004ce0398a3471d6a014df15bc3f96056641cf4abccc97a113fcd73e2
6
+ metadata.gz: 0ab615231b7df6dc1bc6e9a9db48c1120150636c474961ba9d0653c7634e4bbe9580cf360fa4951d9f8257ab7f48b7ff98fee9f19b3c4478275ecb9cfe294110
7
+ data.tar.gz: 18e23b76f1d825bc3dd5bfb26be2756c976d06f58e31aaade8bb89393d6dbcd29c2380c2dca7dd3d13abac32352179813e3f3846fb36acda64daf1eab2ab14f9
data/README.md CHANGED
@@ -6,6 +6,10 @@ This gem provides an intuitive interface to define attributes on your ActiveMode
6
6
 
7
7
  # Changelog
8
8
 
9
+ ### 0.1.4
10
+
11
+ - Add `SSDBAttr.load_attrs(objects, *fields)` to load multiple attrs for multiple same objects at one time.
12
+
9
13
  ### 0.1.3
10
14
 
11
15
  - Add `load_ssdb_attrs` to get multiple values from SSDB once to avoid multiple SSDB calls.
@@ -93,5 +93,44 @@ module SSDBAttr
93
93
  end
94
94
  end
95
95
 
96
+ #
97
+ # 获取多个 AR 对象的多个 SSDB 字段
98
+ #
99
+ # 例如:
100
+ #
101
+ # notes = Note.where("<some where>").limit(15)
102
+ # SSDBAttr.load_attrs(notes, :public_title, :public_content)
103
+ #
104
+ # @param [Array] objects
105
+ # @param [Array] fields
106
+ #
107
+ # @return [ActiveRecord::Relation|Array]
108
+ #
109
+ def load_attrs(objects, *fields)
110
+ fields.map!(&:to_s)
111
+
112
+ keys = objects.flat_map do |object|
113
+ fields.map { |name| object.ssdb_attr_key(name) }
114
+ end
115
+ values = SSDBAttr.pool.with { |conn| conn.mget(keys) }
116
+ key_values = keys.zip(values).to_h
117
+
118
+ objects.each do |object|
119
+ fields.each do |name|
120
+ next unless object.class.ssdb_attr_names.include?(name.to_s)
121
+
122
+ value =
123
+ if (raw_value = key_values[object.ssdb_attr_key(name)]).present?
124
+ object.typecaster(raw_value, object.class.ssdb_attr_definition[name])
125
+ else
126
+ object.public_send("#{name}_default_value")
127
+ end
128
+
129
+ object.instance_variable_set("@#{name}", value)
130
+ end
131
+ end
132
+
133
+ objects
134
+ end
96
135
  end
97
136
  end
@@ -1,3 +1,3 @@
1
1
  module SSDBAttr
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -69,6 +69,10 @@ module SSDB
69
69
  instance_variable_set("@#{name}", val)
70
70
  end
71
71
 
72
+ define_method("#{name}_default_value") do
73
+ typecaster(options[:default], type)
74
+ end
75
+
72
76
  define_method("#{name}_was") { attribute_was(name) }
73
77
 
74
78
  define_method("#{name}_change") { attribute_change(name) }
@@ -113,16 +117,15 @@ module SSDB
113
117
  end
114
118
  end
115
119
 
116
- private
117
-
118
120
  #
119
- # Return the ConnectionPool used by current Class.
121
+ # Return the SSDB key for a attribute
120
122
  #
123
+ # @param [String] name Attribute name.
121
124
  #
122
- # @return [ConnectionPool]
125
+ # @return [String]
123
126
  #
124
- def ssdb_attr_pool
125
- SSDBAttr.pool(self.class.ssdb_attr_pool_name)
127
+ def ssdb_attr_key(name)
128
+ "#{self.class.name.tableize}:#{ssdb_attr_id}:#{name}"
126
129
  end
127
130
 
128
131
  #
@@ -142,20 +145,20 @@ module SSDB
142
145
  end
143
146
  end
144
147
 
145
- def ssdb_attr_id
146
- send(self.class.ssdb_attr_id_field || :id)
147
- end
148
-
148
+ private
149
149
 
150
150
  #
151
- # Return the SSDB key for a attribute
151
+ # Return the ConnectionPool used by current Class.
152
152
  #
153
- # @param [String] name Attribute name.
154
153
  #
155
- # @return [String]
154
+ # @return [ConnectionPool]
156
155
  #
157
- def ssdb_attr_key(name)
158
- "#{self.class.name.tableize}:#{ssdb_attr_id}:#{name}"
156
+ def ssdb_attr_pool
157
+ SSDBAttr.pool(self.class.ssdb_attr_pool_name)
158
+ end
159
+
160
+ def ssdb_attr_id
161
+ send(self.class.ssdb_attr_id_field || :id)
159
162
  end
160
163
 
161
164
  #
@@ -6,6 +6,24 @@ require "ssdb-attr"
6
6
  ActiveRecord::Base.raise_in_transactional_callbacks = true if ActiveRecord::VERSION::STRING >= "4.2"
7
7
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
8
8
 
9
+ RSpec.configure do |config|
10
+ config.expect_with :rspec do |expectations|
11
+ expectations.syntax = :expect
12
+ end
13
+
14
+ config.before(:all) do
15
+ # Connect to test SSDB server
16
+ SSDBAttr.setup(:url => "redis://localhost:8888")
17
+
18
+ # Clean up SSDB
19
+ system('printf "7\nflushdb\n\n4\nping\n\n" | nc 127.0.0.1 8888 -i 1 > /dev/null')
20
+
21
+ ActiveRecord::Base.connection.tables.each do |table|
22
+ ActiveRecord::Base.connection.execute "DELETE FROM #{table}"
23
+ end
24
+ end
25
+ end
26
+
9
27
  # Setup tables for test
10
28
  tbls = [
11
29
  { "posts" => "updated_at DATETIME, saved_at DATETIME, changed_at DATETIME" },
@@ -18,3 +36,40 @@ tbls.each do |tbl|
18
36
  ActiveRecord::Base.connection.execute "CREATE TABLE #{tbl_name} (id INTEGER NOT NULL PRIMARY KEY, #{sql})"
19
37
  end
20
38
  end
39
+
40
+ # ActiveRecord definition
41
+ class Post < ActiveRecord::Base
42
+ include SSDB::Attr
43
+
44
+ ssdb_attr :name, :string
45
+ ssdb_attr :int_version, :integer
46
+ ssdb_attr :default_title, :string, default: "Untitled"
47
+ ssdb_attr :title, :string
48
+ ssdb_attr :content, :string
49
+ ssdb_attr :version, :integer, default: 1
50
+ ssdb_attr :default_version, :integer, :default => 100
51
+ ssdb_attr :field_with_validation, :string
52
+
53
+ validate :validate_field
54
+
55
+ def validate_field
56
+ if field_with_validation == "foobar"
57
+ errors.add(:field_with_validation, "foobar error")
58
+ end
59
+ end
60
+ end
61
+
62
+ class CustomIdField < ActiveRecord::Base
63
+ include SSDB::Attr
64
+
65
+ ssdb_attr_id :uuid
66
+ ssdb_attr :content, :string
67
+ end
68
+
69
+ class CustomPoolName < ActiveRecord::Base
70
+ include SSDB::Attr
71
+
72
+ ssdb_attr_pool :foo_pool
73
+
74
+ ssdb_attr :foo_id, :integer
75
+ end
@@ -1,5 +1,4 @@
1
- # require 'spec_helper'
2
- require "ssdb-attr"
1
+ require "spec_helper"
3
2
 
4
3
  describe SSDBAttr do
5
4
 
@@ -128,4 +127,64 @@ describe SSDBAttr do
128
127
  end
129
128
  end
130
129
  end
130
+
131
+ describe ".load_attrs" do
132
+ it "returns the values correctly" do
133
+ post1 = Post.create(:name => "lol", :version => 2)
134
+ post2 = Post.create(:name => "dota", :version => 3)
135
+
136
+ posts = Post.where(:id => [post1.id, post2.id])
137
+
138
+ posts.each do |post|
139
+ expect(post.instance_variable_get(:@name)).to be(nil)
140
+ expect(post.instance_variable_get(:@version)).to be(nil)
141
+ end
142
+
143
+ SSDBAttr.load_attrs(posts, :name, :version)
144
+
145
+ expect(posts[0].instance_variable_get(:@name)).to eq("lol")
146
+ expect(posts[0].instance_variable_get(:@version)).to eq(2)
147
+
148
+ expect(posts[1].instance_variable_get(:@name)).to eq("dota")
149
+ expect(posts[1].instance_variable_get(:@version)).to eq(3)
150
+ end
151
+
152
+ it "returns default value correctly if no value in ssdb" do
153
+ post1 = Post.create(:name => "lol")
154
+ post2 = Post.create(:name => "dota")
155
+
156
+ posts = Post.where(:id => [post1.id, post2.id])
157
+
158
+ posts.each do |post|
159
+ expect(post.instance_variable_get(:@name)).to be(nil)
160
+ expect(post.instance_variable_get(:@version)).to be(nil)
161
+ end
162
+
163
+ SSDBAttr.load_attrs(posts, :name, :version)
164
+
165
+ expect(posts[0].instance_variable_get(:@name)).to eq("lol")
166
+ expect(posts[0].instance_variable_get(:@version)).to eq(1)
167
+
168
+ expect(posts[1].instance_variable_get(:@name)).to eq("dota")
169
+ expect(posts[1].instance_variable_get(:@version)).to eq(1)
170
+ end
171
+
172
+ it "doesn't define instance variables for undefined ssdb atts" do
173
+ post1 = Post.create(:name => "lol")
174
+ post2 = Post.create(:name => "dota")
175
+
176
+ posts = Post.where(:id => [post1.id, post2.id])
177
+
178
+ posts.each do |post|
179
+ expect(post.instance_variable_get(:@name)).to be(nil)
180
+ expect(post.instance_variable_get(:@version)).to be(nil)
181
+ end
182
+
183
+ SSDBAttr.load_attrs(posts, :undefined_field)
184
+
185
+ posts.each do |post|
186
+ expect(post.instance_variable_defined?(:@undefined_field)).to be(false)
187
+ end
188
+ end
189
+ end
131
190
  end
@@ -1,55 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- class Post < ActiveRecord::Base
4
- include SSDB::Attr
5
-
6
- ssdb_attr :name, :string
7
- ssdb_attr :int_version, :integer
8
- ssdb_attr :default_title, :string, default: "Untitled"
9
- ssdb_attr :title, :string
10
- ssdb_attr :content, :string
11
- ssdb_attr :version, :integer, default: 1
12
- ssdb_attr :default_version, :integer, :default => 100
13
- ssdb_attr :field_with_validation, :string
14
-
15
- validate :validate_field
16
-
17
- def validate_field
18
- if field_with_validation == "foobar"
19
- errors.add(:field_with_validation, "foobar error")
20
- end
21
- end
22
- end
23
-
24
- class CustomIdField < ActiveRecord::Base
25
- include SSDB::Attr
26
-
27
- ssdb_attr_id :uuid
28
- ssdb_attr :content, :string
29
- end
30
-
31
- class CustomPoolName < ActiveRecord::Base
32
- include SSDB::Attr
33
-
34
- ssdb_attr_pool :foo_pool
35
-
36
- ssdb_attr :foo_id, :integer
37
- end
38
-
39
3
  describe SSDB::Attr do
40
-
41
- before(:all) do
42
- # Connect to test SSDB server
43
- SSDBAttr.setup(:url => "redis://localhost:8888")
44
-
45
- # Clean up SSDB
46
- system('printf "7\nflushdb\n\n4\nping\n\n" | nc 127.0.0.1 8888 -i 1 > /dev/null')
47
-
48
- ActiveRecord::Base.connection.tables.each do |table|
49
- ActiveRecord::Base.connection.execute "DELETE FROM #{table}"
50
- end
51
- end
52
-
53
4
  context "Post" do
54
5
  let(:post) { Post.create(updated_at: 1.day.ago, saved_at: 1.day.ago, changed_at: 1.day.ago) }
55
6
  let(:redis) { Redis.new(:url => 'redis://localhost:8888') }
@@ -72,6 +23,7 @@ describe SSDB::Attr do
72
23
  it "should respond to methods" do
73
24
  expect(post.respond_to?(:name)).to be true
74
25
  expect(post.respond_to?(:name=)).to be true
26
+ expect(post.respond_to?(:name_default_value)).to be true
75
27
  expect(post.respond_to?(:name_was)).to be true
76
28
  expect(post.respond_to?(:name_change)).to be true
77
29
  expect(post.respond_to?(:name_changed?)).to be true
@@ -101,6 +53,16 @@ describe SSDB::Attr do
101
53
  end
102
54
  end
103
55
 
56
+ describe "#attirbute_default_value" do
57
+ it "returns correct default value" do
58
+ post.default_title = "changed"
59
+ post.default_version = 99
60
+
61
+ expect(post.default_title_default_value).to eq("Untitled")
62
+ expect(post.default_version_default_value).to eq(100)
63
+ end
64
+ end
65
+
104
66
  describe "#reload_ssdb_attrs" do
105
67
  it "should reload attribute values from SSDB" do
106
68
  post = Post.create(title: "foobar", version: 4)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssdb-attr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Larry Zhao
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-29 00:00:00.000000000 Z
11
+ date: 2017-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis