riagent 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4eadd9aec51f179844d1ac1a5ff54826ba59ad35
4
- data.tar.gz: 4cbaed26f3b6f06e43c0405f401b69835f10ca81
3
+ metadata.gz: 189f3608c683deba5f7d5396006eca9567270aef
4
+ data.tar.gz: 92e10aef1130cbf20a18f5796659f1ea7e6ced30
5
5
  SHA512:
6
- metadata.gz: b31c273dbcc22ad47467ce2f7d5875ce6b04be513124b38973695130266341ed4e8440bc786d34f7e9d044271b0f77a46abc50b05f4f0155086765cfbe852bac
7
- data.tar.gz: e59f9bdd5a8e332de5e56c49e3565c772e485fbff10e19ae3f96fd1ac79e0d6ad0e4436d1c041290c471fe95ffe50c4216710d6bc8f86a187fa5e743966e0acf
6
+ metadata.gz: c6246e9dfff27679cd03f175fd0500fe67f8ad7b410eff03a3b421dccb5b589cf5554464ada2dffa5e3f8828657c1bc36ace4bc431c7a91360325672865fb7d8
7
+ data.tar.gz: a028746246a003269eaf376248b64713415e25d1279a1f6c1ed2dfc6ca6a4d6dd2b52c6ec55a53e382d98540b747c30aaa0c296b21bf5fdcd0580633b5733c98
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- riagent (0.0.1)
4
+ riagent (0.0.2)
5
5
  activemodel (~> 4.0)
6
6
  activesupport (~> 4.0)
7
7
  riagent-document
@@ -11,56 +11,56 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activemodel (4.0.2)
15
- activesupport (= 4.0.2)
14
+ activemodel (4.0.5)
15
+ activesupport (= 4.0.5)
16
16
  builder (~> 3.1.0)
17
- activesupport (4.0.2)
18
- i18n (~> 0.6, >= 0.6.4)
17
+ activesupport (4.0.5)
18
+ i18n (~> 0.6, >= 0.6.9)
19
19
  minitest (~> 4.2)
20
20
  multi_json (~> 1.3)
21
21
  thread_safe (~> 0.1)
22
22
  tzinfo (~> 0.3.37)
23
- atomic (1.1.14)
24
- axiom-types (0.0.5)
25
- descendants_tracker (~> 0.0.1)
26
- ice_nine (~> 0.9)
23
+ axiom-types (0.1.1)
24
+ descendants_tracker (~> 0.0.4)
25
+ ice_nine (~> 0.11.0)
26
+ thread_safe (~> 0.3, >= 0.3.1)
27
27
  beefcake (0.3.7)
28
28
  builder (3.1.4)
29
29
  coercible (1.0.0)
30
30
  descendants_tracker (~> 0.0.1)
31
- descendants_tracker (0.0.3)
31
+ descendants_tracker (0.0.4)
32
+ thread_safe (~> 0.3, >= 0.3.1)
32
33
  equalizer (0.0.9)
33
34
  i18n (0.6.9)
34
35
  ice_nine (0.11.0)
35
36
  innertube (1.0.2)
36
37
  json (1.8.1)
37
- mime-types (2.1)
38
+ mime-types (2.3)
38
39
  minitest (4.7.5)
39
40
  minitest-spec-context (0.0.3)
40
- multi_json (1.8.4)
41
- rake (10.1.1)
41
+ multi_json (1.10.1)
42
+ rake (10.3.2)
42
43
  rest-client (1.6.7)
43
44
  mime-types (>= 1.16)
44
45
  riagent-document (0.0.1)
45
46
  activesupport (~> 4.0)
46
47
  virtus
47
- riak-client (1.4.3)
48
+ riak-client (1.4.4.1)
48
49
  beefcake (~> 0.3.7)
49
50
  builder (>= 2.1.2)
50
51
  i18n (>= 0.4.0)
51
52
  innertube (~> 1.0.2)
52
53
  multi_json (~> 1.0)
53
- riak_json (0.0.2)
54
+ riak_json (0.0.4)
54
55
  json
55
56
  rest-client
56
- thread_safe (0.1.3)
57
- atomic
58
- tzinfo (0.3.38)
59
- virtus (1.0.1)
60
- axiom-types (~> 0.0.5)
57
+ thread_safe (0.3.4)
58
+ tzinfo (0.3.39)
59
+ virtus (1.0.2)
60
+ axiom-types (~> 0.1)
61
61
  coercible (~> 1.0)
62
- descendants_tracker (~> 0.0.1)
63
- equalizer (~> 0.0.7)
62
+ descendants_tracker (~> 0.0.3)
63
+ equalizer (~> 0.0.9)
64
64
 
65
65
  PLATFORMS
66
66
  ruby
@@ -39,6 +39,8 @@ module Riagent
39
39
  include Riagent::Persistence
40
40
  include Riagent::Associations
41
41
  extend Riagent::SearchSchema
42
+
43
+ attr_accessor :source_object
42
44
  end
43
45
 
44
46
  module ClassMethods
@@ -19,6 +19,7 @@
19
19
  ## -------------------------------------------------------------------
20
20
 
21
21
  require "active_support/concern"
