riagent 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ ## -------------------------------------------------------------------
2
+ ##
3
+ ## Copyright (c) "2014" Dmitri Zagidulin
4
+ ##
5
+ ## This file is provided to you under the Apache License,
6
+ ## Version 2.0 (the "License"); you may not use this file
7
+ ## except in compliance with the License. You may obtain
8
+ ## a copy of the License at
9
+ ##
10
+ ## http://www.apache.org/licenses/LICENSE-2.0
11
+ ##
12
+ ## Unless required by applicable law or agreed to in writing,
13
+ ## software distributed under the License is distributed on an
14
+ ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ ## KIND, either express or implied. See the License for the
16
+ ## specific language governing permissions and limitations
17
+ ## under the License.
18
+ ##
19
+ ## -------------------------------------------------------------------
20
+
21
+ require "riak"
22
+ require "riagent/persistence/riak_kv_strategy"
23
+
24
+ module Riagent
25
+ module Persistence
26
+ class RiakDTSetStrategy < RiakKVStrategy
27
+ attr_writer :key_list_set
28
+
29
+ # Adds a key to the collection key list (usually done as part of an insert)
30
+ # Added as a standalone method for ease of testing
31
+ # @param [String] key Key to be added to list
32
+ def add_key(key)
33
+ self.key_list_set.add(key)
34
+ end
35
+
36
+ # Return all the documents in the collection.
37
+ # Uses Riak 2.0 CRDT Set Data type to keep track of collection key list
38
+ # @param [Integer] results_limit Number of results returned (currently ignored)
39
+ # @return [Array<Riagent::ActiveDocument>] List of ActiveDocument instances
40
+ def all(results_limit)
41
+ keys = self.all_keys
42
+ # TODO: Trim keys to results_limit
43
+ all_docs_hash = self.bucket.get_many(keys)
44
+ all_docs_hash.values
45
+ end
46
+
47
+ # Return all keys in the collection
48
+ # @return [Array<String>] List of all keys in the collection
49
+ def all_keys
50
+ self.key_list_set.members.to_a
51
+ end
52
+
53
+ # Deletes a key from the key list (usually called by remove()).
54
+ def delete_key(key)
55
+ key_list_set = self.key_list_set.reload
56
+ key_list_set.remove(key)
57
+ end
58
+
59
+ # Clears the key list set
60
+ def delete_key_list
61
+ # Perform a Riak DELETE operation (using the bucket type interface)
62
+ self.key_lists_bucket.delete self.key_list_set_name, type: 'sets'
63
+ end
64
+
65
+ # Insert a document into the collection.
66
+ # Also inserts the document's key into the key list set.
67
+ # @param [RiakJson::ActiveDocument] document Document to be inserted
68
+ # @return [String] Document key
69
+ def insert(document)
70
+ doc_key = super
71
+ self.add_key(doc_key)
72
+ doc_key
73
+ end
74
+
75
+ # Return the Crdt Set object that keeps track of keys in this collection
76
+ # @return [Riak::Crdt::Set]
77
+ def key_list_set
78
+ # Note: Assumes that the Bucket Type for Sets is the default 'sets'
79
+ @key_list_set || Riak::Crdt::Set.new(self.key_lists_bucket, self.key_list_set_name)
80
+ end
81
+
82
+ # Return the key name of the set that keeps track of keys in this collection
83
+ # @return [String]
84
+ def key_list_set_name
85
+ '_rg_keys_' + self.collection_name()
86
+ end
87
+
88
+ # Return the bucket in which the Riagent collection key lists are kept
89
+ # @return [Riak::Bucket]
90
+ def key_lists_bucket
91
+ self.client.bucket('_rg_key_lists')
92
+ end
93
+
94
+ def remove(document)
95
+ doc_key = document.key
96
+ super
97
+ self.delete_key(doc_key)
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,114 @@
1
+ ## -------------------------------------------------------------------
2
+ ##
3
+ ## Copyright (c) "2014" Dmitri Zagidulin
4
+ ##
5
+ ## This file is provided to you under the Apache License,
6
+ ## Version 2.0 (the "License"); you may not use this file
7
+ ## except in compliance with the License. You may obtain
8
+ ## a copy of the License at
9
+ ##
10
+ ## http://www.apache.org/licenses/LICENSE-2.0
11
+ ##
12
+ ## Unless required by applicable law or agreed to in writing,
13
+ ## software distributed under the License is distributed on an
14
+ ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ ## KIND, either express or implied. See the License for the
16
+ ## specific language governing permissions and limitations
17
+ ## under the License.
18
+ ##
19
+ ## -------------------------------------------------------------------
20
+
21
+ require "riak"
22
+ require "riagent/persistence/persistence_strategy"
23
+
24
+ module Riagent
25
+ module Persistence
26
+ # General Riak Key/Value persistence strategy.
27
+ # Read and Write documents as Riak objects.
28
+ # The listing/indexing method will depend on subclass
29
+ class RiakKVStrategy < PersistenceStrategy
30
+ attr_writer :bucket
31
+
32
+ # @return [Boolean] Does this persistence strategy support querying?
33
+ def allows_query?
34
+ false
35
+ end
36
+
37
+ # @return [Riak::Bucket] Riak bucket associated with this model/collection
38
+ def bucket
39
+ @bucket ||= self.client.bucket(self.collection_name)
40
+ end
41
+
42
+ # @return [Riak::Client] Riak client (lazy-initialized, cached in current Thread)
43
+ def client
44
+ @client ||= Riagent.riak_client # See lib/configuration.rb
45
+ end
46
+
47
+ # Fetch a document by key.
48
+ # @param [String] key
49
+ # @return [ActiveDocument|nil]
50
+ def find(key)
51
+ begin
52
+ result = self.bucket.get(key)
53
+ rescue Riak::FailedRequest => fr
54
+ if fr.not_found?
55
+ result = nil
56
+ else
57
+ raise fr
58
+ end
59
+ end
60
+ self.from_riak_object(result)
61
+ end
62
+
63
+ # Converts from a Riak::RObject instance to an instance of ActiveDocument
64
+ # @param [Riak::RObject] riak_object
65
+ # @param [Boolean] persisted Mark the document as persisted/not new?
66
+ # @return [ActiveDocument|nil] ActiveDocument instance, or nil if the Riak Object is nil
67
+ def from_riak_object(riak_object, persisted=true)
68
+ return nil if riak_object.nil?
69
+ active_doc_instance = self.model_class.from_json(riak_object.raw_data, riak_object.key)
70
+ if persisted
71
+ active_doc_instance.persist! # Mark as persisted / not new
72
+ end
73
+ active_doc_instance.source_object = riak_object
74
+ active_doc_instance
75
+ end
76
+
77
+ # @param [RiakJson::ActiveDocument] document Document to be inserted
78
+ # @return [String] Document key
79
+ def insert(document)
80
+ if document.key.present?
81
+ # Attempt to fetch existing object, just in case
82
+ riak_object = self.bucket.get_or_new(document.key)
83
+ else
84
+ riak_object = self.new_riak_object()
85
+ end
86
+ riak_object.raw_data = document.to_json_document
87
+ riak_object = riak_object.store
88
+ document.source_object = riak_object # store the riak object in document
89
+ document.key = riak_object.key
90
+ end
91
+
92
+ # @param [String|nil] Optional key
93
+ # @return [Riak::RObject] New Riak object instance for this model/collection
94
+ def new_riak_object(key=nil)
95
+ Riak::RObject.new(self.bucket, key).tap do |obj|
96
+ obj.content_type = "application/json"
97
+ end
98
+ end
99
+
100
+ # Deletes the riak object that stores the document
101
+ # @param [RiakJson::ActiveDocument] document Document to be deleted
102
+ def remove(document)
103
+ self.new_riak_object(document.key).delete
104
+ document.source_object = nil
105
+ end
106
+
107
+ # @param [RiakJson::ActiveDocument] document Document to be updated
108
+ # @return [Integer] Document key
109
+ def update(document)
110
+ self.insert(document)
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,6 +1,6 @@
1
1
  ## -------------------------------------------------------------------
