flex 0.4.2 → 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.
- 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
|