1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module ArrayParser # :nodoc:
DOUBLE_QUOTE = '"'
BACKSLASH = "\\"
COMMA = ','
BRACKET_OPEN = '{'
BRACKET_CLOSE = '}'
def parse_pg_array(string) # :nodoc:
local_index = 0
array = []
while(local_index < string.length)
case string[local_index]
when BRACKET_OPEN
local_index,array = parse_array_contents(array, string, local_index + 1)
when BRACKET_CLOSE
return array
end
local_index += 1
end
array
end
private
def parse_array_contents(array, string, index)
is_escaping = false
is_quoted = false
was_quoted = false
current_item = ''
local_index = index
while local_index
token = string[local_index]
if is_escaping
current_item << token
is_escaping = false
else
if is_quoted
case token
when DOUBLE_QUOTE
is_quoted = false
was_quoted = true
when BACKSLASH
is_escaping = true
else
current_item << token
end
else
case token
when BACKSLASH
is_escaping = true
when COMMA
add_item_to_array(array, current_item, was_quoted)
current_item = ''
was_quoted = false
when DOUBLE_QUOTE
is_quoted = true
when BRACKET_OPEN
internal_items = []
local_index,internal_items = parse_array_contents(internal_items, string, local_index + 1)
array.push(internal_items)
when BRACKET_CLOSE
add_item_to_array(array, current_item, was_quoted)
return local_index,array
else
current_item << token
end
end
end
local_index += 1
end
return local_index,array
end
def add_item_to_array(array, current_item, quoted)
return if !quoted && current_item.length == 0
if !quoted && current_item == 'NULL'
array.push nil
else
array.push current_item
end
end
end
end
end
end
|