dyna_model 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|