flex 0.4.2 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +46 -7
- data/VERSION +1 -1
- data/flex.gemspec +13 -19
- data/lib/flex.rb +66 -392
- data/lib/flex/api_stubs.rb +1268 -0
- data/lib/flex/api_templates/cluster_api.yml +94 -0
- data/lib/flex/api_templates/core_api.yml +202 -0
- data/lib/flex/api_templates/indices_api.yml +304 -0
- data/lib/flex/class_proxy/base.rb +20 -6
- data/lib/flex/class_proxy/templates.rb +97 -0
- data/lib/flex/class_proxy/templates/doc.rb +91 -0
- data/lib/flex/class_proxy/templates/search.rb +72 -0
- data/lib/flex/configuration.rb +17 -49
- data/lib/flex/deprecation.rb +153 -0
- data/lib/flex/errors.rb +2 -1
- data/lib/flex/http_clients/base.rb +15 -0
- data/lib/flex/http_clients/loader.rb +51 -0
- data/lib/flex/http_clients/patron.rb +9 -7
- data/lib/flex/http_clients/rest_client.rb +6 -8
- data/lib/flex/logger.rb +24 -3
- data/lib/flex/prog_bar.rb +11 -6
- data/lib/flex/rails.rb +1 -13
- data/lib/flex/result.rb +8 -2
- data/lib/flex/result/document.rb +42 -13
- data/lib/flex/result/multi_get.rb +24 -0
- data/lib/flex/result/search.rb +1 -24
- data/lib/flex/struct/array.rb +25 -0
- data/lib/flex/struct/hash.rb +105 -0
- data/lib/flex/{result/collection.rb → struct/paginable.rb} +16 -9
- data/lib/flex/struct/prunable.rb +60 -0
- data/lib/flex/struct/symbolize.rb +27 -0
- data/lib/flex/tasks.rb +26 -86
- data/lib/flex/template.rb +60 -120
- data/lib/flex/template/common.rb +42 -0
- data/lib/flex/template/logger.rb +66 -0
- data/lib/flex/template/partial.rb +12 -15
- data/lib/flex/template/search.rb +6 -6
- data/lib/flex/template/slim_search.rb +1 -1
- data/lib/flex/template/tags.rb +19 -9
- data/lib/flex/templates.rb +20 -0
- data/lib/flex/utility_methods.rb +80 -89
- data/lib/flex/utils.rb +68 -25
- data/lib/flex/variables.rb +55 -4
- data/lib/tasks.rake +28 -0
- metadata +61 -85
- data/bin/flexes +0 -174
- data/lib/flex/api_methods.yml +0 -108
- data/lib/flex/class_proxy/loader.rb +0 -102
- data/lib/flex/class_proxy/model.rb +0 -45
- data/lib/flex/class_proxy/model_sync.rb +0 -23
- data/lib/flex/class_proxy/related_model.rb +0 -23
- data/lib/flex/instance_proxy/base.rb +0 -29
- data/lib/flex/instance_proxy/model.rb +0 -102
- data/lib/flex/instance_proxy/related_model.rb +0 -7
- data/lib/flex/loader.rb +0 -18
- data/lib/flex/manager.rb +0 -61
- data/lib/flex/model.rb +0 -24
- data/lib/flex/rails/engine.rb +0 -23
- data/lib/flex/rails/helper.rb +0 -16
- data/lib/flex/related_model.rb +0 -16
- data/lib/flex/result/indifferent_access.rb +0 -11
- data/lib/flex/result/source_document.rb +0 -63
- data/lib/flex/result/source_search.rb +0 -32
- data/lib/flex/structure/indifferent_access.rb +0 -44
- data/lib/flex/structure/mergeable.rb +0 -21
- data/lib/flex/template/base.rb +0 -41
- data/lib/flex/template/info.rb +0 -68
- data/lib/generators/flex/setup/setup_generator.rb +0 -48
- data/lib/generators/flex/setup/templates/flex_config.yml +0 -16
- data/lib/generators/flex/setup/templates/flex_dir/es.rb.erb +0 -18
- data/lib/generators/flex/setup/templates/flex_dir/es.yml.erb +0 -19
- data/lib/generators/flex/setup/templates/flex_dir/es_extender.rb.erb +0 -17
- data/lib/generators/flex/setup/templates/flex_initializer.rb.erb +0 -44
- data/lib/tasks/index.rake +0 -17
- data/test/flex.irt +0 -143
- data/test/flex/configuration.irt +0 -53
- data/test/irt_helper.rb +0 -12
data/lib/flex/api_methods.yml
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
# These methods are available as Flex.<method>(variable_hash)
|
2
|
-
# you can get the updated full reference and usage example of these methods
|
3
|
-
# by just doing in the console:
|
4
|
-
# >> puts Flex.info
|
5
|
-
|
6
|
-
# http://www.elasticsearch.org/guide/reference/api/admin-indices-indices-exists.html
|
7
|
-
indices_exists: &exist
|
8
|
-
- HEAD
|
9
|
-
- /<<index>>
|
10
|
-
|
11
|
-
# aliased
|
12
|
-
exist?: *exist
|
13
|
-
|
14
|
-
# http://www.elasticsearch.org/guide/reference/api/admin-indices-create-index.html
|
15
|
-
create_index: &create
|
16
|
-
- PUT
|
17
|
-
- /<<index>>
|
18
|
-
- settings:
|
19
|
-
number_of_shards: <<number_of_shards= 5 >>
|
20
|
-
number_of_replicas: <<number_of_replicas= 1 >>
|
21
|
-
|
22
|
-
# aliased
|
23
|
-
put_index: *create
|
24
|
-
|
25
|
-
post_index:
|
26
|
-
- POST
|
27
|
-
- /<<index>>
|
28
|
-
- settings:
|
29
|
-
number_of_shards: <<number_of_shards= 5 >>
|
30
|
-
number_of_replicas: <<number_of_replicas= 1 >>
|
31
|
-
|
32
|
-
# http://www.elasticsearch.org/guide/reference/api/admin-indices-get-settings.html
|
33
|
-
get_settings:
|
34
|
-
- GET
|
35
|
-
- /<<index>>/_settings
|
36
|
-
|
37
|
-
# http://www.elasticsearch.org/guide/reference/api/admin-indices-put-mapping.html
|
38
|
-
put_mapping:
|
39
|
-
- PUT
|
40
|
-
- /<<index>>/<<type>>/_mapping
|
41
|
-
- <<type>>:
|
42
|
-
properties: <<properties>>
|
43
|
-
|
44
|
-
# http://www.elasticsearch.org/guide/reference/api/admin-indices-get-mapping.html
|
45
|
-
get_mapping:
|
46
|
-
- GET
|
47
|
-
- /<<index>>/<<type>>/_mapping
|
48
|
-
|
49
|
-
# http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-mapping.html
|
50
|
-
delete_mapping:
|
51
|
-
- DELETE
|
52
|
-
- /<<index>>/<<type>>
|
53
|
-
|
54
|
-
# http://www.elasticsearch.org/guide/reference/api/delete.html
|
55
|
-
delete_index:
|
56
|
-
- DELETE
|
57
|
-
- /<<index>>
|
58
|
-
|
59
|
-
# http://www.elasticsearch.org/guide/reference/api/delete-by-query.html
|
60
|
-
delete_by_query:
|
61
|
-
- DELETE
|
62
|
-
- /<<index>>/<<type>>/_query
|
63
|
-
# pass :data variable query if you need
|
64
|
-
|
65
|
-
# http://www.elasticsearch.org/guide/reference/api/bulk.html
|
66
|
-
bulk:
|
67
|
-
- POST
|
68
|
-
- /_bulk
|
69
|
-
- << lines >>
|
70
|
-
|
71
|
-
# http://www.elasticsearch.org/guide/reference/api/count.html
|
72
|
-
count:
|
73
|
-
- GET
|
74
|
-
- /<<index>>/<<type>>/_count
|
75
|
-
# pass :data structure if you need
|
76
|
-
|
77
|
-
# http://www.elasticsearch.org/guide/reference/api/admin-indices-stats.html
|
78
|
-
stats:
|
79
|
-
- GET
|
80
|
-
- /<<index>>/_stats/<<end_point= ~ >>
|
81
|
-
|
82
|
-
# You must pass the :data variable
|
83
|
-
store: &store
|
84
|
-
- PUT
|
85
|
-
- /<<index>>/<<type>>/<<id>>
|
86
|
-
|
87
|
-
# alias for symmetry with post_store
|
88
|
-
put_store: *store
|
89
|
-
|
90
|
-
# id is assigned by ES; you must pass :data
|
91
|
-
post_store:
|
92
|
-
- POST
|
93
|
-
- /<<index>>/<<type>>
|
94
|
-
|
95
|
-
remove:
|
96
|
-
- DELETE
|
97
|
-
- /<<index>>/<<type>>/<<id>>
|
98
|
-
|
99
|
-
# http://www.elasticsearch.org/guide/reference/api/get.html
|
100
|
-
get:
|
101
|
-
- GET
|
102
|
-
- /<<index>>/<<type>>/<<id>>
|
103
|
-
|
104
|
-
# http://www.elasticsearch.org/guide/reference/api/multi-get.html
|
105
|
-
multi_get:
|
106
|
-
- GET
|
107
|
-
- /<<index>>/<<type>>/_mget
|
108
|
-
- ids: << ids >>
|
@@ -1,102 +0,0 @@
|
|
1
|
-
module Flex
|
2
|
-
module ClassProxy
|
3
|
-
class Loader < Base
|
4
|
-
attr_reader :templates, :partials
|
5
|
-
|
6
|
-
include Template::Info
|
7
|
-
|
8
|
-
def initialize(base)
|
9
|
-
super
|
10
|
-
@sources = []
|
11
|
-
@templates = {}
|
12
|
-
@partials = {}
|
13
|
-
end
|
14
|
-
|
15
|
-
# accepts a path to a file or YAML string
|
16
|
-
def load_source_for(klass, source, source_vars)
|
17
|
-
if source.nil? || source != /\n/
|
18
|
-
paths = [ "#{Configuration.flex_dir}/#{source}.yml",
|
19
|
-
"#{Configuration.flex_dir}/#{Manager.class_name_to_type(host_class.name)}.yml",
|
20
|
-
source.to_s ]
|
21
|
-
source = paths.find {|p| File.exist?(p)}
|
22
|
-
end
|
23
|
-
raise ArgumentError, "expected a string (got #{source.inspect})." \
|
24
|
-
unless source.is_a?(String)
|
25
|
-
@sources << [klass, source, source_vars]
|
26
|
-
do_load_source(klass, source, source_vars)
|
27
|
-
end
|
28
|
-
|
29
|
-
# loads a Generic Template source
|
30
|
-
def load_source(source=nil, source_vars=nil)
|
31
|
-
load_source_for(Template, source, source_vars)
|
32
|
-
end
|
33
|
-
|
34
|
-
# loads a Search Template source
|
35
|
-
def load_search_source(source=nil, source_vars=nil)
|
36
|
-
load_source_for(Template::Search, source, source_vars)
|
37
|
-
end
|
38
|
-
|
39
|
-
# loads a SlimSearch Template source
|
40
|
-
def load_slim_search_source(source=nil, source_vars=nil)
|
41
|
-
load_source_for(Template::SlimSearch, source, source_vars)
|
42
|
-
end
|
43
|
-
|
44
|
-
# reloads the sources (useful in the console and used internally)
|
45
|
-
def reload!
|
46
|
-
@sources.each {|k,s,v| do_load_source(k,s,v)}
|
47
|
-
end
|
48
|
-
|
49
|
-
# adds a template instance and defines the template method in the host class
|
50
|
-
def add_template(name, template)
|
51
|
-
templates[name] = template
|
52
|
-
# no define_singleton_method in 1.8.7
|
53
|
-
host_class.instance_eval <<-ruby, __FILE__, __LINE__ + 1
|
54
|
-
def #{name}(vars={})
|
55
|
-
raise ArgumentError, "#{host_class}.#{name} expects a Hash (got \#{vars.inspect})" unless vars.is_a?(Hash)
|
56
|
-
#{host_class.respond_to?(:preprocess_variables) && 'preprocess_variables(vars)'}
|
57
|
-
flex.templates[:#{name}].render(vars)
|
58
|
-
end
|
59
|
-
ruby
|
60
|
-
end
|
61
|
-
|
62
|
-
# http://www.elasticsearch.org/guide/reference/api/multi-search.html
|
63
|
-
# request may be a hash with the templates names as keys and the variable hash as value
|
64
|
-
# or you can also use an array of arrays.
|
65
|
-
# The variables are an hash of variables that will be used to render the msearch template
|
66
|
-
def multi_search(requests, variables={})
|
67
|
-
lines = requests.map { |name, vars| templates[name].to_msearch(vars) }.join()
|
68
|
-
template = Template.new('GET', '/<<index>>/<<type>>/_msearch')
|
69
|
-
template.send(:do_render, variables.merge(:data => lines)) do |http_response|
|
70
|
-
responses = []
|
71
|
-
es_response = MultiJson.decode(http_response.body)
|
72
|
-
es_response['responses'].each_with_index do |result, i|
|
73
|
-
responses << Result.new(templates[requests[i].first], requests[i].last, http_response, result)
|
74
|
-
end
|
75
|
-
es_response['responses'] = responses
|
76
|
-
def es_response.responses
|
77
|
-
self['responses']
|
78
|
-
end
|
79
|
-
es_response
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def do_load_source(klass, source, source_vars)
|
86
|
-
source = Utils.erb_process(source) unless source.match("\n") # skips non-path
|
87
|
-
hash = Utils.data_from_source(source)
|
88
|
-
hash.delete('ANCHORS')
|
89
|
-
hash.each do |name, structure|
|
90
|
-
if name.to_s =~ /^_/ # partial
|
91
|
-
partial = Template::Partial.new(structure, self)
|
92
|
-
partials[name.to_sym] = partial
|
93
|
-
else
|
94
|
-
template = klass.new(*structure).setup(self, name, source_vars)
|
95
|
-
add_template(name.to_sym, template)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Flex
|
2
|
-
module ClassProxy
|
3
|
-
class Model < Base
|
4
|
-
|
5
|
-
include ModelSync
|
6
|
-
|
7
|
-
attr_reader :parent_association, :parent_child_map
|
8
|
-
|
9
|
-
def initialize(base)
|
10
|
-
super
|
11
|
-
variables.add :index => Configuration.variables[:index],
|
12
|
-
:type => Manager.class_name_to_type(host_class.name)
|
13
|
-
end
|
14
|
-
|
15
|
-
def index
|
16
|
-
variables[:index]
|
17
|
-
end
|
18
|
-
|
19
|
-
def index=(val)
|
20
|
-
variables[:index] = val
|
21
|
-
end
|
22
|
-
|
23
|
-
def type
|
24
|
-
variables[:type]
|
25
|
-
end
|
26
|
-
|
27
|
-
def type=(val)
|
28
|
-
variables[:type] = val
|
29
|
-
end
|
30
|
-
|
31
|
-
def parent(parent_association, map)
|
32
|
-
@parent_association = parent_association
|
33
|
-
Manager.parent_types |= map.keys.map(&:to_s)
|
34
|
-
self.type = map.values.map(&:to_s)
|
35
|
-
@parent_child_map = map
|
36
|
-
@is_child = true
|
37
|
-
end
|
38
|
-
|
39
|
-
def is_child?
|
40
|
-
!!@is_child
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Flex
|
2
|
-
module ClassProxy
|
3
|
-
module ModelSync
|
4
|
-
|
5
|
-
def self.included(base)
|
6
|
-
base.class_eval do
|
7
|
-
attr_accessor :synced
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def sync(*synced)
|
12
|
-
@synced = synced
|
13
|
-
host_class.class_eval do
|
14
|
-
raise NotImplementedError, "the class #{self} must implement :after_save and :after_destroy callbacks" \
|
15
|
-
unless respond_to?(:after_save) && respond_to?(:after_destroy)
|
16
|
-
after_save { flex.sync }
|
17
|
-
after_destroy { flex.sync }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Flex
|
2
|
-
module ClassProxy
|
3
|
-
class RelatedModel
|
4
|
-
|
5
|
-
attr_reader :host_class
|
6
|
-
|
7
|
-
def initialize(host_class)
|
8
|
-
@host_class = host_class
|
9
|
-
end
|
10
|
-
|
11
|
-
include ModelSync
|
12
|
-
|
13
|
-
alias_method :full_sync, :sync
|
14
|
-
|
15
|
-
def sync(*synced)
|
16
|
-
raise ArgumentError, 'You cannot flex.sync(self) a Flex::RelatedModel.' \
|
17
|
-
if synced.any?{|s| s == host_class}
|
18
|
-
full_sync
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Flex
|
2
|
-
module InstanceProxy
|
3
|
-
|
4
|
-
class Base
|
5
|
-
attr_reader :instance, :class_flex
|
6
|
-
|
7
|
-
def initialize(instance)
|
8
|
-
@instance = instance
|
9
|
-
@class_flex = instance.class.flex
|
10
|
-
end
|
11
|
-
|
12
|
-
def sync
|
13
|
-
class_flex.synced.each do |s|
|
14
|
-
case
|
15
|
-
when s == instance.class # only called for Flex::Model
|
16
|
-
instance.destroyed? ? remove : store
|
17
|
-
when s.is_a?(Symbol)
|
18
|
-
instance.send(s).flex.sync
|
19
|
-
when s.is_a?(String)
|
20
|
-
parent_instance.flex.sync if s == parent_instance.flex.type
|
21
|
-
else
|
22
|
-
raise ArgumentError, "self, string or symbol expected, got #{s.inspect}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
module Flex
|
2
|
-
module InstanceProxy
|
3
|
-
class Model < Base
|
4
|
-
|
5
|
-
# indexes the document
|
6
|
-
# usually called from after_save, you can eventually call it explicitly for example from another callback
|
7
|
-
# or whenever the DB doesn't get updated by the model
|
8
|
-
# you can also pass the :data=>flex_source explicitly (useful for example to override the flex_source in the model)
|
9
|
-
def store(vars={})
|
10
|
-
if instance.flex_indexable?
|
11
|
-
Flex.store metainfo.merge(:data => instance.flex_source).merge(vars)
|
12
|
-
else
|
13
|
-
Flex.remove(metainfo.merge(vars)) if Flex.get(metainfo.merge(vars.merge(:raise => false)))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# removes the document from the index (called from after_destroy)
|
18
|
-
def remove(vars={})
|
19
|
-
return unless instance.flex_indexable?
|
20
|
-
Flex.remove metainfo.merge(vars)
|
21
|
-
end
|
22
|
-
|
23
|
-
# gets the document from ES
|
24
|
-
def get(vars={})
|
25
|
-
return unless instance.flex_indexable?
|
26
|
-
Flex.get metainfo.merge(vars)
|
27
|
-
end
|
28
|
-
|
29
|
-
def parent_instance(raise=true)
|
30
|
-
return unless is_child?
|
31
|
-
@parent_instance ||= instance.send(class_flex.parent_association) || raise &&
|
32
|
-
raise(MissingParentError, "missing parent instance for document #{instance.inspect}.")
|
33
|
-
end
|
34
|
-
|
35
|
-
# helper that iterates through the parent record chain
|
36
|
-
# record.flex.each_parent{|p| p.do_smething }
|
37
|
-
def each_parent
|
38
|
-
pi = parent_instance
|
39
|
-
while pi do
|
40
|
-
yield pi
|
41
|
-
pi = pi.flex.parent_instance
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def type
|
46
|
-
@type ||= is_child? ? class_flex.parent_child_map[parent_instance.flex.type] : class_flex.type
|
47
|
-
end
|
48
|
-
|
49
|
-
def index
|
50
|
-
class_flex.index
|
51
|
-
end
|
52
|
-
|
53
|
-
def id
|
54
|
-
instance.id
|
55
|
-
end
|
56
|
-
|
57
|
-
def routing(raise=true)
|
58
|
-
@routing ||= case
|
59
|
-
when is_child? then parent_instance(raise).flex.routing
|
60
|
-
when is_parent? then create_routing
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def is_child?
|
65
|
-
@is_child ||= class_flex.is_child?
|
66
|
-
end
|
67
|
-
|
68
|
-
def is_parent?
|
69
|
-
@is_parent ||= Manager.parent_types.include?(type)
|
70
|
-
end
|
71
|
-
|
72
|
-
def metainfo
|
73
|
-
@metainfo ||= begin
|
74
|
-
meta = { :index => index, :type => type, :id => id }
|
75
|
-
params = {}
|
76
|
-
params[:routing] = routing if routing
|
77
|
-
params[:parent] = parent_instance.id if is_child?
|
78
|
-
meta.merge!(:params => params) unless params.empty?
|
79
|
-
meta
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
BASE62_DIGITS = ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a
|
86
|
-
|
87
|
-
def create_routing
|
88
|
-
string = [index, type, id].join
|
89
|
-
remainder = Digest::MD5.hexdigest(string).to_i(16)
|
90
|
-
result = []
|
91
|
-
max_power = ( Math.log(remainder) / Math.log(62) ).floor
|
92
|
-
max_power.downto(0) do |power|
|
93
|
-
digit, remainder = remainder.divmod(62**power)
|
94
|
-
result << digit
|
95
|
-
end
|
96
|
-
result << remainder if remainder > 0
|
97
|
-
result.map{|digit| BASE62_DIGITS[digit]}.join
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|