22
+ require "riak"
22
23
 
23
24
  module Riagent
24
25
  module Configuration
@@ -30,6 +31,9 @@ module Riagent
30
31
  @config = value
31
32
  end
32
33
 
34
+ # Return a configuration hash for a given environment
35
+ # @param [Symbol] environment Environment for which to load the client configs
36
+ # @return [Hash]
33
37
  def config_for(environment=:development)
34
38
  if self.config.present?
35
39
  env_config = self.config[environment.to_s]
@@ -42,15 +46,28 @@ module Riagent
42
46
  end
43
47
  env_config
44
48
  end
45
-
46
- def init_clients(environment=:development)
47
- self.init_riak_json_client(environment)
49
+
50
+ # @param [Hash] env_config Configuration hash for a given environment
51
+ def init_riak_json_client(env_config)
52
+ client = RiakJson::Client.new(env_config['host'], env_config['http_port'])
53
+ self.riak_json_client = client
54
+ end
55
+
56
+ # @param [Hash] env_config Configuration hash for a given environment
57
+ def init_riak_client(env_config)
58
+ client = Riak::Client.new host: env_config['host'], pb_port: env_config['pb_port'], protocol: 'pbc'
59
+ self.riak_client = client
48
60
  end
49
61
 
50
- def init_riak_json_client(environment=:development)
62
+ # Initialize a Riagent persistence client for a given environment
63
+ # Either called explicitly (see test/test_helper.rb for example usage)
64
+ # or called by Rails through the 'riagent.configure_rails_initialization' initializer
65
+ # in lib/railtie.rb
66
+ # @param [Symbol] environment
67
+ def init_clients(environment=:development)
51
68
  env_config = self.config_for(environment)
52
- client = RiakJson::Client.new(env_config['host'], env_config['http_port'])
53
- self.riak_json_client = client
69
+ self.init_riak_json_client(env_config)
70
+ self.init_riak_client(env_config)
54
71
  end
55
72
 
56
73
  def load_config_file(config_file_path)
@@ -59,12 +76,23 @@ module Riagent
59
76
  self.config = config_hash
60
77
  end
61
78
 
62
- # @return [RiakJson::Client] The client for the current thread.
79
+ # @return [Riak::Client] The Riak client for the current thread.
80
+ def riak_client
81
+ Thread.current[:riak_client] ||= nil
82
+ end
83
+
84
+ # Sets the Riak client for the current thread.
85
+ # @param [Riak::Client] value the client
86
+ def riak_client=(value)
87
+ Thread.current[:riak_client] = value
88
+ end
89
+
90
+ # @return [RiakJson::Client] The RiakJson client for the current thread.
63
91
  def riak_json_client
64
92
  Thread.current[:riak_json_client] ||= nil
65
93
  end
66
-
67
- # Sets the client for the current thread.
94
+
95
+ # Sets the RiakJson client for the current thread.
68
96
  # @param [RiakJson::Client] value the client
69
97
  def riak_json_client=(value)
70
98
  Thread.current[:riak_json_client] = value
@@ -29,6 +29,7 @@ module Riagent
29
29
  def destroyed?
30
30
  @destroyed ||= false
31
31
  end
32
+ alias :deleted? :destroyed?
32
33
 
33
34
  # Is this a new, unsaved document?
34
35
  # Required by ActiveModel::Conversion API
@@ -37,7 +38,7 @@ module Riagent
37
38
  !persisted?
38
39
  end
39
40
 
40
- # Mark the document as saved/persisted
41
+ # Marks the document as saved/persisted
41
42
  # Called by +save+, and when instantiating query results (see ::Persistence)
42
43
  def persist!
43
44
  @persisted = true
@@ -66,7 +67,7 @@ module Riagent
66
67
  # Returns a +string+ representing the object's key suitable for use in URLs,
67
68
  # or +nil+ if <tt>persisted?</tt> is +false+.
68
69
  # Required by ActiveModel::Conversion API
69
- # @return [String, nil]
70
+ # @return [String|nil]
70
71
  def to_param
71
72
  self.key
72
73
  end
@@ -19,12 +19,19 @@
19
19
  ## -------------------------------------------------------------------
20
20
 
21
21
  require "active_support/concern"
22
+ require "riagent/persistence/persistence_strategy"
22
23
  require "riagent/persistence/riak_json_strategy"
24
+ require "riagent/persistence/riak_no_index_strategy"
23
25
 
24
26
  module Riagent
27
+ # Provides a common persistence API for RiakJson Documents.
28
+ # Most persistence calls are delegated to the Collection class instance,
29
+ # which are implemented in persistence/*_strategy.rb modules.
25
30
  module Persistence
26
31
  extend ActiveSupport::Concern
27
32
 
33
+ COLLECTION_TYPES = [:riak_json, :riak_no_index]
34
+
28
35
  included do
29
36
  extend ActiveModel::Callbacks
30
37
  define_model_callbacks :create, :update, :save, :destroy
@@ -32,8 +39,9 @@ module Riagent
32
39
 
33
40
  # Delete the document from its collection
34
41
  def destroy
42
+ return nil if self.new_record?
35
43
  run_callbacks(:destroy) do
