sqlconv 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/sqlconv +35 -17
- data/sqlconv.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dad0487cbd81b9dd742216fcbf77cff8cdbe0409599faf1719c52a6eab74429d
|
4
|
+
data.tar.gz: 6472f28fe595994f837c861d2aaa45974fa7327e9473fcf0aaeab1cb424d5713
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa417046fe5c9c5ca098cfade1b042a59d418f7f27e076726d7c6f56a2ac82ae6b66a7a7d2885a6061b6f249636452d673bd352b2ace8085b17dedb3b5ff5d37
|
7
|
+
data.tar.gz: db52a84b235ecda37b54604013922ab68cd53dd702fe62d0888a411714f3ad3db78fa5db18ffef1f0cdd8c0a8583161fd9eee1fb6441e7a0d1905f58fa010420
|
data/bin/sqlconv
CHANGED
@@ -46,16 +46,15 @@ Selector = Struct.new(:want, :func, :text, :zero, :thru, :reps, :from, :till)
|
|
46
46
|
# convert user request into selectors
|
47
47
|
def grok(want)
|
48
48
|
(want || "1-").strip.split(/\s*,\s*/).map do |item|
|
49
|
-
item =~ %r!^
|
50
|
-
(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
)$
|
49
|
+
item =~ %r!^(?:(\d+)\*)?(?:(?:( # $1: repeat
|
50
|
+
(?:\d+(?=\())|[a-zA-Z]\w*) # $2: function name
|
51
|
+
(\()?)?(?: # $3: optional paren
|
52
|
+
(?:(['"])(.*?)\4)? | # $4: quote, $5: literal
|
53
|
+
(0) | # $6: zero
|
54
|
+
((?>[1-9]\d*))? # $7: from
|
55
|
+
((?<=\d)-|-(?=\d))? # $8: thru
|
56
|
+
((?>[1-9]\d*))? # $9: till
|
57
|
+
)\)?)$
|
59
58
|
!iox or raise "invalid selector item '#{item}'"
|
60
59
|
Selector.new(*$~.values_at(0, 2, 5, 6, 8), *$~.values_at(1, 7, 9).map {|e| e&.to_i })
|
61
60
|
end or raise "invalid selector '#{want}'"
|
@@ -81,6 +80,20 @@ def table(cols, rows)
|
|
81
80
|
puts line, "#{seen} rows displayed", ""
|
82
81
|
end
|
83
82
|
|
83
|
+
def escape(str)
|
84
|
+
str =~ /\A(\d+|null)\z/i ? $1 : %|'#{str.gsub("'", "\\\\'")}'|
|
85
|
+
end
|
86
|
+
|
87
|
+
def unescape(str, nulls=false)
|
88
|
+
str =~ /\A['"]/ and return str[1..-2].gsub("|","~").gsub("''", "'")
|
89
|
+
str == 'NULL' and return '' unless nulls
|
90
|
+
str
|
91
|
+
end
|
92
|
+
|
93
|
+
def unescape!(str)
|
94
|
+
unescape(str, true)
|
95
|
+
end
|
96
|
+
|
84
97
|
# convert the insert statements
|
85
98
|
def conv(tab1, map1, tab2, map2, mode, dump)
|
86
99
|
data = StringScanner.new("")
|
@@ -105,10 +118,12 @@ def conv(tab1, map1, tab2, map2, mode, dump)
|
|
105
118
|
into or die "unable to find insert statements for the '#{tab1}' table"
|
106
119
|
|
107
120
|
# if needed, output pipes header
|
108
|
-
if mode == "pipes"
|
109
|
-
puts map2.gsub(',','|')
|
121
|
+
if mode == "pipes"
|
122
|
+
puts map2.gsub(',','|') if map2
|
123
|
+
lean = true
|
110
124
|
elsif mode == "table"
|
111
125
|
rows = []
|
126
|
+
lean = true
|
112
127
|
end
|
113
128
|
|
114
129
|
# process each line
|
@@ -118,6 +133,7 @@ def conv(tab1, map1, tab2, map2, mode, dump)
|
|
118
133
|
if data.scan_str("(") or data.scan_str(into + "(")
|
119
134
|
cols = data.scan_while(/('.*?(?<!\\)'|(?>[^',()]+)|,)/, 2)
|
120
135
|
cols.empty? and die "bad sql parse: '#{line}'"
|
136
|
+
cols.map! {|item| unescape(item)} if lean
|
121
137
|
data.scan(/\)[;,]\s*/)
|
122
138
|
else
|
123
139
|
break
|
@@ -139,7 +155,7 @@ def conv(tab1, map1, tab2, map2, mode, dump)
|
|
139
155
|
exit
|
140
156
|
end
|
141
157
|
need.each do |item|
|
142
|
-
item.text &&=
|
158
|
+
item.text &&= escape(item.text) unless lean
|
143
159
|
if (len2 = [item.from, item.till, 0].compact.max) > len1
|
144
160
|
warn "selector '#{item.want}' referenced source column #{len2}, but only #{len1} are defined"
|
145
161
|
cols &&= nil
|
@@ -159,7 +175,12 @@ def conv(tab1, map1, tab2, map2, mode, dump)
|
|
159
175
|
case item.func
|
160
176
|
when "rand" then ours.push("'random number here!'")
|
161
177
|
when "n","null" then ours.push("null")
|
162
|
-
when "z" then ours.push((val = cols[item.from-1]) == "NULL" ? 0
|
178
|
+
when "z" then ours.push((val = cols[item.from -1]) == "NULL" ? 0 : val)
|
179
|
+
when /^(\d+)$/
|
180
|
+
val = cols[item.func.to_i - 1]
|
181
|
+
val = unescape(val) unless lean
|
182
|
+
val = val[0, item.from]
|
183
|
+
ours.push(val)
|
163
184
|
else
|
164
185
|
defined?(item.func) == "method" or die "undefined function '#{item.func}'"
|
165
186
|
ours.push *(send item.func, *Array[cols[item.from-1]])
|
@@ -195,9 +216,6 @@ def conv(tab1, map1, tab2, map2, mode, dump)
|
|
195
216
|
end
|
196
217
|
|
197
218
|
# generate output
|
198
|
-
if mode == "pipes" || mode == "table"
|
199
|
-
ours.map! {|e| e == 'NULL' ? '' : e !~ /\A['"]/ ? e : e[1..-2].gsub("|","~").gsub("''", "'")}
|
200
|
-
end
|
201
219
|
if mode == "pipes"
|
202
220
|
puts ours * "|"
|
203
221
|
elsif mode == "table"
|
data/sqlconv.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqlconv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Shreeve
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Allows mapping columns from a source to a destination table
|
14
14
|
email: steve.shreeve@gmail.com
|