key_value 0.2.0 → 0.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.
data/Readme.md CHANGED
@@ -1,4 +1,4 @@
1
- Abuse Sql database as Key-Value Store
1
+ Abuse Sql database as Key-Value Store that can be [750k-qps-crazy-fast](http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html) via HandlerSocket
2
2
 
3
3
  Install
4
4
  =======
@@ -6,12 +6,12 @@ Install
6
6
 
7
7
  Migration
8
8
  =========
9
- `rails g migration create_key_value`
9
+ `rails g migration create_key_value` and paste in:
10
10
 
11
11
  class CreateKeyValue < ActiveRecord::Migration
12
12
  def self.up
13
- create_table :key_values do |t|
14
- t.string :key, :null => false
13
+ create_table :key_values, :id => false do |t|
14
+ t.string :key, :null => false, :primary => true
15
15
  t.text :value, :null => false
16
16
  end
17
17
  add_index :key_values, :key, :unique => true
@@ -43,10 +43,10 @@ Usage
43
43
  # cache
44
44
  KeyValue.cache('xxx'){ ..something expensive.. }
45
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/)
46
+ HandlerSocket ([Ubuntu natty guide](http://grosser.it/2011/05/14/installing-mysql-handlersocket-in-ubuntu-natty-for-ruby/)):
48
47
 
49
- KeyValue.handler_socket = {:host => '127.0.0.1', :port=>'9998', :database => 'foo_development'}
48
+ KeyValue.handler_socket = true
49
+ # or Hash with any of these keys :host :port :database :timeout :listen_backlog :sndbuf :rcvbuf
50
50
 
51
51
  # all read requests use HandlerSocket
52
52
  KeyValue['xxx'] # -> same as before but faster :)
@@ -54,9 +54,7 @@ HandlerSocket for [750k-qps](http://yoshinorimatsunobu.blogspot.com/2010/10/usin
54
54
  TODO
55
55
  ====
56
56
  - nice error handling for HandlerSocket
57
- - reuse host/database from normal connection for HandlerSocket
58
57
  - HandlerSocket write support
59
- - use 'key' column as primary key <-> any problems with that ?
60
58
  - make test database configurable
61
59
 
62
60
  Authors
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.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.2.0"
8
+ s.version = "0.3.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-14}
12
+ s.date = %q{2011-05-15}
13
13
  s.email = %q{michael@grosser.it}
14
14
  s.files = [
15
15
  "Gemfile",
data/lib/key_value.rb CHANGED
@@ -4,8 +4,8 @@ class KeyValue < ActiveRecord::Base
4
4
  HS_DEFAULT_CONFIG = {:port => '9998'}
5
5
  HS_INDEX = 31234 # just some high number...
6
6
  VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
7
- validates_presence_of :key
8
7
 
8
+ set_primary_key :key
9
9
  serialize :value
10
10
 
11
11
  cattr_accessor :handler_socket
@@ -18,7 +18,7 @@ class KeyValue < ActiveRecord::Base
18
18
 
19
19
  def self.get(key)
20
20
  if handler_socket
21
- hs_connection.open_index(HS_INDEX, handler_socket[:database], 'key_values', 'index_key_values_on_key', 'value')
21
+ open_key_index
22
22
  result = hs_connection.execute_single(HS_INDEX, '=', [key])
23
23
  return unless result = result[1][0]
24
24
  YAML.load(result[0])
@@ -31,7 +31,10 @@ class KeyValue < ActiveRecord::Base
31
31
  if value.nil?
32
32
  KeyValue.delete_all(:key => key)
33
33
  else
34
- record = KeyValue.find_by_key(key) || KeyValue.new(:key => key)
34
+ unless record = KeyValue.find_by_key(key)
35
+ record = KeyValue.new
36
+ record.key = key # no mass assignment on primary key
37
+ end
35
38
  record.value = value
36
39
  record.save!
37
40
  value
@@ -63,9 +66,18 @@ class KeyValue < ActiveRecord::Base
63
66
  private
64
67
 
65
68
  def self.hs_connection
66
- @@hs_connection ||= begin
69
+ @hs_connection ||= begin
67
70
  require 'handlersocket'
68
- HandlerSocket.new(HS_DEFAULT_CONFIG.merge(handler_socket).slice(:host, :port))
71
+ HandlerSocket.new(hs_connection_config)
69
72
  end
70
73
  end
74
+
75
+ def self.hs_connection_config
76
+ given = (handler_socket == true ? {} : handler_socket)
77
+ HS_DEFAULT_CONFIG.merge(connection_pool.spec.config.merge(given))
78
+ end
79
+
80
+ def self.open_key_index
81
+ @open_key_index ||= hs_connection.open_index(HS_INDEX, hs_connection_config[:database], table_name, "index_#{table_name}_on_key", 'value')
82
+ end
71
83
  end
@@ -104,7 +104,7 @@ describe KeyValue do
104
104
  if ENV['DB'] == 'mysql'
105
105
  describe 'with handlersocket' do
106
106
  before do
107
- KeyValue.handler_socket = {:host => '127.0.0.1', :port => '9998', :database => 'key_values_test'}
107
+ KeyValue.handler_socket = true
108
108
  KeyValue.delete_all
109
109
  end
110
110
 
@@ -123,6 +123,26 @@ describe KeyValue do
123
123
  KeyValue.should_not_receive(:find_by_key)
124
124
  KeyValue['xxx'].should == false
125
125
  end
126
+
127
+ it "uses defaults" do
128
+ KeyValue.send(:hs_connection_config).except(:username, :password).should == {
129
+ :flags=>2,
130
+ :port=>"9998",
131
+ :adapter=>"mysql2",
132
+ :database=>"key_values_test"
133
+ }
134
+ end
135
+
136
+ it "merges in my given settings" do
137
+ KeyValue.handler_socket = {:port => '123'}
138
+ KeyValue.send(:hs_connection_config).except(:username, :password).should == {
139
+ :flags=>2,
140
+ :port=>"123",
141
+ :adapter=>"mysql2",
142
+ :database=>"key_values_test"
143
+ }
144
+
145
+ end
126
146
  end
127
147
  else
128
148
  puts 'not running HandlerSocket specs'
data/spec/spec_helper.rb CHANGED
@@ -19,8 +19,8 @@ end
19
19
  ActiveRecord::Schema.define(:version => 1) do
20
20
  drop_table :key_values rescue nil
21
21
 
22
- create_table :key_values do |t|
23
- t.string :key, :null => false
22
+ create_table :key_values, :id => false do |t|
23
+ t.string :key, :null => false,:primary => true
24
24
  t.text :value, :null => false
25
25
  end
26
26
  add_index :key_values, :key, :unique => true
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: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.3.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-14 00:00:00 +02:00
19
+ date: 2011-05-15 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency