kvom 6.8.0.beta.200.869.9609b39 → 6.8.0.beta.200.883.f5f063b

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/Gemfile CHANGED
@@ -1,12 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem "activesupport" # adapter (core), storage (core), file_system_storage
4
- gem "couchrest" # couchdb_adapter
4
+ gem "rack" # file_system_storage (active_support/cache/file_store requires rack/utils)
5
5
  gem "aws-sdk" # dynamodb_adapter, s3_storage
6
- gem "rack" # file_system_storage
7
- # active_support/cache/file_store requires rack/utils
8
6
 
9
- # not that if any kvom source depends on it ;-)
10
7
  gem "pry" # the debugging shell
11
8
 
12
9
  gemspec
@@ -42,10 +42,13 @@ class DynamodbDocument < KeyAttributesDocument
42
42
  case value
43
43
  when nil
44
44
  # skip
45
+ when ""
46
+ # will not raise an error when persisted, but will be returned as nil
47
+ raise unsupported_value(value)
45
48
  when String, Fixnum, BigDecimal
46
49
  memo[name] = value
47
50
  else
48
- raise "Unsupported value type #{value.class.to_s}"
51
+ raise unsupported_value(value)
49
52
  end
50
53
  memo
51
54
  end
@@ -4,7 +4,17 @@ module Kvom; module Adapter
4
4
 
5
5
  class FilesystemDocument < KeyAttributesDocument
6
6
  def to_json
7
- Lib::Json.dump(attributes || {})
7
+ # supported values restricted to the ones of dynamo_document
8
+ attributes.each do |key, value|
9
+ case value
10
+ when ""
11
+ raise unsupported_value(value)
12
+ when nil, String, Fixnum # BigDecimal is not standard ruby
13
+ else
14
+ raise unsupported_value(value)
15
+ end
16
+ end
17
+ Lib::Json.dump(attributes)
8
18
  end
9
19
  end
10
20
 
@@ -1,5 +1,6 @@
1
- require 'kvom'
1
+ require 'kvom/adapter'
2
2
 
3
+ # :enddoc:
3
4
  module Kvom; module Adapter;
4
5
 
5
6
  class KeyAttributesDocument < Document
@@ -12,15 +13,24 @@ class KeyAttributesDocument < Document
12
13
  end
13
14
 
14
15
  def [](name)
15
- @attributes ||= load_attributes
16
16
  @attributes[name]
17
17
  end
18
18
 
19
19
  def []=(name, value)
20
- @attributes ||= load_attributes
21
20
  @attributes[name] = value
22
21
  end
23
22
 
23
+ private
24
+
25
+ def unsupported_value(value)
26
+ case value
27
+ when ""
28
+ "Unsupported value: empty string"
29
+ else
30
+ "Unsupported value type: #{value.class.to_s}"
31
+ end
32
+ end
33
+
24
34
  end
25
35
 
26
36
  end; end # module Kvom::Adapter
@@ -12,6 +12,7 @@ class Base
12
12
  include ModelIdentity
13
13
  extend ActiveModel::Naming
14
14
 
15
+
15
16
  class_attribute :key_prefix
16
17
 
17
18
  class << self
@@ -63,17 +64,16 @@ class Base
63
64
  end
64
65
 
65
66
  def initialize(doc_or_attrs = {})
66
- if doc_or_attrs.is_a?(Document)
67
- @document = doc_or_attrs
68
- else
69
- attrs = doc_or_attrs.stringify_keys
70
-
71
- attrs["id"] ||= SecureRandom.hex(8)
72
-
73
- id = attrs["id"]
74
- @document = self.class.adapter.new_document(self.class.key_for(id), attrs)
75
- @new = true
76
- end
67
+ @document =
68
+ case doc_or_attrs
69
+ when Document
70
+ doc_or_attrs
71
+ else
72
+ @new = true
73
+ attrs = doc_or_attrs.stringify_keys
74
+ key = self.class.key_for(attrs["id"] ||= SecureRandom.hex(8))
75
+ self.class.adapter.new_document(key, attrs)
76
+ end
77
77
  end
78
78
 
79
79
  def document
@@ -89,14 +89,6 @@ class Base
89
89
  @document["id"]
90
90
  end
91
91
 
92
- def read_attribute(name)
93
- @document[name]
94
- end
95
-
96
- def write_attribute(name, value)
97
- @document[name] = value
98
- end
99
-
100
92
  def new?
101
93
  @new
102
94
  end
@@ -105,6 +97,16 @@ class Base
105
97
  self.class.adapter.destroy(@document)
106
98
  end
107
99
 
100
+ private
101
+
102
+ def read_attribute(name)
103
+ @document[name]
104
+ end
105
+
106
+ def write_attribute(name, value)
107
+ @document[name] = value
108
+ end
109
+
108
110
  end
109
111
 
110
112
  end # module Kvom
@@ -16,12 +16,6 @@ describe Kvom::Base do
16
16
  expect { ModelWithoutAdapter.find("spam") }.to raise_error(/overwritten/)
17
17
  end
18
18
 
19
- it "should provide access to the underlying document" do
20
- example = ExampleModel.create(:spam => "foo")
21
- example.document["spam"].should == "foo"
22
- example.document.should be_a(Kvom::Document)
23
- end
24
-
25
19
  describe "getters and setters" do
26
20
  it "work for freshly created models" do
27
21
  example = ExampleModel.create(:spam => "foo")
@@ -44,6 +38,68 @@ describe Kvom::Base do
44
38
  loaded = ExampleModel.find(example.id)
45
39
  loaded.spam.should == "foo"
46
40
  end
41
+
42
+ context "when setting an empty string as property value" do
43
+
44
+ context "when created" do
45
+ it "raises an error" do
46
+ expect {ExampleModel.create(:spam => "")}.to raise_error "Unsupported value: empty string"
47
+ end
48
+ end
49
+
50
+ context "when saved" do
51
+ let(:example) {ExampleModel.create(:property => "not empty")}
52
+
53
+ it "raises an error" do
54
+ expect {
55
+ example.spam = ""
56
+ example.save
57
+ }.to raise_error "Unsupported value: empty string"
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+
64
+ context "when setting a value of an unsupported value class" do
65
+ context "when saved" do
66
+ let(:example) {ExampleModel.create(:property => "valid type")}
67
+
68
+ it "raises an error" do
69
+ expect {
70
+ example.spam = %w[invalid type array]
71
+ example.save
72
+ }.to raise_error "Unsupported value type: Array"
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ describe "#save" do
82
+
83
+ context "when loaded from database" do
84
+
85
+ let(:example_id) {ExampleModel.create(:spam => "ham").id}
86
+ let(:example_from_db) {ExampleModel.find(example_id)}
87
+
88
+ context "when modified" do
89
+ before do
90
+ example_from_db.spam = "and eggs"
91
+ end
92
+
93
+ it "persists the new value to the database" do
94
+ expect {
95
+ example_from_db.save
96
+ }.to change {
97
+ ExampleModel.find(example_id).spam
98
+ }.to("and eggs")
99
+ end
100
+
101
+ end
102
+ end
47
103
  end
48
104
 
49
105
  it "should accept an id as string or symbol" do
@@ -53,13 +109,13 @@ describe Kvom::Base do
53
109
  ExampleModel.find(second_id)
54
110
  end
55
111
 
56
- describe "model id's" do
112
+ describe "model's id" do
57
113
  it "should use a custom prefix when given" do
58
- CustomKeyPrefixModel.new.document.key.should =~ /^spam_prefix\/id\/.+/
114
+ CustomKeyPrefixModel.new.__send__(:document).key.should =~ /^spam_prefix\/id\/.+/
59
115
  end
60
116
 
61
117
  it "should use a default prefix" do
62
- ExampleModel.new.document.key.should =~ /^ExampleModel\/id\/.+/
118
+ ExampleModel.new.__send__(:document).key.should =~ /^ExampleModel\/id\/.+/
63
119
  end
64
120
  end
65
121
 
@@ -5,16 +5,7 @@ require File.expand_path("../../lib/kvom", __FILE__)
5
5
  class TestModel < Kvom::Base
6
6
  def self.adapter
7
7
  @adapter ||=
8
- case (type = ENV['KVOM_ADAPTER_TYPE'] || "couch")
9
- when "couch"
10
- require 'multi_json'
11
- MultiJson.engine = :yajl
12
- database_name = "kvom-unit_tests"
13
- adapter = Kvom::Adapter::CouchdbAdapter.new({
14
- :url => database_name,
15
- })
16
- CouchRest.database!(database_name)
17
- adapter
8
+ case (type = ENV['KVOM_ADAPTER_TYPE'] || "file")
18
9
  when /dynamo/
19
10
  require File.expand_path("../../../tasks/support/local_config", __FILE__)
20
11
  options = {
@@ -24,7 +15,7 @@ class TestModel < Kvom::Base
24
15
  }
25
16
  options[:partition] = "korb" if type == "partitioned_dynamo"
26
17
  Kvom::Adapter::DynamodbAdapter.new(options)
27
- when /filesystem/
18
+ when /file/
28
19
  Kvom::Adapter::FilesystemAdapter.new(:path => File.expand_path("../../tmp/fsa", __FILE__))
29
20
  end
30
21
  end
@@ -35,28 +26,17 @@ class ExampleModel < TestModel
35
26
  end
36
27
 
37
28
  RSpec.configure do |config|
38
- output = config.output_stream || $stdout
39
-
40
- adapter_specified_and_different = lambda {|adapter_name|
41
- if adapter_name # no adapter_name => do not exclude
42
- application_adapter = TestModel.adapter.class.to_s.demodulize
43
- name = application_adapter.sub("Adapter", "").sub("db", "").downcase
44
- if name != adapter_name.to_s # same adapter name => do not exclude
45
- output.print "a"
46
- true # yes, exclude
47
- end
48
- end
29
+ adapter = TestModel.adapter.class.to_s.demodulize.sub("Adapter", "").sub("db", "").downcase
30
+ adapter_specified_and_different = lambda {|required_adapter|
31
+ required_adapter && required_adapter.to_s != adapter
49
32
  }
50
33
 
34
+ multi_json_version = Gem.loaded_specs["multi_json"].version
51
35
  multi_json_version_and_insufficient = lambda {|multi_json_version_restriction|
52
- if multi_json_version_restriction
53
- multi_json_version = Gem.loaded_specs["multi_json"].version
54
- requirement = Gem::Requirement.create(multi_json_version_restriction)
55
- !requirement.satisfied_by?(multi_json_version)
56
- end
36
+ multi_json_version_restriction && !Gem::Requirement.create(multi_json_version_restriction).
37
+ satisfied_by?(multi_json_version)
57
38
  }
58
39
 
59
- output.puts "Run filtered using adapter metadata (a - when skipped)"
60
40
  config.filter_run_excluding :adapter => adapter_specified_and_different
61
41
  config.filter_run_excluding :multi_json_version => multi_json_version_and_insufficient
62
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kvom
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11187448661
4
+ hash: 988956767
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 6
@@ -9,11 +9,13 @@ version: !ruby/object:Gem::Version
9
9
  - 0
10
10
  - beta
11
11
  - 200
12
- - 869
13
- - 9609
12
+ - 883
13
+ - f
14
+ - 5
15
+ - f
16
+ - 63
14
17
  - b
15
- - 39
16
- version: 6.8.0.beta.200.869.9609b39
18
+ version: 6.8.0.beta.200.883.f5f063b
17
19
  platform: ruby
18
20
  authors:
19
21
  - Kristian Hanekamp, Infopark AG
@@ -21,11 +23,10 @@ autorequire:
21
23
  bindir: bin
22
24
  cert_chain: []
23
25
 
24
- date: 2012-07-26 00:00:00 +02:00
26
+ date: 2012-08-10 00:00:00 +02:00
25
27
  default_executable:
26
28
  dependencies:
27
29
  - !ruby/object:Gem::Dependency
28
- type: :runtime
29
30
  requirement: &id001 !ruby/object:Gem::Requirement
30
31
  none: false
31
32
  requirements:
@@ -35,11 +36,11 @@ dependencies:
35
36
  segments:
36
37
  - 1
37
38
  version: "1"
38
- prerelease: false
39
- name: multi_json
40
39
  version_requirements: *id001
41
- - !ruby/object:Gem::Dependency
40
+ name: multi_json
41
+ prerelease: false
42
42
  type: :runtime
43
+ - !ruby/object:Gem::Dependency
43
44
  requirement: &id002 !ruby/object:Gem::Requirement
44
45
  none: false
45
46
  requirements:
@@ -49,11 +50,11 @@ dependencies:
49
50
  segments:
50
51
  - 3
51
52
  version: "3"
52
- prerelease: false
53
- name: activesupport
54
53
  version_requirements: *id002
55
- - !ruby/object:Gem::Dependency
54
+ name: activesupport
55
+ prerelease: false
56
56
  type: :runtime
57
+ - !ruby/object:Gem::Dependency
57
58
  requirement: &id003 !ruby/object:Gem::Requirement
58
59
  none: false
59
60
  requirements:
@@ -63,11 +64,11 @@ dependencies:
63
64
  segments:
64
65
  - 3
65
66
  version: "3"
66
- prerelease: false
67
- name: activemodel
68
67
  version_requirements: *id003
68
+ name: activemodel
69
+ prerelease: false
70
+ type: :runtime
69
71
  - !ruby/object:Gem::Dependency
70
- type: :development
71
72
  requirement: &id004 !ruby/object:Gem::Requirement
72
73
  none: false
73
74
  requirements:
@@ -78,11 +79,11 @@ dependencies:
78
79
  - 2
79
80
  - 8
80
81
  version: "2.8"
81
- prerelease: false
82
- name: rspec
83
82
  version_requirements: *id004
84
- - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ prerelease: false
85
85
  type: :development
86
+ - !ruby/object:Gem::Dependency
86
87
  requirement: &id005 !ruby/object:Gem::Requirement
87
88
  none: false
88
89
  requirements:
@@ -92,11 +93,11 @@ dependencies:
92
93
  segments:
93
94
  - 0
94
95
  version: "0"
95
- prerelease: false
96
- name: helpful_configuration
97
96
  version_requirements: *id005
98
- - !ruby/object:Gem::Dependency
97
+ name: helpful_configuration
98
+ prerelease: false
99
99
  type: :development
100
+ - !ruby/object:Gem::Dependency
100
101
  requirement: &id006 !ruby/object:Gem::Requirement
101
102
  none: false
102
103
  requirements:
@@ -106,9 +107,10 @@ dependencies:
106
107
  segments:
107
108
  - 0
108
109
  version: "0"
109
- prerelease: false
110
- name: yajl-ruby
111
110
  version_requirements: *id006
111
+ name: yajl-ruby
112
+ prerelease: false
113
+ type: :development
112
114
  description: Use it to build object models in ruby on top of a key value store.
113
115
  email:
114
116
  - kristian.hanekamp@infopark.de
@@ -126,8 +128,6 @@ files:
126
128
  - lib/kvom.rb
127
129
  - lib/kvom/adapter.rb
128
130
  - lib/kvom/adapter/base.rb
129
- - lib/kvom/adapter/couchdb_adapter.rb
130
- - lib/kvom/adapter/couchdb_document.rb
131
131
  - lib/kvom/adapter/dynamodb_adapter.rb
132
132
  - lib/kvom/adapter/dynamodb_document.rb
133
133
  - lib/kvom/adapter/filesystem_adapter.rb
@@ -1,83 +0,0 @@
1
- require 'kvom/adapter'
2
- require 'couchrest'
3
-
4
- module Kvom; module Adapter
5
-
6
- class CouchdbAdapter < Base
7
-
8
- def new_document(key, attributes)
9
- new_document_from_attributes(attributes.merge("_id" => key))
10
- end
11
-
12
- def save(doc)
13
- doc.couchrest_document.save
14
- end
15
-
16
- def get(key)
17
- doc =
18
- begin
19
- count_request {database.get(key) }
20
- rescue RestClient::ResourceNotFound
21
- raise NotFound.for_key(key)
22
- end
23
- CouchdbDocument.new(doc)
24
- end
25
-
26
- def query(hash_value, range_value)
27
- params =
28
- case range_value
29
- when Range
30
- {
31
- :startkey => "#{hash_value}|#{range_value.begin}",
32
- :endkey => "#{hash_value}|#{range_value.end}",
33
- }
34
- else
35
- {
36
- :key => "#{hash_value}|#{range_value}",
37
- }
38
- end
39
-
40
- params[:include_docs] = true
41
- count_request {database.all_docs(params)["rows"]}.map do |entry|
42
- new_document_from_attributes(entry["doc"])
43
- end
44
- end
45
-
46
- def destroy(doc)
47
- doc.couchrest_document.destroy
48
- end
49
-
50
- private
51
-
52
- def database_url
53
- connection_spec[:url]
54
- end
55
-
56
- def new_document_from_attributes(attributes)
57
- couch_doc = CouchRest::Document.new(attributes)
58
- couch_doc.database = database
59
- CouchdbDocument.new(couch_doc)
60
- end
61
-
62
- def database
63
- @database ||= CouchRest.database(database_url)
64
- end
65
-
66
- module BlobSupport
67
-
68
- def blob_url(id)
69
- "#{ database_url }/#{ id }/blob"
70
- end
71
-
72
- def blob_attachment(id)
73
- document = count_request {database.get(id)}
74
- document["_attachments"]["blob"]
75
- end
76
-
77
- end
78
-
79
- include BlobSupport
80
-
81
- end
82
-
83
- end; end # module Kvom::Adapter
@@ -1,27 +0,0 @@
1
- require 'kvom/adapter'
2
-
3
- module Kvom; module Adapter
4
-
5
- class CouchdbDocument < Document
6
-
7
- attr_accessor :couchrest_document
8
-
9
- def initialize(couchrest_document)
10
- self.couchrest_document = couchrest_document
11
- end
12
-
13
- def [](name)
14
- couchrest_document[name]
15
- end
16
-
17
- def []=(name, value)
18
- couchrest_document[name] = value
19
- end
20
-
21
- def key
22
- couchrest_document.id
23
- end
24
-
25
- end
26
-
27
- end; end # module Kvom::Adapter