36
- self.class.collection.remove(self)
44
+ self.class.persistence.remove(self)
37
45
  @destroyed = true
38
46
  end
39
47
  end
@@ -43,13 +51,17 @@ module Riagent
43
51
  # Also triggers :before_create / :after_create type callbacks
44
52
  # @return [String] Returns the key for the inserted document
45
53
  def save(options={:validate => true})
46
- context = new_record? ? :create : :update
54
+ context = self.new_record? ? :create : :update
47
55
  return false if options[:validate] && !valid?(context)
48
56
 
49
57
  run_callbacks(context) do
50
- result = self.class.collection.insert(self)
58
+ if context == :create
59
+ key = self.class.persistence.insert(self)
60
+ else
61
+ key = self.class.persistence.update(self)
62
+ end
51
63
  self.persist!
52
- result
64
+ key
53
65
  end
54
66
  end
55
67
 
@@ -84,25 +96,14 @@ module Riagent
84
96
  end
85
97
 
86
98
  module ClassMethods
87
- # Returns all documents (within results/pagination limit)
88
- # from a collection.
89
- # Implemented instead of all() to get around current RiakJson API limitations
90
- # @param [String,Symbol] Name of a document field
91
- # @param [Integer] Optional results limit
92
- # @return [Array] of ActiveDocument instances
93
- def all_for_field(field_name, results_limit=1000)
94
- query = {
95
- field_name => {'$regex' => "/.*/"},
96
- '$per_page'=>results_limit
97
- }.to_json
98
- result = self.collection.find_all(query)
99
- if result.present?
100
- result.documents.map {|doc| self.from_rj_document(doc, persisted=true) }
101
- end
99
+ # Return all the documents in the collection
100
+ # @param [Integer] results_limit Number of results returned
101
+ # @return [Array|nil] of ActiveDocument instances
102
+ def all(results_limit=1000)
103
+ self.persistence.all(results_limit)
102
104
  end
103
105
 
104
- # Determines the document's persistence strategy
105
- # Valid options: [:riak_json]
106
+ # Set the document's persistence strategy
106
107
  # Usage:
107
108
  # <code>
108
109
  # class SomeModel
@@ -111,55 +112,50 @@ module Riagent
111
112
  # end
112
113
  # </code>
113
114
  def collection_type(coll_type)
115
+ unless COLLECTION_TYPES.include? coll_type
116
+ raise ArgumentError, "Invalid collection type: #{coll_type.to_s}"
117
+ end
114
118
  @collection_type = coll_type
115
119
  case @collection_type
116
120
  when :riak_json
117
- self.persistence_strategy = :riak_json
118
- include Riagent::Persistence::RiakJsonStrategy
121
+ self.persistence = Riagent::Persistence::RiakJsonStrategy.new(self)
122
+ when :riak_no_index
123
+ self.persistence = Riagent::Persistence::RiakNoIndexStrategy.new(self)
119
124
  end
120
125
  end
121
126
 
122
127
  # Load a document by key.
123
128
  def find(key)
124
129
  return nil if key.nil? or key.empty?
125
- doc = self.collection.find_by_key(key)
126
- self.from_rj_document(doc, persisted=true)
130
+ self.persistence.find(key)
127
131
  end
128
132
 
129
133
  # Return the first document that matches the query
130
134
  def find_one(query)
131
- if query.kind_of? Hash
132
- query = query.to_json
133
- end
134
- doc = self.collection.find_one(query)
135
- if doc.present?
136
- self.from_rj_document(doc, persisted=true)
135
+ unless self.persistence.allows_query?
136
+ raise NotImplementedError, "This collection type does not support querying"
137
137
  end
138
+ self.persistence.find_one(query)
138
139
  end
139
140
 
140
141
  def get_collection_type
141
142
  @collection_type ||= nil
142
143
  end
143
144
 
144
- def persistence_strategy
145
- @persistence_strategy ||= nil
145
+ def persistence
146
+ @persistence ||= nil
146
147
  end
147
148
 
148
- def persistence_strategy=(strategy)
149
- @persistence_strategy = strategy
149
+ def persistence=(persistence_strategy)
150
+ @persistence = persistence_strategy
150
151
  end
151
152
 
152
153
  # Return all documents that match the query
153
154
  def where(query)
154
- if query.kind_of? Hash
155
- query = query.to_json
156
- end
157
- result = self.collection.find_all(query)
158
- if result.present?
159
- result.documents.map do |doc|
160
- self.from_rj_document(doc, persisted=true)
161
- end
155
+ unless self.persistence.allows_query?
156
+ raise NotImplementedError, "This collection type does not support querying"
162
157
  end
158
+ self.persistence.where(query)
163
159
  end
164
160
  end
165
161
  end
@@ -0,0 +1,37 @@
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_json"
22
+
23
+ module Riagent
24
+ module Persistence
25
+ # Riagent document persistence strategy
26
+ class PersistenceStrategy
27
+ attr_accessor :client
28
+ attr_accessor :collection_name
29
+ attr_accessor :model_class
30
+
31
+ def initialize(model_class)
32
+ self.model_class = model_class
33
+ self.collection_name = model_class.collection_name
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
- ## -------------------------------------------------------------------
2
- ##
1
+ ## -------------------------------------------------------------------
2
+ ##
3
3
  ## Copyright (c) "2014" Dmitri Zagidulin and Basho Technologies, Inc.
4
4
  ##
5
5
  ## This file is provided to you under the Apache License,
@@ -19,42 +19,101 @@
19
19
  ## -------------------------------------------------------------------
20
20
 
21
21
  require "riak_json"
22
- require "active_support/concern"
22
+ require "riagent/persistence/persistence_strategy"
23
23
 
24
24
  module Riagent
25
25
  module Persistence
26
- module RiakJsonStrategy
27
- extend ActiveSupport::Concern
26
+ class RiakJsonStrategy < PersistenceStrategy
27
+ attr_writer :collection
28
+
29
+ # Return all the documents in the collection
30
+ # @param [Integer] results_limit Number of results returned
31
+ # @return [Array|nil] of ActiveDocument instances
32
+ def all(results_limit=1000)
33
+ result = self.collection.all(results_limit)
34
+ if result.present?
35
+ result.documents.map do |doc|
36
+ self.from_rj_document(doc, persisted=true)
37
+ end
38
+ end
39
+ end
40
+
41
+ # @return [Boolean] Does this persistence strategy support querying?
42
+ def allows_query?
43
+ true
44
+ end
45
+
46
+ # @return [RiakJson::Client] RiakJson client for this persistence strategy (lazy initialize)
47
+ def client
48
+ @client ||= Riagent.riak_json_client # See lib/configuration.rb
49
+ end
50
+
51
+ # @return [RiakJson::Collection] instance for this persistence strategy (lazy initialize)
52
+ def collection
53
+ @collection ||= self.client.collection(self.collection_name)
54
+ end
55
+
56
+ # Fetch a document by key.
57
+ # @param [String] key
58
+ # @return [ActiveDocument|nil]
59
+ def find(key)
60
+ return nil if key.nil? or key.empty?
61
+ doc = self.collection.find_by_key(key)
62
+ self.from_rj_document(doc, persisted=true)
63
+ end
28
64
 
29
- module ClassMethods
30
- def client
31
- @client ||= Riagent.riak_json_client
65
+ # Return the first document that matches the query
66
+ # @param [String] query RiakJson query, in JSON string form
67
+ def find_one(query)
68
+ if query.kind_of? Hash
69
+ query = query.to_json
32
70
  end
33
-
34
- def client=(client)
35
- @client = client
71
+ doc = self.collection.find_one(query)
72
+ if doc.present?
73
+ self.from_rj_document(doc, persisted=true)
36
74
  end
37
-
38
- # Returns a RiakJson::Collection instance for this document
39
- def collection
40
- @collection ||= self.client.collection(self.collection_name)
75
+ end
76
+
77
+ # Converts from a RiakJson::Document instance to an instance of ActiveDocument
78
+ # @return [ActiveDocument|nil] ActiveDocument instance, or nil if the Document is nil
79
+ def from_rj_document(doc, persisted=false)
80
+ return nil if doc.nil?
81
+ active_doc_instance = self.model_class.instantiate(doc.attributes)
82
+ active_doc_instance.key = doc.key
83
+ if persisted
84
+ active_doc_instance.persist! # Mark as persisted / not new
41
85
  end
42
-
43
- # Sets the RiakJson::Collection instance for this document
44
- def collection=(collection_obj)
45
- @collection = collection_obj
86
+ active_doc_instance
87
+ end
88
+
89
+ # @param [RiakJson::ActiveDocument] doc Document to be inserted
90
+ # @return [Integer] Document key
91
+ def insert(doc)
92
+ self.collection.insert(doc)
93
+ end
94
+
95
+ # @param [RiakJson::ActiveDocument] doc Document to be deleted
96
+ def remove(doc)
97
+ self.collection.remove(doc)
98
+ end
99
+
100
+ # @param [RiakJson::ActiveDocument] doc Document to be updated
101
+ # @return [Integer] Document key
102
+ def update(doc)
103
+ self.collection.update(doc)
104
+ end
105
+
106
+ # Return all documents that match the query
107
+ # @param [String] query RiakJson query, in JSON string form
108
+ def where(query)
109
+ if query.kind_of? Hash
110
+ query = query.to_json
46
111
  end
47
-
48
- # Converts from a RiakJson::Document instance to an instance of ActiveDocument
49
- # @return [ActiveDocument, nil] ActiveDocument instance, or nil if the Document is nil
50
- def from_rj_document(doc, persisted=false)
51
- return nil if doc.nil?
52
- active_doc_instance = self.instantiate(doc.attributes)
53
- active_doc_instance.key = doc.key
54
- if persisted
55
- active_doc_instance.persist! # Mark as persisted / not new
112
+ result = self.collection.find_all(query)
113
+ if result.present?
114
+ result.documents.map do |doc|
115
+ self.from_rj_document(doc, persisted=true)
56
116
  end
57
- active_doc_instance
58
117
  end
59
118
  end
60
119
  end
