activerecord-turntable 2.0.2 → 2.0.3

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: 4906bb6f73e98fee1490a6470ec0e6fb5d46e799
4
- data.tar.gz: 6304957da987dd1e9315a3a3ce8be4b1bb720bd9
3
+ metadata.gz: c7d26c10b2a5821aa33e7136734bcf2e5ef25080
4
+ data.tar.gz: 5a4709f8c44aaf2f2d9ac437c8b1bc3ff679fa1d
5
5
  SHA512:
6
- metadata.gz: 40b81ab32f081801cffa81d68921fc94b3dd6f62284d9c3cf54081c8f949203c2417c51b7e9d6a93e8bcac557d9124632d706a12eb45023f33a0a6ebaa48e95d
7
- data.tar.gz: e99818a708e9b58f6d5924e6af43eb0a0f7446b50c8cfaa3c98a0bdfcb6ca1b281b62e79a39d44c1043629fd1ea08b46c1e1218d8d0200590dd356f782394df7
6
+ metadata.gz: c990394e1144fc5f7b20fa6c5a9a2a818e8937683676bb0c5752f26582109a17ef43c8548e8645d811884facf0e4a9a4f196a62b4025947dde23fcfcb65bfbfd
7
+ data.tar.gz: 7afc6bc759ecbe127e720664888576b91c3628990a02c38bdd1cf5f4af8c71dff0e426f211fee76b640d5d5c6de4f7fbcc13509690c5db6b057007340c2d4323
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## activerecord-turntable 2.0.3 ##
2
+
3
+ ### Bugfixes
4
+
5
+ * Fix parse error on sql with binary string literal: ```x'...'```
6
+
1
7
  ## activerecord-turntable 2.0.2 ##
2
8
 
3
9
  ### Bugfixes
@@ -15,6 +15,8 @@ class SQLTree::Token
15
15
  const_set('BINARY', Class.new(SQLTree::Token::Keyword))
16
16
  const_set('LIMIT', Class.new(SQLTree::Token::Keyword))
17
17
  const_set('OFFSET', Class.new(SQLTree::Token::Keyword))
18
+
19
+ BINARY_ESCAPE = Class.new(SQLTree::Token).new('x')
18
20
  end
19
21
 
20
22
  class SQLTree::Tokenizer
@@ -25,6 +27,44 @@ class SQLTree::Tokenizer
25
27
  end
26
28
  handle_token(SQLTree::Token::String.new(string), &block)
27
29
  end
30
+
31
+ # @note Override to handle x'..' binary string
32
+ def each_token(&block) # :yields: SQLTree::Token
33
+
34
+ while next_char
35
+ case current_char
36
+ when /^\s?$/; # whitespace, go to next character
37
+ when '('; handle_token(SQLTree::Token::LPAREN, &block)
38
+ when ')'; handle_token(SQLTree::Token::RPAREN, &block)
39
+ when '.'; handle_token(SQLTree::Token::DOT, &block)
40
+ when ','; handle_token(SQLTree::Token::COMMA, &block)
41
+ when /\d/; tokenize_number(&block)
42
+ when "'"; tokenize_quoted_string(&block)
43
+ when 'E', 'x', 'X'; tokenize_possible_escaped_string(&block)
44
+ when /\w/; tokenize_keyword(&block)
45
+ when OPERATOR_CHARS; tokenize_operator(&block)
46
+ when SQLTree.identifier_quote_char; tokenize_quoted_identifier(&block)
47
+ end
48
+ end
49
+
50
+ # Make sure to yield any tokens that are still stashed on the queue.
51
+ empty_keyword_queue!(&block)
52
+ end
53
+ alias :each :each_token
54
+
55
+ def tokenize_possible_escaped_string(&block)
56
+ if peek_char == "'"
57
+ token = case current_char
58
+ when 'E'
59
+ SQLTree::Token::STRING_ESCAPE
60
+ when 'x', 'X'
61
+ SQLTree::Token::BINARY_ESCAPE
62
+ end
63
+ handle_token(token, &block)
64
+ else
65
+ tokenize_keyword(&block)
66
+ end
67
+ end
28
68
  end
29
69
 
30
70
  module SQLTree::Node
@@ -167,6 +207,65 @@ module SQLTree::Node
167
207
  @table.nil? ? quote_field_name(@name) : quote_field_name(@table) + '.' + quote_field_name(@name)
168
208
  end
169
209
  end
210
+
211
+ class EscapedValue < Value
212
+ def initialize(value, escape = nil)
213
+ @value = value
214
+ @escape = escape
215
+ end
216
+
217
+ def to_sql(options = {})
218
+ case value
219
+ when nil; 'NULL'
220
+ when String; "#{escape_string}#{quote_str(@value)}"
221
+ when Numeric; @value.to_s
222
+ when Date; @value.strftime("'%Y-%m-%d'")
223
+ when DateTime, Time; @value.strftime("'%Y-%m-%d %H:%M:%S'")
224
+ else raise "Don't know how te represent this value in SQL!"
225
+ end
226
+ end
227
+
228
+ def escape_string
229
+ @escape.to_s
230
+ end
231
+
232
+ def self.parse(tokens)
233
+ escape = tokens.next
234
+ case tokens.next
235
+ when SQLTree::Token::String
236
+ SQLTree::Node::Expression::EscapedValue.new(tokens.current.literal, escape.literal)
237
+ else
238
+ raise SQLTree::Parser::UnexpectedToken.new(tokens.current, :literal)
239
+ end
240
+ end
241
+ end
242
+
243
+ def self.parse_atomic(tokens)
244
+ if SQLTree::Token::LPAREN === tokens.peek
245
+ tokens.consume(SQLTree::Token::LPAREN)
246
+ expr = self.parse(tokens)
247
+ tokens.consume(SQLTree::Token::RPAREN)
248
+ expr
249
+ elsif tokens.peek.prefix_operator?
250
+ PrefixOperator.parse(tokens)
251
+ elsif tokens.peek.variable?
252
+ if SQLTree::Token::LPAREN === tokens.peek(2)
253
+ FunctionCall.parse(tokens)
254
+ elsif SQLTree::Token::DOT === tokens.peek(2)
255
+ Field.parse(tokens)
256
+ else
257
+ Variable.parse(tokens)
258
+ end
259
+ elsif SQLTree::Token::STRING_ESCAPE == tokens.peek
260
+ EscapedValue.parse(tokens)
261
+ elsif SQLTree::Token::BINARY_ESCAPE == tokens.peek
262
+ EscapedValue.parse(tokens)
263
+ elsif SQLTree::Token::INTERVAL === tokens.peek
264
+ IntervalValue.parse(tokens)
265
+ else
266
+ Value.parse(tokens)
267
+ end
268
+ end
170
269
  end
171
270
 
172
271
  class InsertQuery < Base
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Turntable
3
- VERSION = "2.0.2"
3
+ VERSION = "2.0.3"
4
4
  end
5
5
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'active_record/turntable/sql_tree_patch'
3
+
4
+ describe SQLTree do
5
+ before(:all) do
6
+ reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
7
+ end
8
+
9
+ context "Insert query with binary string" do
10
+ subject { SQLTree["INSERT INTO `hogehoge` (`name`) VALUES (x'deadbeef')"] }
11
+ it { expect { subject }.to_not raise_error }
12
+ its(:to_sql) { is_expected.to include("x'deadbeef") }
13
+ end
14
+ 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.0.2
4
+ version: 2.0.3
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: 2014-11-17 00:00:00.000000000 Z
12
+ date: 2014-11-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -396,6 +396,7 @@ files:
396
396
  - spec/active_record/turntable/sequencer/barrage_spec.rb
397
397
  - spec/active_record/turntable/sequencer/mysql_spec.rb
398
398
  - spec/active_record/turntable/shard_spec.rb
399
+ - spec/active_record/turntable/sql_tree_patch_spec.rb
399
400
  - spec/active_record/turntable/transaction_spec.rb
400
401
  - spec/active_record/turntable_spec.rb
401
402
  - spec/config/database.yml
@@ -461,6 +462,7 @@ test_files:
461
462
  - spec/active_record/turntable/sequencer/barrage_spec.rb
462
463
  - spec/active_record/turntable/sequencer/mysql_spec.rb
463
464
  - spec/active_record/turntable/shard_spec.rb
465
+ - spec/active_record/turntable/sql_tree_patch_spec.rb
464
466
  - spec/active_record/turntable/transaction_spec.rb
465
467
  - spec/active_record/turntable_spec.rb
466
468
  - spec/config/database.yml