dyna_model 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 +4 -4
- data/README.md +10 -0
- data/lib/dyna_model/adapters/elasticsearch/dyna_model_adapter.rb +86 -0
- data/lib/dyna_model/document.rb +16 -1
- data/lib/dyna_model/query.rb +17 -9
- data/lib/dyna_model/table.rb +2 -5
- data/lib/dyna_model/version.rb +1 -1
- data/spec/dyna_model/query_spec.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 254b9c0ebdd7a60601af697b4702fa53d9dc3f0e
|
4
|
+
data.tar.gz: 9129d092e187f9284e1853d63e744ffa56e9d84a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3dd8cca0fe4249f173fceb88d4a29b706409de9a017049844493a6066ef67f2238548bddd18b9278d5ba390eeeb0910d82c103ad4db3ffe4e7171903433d164f
|
7
|
+
data.tar.gz: 9c27a58d8bb188a5a29bf49c4ab6163ae9d3f3525d85e4d6a16f6466a586c31aed0e744a36ba7de1ff31b37f4d0aefd0a50cf95ca1bbb07cce6122d5defd1ab7
|
data/README.md
CHANGED
@@ -76,6 +76,16 @@ rake ddb:destroy CLASS=Dude
|
|
76
76
|
rake ddb:destroy CLASS=all
|
77
77
|
```
|
78
78
|
|
79
|
+
## Elasticsearch::Model compatible adapter
|
80
|
+
```
|
81
|
+
require 'dyna_model/adapters/elasticsearch/dyna_model_adapter'
|
82
|
+
class Item
|
83
|
+
include DynaModel::Document
|
84
|
+
include Elasticsearch::Model
|
85
|
+
include Elasticsearch::Model::Callbacks
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
79
89
|
# AWS::Record
|
80
90
|
* http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Record.html
|
81
91
|
* https://github.com/aws/aws-sdk-ruby/blob/master/lib/aws/record/abstract_base.rb
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Model
|
3
|
+
module Adapter
|
4
|
+
module DynaModelAdapter
|
5
|
+
|
6
|
+
Adapter.register self, lambda { |klass| !!defined?(::DynaModel::Document) && klass.ancestors.include?(::DynaModel::Document) }
|
7
|
+
|
8
|
+
module Records
|
9
|
+
|
10
|
+
def records
|
11
|
+
records_arr = klass.read_multiple(ids, format: :array)
|
12
|
+
records_arr.sort_by { |e| response.response['hits']['hits'].index { |hit| hit['_id'].to_s == e.id.to_s } }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Intercept call to sorting methods, so we can ignore the order from Elasticsearch
|
16
|
+
%w| asc desc order_by |.each do |name|
|
17
|
+
define_method name do |*args|
|
18
|
+
raise "TODO - not supported yet"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Callbacks
|
24
|
+
def self.included(base)
|
25
|
+
base.after_create { |document| document.__elasticsearch__.index_document }
|
26
|
+
base.after_update { |document| document.__elasticsearch__.update_document }
|
27
|
+
base.after_destroy { |document| document.__elasticsearch__.delete_document }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module Importing
|
32
|
+
|
33
|
+
def __find_in_batches(options={}, &block)
|
34
|
+
items = []
|
35
|
+
|
36
|
+
# Use 1/4 or read provision
|
37
|
+
read_provision = self.dynamo_db_table.table_schema[:provisioned_throughput][:read_capacity_units]
|
38
|
+
raise "read_provision not set for class!" unless read_provision
|
39
|
+
default_batch_size = (read_provision / 2.0).floor
|
40
|
+
batch_size = options[:batch_size] || default_batch_size
|
41
|
+
puts "Indexing via scan with batch size of #{batch_size}..."
|
42
|
+
|
43
|
+
# :consumed_capacity
|
44
|
+
scan_idx = 0
|
45
|
+
results_hash = {}
|
46
|
+
while scan_idx == 0 || (results_hash && results_hash[:last_evaluated_key])
|
47
|
+
puts "Batch iteration #{scan_idx+1}..."
|
48
|
+
scan_options = {
|
49
|
+
batch: batch_size,
|
50
|
+
manual_batching: true,
|
51
|
+
return_consumed_capacity: :total
|
52
|
+
}
|
53
|
+
scan_options.merge!(exclusive_start_key: results_hash[:last_evaluated_key]) if results_hash[:last_evaluated_key]
|
54
|
+
scan_options.merge!(scan_filter: options[:scan_filter]) if options[:scan_filter]
|
55
|
+
results_hash = self.scan(scan_options)
|
56
|
+
|
57
|
+
unless results_hash[:results].blank?
|
58
|
+
puts "Indexing #{results_hash[:results].size} results..."
|
59
|
+
batch_for_bulk = results_hash[:results].map { |a| { index: {
|
60
|
+
_id: a.id,
|
61
|
+
data: a.__elasticsearch__.as_indexed_json
|
62
|
+
} } }
|
63
|
+
yield batch_for_bulk
|
64
|
+
end
|
65
|
+
|
66
|
+
# If more results to scan, sleep to throttle...
|
67
|
+
# Local Dynamo is not returning consumed_capacity 2014-01-12
|
68
|
+
if results_hash[:last_evaluated_key] && results_hash[:consumed_capacity]
|
69
|
+
# try to keep read usage under 50% of read_provision
|
70
|
+
sleep_time = results_hash[:consumed_capacity][:capacity_units].to_f / (read_provision / 2.0)
|
71
|
+
puts "Sleeping for #{sleep_time}..."
|
72
|
+
sleep(sleep_time)
|
73
|
+
end
|
74
|
+
|
75
|
+
scan_idx += 1
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/dyna_model/document.rb
CHANGED
@@ -34,6 +34,17 @@ module DynaModel
|
|
34
34
|
end
|
35
35
|
super
|
36
36
|
end
|
37
|
+
|
38
|
+
# OVERRIDE
|
39
|
+
# https://github.com/aws/aws-sdk-ruby/blob/master/lib/aws/record/abstract_base.rb#L76
|
40
|
+
# AWS::Record::AbstractBase for :select attributes
|
41
|
+
public
|
42
|
+
def attributes
|
43
|
+
attributes = AWS::Core::IndifferentHash.new
|
44
|
+
(self.instance_variable_get("@_selected_attributes") || self.class.attributes.keys).inject(attributes) do |hash,attr_name|
|
45
|
+
hash.merge(attr_name => __send__(attr_name))
|
46
|
+
end
|
47
|
+
end
|
37
48
|
end
|
38
49
|
|
39
50
|
include ActiveModel::Conversion
|
@@ -47,6 +58,10 @@ module DynaModel
|
|
47
58
|
include DynaModel::Schema
|
48
59
|
include DynaModel::Query
|
49
60
|
|
61
|
+
def id
|
62
|
+
self.dynamo_db_guid
|
63
|
+
end
|
64
|
+
|
50
65
|
def to_param
|
51
66
|
self.dynamo_db_guid
|
52
67
|
end
|
@@ -64,7 +79,7 @@ module DynaModel
|
|
64
79
|
end
|
65
80
|
|
66
81
|
def all_attributes_loaded?
|
67
|
-
self.instance_variable_get("@_select") == :all
|
82
|
+
self.instance_variable_get("@_select").nil? && self.instance_variable_get("@_select") == :all
|
68
83
|
end
|
69
84
|
|
70
85
|
# When only partial attributes were selected (via GSI or projected attributes on an index)
|
data/lib/dyna_model/query.rb
CHANGED
@@ -30,18 +30,26 @@ module DynaModel
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def read_multiple(keys, options={})
|
33
|
+
options[:format] = (options[:format] && options[:format] == :array) ? :array : :hash
|
33
34
|
results_map = {}
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
(
|
40
|
-
|
41
|
-
|
35
|
+
results_arr = []
|
36
|
+
if keys.present?
|
37
|
+
results = self.dynamo_db_table.batch_get_item(keys, options)
|
38
|
+
results[:responses][self.dynamo_db_table_name(options[:shard_name])].each do |result|
|
39
|
+
attrs = Response.strip_attr_types(result)
|
40
|
+
obj = self.obj_from_attrs(attrs, options)
|
41
|
+
if options[:format] == :array
|
42
|
+
results_arr << obj
|
43
|
+
else
|
44
|
+
if self.dynamo_db_table.range_keys.present? && primary_range_key = self.dynamo_db_table.range_keys.find{|rk| rk[:primary_range_key] }
|
45
|
+
(results_map[attrs[self.dynamo_db_table.hash_key[:attribute_name]]] ||= {})[attrs[primary_range_key[:attribute_name]]] = obj
|
46
|
+
else
|
47
|
+
results_map[attrs[self.dynamo_db_table.hash_key[:attribute_name]]] = obj
|
48
|
+
end
|
49
|
+
end
|
42
50
|
end
|
43
51
|
end
|
44
|
-
results_map
|
52
|
+
options[:format] == :array ? results_arr : results_map
|
45
53
|
end
|
46
54
|
|
47
55
|
# Read results up to the limit
|
data/lib/dyna_model/table.rb
CHANGED
@@ -281,16 +281,13 @@ module DynaModel
|
|
281
281
|
keys.each do |k|
|
282
282
|
key_request = {}
|
283
283
|
if @primary_range_key
|
284
|
-
hash_value = k
|
284
|
+
hash_value, range_value = k.split(@model.guid_delimiter)
|
285
285
|
else
|
286
|
-
raise ArgumentError, "expected keys to be in the form of ['hash key here'] for table with no range keys" if hash_value.is_a?(Hash)
|
287
286
|
hash_value = k
|
288
287
|
end
|
289
|
-
raise ArgumentError, "every key must include a :hash_value" if hash_value.blank?
|
290
288
|
key_request[@hash_key[:attribute_name]] = { @hash_key[:attribute_type] => hash_value.to_s }
|
291
289
|
if @primary_range_key
|
292
|
-
range_value
|
293
|
-
raise ArgumentError, "every key must include a :range_value" if range_value.blank?
|
290
|
+
raise ArgumentError, "every key must include a range_value" if range_value.blank?
|
294
291
|
key_request[@primary_range_key[:attribute_name]] = { @primary_range_key[:attribute_type] => range_value.to_s }
|
295
292
|
end
|
296
293
|
keys_request << key_request
|
data/lib/dyna_model/version.rb
CHANGED
@@ -99,7 +99,7 @@ describe "DynaModel::Query" do
|
|
99
99
|
multi[@cacher2.key].should_not be_nil
|
100
100
|
@user = User.create(@user_attrs)
|
101
101
|
@user2 = User.create(@user2_attrs)
|
102
|
-
multi = User.read_multiple([
|
102
|
+
multi = User.read_multiple([@user.dynamo_db_guid, @user2.dynamo_db_guid])
|
103
103
|
multi[@user.hashy].should_not be_nil
|
104
104
|
multi[@user.hashy][@user.ranger.to_s].should_not be_nil
|
105
105
|
multi[@user2.hashy].should_not be_nil
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dyna_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cary Dunn
|
@@ -136,6 +136,7 @@ files:
|
|
136
136
|
- Rakefile
|
137
137
|
- dyna_model.gemspec
|
138
138
|
- lib/dyna_model.rb
|
139
|
+
- lib/dyna_model/adapters/elasticsearch/dyna_model_adapter.rb
|
139
140
|
- lib/dyna_model/attributes.rb
|
140
141
|
- lib/dyna_model/aws/record/attributes/serialized_attr.rb
|
141
142
|
- lib/dyna_model/config.rb
|