@@ -0,0 +1,122 @@
1
+ ## -------------------------------------------------------------------
2
+ ##
3
+ ## Copyright (c) "2014" Dmitri Zagidulin and Basho Technologies, Inc.
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
+ class RiakNoIndexStrategy < PersistenceStrategy
27
+ attr_writer :bucket
28
+
29
+ # Return all the documents in the collection.
30
+ # Since this is a "no index" strategy, this can only be done via a streaming list keys
31
+ # @param [Integer] results_limit Number of results returned (currently ignored)
32
+ # @return [Array<Riagent::ActiveDocument>] List of ActiveDocument instances
33
+ def all(results_limit)
34
+ self.bucket.keys.inject([]) do |acc, k|
35
+ obj = self.find(k)
36
+ obj ? acc << obj : acc
37
+ end
38
+ 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
+ end
121
+ end
122
+ end
@@ -52,7 +52,7 @@ module Riagent
52
52
  # SampleModel.save_solr_schema()
53
53
  # </code>
54
54
  def save_solr_schema
55
- self.collection.set_schema(self.schema)
55
+ self.persistence.collection.set_schema(self.schema)
56
56
  end
57
57
  end
58
58
  end
@@ -19,5 +19,5 @@
19
19
  ## -------------------------------------------------------------------
20
20
 
21
21
  module Riagent
22
- VERSION = "0.0.1"
22
+ VERSION = "0.0.2"
23
23
  end
@@ -0,0 +1,30 @@
1
+ ## -------------------------------------------------------------------
2
+ ##
3
+ ## Copyright (c) "2014" Dmitri Zagidulin and Basho Technologies, Inc.
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 UserPreference
22
+ include Riagent::ActiveDocument
23
+
24
+ collection_type :riak_no_index # Persist to a plain Riak bucket (k/v only)
25
+
26
+ # Explicit attributes
27
+ # (key is an implied attribute, present in all ActiveDocument instances)
28
+ attribute :email_ok, Boolean, default: true
29
+ attribute :email_format, String, default: 'txt'
30
+ end
@@ -0,0 +1,52 @@
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 'test_helper'
22
+
23
+ describe "RiakNoIndexStrategy persistence" do
24
+ it "can save an ActiveDocument to a Riak object" do
25
+ # First, save the object to Riak
26
+ user_pref = UserPreference.new email_format: 'html'
27
+ generated_key = user_pref.save
28
+ generated_key.wont_be_empty
29
+ assert user_pref.persisted?
30
+ user_pref.source_object.must_be_kind_of Riak::RObject
31
+
32
+ # Test all() / List Keys operation. (Obviously not recommended in production)
33
+ all_docs = UserPreference.all()
34
+ all_docs[0].must_be_kind_of UserPreference
35
+
36
+ # Now read the object back
37
+ fetched_pref = UserPreference.find(generated_key)
38
+ fetched_pref.must_be_kind_of UserPreference
39
+ fetched_pref.key.must_equal generated_key
40
+ fetched_pref.email_format.must_equal 'html'
41
+ fetched_pref.source_object.must_be_kind_of Riak::RObject
42
+
43
+ # Update the object
44
+ fetched_pref.update(email_format: 'pdf')
45
+ updated_pref = fetched_pref = UserPreference.find(generated_key)
46
+ updated_pref.email_format.must_equal 'pdf'
47
+
48
+ # Delete the object (clean up)
49
+ fetched_pref.destroy
50
+ assert fetched_pref.destroyed?
51
+ end
52
+ end
data/test/test_helper.rb CHANGED
@@ -24,10 +24,12 @@ require 'riagent'
24
24
  require 'examples/models/address_book'
25
25
  require 'examples/models/contact'
26
26
  require 'examples/models/user'
27
+ require 'examples/models/user_preference'
27
28
 
28
29
  # Set this to silence "[deprecated] I18n.enforce_available_locales will default to true in the future." warnings
29
30
  I18n.config.enforce_available_locales = true
30
31
 
31
32
  # Load config file and set up the relevant clients for integration testing
33
+ Riak.disable_list_keys_warnings = true
32
34
  Riagent.load_config_file('test/config/riak.yml')
33
35
  Riagent.init_clients(:test) # Set up the client for the test environment
@@ -23,7 +23,7 @@ require 'active_model/lint'
23
23
 
24
24
  # Runs the ActiveModel::Lint test suite, to make sure a model fits the ActiveModel API
25
25
  # See http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/
26
- class ActiveModelLintTest < MiniTest::Test
26
+ class ActiveModelLintTest < Minitest::Unit::TestCase
27
27
  include ActiveModel::Lint::Tests
28
28
 
29
29
  def setup
@@ -63,15 +63,15 @@ describe "Riagent::Document has_one association" do
63
63
  mock_loaded_address_book = AddressBook.new
64
64
  mock_loaded_address_book.key = 'test-book-123'
65
65
 
66
- AddressBook.collection = MiniTest::Mock.new
67
- AddressBook.collection.expect :find_by_key, mock_loaded_address_book, ['test-book-123']
66
+ AddressBook.persistence = MiniTest::Mock.new
67
+ AddressBook.persistence.expect :find, mock_loaded_address_book, ['test-book-123']
68
68
 
69
69
  # Calling user.address_book should lazy-load via the target collection.find_by_key()
70
70
  user.address_book
71
- AddressBook.collection.verify
71
+ AddressBook.persistence.verify
72
72
 
73
73
  # Reset
74
- AddressBook.collection = nil
74
+ AddressBook.persistence = nil
75
75
  end
76
76
 
77
77
  it "adds a build_<target> method" do
@@ -28,10 +28,18 @@ describe "Riagent" do
28
28
  Riagent.must_respond_to :init_clients
29
29
  Riagent.must_respond_to :init_riak_json_client
30
30
  Riagent.must_respond_to :riak_json_client
31
+ Riagent.must_respond_to :init_riak_client
32
+ Riagent.must_respond_to :riak_client
31
33
  end
32
34
 
33
35
  it "initializes a RiakJson client" do
34
36
  # This should have been initialized from config file in test_helper.rb
35
37
  Riagent.riak_json_client.must_be_kind_of RiakJson::Client
36
38
  end
39
+
40
+ it "initializes a Riak ruby client" do
41
+ # This should have been initialized from config file in test_helper.rb
42
+ Riagent.riak_client.must_be_kind_of Riak::Client
43
+ Riagent.riak_client.protocol.must_equal 'pbc'
44
+ end
37
45
  end
@@ -21,43 +21,66 @@
21
21
  require 'test_helper'
22
22
 
23
23
  describe "a Riagent::ActiveDocument that persists to RiakJson" do
24
+ it "#model persistence instance methods" do
25
+ user = User.new
26
+
27
+ # Adding the line +collection_type :riak_json+ to a model
28
+ # exposes the usual array of persistence methods
29
+ user.must_respond_to :save
30
+ user.must_respond_to :save!
31
+ user.must_respond_to :update
32
+ user.must_respond_to :update_attributes # alias for update()
33
+ user.must_respond_to :update!
34
+ user.must_respond_to :destroy
35
+ end
36
+
37
+ it "#model persistence class methods" do
38
+ User.must_respond_to :all
39
+ User.must_respond_to :find
40
+ User.must_respond_to :find_one
41
+ User.must_respond_to :where
42
+ end
43
+
24
44
  it "saves via collection.insert()" do
25
45
  user = User.new
26
- User.collection = MiniTest::Mock.new
27
- User.collection.expect :insert, nil, [user]
46
+ User.persistence.collection = MiniTest::Mock.new
47
+ User.persistence.collection.expect :insert, nil, [user]
28
48
 
29
49
  # Calling model.save() should result in a collection.insert() call
30
50
  user.save({:validate => false})
31
- User.collection.verify
51
+ User.persistence.collection.verify
32
52
 
33
53
  # Reset
34
- User.collection = nil
54
+ User.persistence.collection = nil
35
55
  end
36
56
 
37
57
  it "updates via collection.update()" do
38
58
  user = User.new username: 'TestUserInitial'
39
- User.collection = MiniTest::Mock.new
40
- User.collection.expect :insert, nil, [user]
59
+ user.persist! # Updates only make sense for a persisted document
60
+ User.persistence.collection = MiniTest::Mock.new
61
+ User.persistence.collection.expect :update, nil, [user]
41
62
 
42
63
  # model.update() is implemented as a save() call (with updated attributes)
43
64
  user.update({ username: 'TestUserNewName'} )
44
- User.collection.verify
65
+ User.persistence.collection.verify
45
66
 
46
67
  # Reset
47
- User.collection = nil
68
+ User.persistence.collection = nil
48
69
  end
49
70
 
50
71
  it "destroys via collection.remove()" do
51
72
  user = User.new
52
- User.collection = MiniTest::Mock.new
53
- User.collection.expect :remove, nil, [user]
73
+ user.key = 'user123'
74
+ user.persist! # Remove can only be called on persisted objects that have a key
75
+ User.persistence.collection = MiniTest::Mock.new
76
+ User.persistence.collection.expect :remove, nil, [user]
54
77
 
55
78
  # Calling model.destroy() should result in a collection.remove() call
56
79
  user.destroy
57
- User.collection.verify
80
+ User.persistence.collection.verify
58
81
 
59
82
  # Reset
60
- User.collection = nil
83
+ User.persistence.collection = nil
61
84
  end
62
85
 
63
86
  it "returns nil when doing a find() for nil or empty key" do
@@ -67,52 +90,52 @@ describe "a Riagent::ActiveDocument that persists to RiakJson" do
67
90
 
68
91
  it "performs a find() via collection.find_by_key()" do
69
92
  test_key = 'user123'
70
- User.collection = MiniTest::Mock.new
71
- User.collection.expect :find_by_key, nil, [test_key]
93
+ User.persistence.collection = MiniTest::Mock.new
94
+ User.persistence.collection.expect :find_by_key, nil, [test_key]
72
95
 
73
96
  # Calling Model class find() should result in a collection.find_by_key()
74
97
  User.find(test_key)
