csdn-tire 0.5

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.
@@ -0,0 +1,54 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Stolen from ruby core's uri/common.rb, with modifications to support 1.8.x
3
+ #
4
+ # https://github.com/ruby/ruby/blob/trunk/lib/uri/common.rb
5
+ #
6
+
7
+ module URI
8
+ TBLENCWWWCOMP_ = {} # :nodoc:
9
+ 256.times do |i|
10
+ TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
11
+ end
12
+ TBLENCWWWCOMP_[' '] = '+'
13
+ TBLENCWWWCOMP_.freeze
14
+ TBLDECWWWCOMP_ = {} # :nodoc:
15
+ 256.times do |i|
16
+ h, l = i>>4, i&15
17
+ TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
18
+ TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
19
+ TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
20
+ TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
21
+ end
22
+ TBLDECWWWCOMP_['+'] = ' '
23
+ TBLDECWWWCOMP_.freeze
24
+
25
+ # Encode given +s+ to URL-encoded form data.
26
+ #
27
+ # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
28
+ # (ASCII space) to + and converts others to %XX.
29
+ #
30
+ # This is an implementation of
31
+ # http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
32
+ #
33
+ # See URI.decode_www_form_component, URI.encode_www_form
34
+ def self.encode_www_form_component(s)
35
+ str = s.to_s
36
+ if RUBY_VERSION < "1.9" && $KCODE =~ /u/i
37
+ str.gsub(/([^ a-zA-Z0-9_.-]+)/) do
38
+ '%' + $1.unpack('H2' * Rack::Utils.bytesize($1)).join('%').upcase
39
+ end.tr(' ', '+')
40
+ else
41
+ str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]}
42
+ end
43
+ end
44
+
45
+ # Decode given +str+ of URL-encoded form data.
46
+ #
47
+ # This decods + to SP.
48
+ #
49
+ # See URI.encode_www_form_component, URI.decode_www_form
50
+ def self.decode_www_form_component(str, enc=nil)
51
+ raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%])*\z/ =~ str
52
+ str.gsub(/\+|%[0-9a-fA-F]{2}/) {|m| TBLDECWWWCOMP_[m]}
53
+ end
54
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'time'
3
+
4
+ class Array
5
+ def to_json(options=nil)
6
+ MultiJson.encode(self)
7
+ end unless method_defined? :to_json
8
+ end
9
+
10
+ class Hash
11
+ def to_json(options=nil)
12
+ MultiJson.encode(self)
13
+ end unless method_defined? :to_json
14
+
15
+ alias_method :to_indexed_json, :to_json
16
+ end
17
+
18
+ class Time
19
+ def to_json(options=nil)
20
+ %Q/"#{self.iso8601}"/
21
+ end
22
+ end
@@ -0,0 +1,80 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Tire
3
+ class SearchRequestFailed < StandardError; end
4
+
5
+ class Search
6
+
7
+ attr_reader :payload, :payload_hash, :indices
8
+
9
+ def initialize(indices, types, payload)
10
+ @indices = Array(indices)
11
+ @types = Array(types).map { |type| Utils.escape(type) }
12
+ if payload.is_a?(String)
13
+ @payload = payload
14
+ else
15
+ @payload_hash = payload
16
+ end
17
+
18
+ @path = ['/', @indices.join(','), @types.join(','), '_search'].compact.join('/').squeeze('/')
19
+ end
20
+
21
+ def results
22
+ @json || (perform; @json)
23
+ end
24
+
25
+ def response
26
+ @response || (perform; @response)
27
+ end
28
+
29
+ def url
30
+ Configuration.url + @path
31
+ end
32
+
33
+ def perform
34
+ @response = Configuration.client.get(self.url, self.payload)
35
+ if @response.failure?
36
+ STDERR.puts "[REQUEST FAILED] #{self.to_curl}\n"
37
+ raise SearchRequestFailed, @response.to_s
38
+ end
39
+ @json = MultiJson.decode(@response.body)
40
+ return @json
41
+ ensure
42
+ logged
43
+ end
44
+
45
+ def to_curl
46
+ %Q|curl -X GET #{url} -d '#{payload}'|
47
+ end
48
+
49
+ def payload
50
+ @payload || MultiJson.encode(@payload_hash)
51
+ end
52
+
53
+ def to_hash
54
+ @hash_payload ||= MultiJson.decode(payload)
55
+ end
56
+
57
+ def logged(error=nil)
58
+ if Configuration.logger
59
+
60
+ Configuration.logger.log_request '_search', indices, to_curl
61
+
62
+ code = @response.code rescue nil
63
+
64
+ if Configuration.logger.level.to_s == 'debug'
65
+ # FIXME: Depends on RestClient implementation
66
+ body = if @json
67
+ defined?(Yajl) ? Yajl::Encoder.encode(@json, :pretty => true) : MultiJson.encode(@json)
68
+ else
69
+ @response.body rescue nil
70
+ end
71
+ else
72
+ body = ''
73
+ end
74
+
75
+ Configuration.logger.log_response code || 'N/A', "N/A", body || 'N/A'
76
+ end
77
+ end
78
+
79
+ end
80
+ end
data/lib/tire/state.rb ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Tire
3
+ class State
4
+ include Utils
5
+
6
+ def initialize
7
+
8
+ end
9
+
10
+ def url
11
+ "#{Configuration.url}/cluster/_state"
12
+ end
13
+
14
+ def info(more = false)
15
+ desc_url = more ? "#{url}?more=true" : "#{url}?more=false"
16
+ @response = Configuration.client.get(desc_url)
17
+ if @response.success?
18
+ MultiJson.decode(@response.body)
19
+ else
20
+ []
21
+ end
22
+ ensure
23
+ curl = %Q|curl -X GET #{desc_url}|
24
+ logged('CLUSTER_STATE', curl)
25
+ end
26
+ end
27
+ end
data/lib/tire/utils.rb ADDED
@@ -0,0 +1,40 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'uri'
3
+
4
+ module Tire
5
+ module Utils
6
+
7
+ def escape(s)
8
+ URI.encode_www_form_component(s.to_s)
9
+ end
10
+
11
+ def unescape(s)
12
+ s = s.to_s.respond_to?(:force_encoding) ? s.to_s.force_encoding(Encoding::UTF_8) : s.to_s
13
+ URI.decode_www_form_component(s)
14
+ end
15
+
16
+ def logged(endpoint='/', curl='')
17
+ if Configuration.logger
18
+ error = $!
19
+
20
+ Configuration.logger.log_request endpoint, @name, curl
21
+
22
+ code = @response ? @response.code : error.class rescue 200
23
+
24
+ if Configuration.logger.level.to_s == 'debug'
25
+ body = if @response
26
+ defined?(Yajl) ? Yajl::Encoder.encode(@response.body, :pretty => true) : MultiJson.encode(@response.body)
27
+ else
28
+ error.message rescue ''
29
+ end
30
+ else
31
+ body = ''
32
+ end
33
+
34
+ Configuration.logger.log_response code, nil, body
35
+ end
36
+ end
37
+
38
+ module_function :escape, :unescape
39
+ end
40
+ end
@@ -0,0 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Tire
3
+ VERSION = "0.5"
4
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+
4
+ module Tire
5
+
6
+ class CountIntegrationTest < Test::Unit::TestCase
7
+ include Test::Integration
8
+
9
+ context "count" do
10
+ should "count results" do
11
+ setup_bulk
12
+ @index.refresh
13
+ count = Tire.count(INDEX, TYPE, '{"query":{"text":{"title":"java"}},"size":4,"from":0}')
14
+ num = count.results
15
+ assert_kind_of Integer, num
16
+ assert_equal 6, num
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,58 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+
4
+ module Tire
5
+
6
+ class IndexIntegrationTest < Test::Unit::TestCase
7
+ include Test::Integration
8
+
9
+ context "index" do
10
+
11
+ should "regist_shard" do
12
+ assert @index.regist_shard(6)
13
+ end
14
+
15
+ should "not regist exist index" do
16
+ @index.regist_shard(6)
17
+ assert !@index.regist_shard(6)
18
+ end
19
+
20
+ should "delete index" do
21
+ assert @index.delete
22
+ end
23
+
24
+ should "get shard info" do
25
+ @index.regist_shard(6)
26
+ assert_kind_of Array, @index.shard_info
27
+ assert !@index.shard_info.empty?
28
+ end
29
+
30
+ should "create mapping" do
31
+ assert setup_mapping
32
+ end
33
+
34
+ should "get mapping info" do
35
+ setup_mapping
36
+ assert_kind_of Hash, @index.mapping(TYPE)
37
+ assert_not_nil @index.mapping(TYPE)[TYPE]
38
+ end
39
+
40
+ should "bulk insert" do
41
+ assert setup_bulk
42
+ end
43
+
44
+ should "flush index" do
45
+ setup_bulk
46
+ assert @index.flush
47
+ end
48
+
49
+ should "refresh index" do
50
+ setup_bulk
51
+ assert @index.refresh
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+
4
+ module Tire
5
+
6
+ class SearchIntegrationTest < Test::Unit::TestCase
7
+ include Test::Integration
8
+
9
+ context "search" do
10
+ should "search results" do
11
+ setup_bulk
12
+ @index.refresh
13
+ search = Tire.search(INDEX, TYPE, '{"query":{"text":{"title":"java"}},"size":4,"from":0}')
14
+ results = search.results
15
+ assert_kind_of Hash, results
16
+ assert results["total"] > 0
17
+ assert_kind_of Array, results["hits"]
18
+ assert_equal 6, results["total"]
19
+ assert_equal 4, results["hits"].size
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+
4
+ module Tire
5
+
6
+ class StateIntegrationTest < Test::Unit::TestCase
7
+ include Test::Integration
8
+
9
+ context "state" do
10
+ should "get short state" do
11
+ assert_kind_of Array, Tire.state.info
12
+ assert_kind_of Hash, Tire.state.info.first
13
+ end
14
+
15
+ should "get more state" do
16
+ assert_kind_of Array, Tire.state.info(true)
17
+ assert_kind_of Hash, Tire.state.info(true).first
18
+ assert_not_nil Tire.state.info(true).first["blog"]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,104 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+
5
+ require 'test/unit'
6
+
7
+ require 'yajl'
8
+ #require 'yajl/json_gem'
9
+
10
+ require 'shoulda'
11
+ require 'turn/autorun' unless defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
12
+ require 'mocha'
13
+
14
+ require 'tire'
15
+
16
+ class Test::Unit::TestCase
17
+
18
+ def mock_response(body, code=200, headers={})
19
+ Tire::HTTP::Response.new(body, code, headers)
20
+ end
21
+
22
+ end
23
+
24
+ module Test::Integration
25
+ URL = "http://192.168.6.35:9400"
26
+ INDEX = "articles_test"
27
+ TYPE = "type_test"
28
+
29
+ def setup
30
+ ENV['ELASTICSEARCH_URL'] = URL
31
+ @index = Tire.index(INDEX)
32
+ end
33
+
34
+ def setup_shard
35
+ @index.regist_shard(6)
36
+ end
37
+
38
+ def setup_mapping
39
+ mapping = {TYPE => {"_source"=>{"enabled"=>false},
40
+ "properties"=>
41
+ {"title"=>
42
+ {"type"=>"string",
43
+ "term_vector"=>"with_positions_offsets",
44
+ "boost"=>2.0},
45
+ "body"=>{"type"=>"string", "term_vector"=>"with_positions_offsets"},
46
+ "username"=>{"type"=>"string", "index"=>"not_analyzed", "store"=>"no"},
47
+ "id"=>
48
+ {"type"=>"integer", "index"=>"not_analyzed", "include_in_all"=>false},
49
+ "created_at"=>
50
+ {"type"=>"integer", "index"=>"not_analyzed", "include_in_all"=>false}
51
+ }
52
+ }
53
+ }
54
+ setup_shard
55
+ @index.create_mapping(TYPE, mapping)
56
+ end
57
+
58
+ def setup_bulk
59
+ doc = [
60
+ {"title"=>"java 是好东西",
61
+ "body"=>"hey java",
62
+ "id"=>"1",
63
+ "username"=>"jack",
64
+ "created_at"=>2007072323},
65
+ {"title"=>"this java cool",
66
+ "body"=>"hey java",
67
+ "id"=>"2",
68
+ "created_at"=>2009072323,
69
+ "username"=>"robbin"},
70
+ {"title"=>"this is java cool",
71
+ "body"=>"hey java",
72
+ "id"=>"3",
73
+ "created_at"=>2010072323,
74
+ "username"=>"www"},
75
+ {"title"=>"java is really cool",
76
+ "body"=>"hey java",
77
+ "id"=>"4",
78
+ "created_at"=>2007062323,
79
+ "username"=>"google"},
80
+ {"title"=>"this is wakak cool",
81
+ "body"=>"hey java",
82
+ "id"=>"5",
83
+ "created_at"=>2007062323,
84
+ "username"=>"jackde"},
85
+ {"title"=>"this is java cool",
86
+ "body"=>"hey java",
87
+ "id"=>"6",
88
+ "created_at"=>2007012323,
89
+ "username"=>"jackk wa"},
90
+ {"title"=>"this java really cool",
91
+ "body"=>"hey java",
92
+ "id"=>"7",
93
+ "created_at"=>2002072323,
94
+ "username"=>"william"}
95
+ ]
96
+ setup_mapping
97
+ @index.bulk(TYPE, doc)
98
+ end
99
+
100
+
101
+ def teardown
102
+ ::RestClient.delete "#{URL}/#{INDEX}" rescue nil
103
+ end
104
+ end