sqlconv 1.0 → 1.1

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.
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