activerecord-turntable 2.0.2 → 2.0.3
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
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
|