activerecord-turntable 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bf0ede019f3de7c07755243eef39d924ba553535
4
- data.tar.gz: 7790c3e307778292759c3683c5381b7f1c8c1525
3
+ metadata.gz: 0183e069709e21d8fd4f93be3b443e9dab8ae88c
4
+ data.tar.gz: c2f793eebeaa9d49278d09892eef7060fddcd757
5
5
  SHA512:
6
- metadata.gz: 22af41085ea74b9b442dec5f7e26b5ddff9086e404486ec6e16c2b56dd2febd333d90b29dfcc912b3d409cec185a1970577db66deead6827dcc3787ff2b1787c
7
- data.tar.gz: 2b5292a67a7c018733515d79fb52ce3ee0474d7b67a551d5f6be159643c780f1187a336caf1b5bbed46651c49b6a37d514b963baed8b7512fe931228ebeb1ae4
6
+ metadata.gz: 3e2305795803f74373a78c8bae47f24054b8abc358d54e49b106f09993b262e96ea8081d37268db7e7c38b5c56a4701720b1c2a3d09669bc5655d38cf20e6b22
7
+ data.tar.gz: c17da81b6c308cb370183d96edfff8b39a9f4431f9af6e76b3e2778c80f414c6cdab1172db34ff0e7e62899bb64619961f658915a24f7988bb2d4cb4151639af
data/.travis.yml CHANGED
@@ -15,3 +15,5 @@ script: bundle exec rake spec
15
15
  matrix:
16
16
  allow_failures:
17
17
  - rvm: ruby-head
18
+ sudo: false
19
+ cache: bundler
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## activerecord-turntable 2.3.0 ##
2
+
3
+ ### Features
4
+
5
+ * Support index hint
6
+
1
7
  ## activerecord-turntable 2.2.2 ##
2
8
 
3
9
  ### Bugfix
@@ -9,14 +9,22 @@ module SQLTree
9
9
  end
10
10
 
11
11
  class SQLTree::Token
12
- KEYWORDS << 'BINARY'
13
- KEYWORDS << 'LIMIT'
14
- KEYWORDS << 'OFFSET'
15
- const_set('BINARY', Class.new(SQLTree::Token::Keyword))
16
- const_set('LIMIT', Class.new(SQLTree::Token::Keyword))
17
- const_set('OFFSET', Class.new(SQLTree::Token::Keyword))
12
+ extended_keywords = ['BINARY', 'LIMIT', 'OFFSET', 'INDEX', 'KEY', 'USE', 'FORCE', 'IGNORE']
13
+ KEYWORDS.concat(extended_keywords)
14
+
15
+ extended_keywords.each do |kwd|
16
+ const_set(kwd, Class.new(SQLTree::Token::Keyword))
17
+ end
18
18
 
19
19
  BINARY_ESCAPE = Class.new(SQLTree::Token).new('x')
20
+
21
+ def possible_index_hint?
22
+ [SQLTree::Token::USE, SQLTree::Token::FORCE, SQLTree::Token::IGNORE].include?(self.class)
23
+ end
24
+
25
+ def index_keyword?
26
+ [SQLTree::Token::INDEX, SQLTree::Token::KEY].include?(self.class)
27
+ end
20
28
  end
21
29
 
22
30
  class SQLTree::Tokenizer
@@ -141,9 +149,16 @@ module SQLTree::Node
141
149
  end
142
150
 
143
151
  class TableReference < Base
152
+ leaf :index_hint
153
+
154
+ def initialize(table, table_alias = nil, index_hint = nil)
155
+ @table, @table_alias, @index_hint = table, table_alias, index_hint
156
+ end
157
+
144
158
  def to_sql(options={})
145
159
  sql = (SQLTree::Node::SubQuery === table) ? table.to_sql : quote_field_name(table)
146
160
  sql << " AS " << quote_field_name(table_alias) if table_alias
161
+ sql << " " << index_hint.to_sql if index_hint
147
162
  return sql
148
163
  end
149
164
 
@@ -151,10 +166,14 @@ module SQLTree::Node
151
166
  if SQLTree::Token::Identifier === tokens.peek
