key_value 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -4,6 +4,8 @@ gem 'activerecord'
4
4
 
5
5
  group :dev do # not development <-> would add unneeded development dependencies in gemspec
6
6
  gem 'sqlite3'
7
+ gem 'mysql2', '~>0.2.0'
8
+ gem 'handlersocket'
7
9
  gem 'rake'
8
10
  gem 'rspec', '~>2'
9
11
  gem 'jeweler'
data/Gemfile.lock CHANGED
@@ -15,20 +15,22 @@ GEM
15
15
  builder (2.1.2)
16
16
  diff-lcs (1.1.2)
17
17
  git (1.2.5)
18
+ handlersocket (0.0.2)
18
19
  i18n (0.5.0)
19
20
  jeweler (1.6.0)
20
21
  bundler (~> 1.0.0)
21
22
  git (>= 1.2.5)
22
23
  rake
24
+ mysql2 (0.2.7)
23
25
  rake (0.8.7)
24
- rspec (2.5.0)
25
- rspec-core (~> 2.5.0)
26
- rspec-expectations (~> 2.5.0)
27
- rspec-mocks (~> 2.5.0)
28
- rspec-core (2.5.1)
29
- rspec-expectations (2.5.0)
26
+ rspec (2.6.0)
27
+ rspec-core (~> 2.6.0)
28
+ rspec-expectations (~> 2.6.0)
29
+ rspec-mocks (~> 2.6.0)
30
+ rspec-core (2.6.0)
31
+ rspec-expectations (2.6.0)
30
32
  diff-lcs (~> 1.1.2)
31
- rspec-mocks (2.5.0)
33
+ rspec-mocks (2.6.0)
32
34
  sqlite3 (1.3.3)
33
35
  tzinfo (0.3.27)
34
36
 
@@ -37,7 +39,9 @@ PLATFORMS
37
39
 
38
40
  DEPENDENCIES
39
41
  activerecord
42
+ handlersocket
40
43
  jeweler
44
+ mysql2 (~> 0.2.0)
41
45
  rake
42
46
  rspec (~> 2)
43
47
  sqlite3
data/Readme.md CHANGED
@@ -24,23 +24,40 @@ Migration
24
24
 
25
25
  Usage
26
26
  =====
27
- KeyValue['xxx'] = {:baz=>'foo'})
28
- or KeyValue.set('xxx', {:baz=>'foo'})
29
-
27
+ # get
30
28
  KeyValue['xxx'] -> {:baz=>'foo'}
31
29
  or KeyValue.get('xxx') -> {:baz=>'foo'}
32
30
 
31
+ # set
32
+ KeyValue['xxx'] = {:baz=>'foo'})
33
+ or KeyValue.set('xxx', {:baz=>'foo'})
34
+
35
+ # delete
33
36
  KeyValue['xxx'] = nil
34
37
  or KeyValue.del('xxx')
35
38
 
39
+ # increment
36
40
  KeyValue.inc('xxx') # !! Not atomic
37
41
  or KeyValue.inc('xxx', 5)
38
42
 
43
+ # cache
39
44
  KeyValue.cache('xxx'){ ..something expensive.. }
40
45
 