75
- User.collection.verify
98
+ User.persistence.collection.verify
99
+
100
+ # Reset
101
+ User.persistence.collection = nil
102
+ end
103
+
104
+ it "performs an all() listing via collection.all()" do
105
+ User.persistence.collection = MiniTest::Mock.new
106
+ User.persistence.collection.expect :all, [], [1000] # default results limit of 1000
107
+
108
+ # Calling Model class where() should result in a collection.all()
109
+ User.all()
110
+ User.persistence.collection.verify
76
111
 
77
112
  # Reset
78
- User.collection = nil
113
+ User.persistence.collection = nil
79
114
  end
80
115
 
81
116
  it "performs a where() via collection.find_all()" do
82
- User.collection = MiniTest::Mock.new
117
+ User.persistence.collection = MiniTest::Mock.new
83
118
  query = { country: 'USA' }
84
- User.collection.expect :find_all, [], [query.to_json]
119
+ User.persistence.collection.expect :find_all, [], [query.to_json]
85
120
 
86
121
  # Calling Model class where() should result in a collection.find_all()
87
122
  User.where(query)
88
- User.collection.verify
123
+ User.persistence.collection.verify
89
124
 
90
125
  # Reset
91
- User.collection = nil
126
+ User.persistence.collection = nil
92
127
  end
93
128
 
94
129
  it "performs a find_one() via collection.find_one()" do
95
- User.collection = MiniTest::Mock.new
130
+ User.persistence.collection = MiniTest::Mock.new
96
131
  query = { username: 'TestUser' }
97
- User.collection.expect :find_one, [], [query.to_json]
132
+ User.persistence.collection.expect :find_one, [], [query.to_json]
98
133
 
99
134
  # Calling Model class find_one() should result in a collection.find_one()
100
135
  User.find_one(query)
101
- User.collection.verify
102
-
103
- # Reset
104
- User.collection = nil
105
- end
106
-
107
- it "performs an all_for_field() via collection.find_all()" do
108
- User.collection = MiniTest::Mock.new
109
- User.collection.expect :find_all, [], [String]
110
-
111
- # Calling Model class all_for_field() should result in a collection.find_all()
112
- User.all_for_field(:username)
113
- User.collection.verify
136
+ User.persistence.collection.verify
114
137
 
115
138
  # Reset
116
- User.collection = nil
139
+ User.persistence.collection = nil
117
140
  end
118
141
  end
@@ -0,0 +1,41 @@
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 'test_helper'
22
+
23
+ describe "a Riagent::ActiveDocument that persists via RiakNoIndex strategy" do
24
+ it "#model persistence instance methods" do
25
+ user_pref = UserPreference.new
26
+
27
+ # Adding the line +collection_type :riak_no_index+ to a model
28
+ # exposes the usual array of persistence methods
29
+ user_pref.must_respond_to :save
30
+ user_pref.must_respond_to :save!
31
+ user_pref.must_respond_to :update
32
+ user_pref.must_respond_to :update_attributes # alias for update()
33
+ user_pref.must_respond_to :update!
34
+ user_pref.must_respond_to :destroy
35
+ end
36
+
37
+ it "#model persistence class methods" do
38
+ UserPreference.must_respond_to :all
39
+ UserPreference.must_respond_to :find
40
+ end
41
+ end
@@ -1,5 +1,5 @@
1
- ## -------------------------------------------------------------------
2
- ##
1
+ ## -------------------------------------------------------------------
2
+ ##
3
3
  ## Copyright (c) "2014" Dmitri Zagidulin and Basho Technologies, Inc.
4
4
  ##
5
5
  ## This file is provided to you under the Apache License,
@@ -21,37 +21,40 @@
21
21
  require 'test_helper'
22
22
 
23
23
  describe "a Riagent::ActiveDocument has Persistence options" do
