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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7d26c10b2a5821aa33e7136734bcf2e5ef25080
|
4
|
+
data.tar.gz: 5a4709f8c44aaf2f2d9ac437c8b1bc3ff679fa1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c990394e1144fc5f7b20fa6c5a9a2a818e8937683676bb0c5752f26582109a17ef43c8548e8645d811884facf0e4a9a4f196a62b4025947dde23fcfcb65bfbfd
|
7
|
+
data.tar.gz: 7afc6bc759ecbe127e720664888576b91c3628990a02c38bdd1cf5f4af8c71dff0e426f211fee76b640d5d5c6de4f7fbcc13509690c5db6b057007340c2d4323
|
data/CHANGELOG.md
CHANGED
@@ -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
|
@@ -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.
|
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-
|
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
|