46
+ HandlerSocket for [750k-qps](http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html),
47
+ [Ubuntu natty guide](http://grosser.it/2011/05/14/installing-mysql-handlersocket-in-ubuntu-natty-for-ruby/)
48
+
49
+ KeyValue.handler_socket = {:host => '127.0.0.1', :port=>'9998', :database => 'foo_development'}
50
+
51
+ # all read requests use HandlerSocket
52
+ KeyValue['xxx'] # -> same as before but faster :)
53
+
41
54
  TODO
42
55
  ====
43
- - HandlerSocket support
56
+ - nice error handling for HandlerSocket
57
+ - reuse host/database from normal connection for HandlerSocket
58
+ - HandlerSocket write support
59
+ - use 'key' column as primary key <-> any problems with that ?
60
+ - make test database configurable
44
61
 
45
62
  Authors
46
63
  =======
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.4
1
+ 0.2.0
data/key_value.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{key_value}
8
- s.version = "0.1.4"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Roman Heinrich", "Michael Grosser"]
12
- s.date = %q{2011-05-13}
12
+ s.date = %q{2011-05-14}
13
13
  s.email = %q{michael@grosser.it}
14
14
  s.files = [
15
15
  "Gemfile",
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  "VERSION",
20
20
  "key_value.gemspec",
21
21
  "lib/key_value.rb",
22
+ "spec/Readme.md",
22
23
  "spec/key_value_spec.rb",
23
24
  "spec/spec_helper.rb"
24
25
  ]
data/lib/key_value.rb CHANGED
@@ -1,11 +1,15 @@
1
1
  require 'active_record'
2
2
 
3
3
  class KeyValue < ActiveRecord::Base
4
+ HS_DEFAULT_CONFIG = {:port => '9998'}
5
+ HS_INDEX = 31234 # just some high number...
4
6
  VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
5
7
  validates_presence_of :key
6
8
 
7
9
  serialize :value
8
10
 
11
+ cattr_accessor :handler_socket
12
+
9
13
  # serialize would treat false the same as nil
10
14
  def value=(x)
11
15
  x = x.to_yaml unless x.nil?
@@ -13,7 +17,14 @@ class KeyValue < ActiveRecord::Base
13
17
  end
14
18
 
15
19
  def self.get(key)
16
- KeyValue.find_by_key(key).try(:value)
20
+ if handler_socket
21
+ hs_connection.open_index(HS_INDEX, handler_socket[:database], 'key_values', 'index_key_values_on_key', 'value')
22
+ result = hs_connection.execute_single(HS_INDEX, '=', [key])
23
+ return unless result = result[1][0]
24
+ YAML.load(result[0])
25
+ else
26
+ KeyValue.find_by_key(key).try(:value)
27
+ end
17
28
  end
18
29
 
19
30
  def self.set(key, value)
@@ -48,4 +59,13 @@ class KeyValue < ActiveRecord::Base
48
59
  value
49
60
  end
50
61
  end
62
+
63
+ private
64
+
65
+ def self.hs_connection
66
+ @@hs_connection ||= begin
67
+ require 'handlersocket'
68
+ HandlerSocket.new(HS_DEFAULT_CONFIG.merge(handler_socket).slice(:host, :port))
69
+ end
70
+ end
51
71
  end
data/spec/Readme.md ADDED
@@ -0,0 +1,4 @@
1
+ You can run the tests with sqlite.
2
+
3
+ To get full handlersocket coverage, use `DB=mysql rake`.
4
+ Handlersocket should be configured on localhost prot 9998 with database key_value_test.
@@ -2,6 +2,7 @@ require File.expand_path('spec/spec_helper')
2
2
 
3
3
  describe KeyValue do
4
4
  before do
5
+ KeyValue.handler_socket = false
5
6
  KeyValue.delete_all
6
7
  end
7
8
 
@@ -99,4 +100,31 @@ describe KeyValue do
99
100
  KeyValue.cache('xxx'){true}.should == false
100
101
  end
101
102
  end
103
+
104
+ if ENV['DB'] == 'mysql'
105
+ describe 'with handlersocket' do
106
+ before do
107
+ KeyValue.handler_socket = {:host => '127.0.0.1', :port => '9998', :database => 'key_values_test'}
108
+ KeyValue.delete_all
109
+ end
110
+
111
+ it "can get" do
112
+ KeyValue['xxx'] = '123'
113
+ KeyValue.should_not_receive(:find_by_key)
114
+ KeyValue['xxx'].should == '123'
115
+ end
116
+
117
+ it "can get nil" do
118
+ KeyValue['xxx'].should == nil
119
+ end
120
+
121
+ it "can get false" do
122
+ KeyValue['xxx'] = false
123
+ KeyValue.should_not_receive(:find_by_key)
124
+ KeyValue['xxx'].should == false
125
+ end
126
+ end
127
+ else
128
+ puts 'not running HandlerSocket specs'
129
+ end
102
130
  end
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,24 @@
1
1
  require 'active_record'
2
2
 
3
- # connect
4
- ActiveRecord::Base.establish_connection(
5
- :adapter => "sqlite3",
6
- :database => ":memory:"
7
- )
3
+ # connect
4
+ if ENV['DB'] == 'mysql'
5
+ puts 'using mysql'
6
+ ActiveRecord::Base.establish_connection(
7
+ :adapter => "mysql2",
8
+ :database => "key_values_test"
9
+ )
10
+ else
11
+ puts 'using sqlite'
12
+ ActiveRecord::Base.establish_connection(
13
+ :adapter => "sqlite3",
14
+ :database => ":memory:"
15
+ )
16
+ end
8
17
 
9
18
  # create tables
10
19
  ActiveRecord::Schema.define(:version => 1) do
20
+ drop_table :key_values rescue nil
21
+
11
22
  create_table :key_values do |t|
12
23
  t.string :key, :null => false
13
24
  t.text :value, :null => false
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: key_value
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 4
10
- version: 0.1.4
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Roman Heinrich
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-05-13 00:00:00 +02:00
19
+ date: 2011-05-14 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -49,6 +49,7 @@ files:
49
49
  - VERSION
50
50
  - key_value.gemspec
51
51
  - lib/key_value.rb
52
+ - spec/Readme.md
52
53
  - spec/key_value_spec.rb
53
54
  - spec/spec_helper.rb
54
55
  has_rdoc: true