24
- context "via collection_type :riak_json" do
25
- it "#model class methods" do
26
- # Adding the line +collection_type :riak_json+ to a model
27
- # means that it will be persisted to a RiakJson::Collection
28
- User.get_collection_type.must_equal :riak_json
29
- User.persistence_strategy.must_equal :riak_json
30
-
31
- # It also grants access to a RiakJson::Client instance, to the model class
32
- User.client.must_be_kind_of RiakJson::Client
33
-
34
- User.collection.must_be_kind_of RiakJson::Collection
35
- User.collection_name.must_equal 'users'
36
- end
37
-
38
- it "#model persistence instance methods" do
39
- user = User.new
40
-
41
- # Adding the line +collection_type :riak_json+ to a model
42
- # exposes the usual array of persistence methods
43
- user.must_respond_to :save
44
- user.must_respond_to :save!
45
- user.must_respond_to :update
46
- user.must_respond_to :update_attributes # alias for update()
47
- user.must_respond_to :update!
48
- user.must_respond_to :destroy
49
- end
50
-
51
- it "#model persistence class methods" do
52
- User.must_respond_to :find
53
- User.must_respond_to :find_one
54
- User.must_respond_to :where
55
- end
24
+ it "can only persist to valid collection types" do
25
+ lambda { User.collection_type :invalid }.must_raise ArgumentError
26
+ end
27
+
28
+ it "#:riak_json collection_type" do
29
+ # Adding the line +collection_type :riak_json+ to a model
30
+ # means that it will be persisted to a RiakJson::Collection
31
+ User.get_collection_type.must_equal :riak_json
32
+ User.persistence.must_be_kind_of Riagent::Persistence::RiakJsonStrategy
33
+
34
+ # It also grants access to a RiakJson::Client instance, to the model class
35
+ User.persistence.client.must_be_kind_of RiakJson::Client
36
+
37
+ User.persistence.collection.must_be_kind_of RiakJson::Collection
38
+ User.persistence.collection_name.must_equal 'users'
39
+
40
+ # Check to see if the RiakJson persistence strategy supports querying
41
+ assert User.persistence.allows_query?
42
+ end
43
+
44
+ it "#:riak_no_index collection type" do
45
+ # Adding the line +collection_type :riak_no_index+ to a model
46
+ # means that it will be persisted as a Riak object with no indices (k/v operations only)
47
+ UserPreference.get_collection_type.must_equal :riak_no_index
48
+ UserPreference.persistence.must_be_kind_of Riagent::Persistence::RiakNoIndexStrategy
49
+
50
+ # It also grants access to a RiakJson::Client instance, to the model class
51
+ UserPreference.persistence.client.must_be_kind_of Riak::Client
52
+
53
+ UserPreference.persistence.collection_name.must_equal 'user_preferences'
54
+ UserPreference.persistence.bucket.must_be_kind_of Riak::Bucket
55
+
56
+ refute UserPreference.persistence.allows_query?, "RiakNoIndex strategy does not allow querying"
57
+ lambda { UserPreference.where({}) }.must_raise NotImplementedError, "RiakNoIndex strategy does not support querying"
58
+ lambda { UserPreference.find_one({}) }.must_raise NotImplementedError, "RiakNoIndex strategy does not support querying"
56
59
  end
57
60
  end
@@ -16,11 +16,14 @@ describe "an Active Document" do
16
16
 
17
17
  it "can save the Solr indexing schema to RiakJson" do
18
18
  schema = User.schema
19
- User.collection = MiniTest::Mock.new
19
+ User.persistence.collection = MiniTest::Mock.new
20
20
 
21
21
  # Ensure that calling User.save_solr_schema() results in a call to collection.set_schema()
22
- User.collection.expect :set_schema, nil, [RiakJson::CollectionSchema]
22
+ User.persistence.collection.expect :set_schema, nil, [RiakJson::CollectionSchema]
23
23
  User.save_solr_schema
24
- User.collection.verify
24
+ User.persistence.collection.verify
25
+
26
+ # Reset
27
+ User.persistence.collection = nil
25
28
  end
26
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riagent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitri Zagidulin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-01 00:00:00.000000000 Z
11
+ date: 2014-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: riak_json
@@ -159,7 +159,9 @@ files:
159
159
  - lib/riagent/conversion.rb
160
160
  - lib/riagent/errors.rb
161
161
  - lib/riagent/persistence.rb
162
+ - lib/riagent/persistence/persistence_strategy.rb
162
163
  - lib/riagent/persistence/riak_json_strategy.rb
164
+ - lib/riagent/persistence/riak_no_index_strategy.rb
163
165
  - lib/riagent/railtie.rb
164
166
  - lib/riagent/search_schema.rb
165
167
  - lib/riagent/version.rb
@@ -169,7 +171,9 @@ files:
169
171
  - test/examples/models/blog_post.rb
170
172
  - test/examples/models/contact.rb
171
173
  - test/examples/models/user.rb
172
- - test/integration/persistence_integration_test.rb
174
+ - test/examples/models/user_preference.rb
175
+ - test/integration/persistence_riak_json_integration_test.rb
176
+ - test/integration/persistence_riak_no_index_integration_test.rb
173
177
  - test/seeds.rb
174
178
  - test/test_helper.rb
175
179
  - test/unit/active_document_test.rb
@@ -179,6 +183,7 @@ files:
179
183
  - test/unit/config_test.rb
180
184
  - test/unit/embedded_test.rb
181
185
  - test/unit/persistence_riak_json_test.rb
186
+ - test/unit/persistence_riak_no_index_test.rb
182
187
  - test/unit/persistence_test.rb
183
188
  - test/unit/search_schema_test.rb
184
189
  - test/unit/validation_test.rb
@@ -212,7 +217,9 @@ test_files:
212
217
  - test/examples/models/blog_post.rb
213
218
  - test/examples/models/contact.rb
214
219
  - test/examples/models/user.rb
215
- - test/integration/persistence_integration_test.rb
220
+ - test/examples/models/user_preference.rb
221
+ - test/integration/persistence_riak_json_integration_test.rb
222
+ - test/integration/persistence_riak_no_index_integration_test.rb
216
223
  - test/seeds.rb
217
224
  - test/test_helper.rb
218
225
  - test/unit/active_document_test.rb
@@ -222,6 +229,7 @@ test_files:
222
229
  - test/unit/config_test.rb
223
230
  - test/unit/embedded_test.rb
224
231
  - test/unit/persistence_riak_json_test.rb
232
+ - test/unit/persistence_riak_no_index_test.rb
225
233
  - test/unit/persistence_test.rb
226
234
  - test/unit/search_schema_test.rb
227
235
  - test/unit/validation_test.rb