2
2
  ##
3
- ## Copyright (c) "2014" Dmitri Zagidulin and Basho Technologies, Inc.
3
+ ## Copyright (c) "2014" Dmitri Zagidulin
4
4
  ##
5
5
  ## This file is provided to you under the Apache License,
6
6
  ## Version 2.0 (the "License"); you may not use this file
@@ -19,13 +19,11 @@
19
19
  ## -------------------------------------------------------------------
20
20
 
21
21
  require "riak"
22
- require "riagent/persistence/persistence_strategy"
22
+ require "riagent/persistence/riak_kv_strategy"
23
23
 
24
24
  module Riagent
25
25
  module Persistence
26
- class RiakNoIndexStrategy < PersistenceStrategy
27
- attr_writer :bucket
28
-
26
+ class RiakNoIndexStrategy < RiakKVStrategy
29
27
  # Return all the documents in the collection.
30
28
  # Since this is a "no index" strategy, this can only be done via a streaming list keys
31
29
  # @param [Integer] results_limit Number of results returned (currently ignored)
@@ -36,87 +34,6 @@ module Riagent
36
34
  obj ? acc << obj : acc
37
35
  end
38
36
  end
39
-
40
- # @return [Boolean] Does this persistence strategy support querying?
41
- def allows_query?
42
- false
43
- end
44
-
45
- # @return [Riak::Bucket] Riak bucket associated with this model/collection
46
- def bucket
47
- @bucket ||= self.client.bucket(self.collection_name)
48
- end
49
-
50
- # @return [Riak::Client] Riak client (lazy-initialized, cached in current Thread)
51
- def client
52
- @client ||= Riagent.riak_client # See lib/configuration.rb
53
- end
54
-
55
- # Fetch a document by key.
56
- # @param [String] key
57
- # @return [ActiveDocument|nil]
58
- def find(key)
59
- begin
60
- result = self.bucket.get(key)
61
- rescue Riak::FailedRequest => fr
62
- if fr.not_found?
63
- result = nil
64
- else
65
- raise fr
66
- end
67
- end
68
- self.from_riak_object(result)
69
- end
70
-
71
- # Converts from a Riak::RObject instance to an instance of ActiveDocument
72
- # @param [Riak::RObject] riak_object
73
- # @param [Boolean] persisted Mark the document as persisted/not new?
74
- # @return [ActiveDocument|nil] ActiveDocument instance, or nil if the Riak Object is nil
75
- def from_riak_object(riak_object, persisted=true)
76
- return nil if riak_object.nil?
77
- active_doc_instance = self.model_class.from_json(riak_object.raw_data, riak_object.key)
78
- if persisted
79
- active_doc_instance.persist! # Mark as persisted / not new
80
- end
81
- active_doc_instance.source_object = riak_object
82
- active_doc_instance
83
- end
84
-
85
- # @param [RiakJson::ActiveDocument] document Document to be inserted
86
- # @return [Integer] Document key
87
- def insert(document)
88
- if document.key.present?
89
- # Attempt to fetch existing object, just in case
90
- riak_object = self.bucket.get_or_new(document.key)
91
- else
92
- riak_object = self.new_riak_object()
93
- end
94
- riak_object.raw_data = document.to_json_document
95
- riak_object = riak_object.store
96
- document.source_object = riak_object # store the riak object in document
97
- document.key = riak_object.key
98
- end
99
-
100
- # @param [String|nil] Optional key
101
- # @return [Riak::RObject] New Riak object instance for this model/collection
102
- def new_riak_object(key=nil)
103
- Riak::RObject.new(self.bucket, key).tap do |obj|
104
- obj.content_type = "application/json"
105
- end
106
- end
107
-
108
- # Deletes the riak object that stores the document
109
- # @param [RiakJson::ActiveDocument] document Document to be deleted
110
- def remove(document)
111
- self.new_riak_object(document.key).delete
112
- document.source_object = nil
113
- end
114
-
115
- # @param [RiakJson::ActiveDocument] document Document to be updated
116
- # @return [Integer] Document key
117
- def update(document)
118
- self.insert(document)
119
- end
120
37
  end