152
167
  tokens.next
153
168
  table_reference = self.new(tokens.current.literal)
154
- if SQLTree::Token::AS === tokens.peek || SQLTree::Token::Identifier === tokens.peek
169
+ if tokens.peek && !tokens.peek.possible_index_hint? &&
170
+ (SQLTree::Token::AS === tokens.peek || SQLTree::Token::Identifier === tokens.peek)
155
171
  tokens.consume(SQLTree::Token::AS) if SQLTree::Token::AS === tokens.peek
156
172
  table_reference.table_alias = tokens.next.literal
157
173
  end
174
+ if tokens.peek && tokens.peek.possible_index_hint? && tokens.peek(2).index_keyword?
175
+ table_reference.index_hint = SQLTree::Node::IndexHint.parse(tokens)
176
+ end
158
177
  return table_reference
159
178
  elsif SQLTree::Token::SELECT === tokens.peek(2)
160
179
  table_reference = self.new(SQLTree::Node::SubQuery.parse(tokens))
@@ -169,6 +188,35 @@ module SQLTree::Node
169
188
  end
170
189
  end
171
190
 
191
+ class IndexHint < Base
192
+ leaf :hint_method
193
+ leaf :hint_key
194
+ leaf :index_list
195
+
196
+ def initialize(hint_method, hint_key, index_list)
197
+ @hint_method, @hint_key, @index_list = hint_method, hint_key, index_list
198
+ end
199
+
200
+ def to_sql(options={})
201
+ sql = "#{hint_method} #{hint_key} "
202
+ sql << "(#{index_list.map {|idx| idx.to_sql }.join(' ')})"
203
+ sql
204
+ end
205
+
206
+ def self.parse(tokens)
207
+ hint_method = tokens.next.literal
208
+ if tokens.peek.index_keyword?
209
+ hint_key = tokens.next.literal
210
+ tokens.consume(SQLTree::Token::LPAREN)
211
+ index_list = parse_list(tokens, SQLTree::Node::Expression::Field)
212
+ tokens.consume(SQLTree::Token::RPAREN)
213
+ self.new(hint_method, hint_key, index_list)
214
+ else
215
+ raise SQLTree::Parser::UnexpectedToken.new(tokens.current)
216
+ end
217
+ end
218
+ end
219
+
172
220
  class Expression < Base
173
221
  class BinaryOperator < SQLTree::Node::Expression
174
222
  TOKEN_PRECEDENCE[2] << SQLTree::Token::BETWEEN
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Turntable
3
- VERSION = "2.2.2"
3
+ VERSION = "2.3.0"
4
4
  end
5
5
  end
@@ -11,4 +11,24 @@ describe SQLTree do
11
11
  it { expect { subject }.to_not raise_error }
12
12
  its(:to_sql) { is_expected.to include("x'deadbeef") }
13
13
  end
14
+
15
+ context "Select query with index hint" do
16
+ ["FORCE INDEX", "IGNORE INDEX", "USE INDEX"].each do |hint|
17
+ context hint do
18
+ subject { SQLTree["SELECT * FROM table #{hint} (`foo`) WHERE field = 'value'"] }
19
+ it { expect { subject }.to_not raise_error }
20
+ its(:to_sql) { is_expected.to include("#{hint} (`foo`)") }
21
+ end
22
+ end
23
+ end
24
+
25
+ context "Select query without index hint" do
26
+ subject { SQLTree["SELECT * FROM table WHERE field = 'value'"] }
27
+ it { expect { subject }.to_not raise_error }
28
+ end
29
+
30
+ context "Delete query" do
31
+ subject { SQLTree["DELETE FROM table"] }
32
+ it { expect { subject }.to_not raise_error }
33
+ end
14
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-turntable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - gussan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-24 00:00:00.000000000 Z
12
+ date: 2015-07-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -522,4 +522,3 @@ test_files:
522
522
  - spec/spec_helper.rb
523
523
  - spec/support/matchers/be_saved_to.rb
524
524
  - spec/support/turntable_helper.rb
525
- has_rdoc: