sqlconv 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/bin/sqlconv +35 -17
  3. data/sqlconv.gemspec +1 -1
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 953b48afedc6e52ef6430f3d1bc1b66d6d652dfdc33c494b5950a961f157b6ec
4
- data.tar.gz: 6d6d791ba8c0611245143d0198a9ef8a2be00f84e2b5faf1d01c16a3426826e3
3
+ metadata.gz: dad0487cbd81b9dd742216fcbf77cff8cdbe0409599faf1719c52a6eab74429d
4
+ data.tar.gz: 6472f28fe595994f837c861d2aaa45974fa7327e9473fcf0aaeab1cb424d5713
5
5
  SHA512:
6
- metadata.gz: 9a9cfa9b993be6d3ffbeadd9deef4e6c5af05933a1d680e0e4975a335530d11029066f7b26cd76d7e2466bc809d16a15f98164fc60664ec86dab67f423d0184f
7
- data.tar.gz: 2cbe842f8898108c0b627151f6ae5014df61b5d6ea5f3d31300f11067563739bd96520cfec746d670e4951a7d0e7ee38ba55c7aed99a110e1deec4048d8d02c7
6
+ metadata.gz: fa417046fe5c9c5ca098cfade1b042a59d418f7f27e076726d7c6f56a2ac82ae6b66a7a7d2885a6061b6f249636452d673bd352b2ace8085b17dedb3b5ff5d37
7
+ data.tar.gz: db52a84b235ecda37b54604013922ab68cd53dd702fe62d0888a411714f3ad3db78fa5db18ffef1f0cdd8c0a8583161fd9eee1fb6441e7a0d1905f58fa010420
@@ -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
- (?:(\d+)\*)?(?: # $1: repeat
51
- (?:([a-zA-Z]\w*)(\()?)?(?: # $2: function, $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
- )\)?
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" && map2
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 &&= ["'", item.text.gsub("'", "\\\\'"), "'"].join
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 : val)
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"
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "sqlconv"
5
- s.version = "1.0"
5
+ s.version = "1.1"
6
6
  s.author = "Steve Shreeve"
7
7
  s.email = "steve.shreeve@gmail.com"
8
8
  s.summary = "Handy utility to massage MySQL dump files"
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.0'
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-28 00:00:00.000000000 Z
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