121
38
  end
122
39
  end
@@ -1,6 +1,6 @@
1
1
  ## -------------------------------------------------------------------
2
2
  ##
3
- ## Copyright (c) "2014" Dmitri Zagidulin and Basho Technologies, Inc.
3
+ ## Copyright (c) "2014-2015" Dmitri Zagidulin
4
4
  ##
5
5
  ## This file is provided to you under the Apache License,
6
6
  ## Version 2.0 (the "License"); you may not use this file
@@ -19,5 +19,5 @@
19
19
  ## -------------------------------------------------------------------
20
20
 
21
21
  module Riagent
22
- VERSION = "0.0.2"
22
+ VERSION = "0.0.3"
23
23
  end
data/riagent.gemspec CHANGED
@@ -28,8 +28,8 @@ Gem::Specification.new do |spec|
28
28
  spec.version = Riagent::VERSION
29
29
  spec.authors = ["Dmitri Zagidulin"]
30
30
  spec.email = ["dzagidulin@gmail.com"]
31
- spec.summary = %q{Rails integration for RiakJson document store}
32
- spec.description = %q{Provides Ruby on Rails integration for RiakJson (Riak + Solr document store API)}
31
+ spec.summary = %q{Rails integration for the Riak KV NoSQL database}
32
+ spec.description = %q{Provides Ruby on Rails integration for the Riak KV NoSQL database (plus Solr search)}
33
33
  spec.homepage = "https://github.com/dmitrizagidulin/riagent"
