elasticord 1.0.0 → 1.0.1
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/Gemfile.lock +3 -1
- data/dash_overlord.gemspec +2 -2
- data/elasticord.gemspec +1 -1
- data/lib/dash_overlord/models/v1/dynamo_db/base.rb +22 -11
- data/lib/dash_overlord/models/v1/dynamo_db/migration.rb +13 -3
- data/lib/dash_overlord/models/v1/dynamo_db/paginated_result.rb +16 -0
- data/lib/dash_overlord/models/v1/dynamo_db/scan.rb +114 -0
- data/lib/dash_overlord/use_cases/v1/dummy_data/create/charts/base.rb +3 -2
- data/lib/dash_overlord/use_cases/v1/dummy_data/create/charts/build.rb +1 -1
- data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/create/batch.rb +3 -2
- data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/apply_filters.rb +21 -0
- data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/apply_pagination.rb +62 -0
- data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/base.rb +39 -0
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/apply_filters.rb +2 -2
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/apply_pagination.rb +4 -11
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/base.rb +2 -6
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/build_meta_data.rb +26 -0
- data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/execute_query.rb +21 -0
- data/lib/dash_overlord/use_cases/v1/videos/index/dynamodb/search_and_paginate_videos.rb +7 -2
- data/lib/dash_overlord/use_cases/v1/videos/index/elastic_search/search_and_paginate_videos.rb +2 -80
- data/lib/elasticord/base.rb +10 -11
- data/lib/elasticord/entities/array_with_meta_data.rb +37 -0
- data/lib/elasticord/orm/search_builder.rb +101 -0
- data/lib/elasticord/version.rb +1 -1
- data/lib/tasks/create_dummy_data.rake +1 -0
- data/spec/dash_overlord/use_cases/v1/videos/index/dynamo_db_spec.rb +71 -9
- data/spec/elasticord/base_spec.rb +42 -155
- data/spec/elasticord/orm/search_builder_spec.rb +269 -0
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5e4119d7285ad68f49090e7b9344e88c24561c8
|
4
|
+
data.tar.gz: 9cbf209b6d0dc56674975cbe9672dcfbba414444
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f6a9926758e9ffdafc6439208ddd82fb96480e7102f1f91914407f7c30be698572703b95d6939c49ae9625a2407403dca8f9510e4a8170ee55982d1703ea018
|
7
|
+
data.tar.gz: 845a169cd4b027b00d26cc7aa76acf5c634fb45d675e55ce6d2c08179003b5f6d1b5df798987975b480f61a6a70db3e2d838f1a246abfbf7fd0f9f40d0e7b840
|
data/Gemfile.lock
CHANGED
@@ -6,12 +6,14 @@ PATH
|
|
6
6
|
aws-sdk (>= 2.2.35)
|
7
7
|
bcrypt (>= 2.0.0)
|
8
8
|
dotenv (>= 2.1.1)
|
9
|
-
|
9
|
+
elasticord (>= 1.0.0)
|
10
10
|
i18n (>= 0.7.0)
|
11
11
|
kaminari (>= 1.0.0.rc1)
|
12
12
|
object_attorney (>= 3.0.7)
|
13
13
|
pg (>= 0.17)
|
14
14
|
ransack (>= 1.7.0)
|
15
|
+
elasticord (1.0.1)
|
16
|
+
elasticsearch (~> 5.0)
|
15
17
|
|
16
18
|
GEM
|
17
19
|
remote: https://rubygems.org/
|
data/dash_overlord.gemspec
CHANGED
@@ -30,10 +30,10 @@ Gem::Specification.new do |gem|
|
|
30
30
|
gem.add_runtime_dependency 'i18n', '>= 0.7.0'
|
31
31
|
gem.add_runtime_dependency 'dotenv', '>= 2.1.1'
|
32
32
|
gem.add_runtime_dependency 'bcrypt', '>= 2.0.0'
|
33
|
+
gem.add_runtime_dependency 'aws-sdk', '>= 2.2.35'
|
33
34
|
gem.add_runtime_dependency 'ransack', '>= 1.7.0'
|
34
35
|
gem.add_runtime_dependency 'kaminari', '>= 1.0.0.rc1'
|
36
|
+
gem.add_runtime_dependency 'elasticord', '>= 1.0.0'
|
35
37
|
gem.add_runtime_dependency 'activerecord', '>= 3'
|
36
|
-
gem.add_runtime_dependency 'elasticsearch', '>= 5.0.3'
|
37
38
|
gem.add_runtime_dependency 'object_attorney', '>= 3.0.7'
|
38
|
-
gem.add_runtime_dependency 'aws-sdk', '>= 2.2.35'
|
39
39
|
end
|
data/elasticord.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.email = "dev@streetbees.com"
|
13
13
|
gem.summary = "Elastic search client"
|
14
14
|
gem.description = "Elastic search client on top of elasticsearch gem"
|
15
|
-
gem.homepage = "https://github.com/
|
15
|
+
gem.homepage = "https://github.com/Streetbees/dashlord"
|
16
16
|
|
17
17
|
gem.files = `git ls-files`.split($/)
|
18
18
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -31,19 +31,28 @@ module DashOverlord
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.all
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
collection += result.items
|
34
|
+
DynamoDb::Scan.new \
|
35
|
+
client: client,
|
36
|
+
table_name: table_name,
|
37
|
+
resource_class: self
|
38
|
+
end
|
40
39
|
|
41
|
-
|
40
|
+
def self.page(page, last_evaluated_key)
|
41
|
+
DynamoDb::Scan.new \
|
42
|
+
current_page: page,
|
43
|
+
last_evaluated_key: last_evaluated_key,
|
44
|
+
client: client,
|
45
|
+
table_name: table_name,
|
46
|
+
resource_class: self
|
42
47
|
|
43
|
-
|
44
|
-
end
|
48
|
+
end
|
45
49
|
|
46
|
-
|
50
|
+
def self.search(filters)
|
51
|
+
DynamoDb::Scan.new \
|
52
|
+
client: client,
|
53
|
+
table_name: table_name,
|
54
|
+
resource_class: self,
|
55
|
+
filters: filters
|
47
56
|
end
|
48
57
|
|
49
58
|
def self.table_name
|
@@ -85,9 +94,11 @@ module DashOverlord
|
|
85
94
|
end
|
86
95
|
end
|
87
96
|
|
88
|
-
def self.
|
97
|
+
def self.scan_params
|
89
98
|
{
|
90
99
|
table_name: table_name,
|
100
|
+
exclusive_start_key: @last_evaluated_key,
|
101
|
+
limit: @per_page
|
91
102
|
}
|
92
103
|
end
|
93
104
|
|
@@ -20,14 +20,24 @@ module DashOverlord
|
|
20
20
|
{
|
21
21
|
table_name: @migration_class.table_name,
|
22
22
|
key_schema: [
|
23
|
-
|
24
|
-
|
23
|
+
{
|
24
|
+
attribute_name: "dashboard_id",
|
25
|
+
key_type: "HASH" #PRIMARY KEY
|
26
|
+
},
|
27
|
+
{
|
28
|
+
attribute_name: "id",
|
29
|
+
key_type: "RANGE" # SORT KEY
|
30
|
+
},
|
25
31
|
],
|
26
32
|
attribute_definitions: [
|
27
33
|
{
|
28
|
-
attribute_name: "
|
34
|
+
attribute_name: "dashboard_id",
|
29
35
|
attribute_type: "N"
|
30
36
|
},
|
37
|
+
{
|
38
|
+
attribute_name: "id",
|
39
|
+
attribute_type: "N"
|
40
|
+
}
|
31
41
|
],
|
32
42
|
provisioned_throughput: {
|
33
43
|
read_capacity_units: 10,
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module DashOverlord
|
4
|
+
module Models
|
5
|
+
module V1
|
6
|
+
module DynamoDb
|
7
|
+
class PaginatedResult < OpenStruct
|
8
|
+
include Enumerable
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def_delegators :items, :each, :map, :first, :last, :length, :count
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module DashOverlord
|
2
|
+
module Models
|
3
|
+
module V1
|
4
|
+
module DynamoDb
|
5
|
+
class Scan < DynamoDb::Base
|
6
|
+
# resource.page(page).per(per_page)
|
7
|
+
def search(filters)
|
8
|
+
self.filters = filters
|
9
|
+
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def page(page, last_evaluated_key)
|
14
|
+
self.current_page = page
|
15
|
+
self.last_evaluated_key = last_evaluated_key
|
16
|
+
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def per(per_page)
|
21
|
+
self.limit = per_page
|
22
|
+
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def execute #choose a better name than this...
|
27
|
+
if paginated_scan
|
28
|
+
return scan_page
|
29
|
+
end
|
30
|
+
|
31
|
+
scan_all
|
32
|
+
end
|
33
|
+
|
34
|
+
protected ##################### PROTECTED ###########################
|
35
|
+
|
36
|
+
def scan_all
|
37
|
+
scan_params = params
|
38
|
+
items = []
|
39
|
+
|
40
|
+
loop do
|
41
|
+
result = client.scan(scan_params)
|
42
|
+
items += result.items
|
43
|
+
|
44
|
+
break unless result.last_evaluated_key
|
45
|
+
|
46
|
+
scan_params[:exclusive_start_key] = result.last_evaluated_key
|
47
|
+
end
|
48
|
+
|
49
|
+
items.map{ |item| resource_class.new(item) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def paginated_scan
|
53
|
+
(limit && current_page)
|
54
|
+
end
|
55
|
+
|
56
|
+
def scan_page
|
57
|
+
result = client.scan(params)
|
58
|
+
|
59
|
+
DynamoDb::PaginatedResult.new \
|
60
|
+
items: result.items.map{ |item| resource_class.new(item) },
|
61
|
+
last_evaluated_key: result.last_evaluated_key,
|
62
|
+
exclusive_start_key: last_evaluated_key,
|
63
|
+
limit: limit
|
64
|
+
end
|
65
|
+
|
66
|
+
def params
|
67
|
+
{
|
68
|
+
table_name: "#{table_name}",
|
69
|
+
exclusive_start_key: last_evaluated_key,
|
70
|
+
limit: limit
|
71
|
+
}.merge(filter_params)
|
72
|
+
end
|
73
|
+
|
74
|
+
def filter_params
|
75
|
+
return {} unless filters
|
76
|
+
|
77
|
+
initial_params = {
|
78
|
+
filter_expression: [],
|
79
|
+
expression_attribute_names: {},
|
80
|
+
expression_attribute_values: {}
|
81
|
+
}
|
82
|
+
|
83
|
+
filters_mapped = \
|
84
|
+
filters.each_with_object(initial_params) do |(key, value), object|
|
85
|
+
process_filter(key, value, object)
|
86
|
+
|
87
|
+
object
|
88
|
+
end
|
89
|
+
|
90
|
+
filters_mapped[:filter_expression] = \
|
91
|
+
filters_mapped[:filter_expression].join(' and ')
|
92
|
+
|
93
|
+
filters_mapped
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def process_filter(attribute_expression, value, object)
|
99
|
+
attribute = attribute_expression.to_s.gsub('_eq', '')
|
100
|
+
|
101
|
+
object[:expression_attribute_names]["##{attribute}"] = \
|
102
|
+
attribute
|
103
|
+
|
104
|
+
object[:expression_attribute_values][":#{attribute}"] = \
|
105
|
+
value
|
106
|
+
|
107
|
+
object[:filter_expression] << \
|
108
|
+
"##{attribute} = :#{attribute}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -6,7 +6,7 @@ module DashOverlord
|
|
6
6
|
module Charts
|
7
7
|
|
8
8
|
class Base < V1::Base
|
9
|
-
context_reader :num_of_records, :repo
|
9
|
+
context_reader :num_of_records, :repo, :table_name
|
10
10
|
|
11
11
|
def perform
|
12
12
|
return unless num_of_records && repo
|
@@ -14,7 +14,8 @@ module DashOverlord
|
|
14
14
|
invoke! Charts::Build
|
15
15
|
|
16
16
|
repository_create.perform \
|
17
|
-
items: context.items
|
17
|
+
items: context.items,
|
18
|
+
table_name: table_name
|
18
19
|
end
|
19
20
|
|
20
21
|
protected
|
@@ -7,7 +7,8 @@ module DashOverlord
|
|
7
7
|
|
8
8
|
class Batch < V1::Base
|
9
9
|
context_reader :items,
|
10
|
-
:client
|
10
|
+
:client,
|
11
|
+
:table_name
|
11
12
|
|
12
13
|
def perform
|
13
14
|
return unless items
|
@@ -23,7 +24,7 @@ module DashOverlord
|
|
23
24
|
records.each_slice(25) do |batch|
|
24
25
|
client.batch_write_item \
|
25
26
|
request_items: {
|
26
|
-
"
|
27
|
+
"#{table_name}" => batch
|
27
28
|
}
|
28
29
|
end
|
29
30
|
end
|
data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/apply_filters.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module DashOverlord
|
2
|
+
module UseCases
|
3
|
+
module V1
|
4
|
+
module Repositories
|
5
|
+
module DynamoDb
|
6
|
+
module SearchAndPaginate
|
7
|
+
|
8
|
+
class ApplyFilters < V1::Base
|
9
|
+
context_reader :filter_query, :resource
|
10
|
+
|
11
|
+
def perform
|
12
|
+
context.resource = \
|
13
|
+
resource.search(filter_query.presence)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/apply_pagination.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module DashOverlord
|
2
|
+
module UseCases
|
3
|
+
module V1
|
4
|
+
module Repositories
|
5
|
+
module DynamoDb
|
6
|
+
module SearchAndPaginate
|
7
|
+
|
8
|
+
class ApplyPagination < V1::Base
|
9
|
+
PAGE_DEFAULT = 1
|
10
|
+
PER_PAGE_DEFAULT = 10
|
11
|
+
|
12
|
+
context_reader :page,
|
13
|
+
:last_evaluated_key,
|
14
|
+
:per_page,
|
15
|
+
:resources,
|
16
|
+
:resource
|
17
|
+
|
18
|
+
def perform
|
19
|
+
context.page = fix_page(page)
|
20
|
+
|
21
|
+
if page == 0
|
22
|
+
no_pagination
|
23
|
+
else
|
24
|
+
apply_pagination
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected ###################### PROTECTED ###########################
|
29
|
+
|
30
|
+
def no_pagination
|
31
|
+
context.resources = resource.all
|
32
|
+
|
33
|
+
context.per_page = 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def apply_pagination
|
37
|
+
context.per_page = fix_per_page(per_page)
|
38
|
+
|
39
|
+
context.resource = \
|
40
|
+
resource.page(page, last_evaluated_key).per(per_page)
|
41
|
+
end
|
42
|
+
|
43
|
+
def fix_page(page)
|
44
|
+
page_or_nil = page.class == String ? page.presence : page
|
45
|
+
|
46
|
+
(page_or_nil || PAGE_DEFAULT).to_i
|
47
|
+
end
|
48
|
+
|
49
|
+
def fix_per_page(per_page)
|
50
|
+
per_page_or_nil = \
|
51
|
+
per_page.class == String ? per_page.presence : per_page
|
52
|
+
|
53
|
+
(per_page_or_nil || PER_PAGE_DEFAULT).to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module DashOverlord
|
2
|
+
module UseCases
|
3
|
+
module V1
|
4
|
+
module Repositories
|
5
|
+
module DynamoDb
|
6
|
+
module SearchAndPaginate
|
7
|
+
|
8
|
+
class Base < V1::Base
|
9
|
+
|
10
|
+
# EXPECTED CONTEXT
|
11
|
+
# :resource_class
|
12
|
+
# :page
|
13
|
+
# :per_page
|
14
|
+
# :filter_query
|
15
|
+
# :full_text_term
|
16
|
+
|
17
|
+
def search_and_paginate(resource)
|
18
|
+
context.resource = resource
|
19
|
+
|
20
|
+
invoke! ApplyFilters
|
21
|
+
invoke! ApplyPagination
|
22
|
+
|
23
|
+
context.resource = context.resource.execute
|
24
|
+
|
25
|
+
context.meta = Entities::V1::MetaData.new \
|
26
|
+
context.attributes.slice :page,
|
27
|
+
:per_page,
|
28
|
+
:total_pages,
|
29
|
+
:total_results
|
30
|
+
|
31
|
+
context.resource
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -10,9 +10,9 @@ module DashOverlord
|
|
10
10
|
context_reader :filter_query, :resources
|
11
11
|
|
12
12
|
def perform
|
13
|
-
return unless resources.respond_to?(:
|
13
|
+
return unless resources.respond_to?(:ransack)
|
14
14
|
|
15
|
-
context.search_builder = resources.
|
15
|
+
context.search_builder = resources.ransack(filter_query.presence)
|
16
16
|
|
17
17
|
context.resources = context.search_builder.result(distinct: true)
|
18
18
|
end
|