riagent 0.0.2 → 0.0.3

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.
@@ -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)