34
34
  spec.license = "Apache 2.0"
35
35
 
@@ -39,13 +39,13 @@ Gem::Specification.new do |spec|
39
39
  spec.require_paths = ["lib"]
40
40
 
41
41
  spec.add_runtime_dependency "riak_json"
42
- spec.add_runtime_dependency "riak-client"
42
+ spec.add_runtime_dependency "riak-client", "~> 2.0.0.rc1"
43
43
  spec.add_runtime_dependency "riagent-document"
44
44
  spec.add_runtime_dependency "activemodel", "~> 4.0"
45
45
  spec.add_runtime_dependency "activesupport", "~> 4.0"
46
46
 
47
47
  spec.add_development_dependency "bundler"
48
48
  spec.add_development_dependency "rake"
49
- spec.add_development_dependency "minitest", "~> 4.2"
49
+ spec.add_development_dependency "minitest", "~> 4.7"
50
50
  spec.add_development_dependency "minitest-spec-context"
51
51
  end
@@ -4,16 +4,16 @@
4
4
  # Configure Riak and RiakJson connections for the client, by environment
5
5
  development:
6
6
  http_port: 8098
7
- pb_port: 8097 # Protocol Buffer port
7
+ pb_port: 8087 # Protocol Buffer port
8
8
  host: 127.0.0.1
9
9
 
10
10
  # You should spin up another Riak instance to use as a test server
11
11
  test:
12
12
  http_port: 8098
13
- pb_port: 8097
13
+ pb_port: 8087
14
14
  host: 127.0.0.1
15
15
 
16
16
  production:
17
17
  http_port: 8098
18
- pb_port: 8097
18
+ pb_port: 8087
19
19
  host: 127.0.0.1
@@ -0,0 +1,34 @@
1
+ ## -------------------------------------------------------------------
2
+ ##
3
+ ## Copyright (c) "2014" Dmitri Zagidulin
4
+ ##
5
+ ## This file is provided to you under the Apache License,
6
+ ## Version 2.0 (the "License"); you may not use this file
7
+ ## except in compliance with the License. You may obtain
8
+ ## a copy of the License at
9
+ ##
10
+ ## http://www.apache.org/licenses/LICENSE-2.0
11
+ ##
12
+ ## Unless required by applicable law or agreed to in writing,
13
+ ## software distributed under the License is distributed on an
14
+ ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ ## KIND, either express or implied. See the License for the
16
+ ## specific language governing permissions and limitations
17
+ ## under the License.
18
+ ##
19
+ ## -------------------------------------------------------------------
20
+
21
+ class Category
22
+ include Riagent::ActiveDocument
23
+
24
+ # Persist to a Riak::Bucket, keep track of keys in a server-side Set CRDT data type
25
+ collection_type :riak_kv, list_keys_using: :riak_dt_set
26
+
27
+ # Explicit attributes
28
+ # key is an implied attribute, present in all ActiveDocument instances
29
+ attribute :name, String
30
+ attribute :description, String, default: ''
31
+
32
+ # Validations
33
+ validates_presence_of :name
34
+ end
@@ -24,6 +24,9 @@
24
24
  class Contact
25
25
  include Riagent::ActiveDocument
26
26
 
27
+ # Persist to a Riak::Bucket, keep track of keys via a streaming List Keys operation (not recommended)
28
+ collection_type :riak_kv, list_keys_using: :streaming_list_keys
29
+
27
30
  attribute :contact_name, String
28
31
  attribute :contact_email, String
29
32
  end
@@ -20,8 +20,9 @@
20
20
 
21
21
  class UserPreference
22
22
  include Riagent::ActiveDocument
23
-
24
- collection_type :riak_no_index # Persist to a plain Riak bucket (k/v only)
23
+
24
+ # Persist to a Riak::Bucket
25
+ collection_type :riak_kv
25
26
 
26
27
  # Explicit attributes
27
28
  # (key is an implied attribute, present in all ActiveDocument instances)