riak-yz-query 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 14bc1032d645d5a7493cc47b6135318baba3480a
4
+ data.tar.gz: dde740329c41482fb288c07679fe79803765f367
5
+ SHA512:
6
+ metadata.gz: e46c72a4d779115c680e554ae20b8eb40d0e46c9fb4f0738825dc3ae06dc2ed3ebd6103aa5e53dcfd33d28eece4c80fd4f2a95024ab403ca9104fd0adcd0591e
7
+ data.tar.gz: 1636294e3fcde489e96d753fbc3742512ad24731f512751f938ef80bb66650c26ad458a114123a96c916d23f5ccf1021827eb26b9118c98056f93d19bd227661
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in riak-yz-query.gemspec
4
+ gemspec
5
+
6
+ gem 'riak-client', github: 'basho/riak-ruby-client', ref: '45b5e29b75d98ad0150959602033843997ef968c'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Bryce Kerley
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Riak::YzQuery
2
+
3
+ ***EXPERIMENTAL! DO NOT USE IN PRODUCTION! THERE ARE SECURITY HOLES!***
4
+
5
+ Riak 2.0 will feature [Yokozuna](https://github.com/basho/yokozuna/), a
6
+ distributed search system built on Apache Solr. `Riak::YzQuery` aims to provide
7
+ [Arel-style](http://guides.rubyonrails.org/active_record_querying.html#limit-and-offset)
8
+ querying for Yokozuna.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'riak-yz-query'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install riak-yz-query
23
+
24
+ ## Usage
25
+
26
+ You've already got a Riak bucket full of JSON documents as such:
27
+
28
+ ```json
29
+ {
30
+ name_t: "Bryce Kerley",
31
+ title_t: "Cosmopolitan Space Emperor",
32
+ created_dt: "2007-12-13T23:59:59Z"
33
+ }
34
+ ```
35
+
36
+ To create a blank query, pull it from the `Riak::Bucket`:
37
+
38
+ ```ruby
39
+ q = @bucket.query
40
+ ```
41
+
42
+ Let's look for Bryce:
43
+
44
+ ```ruby
45
+ q = @bucket.query.where name_t: 'Bryce'
46
+ q.keys #=> ['Hswdh9zli0CDcnPSKmEGeIcd6tU']
47
+ q.values #=> {"Hswdh9zli0CDcnPSKmEGeIcd6tU"=> #<Riak::RObject {user,Hswdh...}>}
48
+ ```
49
+
50
+ In the above example, `q` is a `Riak::YzQuery::QueryBuilder` instance. As the
51
+ name implies, and much like Active Record, you can build up more complex queries
52
+ by chaining constraints.
53
+
54
+ ```ruby
55
+ q = @bucket.query.where name_t: 'Andrew'
56
+ q.keys #=> ["PtgA5YsxWpSg7RzTY2eJVJ81hDQ", "OL1quOfOKiYEmxYsqvjf9cyRmH3"]
57
+ q2 = q.where name_t: 'Stone'
58
+ q2.keys #=> ["OL1quOfOKiYEmxYsqvjf9cyRmH3"]
59
+ ```
60
+
61
+ `where` clauses are ANDed together. To OR together two values, use a string:
62
+
63
+ ```ruby
64
+ q = @bucket.query.where 'name_t:Andrew OR name_t:Drew'
65
+ q.keys #=> ["Z0tsBudxTQp50pBlTNeBw6CtwZx", "OL1quOfOKiYEmxYsqvjf9cyRmH3", "PtgA5YsxWpSg7RzTY2eJVJ81hDQ"]
66
+ ```
67
+
68
+ If you don't want to concatenate the string yourself, use an array.
69
+
70
+
71
+ ***WARNING: THIS DOES NOT ADEQUATELY ESCAPE THINGS!*** Your application
72
+ could host the first Yokozuna-injection exploit!
73
+
74
+ ```ruby
75
+ q = @bucket.query.where ['name_t:? OR name_t:?', 'Drew', 'Andrew']
76
+ q.keys #=> ["Z0tsBudxTQp50pBlTNeBw6CtwZx", "OL1quOfOKiYEmxYsqvjf9cyRmH3", "PtgA5YsxWpSg7RzTY2eJVJ81hDQ"]
77
+ ```
78
+
79
+ You can sort:
80
+
81
+ ```ruby
82
+ q = @bucket.query.where(name_t: 'Andrew').order(created_dt: 'asc').keys
83
+ #=> ["OL1quOfOKiYEmxYsqvjf9cyRmH3", "PtgA5YsxWpSg7RzTY2eJVJ81hDQ"]
84
+ q = @bucket.query.where(name_t: 'Andrew').order('created_dt desc').keys
85
+ #=> ["PtgA5YsxWpSg7RzTY2eJVJ81hDQ", "OL1quOfOKiYEmxYsqvjf9cyRmH3"]
86
+ ```
87
+
88
+ And you can paginate:
89
+
90
+ ```ruby
91
+ q = @bucket.query.
92
+ where(name_t: '*e*').
93
+ order(created_dt: 'asc').
94
+ limit(5).
95
+ offset(5)
96
+ ```
97
+
98
+ ## Contributing
99
+
100
+ 1. Fork it
101
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
102
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
103
+ 4. Push to the branch (`git push origin my-new-feature`)
104
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+
6
+ task :default => :test
7
+
8
+ Rake::TestTask.new :test do |t|
9
+ t.libs << 'lib' << 'test'
10
+ t.pattern = 'test/*_test.rb'
11
+ end
@@ -0,0 +1 @@
1
+ require "riak/yz_query"
@@ -0,0 +1,8 @@
1
+ %w{where_clause order_clause bucket_extension version}.each do |f|
2
+ require "riak/yz_query/#{f}"
3
+ end
4
+
5
+ module Riak
6
+ module YzQuery
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ require 'riak'
2
+ require 'riak/yz_query/query_builder'
3
+
4
+ module Riak
5
+ module YzQuery
6
+ module BucketExtension
7
+ def query
8
+ QueryBuilder.new self
9
+ end
10
+ end
11
+ end
12
+
13
+ class Bucket
14
+ include YzQuery::BucketExtension
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ module Riak
2
+ module YzQuery
3
+ class OrderClause
4
+ def initialize(clause)
5
+ @clause = clause
6
+ end
7
+
8
+ def to_yz_query
9
+ return nil if @clause.empty?
10
+
11
+ case @clause
12
+ when Hash
13
+ build_clause_hash
14
+ when Array
15
+ build_clause_array
16
+ when String
17
+ @clause
18
+ end
19
+ end
20
+
21
+ def consume(new_clause)
22
+ new_clause_query = self.class.new(new_clause)
23
+ return new_clause_query if @clause.empty?
24
+ return self.class.new "#{to_yz_query}, #{new_clause.to_yz_query}"
25
+ end
26
+
27
+ def build_clause_hash
28
+ @clause.map do |k,v|
29
+ v = v.to_s.downcase
30
+ raise ArgumentError.new "Couldn't use #{v.inspect} in an order clause" unless %w{asc desc}.include? v
31
+
32
+ "#{k} #{v}"
33
+ end.join ', '
34
+ end
35
+
36
+ def build_clause_array
37
+ @clause.join ', '
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,80 @@
1
+ module Riak
2
+ module YzQuery
3
+ class QueryBuilder
4
+ def initialize(bucket)
5
+ @bucket = bucket
6
+ end
7
+
8
+ def initialize_from_opts(opts)
9
+ @bucket = opts[:bucket]
10
+ @where_clauses = opts[:where_clauses]
11
+ @order_clauses = opts[:order_clauses]
12
+ @limit = opts[:limit]
13
+ @offset = opts[:offset]
14
+ end
15
+
16
+ def where(opts)
17
+ chain where_clauses: where_clauses.consume(opts)
18
+ end
19
+
20
+ def order(opts)
21
+ chain order_clauses: order_clauses.consume(opts)
22
+ end
23
+
24
+ def limit(lim)
25
+ chain limit: lim
26
+ end
27
+
28
+ def offset(off)
29
+ chain offset: off
30
+ end
31
+
32
+ def keys
33
+ @keys ||= results['docs'].map{|d| d['_yz_rk']}
34
+ end
35
+
36
+ def values
37
+ @bucket.get_many keys
38
+ end
39
+
40
+ def to_yz_query
41
+ where_clauses.to_yz_query
42
+ end
43
+
44
+ private
45
+ def chain(opts)
46
+ new_options = {
47
+ bucket: @bucket,
48
+ where_clauses: where_clauses,
49
+ order_clauses: order_clauses,
50
+ limit: @limit,
51
+ offset: @offset
52
+ }.merge opts
53
+
54
+ chain = self.class.allocate
55
+ chain.initialize_from_opts new_options
56
+
57
+ return chain
58
+ end
59
+
60
+ def results
61
+ opts = {}
62
+ opts[:rows] = @limit if @limit
63
+ opts[:start] = @offset if @offset
64
+ if order = order_clauses.to_yz_query
65
+ opts[:sort] = order
66
+ end
67
+
68
+ @results ||= @bucket.client.search @bucket.name, to_yz_query, opts
69
+ end
70
+
71
+ def where_clauses
72
+ @where_clauses ||= WhereClause.new Hash.new
73
+ end
74
+
75
+ def order_clauses
76
+ @order_clauses ||= OrderClause.new Hash.new
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,5 @@
1
+ module Riak
2
+ module YzQuery
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,77 @@
1
+ require 'time'
2
+
3
+ module Riak
4
+ module YzQuery
5
+ class WhereClause
6
+ def initialize(clause)
7
+ @clause = clause
8
+ end
9
+
10
+ def to_yz_query
11
+ case @clause
12
+ when Hash
13
+ build_clause_hash
14
+ when Array
15
+ escape_clause_array
16
+ when String
17
+ @clause
18
+ end
19
+ end
20
+
21
+ def consume(new_clause)
22
+ if @clause.is_a? Hash and new_clause.is_a? Hash
23
+ return self.class.new(@clause.merge new_clause)
24
+ end
25
+
26
+ if @clause.empty?
27
+ return self.class.new new_clause
28
+ end
29
+
30
+ new_clause_query = self.class.new(new_clause).to_yz_query
31
+
32
+ return self.class.new "(#{to_yz_query}) AND #{new_clause_query}"
33
+ end
34
+
35
+ private
36
+ def build_clause_hash
37
+ @clause.map do |k,v|
38
+ "#{k}:#{escape v}"
39
+ end.join ' AND '
40
+ end
41
+
42
+ def escape_clause_array
43
+ working = @clause.first.dup
44
+ remaining = @clause[1..-1].dup
45
+
46
+ while remaining.length > 0
47
+ working['?'] = escape remaining.shift
48
+ end
49
+
50
+ working
51
+ end
52
+
53
+ def escape(candidate)
54
+ case candidate
55
+ when Range
56
+ return "[#{escape(candidate.begin)} TO #{escape(candidate.end)}]"
57
+ when Time
58
+ return candidate.iso8601
59
+ else
60
+ escape_string candidate.to_s
61
+ end
62
+ end
63
+
64
+ def escape_string(str)
65
+ if (str.include? ' ' or str.include? '"') and str.include? '*'
66
+ raise ArgumentError.new "Couldn't figure out how to escape #{str.inspect}"
67
+ end
68
+
69
+ if str.include? '*'
70
+ return str
71
+ end
72
+
73
+ return %Q{"#{str}"}
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'riak/yz_query/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "riak-yz-query"
8
+ spec.version = Riak::YzQuery::VERSION
9
+ spec.authors = ["Bryce Kerley"]
10
+ spec.email = ["bkerley@brycekerley.net"]
11
+ spec.description = %q{Arel-style queries for Riak Yokozuna}
12
+ spec.summary = %q{Arel-style queries for Riak Yokozuna}
13
+ spec.homepage = "https://github.com/bkerley/riak-yz-query"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = '> 2.0'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "minitest", "~> 4.7"
26
+ spec.add_development_dependency "shoulda-context", "~> 1.1.5"
27
+ spec.add_development_dependency "mocha", "~> 0.14.0"
28
+
29
+ spec.add_dependency 'riak-client'
30
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'minitest/autorun'
4
+
5
+ require 'shoulda/context'
6
+ require 'mocha/setup'
7
+
8
+ require 'riak'
9
+ require 'riak-yz-query'
10
+
11
+ class TestCase < MiniTest::Unit::TestCase
12
+ include ShouldaContextLoadable
13
+
14
+ def client
15
+ @client ||= Riak::Client.new pb_port: 10017
16
+ end
17
+
18
+ def bucket_name
19
+ return @bucket_name if defined? @bucket_name
20
+ @bucket_name = "riak-yz-query-#{rand(36**10).to_s(36)}"
21
+ $stderr.puts "Using bucket name #{@bucket_name.inspect}"
22
+ end
23
+
24
+ def bucket
25
+ return @bucket if defined? @bucket
26
+
27
+ @bucket = client.bucket bucket_name
28
+ end
29
+
30
+
31
+ end
32
+
@@ -0,0 +1,71 @@
1
+ require 'helper'
2
+ require 'time'
3
+
4
+ class IntegrationTest < TestCase
5
+ context 'riak-yz-query with some data' do
6
+ setup do
7
+ @bucket = client.bucket 'user'
8
+ end
9
+
10
+ should 'perform single-term queries' do
11
+ q = @bucket.query.where(name_t: '*drew*')
12
+ ['Z0tsBudxTQp50pBlTNeBw6CtwZx',
13
+ 'PtgA5YsxWpSg7RzTY2eJVJ81hDQ',
14
+ 'OL1quOfOKiYEmxYsqvjf9cyRmH3'].each do |k|
15
+ assert_includes q.keys, k
16
+ end
17
+ end
18
+
19
+ should 'perform multi-term AND queries' do
20
+ q = @bucket.query.where(name_t: '*drew*', title_t: '*engineer*')
21
+ ['Z0tsBudxTQp50pBlTNeBw6CtwZx',
22
+ 'PtgA5YsxWpSg7RzTY2eJVJ81hDQ'].each do |k|
23
+ assert_includes q.keys, k
24
+ end
25
+ ['OL1quOfOKiYEmxYsqvjf9cyRmH3'].each do |k|
26
+ refute_includes q.keys, k
27
+ end
28
+ end
29
+
30
+ should 'perform multi-term OR queries' do
31
+ q = @bucket.query.where(['name_t:? OR name_t:?', 'Drew', 'Bryce'])
32
+ ['Z0tsBudxTQp50pBlTNeBw6CtwZx',
33
+ 'Hswdh9zli0CDcnPSKmEGeIcd6tU'].each do |k|
34
+ assert_includes q.keys, k
35
+ end
36
+ end
37
+
38
+ should 'perform range queries with times' do
39
+ open = Time.parse '2007-12-10T23:59:59Z'
40
+ close = Time.parse '2007-12-20T23:59:59Z'
41
+ q = @bucket.query.where created_dt: (open..close)
42
+
43
+ assert_includes q.keys, 'Hswdh9zli0CDcnPSKmEGeIcd6tU'
44
+ end
45
+
46
+ should 'perform multi-term queries with ranges' do
47
+ open = Time.parse '2007-12-10T23:59:59Z'
48
+ close = Time.parse '2007-12-20T23:59:59Z'
49
+ q = @bucket.query.where created_dt: (open..close)
50
+ q_merge = q.where name_t: 'Bryce'
51
+
52
+ assert_includes q.keys, 'Hswdh9zli0CDcnPSKmEGeIcd6tU'
53
+ end
54
+
55
+ should 'perform single-term queries with pagination controls' do
56
+ q = @bucket.query.
57
+ where(name_t: '*e*').
58
+ order(created_dt: 'asc').
59
+ limit(5).
60
+ offset(5)
61
+
62
+ assert_equal(['RvOzMXHJrDG6HbqQaZGrq50qzP',
63
+ 'AGB7aYJ31jvMTaaolur9Hqp2gyF',
64
+ 'LYNcKRvQiUNaKW1zTEDdzZytrQp',
65
+ 'Hswdh9zli0CDcnPSKmEGeIcd6tU',
66
+ '6l5cpsxsyDb9mDHEtcS9U6mNCbO'
67
+ ],
68
+ q.keys)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,78 @@
1
+ require 'helper'
2
+
3
+ class QueryBuilderTest < TestCase
4
+ context "a QueryBuilder" do
5
+ setup do
6
+ @bucket = client.bucket 'user'
7
+ end
8
+
9
+ should "chain from 'where'" do
10
+ q = @bucket.query
11
+ q_where = q.where(asdf: 'asdf')
12
+ refute_equal q, q_where
13
+ assert_instance_of Riak::YzQuery::QueryBuilder, q_where
14
+ end
15
+
16
+ should "convert to a yokozuna query" do
17
+ q = @bucket.query.where(asdf: 'jkl')
18
+ assert_equal 'asdf:"jkl"', q.to_yz_query
19
+ end
20
+
21
+ should "query on #keys" do
22
+ q = @bucket.query
23
+ client.
24
+ expects(:search).
25
+ with(@bucket.name, 'asdf:"jkl"', {}).
26
+ returns({
27
+ 'docs' => [
28
+ 'score' => 1.0,
29
+ '_yz_rk' => 'jkl',
30
+ ],
31
+ 'max_score' => 1.0,
32
+ 'num_found' => 1
33
+ })
34
+
35
+ keys = q.where(asdf: 'jkl').keys
36
+ assert_equal ['jkl'], keys
37
+ end
38
+
39
+ context 'where clauses' do
40
+ should 'support hashes' do
41
+ assert_produces 'asdf:"jkl"', {asdf: 'jkl'}
42
+ assert_produces 'asdf:"jkl"', {'asdf' => 'jkl'}
43
+ end
44
+ should 'support strings' do
45
+ assert_produces 'asdf:jkl', 'asdf:jkl'
46
+ end
47
+ should 'support arrays with interpolation' do
48
+ assert_produces 'asdf:"jkl"', ['asdf:?', 'jkl']
49
+ end
50
+ end
51
+
52
+ context 'limit and offset' do
53
+ should "pass limit and offset through" do
54
+ q = @bucket.query
55
+ client.
56
+ expects(:search).
57
+ with(@bucket.name, 'asdf:"jkl"', {rows: 4, start: 5}).
58
+ returns({
59
+ 'docs' => [
60
+ 'score' => 1.0,
61
+ '_yz_rk' => 'jkl',
62
+ ],
63
+ 'max_score' => 1.0,
64
+ 'num_found' => 1
65
+ })
66
+
67
+ keys = q.where(asdf: 'jkl').limit(4).offset(5).keys
68
+ assert_equal ['jkl'], keys
69
+ end
70
+ end
71
+ end
72
+
73
+ def assert_produces(desired_query, *clause)
74
+ assert_equal(desired_query,
75
+ @bucket.query.where(*clause).to_yz_query,
76
+ "Clause #{clause.inspect} did not produce expected query #{desired_query.inspect}")
77
+ end
78
+ end
@@ -0,0 +1,36 @@
1
+ require 'helper'
2
+
3
+ class WhereClauseTest < TestCase
4
+ WhereClause = Riak::YzQuery::WhereClause
5
+
6
+ context 'a WhereClause' do
7
+ should 'merge a hash and a hash' do
8
+ c = WhereClause.new asdf: 'jkl'
9
+ c_merge = c.consume qwe: 'rty'
10
+ assert_equal 'asdf:"jkl" AND qwe:"rty"', c_merge.to_yz_query
11
+ end
12
+
13
+ should 'merge a hash and a string' do
14
+ c = WhereClause.new asdf: 'jkl'
15
+ c_merge = c.consume 'qwe:rty'
16
+ assert_equal '(asdf:"jkl") AND qwe:rty', c_merge.to_yz_query
17
+ end
18
+
19
+ should 'merge a string and a hash' do
20
+ c = WhereClause.new 'qwe:rty'
21
+ c_merge = c.consume asdf: 'jkl'
22
+ assert_equal '(qwe:rty) AND asdf:"jkl"', c_merge.to_yz_query
23
+ end
24
+
25
+ should 'merge a string and a string' do
26
+ c = WhereClause.new "bryce:hello"
27
+ c_merge = c.consume "hello:to_u"
28
+ assert_equal '(bryce:hello) AND hello:to_u', c_merge.to_yz_query
29
+ end
30
+
31
+ should 'escape an array into a string' do
32
+ c = WhereClause.new ["bryce:? OR bryce:?", 'hi', 'hello']
33
+ assert_equal 'bryce:"hi" OR bryce:"hello"', c.to_yz_query
34
+ end
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: riak-yz-query
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Bryce Kerley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '4.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '4.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: shoulda-context
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.5
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.5
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 0.14.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 0.14.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: riak-client
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Arel-style queries for Riak Yokozuna
98
+ email:
99
+ - bkerley@brycekerley.net
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - Gemfile
106
+ - LICENSE.txt
107
+ - README.md
108
+ - Rakefile
109
+ - lib/riak-yz-query.rb
110
+ - lib/riak/yz_query.rb
111
+ - lib/riak/yz_query/bucket_extension.rb
112
+ - lib/riak/yz_query/order_clause.rb
113
+ - lib/riak/yz_query/query_builder.rb
114
+ - lib/riak/yz_query/version.rb
115
+ - lib/riak/yz_query/where_clause.rb
116
+ - riak-yz-query.gemspec
117
+ - test/helper.rb
118
+ - test/integration_test.rb
119
+ - test/query_builder_test.rb
120
+ - test/where_clause_test.rb
121
+ homepage: https://github.com/bkerley/riak-yz-query
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - '>'
132
+ - !ruby/object:Gem::Version
133
+ version: '2.0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.0.7
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Arel-style queries for Riak Yokozuna
145
+ test_files:
146
+ - test/helper.rb
147
+ - test/integration_test.rb
148
+ - test/query_builder_test.rb
149
+ - test/where_clause_test.rb