coopy 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +8 -0
- data/bin/sqlite_diff +4 -0
- data/bin/sqlite_patch +4 -0
- data/bin/sqlite_rediff +4 -0
- data/lib/coopy.rb +178 -0
- data/lib/coopy/dbi_sql_wrapper.rb +89 -0
- data/lib/coopy/diff_apply_sql.rb +35 -0
- data/lib/coopy/diff_columns.rb +33 -0
- data/lib/coopy/diff_output.rb +21 -0
- data/lib/coopy/diff_output_action.rb +34 -0
- data/lib/coopy/diff_output_group.rb +40 -0
- data/lib/coopy/diff_output_raw.rb +17 -0
- data/lib/coopy/diff_output_stats.rb +45 -0
- data/lib/coopy/diff_output_table.rb +49 -0
- data/lib/coopy/diff_output_tdiff.rb +48 -0
- data/lib/coopy/diff_parser.rb +92 -0
- data/lib/coopy/diff_render_csv.rb +29 -0
- data/lib/coopy/diff_render_html.rb +74 -0
- data/lib/coopy/diff_render_log.rb +52 -0
- data/lib/coopy/row_change.rb +25 -0
- data/lib/coopy/scraperwiki_sql_wrapper.rb +8 -0
- data/lib/coopy/scraperwiki_utils.rb +23 -0
- data/lib/coopy/sequel_sql_wrapper.rb +73 -0
- data/lib/coopy/sql_compare.rb +222 -0
- data/lib/coopy/sql_wrapper.rb +34 -0
- data/lib/coopy/sqlite_sql_wrapper.rb +143 -0
- data/test/test_coopy.rb +126 -0
- metadata +86 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'coopy/diff_output'
|
2
|
+
|
3
|
+
class DiffOutputRaw < DiffOutput
|
4
|
+
def apply_row(rc)
|
5
|
+
unless @shown_columns
|
6
|
+
puts "COLUMN NAMES: #{rc.columns.column_name}"
|
7
|
+
puts "COLUMN OFFSETS: #{rc.columns.column_offset}"
|
8
|
+
puts "COLUMN CHANGE ROW: #{rc.columns.change_row}"
|
9
|
+
puts "COLUMN TITLE ROW: #{rc.columns.title_row}"
|
10
|
+
puts " "
|
11
|
+
@shown_columns = true
|
12
|
+
end
|
13
|
+
puts "Mode: [#{rc.row_mode}]"
|
14
|
+
puts "Cells: #{rc.cells}"
|
15
|
+
puts " "
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'coopy/diff_output'
|
2
|
+
|
3
|
+
class Coopy::DiffOutputStats < DiffOutput
|
4
|
+
attr_accessor :row
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@row = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def row_inc(tag)
|
11
|
+
@row[tag] = 0 unless @row.has_key? tag
|
12
|
+
@row[tag] = @row[tag]+1
|
13
|
+
end
|
14
|
+
|
15
|
+
def apply_row(rc)
|
16
|
+
row_inc(:all)
|
17
|
+
case rc.row_mode
|
18
|
+
when "+++"
|
19
|
+
row_inc(:insert)
|
20
|
+
when "---"
|
21
|
+
row_inc(:delete)
|
22
|
+
when "->"
|
23
|
+
row_inc(:update)
|
24
|
+
when "..."
|
25
|
+
row_inc(:skip)
|
26
|
+
when ""
|
27
|
+
row_inc(:context)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def add(sel,sel_tag,tag)
|
32
|
+
v = 0
|
33
|
+
v = sel[tag] if sel.has_key? tag
|
34
|
+
"#{sel_tag.to_s},#{tag.to_s},#{v}\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_string
|
38
|
+
txt = ""
|
39
|
+
[:all,:insert,:delete,:update,:skip,:context].each do |tag|
|
40
|
+
txt = txt + add(@row,:row,tag)
|
41
|
+
end
|
42
|
+
txt
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'coopy/diff_output'
|
2
|
+
|
3
|
+
class DiffOutputTable < DiffOutput
|
4
|
+
def begin_table
|
5
|
+
end
|
6
|
+
|
7
|
+
def end_table
|
8
|
+
end
|
9
|
+
|
10
|
+
def begin_row(mode)
|
11
|
+
end
|
12
|
+
|
13
|
+
def insert_cell(txt,mode,separator)
|
14
|
+
end
|
15
|
+
|
16
|
+
def end_row
|
17
|
+
end
|
18
|
+
|
19
|
+
def quote(x)
|
20
|
+
return "" if x.nil?
|
21
|
+
x
|
22
|
+
end
|
23
|
+
|
24
|
+
def apply_row(rc)
|
25
|
+
self.begin_row(rc.row_mode)
|
26
|
+
self.insert_cell(rc.row_mode,
|
27
|
+
(rc.row_mode=="->") ? rc.row_mode : "",
|
28
|
+
(rc.row_mode=="->") ? rc.row_mode : "")
|
29
|
+
rc.cells.each do |cell|
|
30
|
+
if cell[:new_value]
|
31
|
+
self.insert_cell(quote(cell[:value]) + "->" + quote(cell[:new_value]),
|
32
|
+
cell[:cell_mode],
|
33
|
+
"->")
|
34
|
+
else
|
35
|
+
self.insert_cell(cell[:txt],cell[:cell_mode],cell[:separator])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
self.end_row
|
39
|
+
end
|
40
|
+
|
41
|
+
def begin_diff
|
42
|
+
self.begin_table
|
43
|
+
end
|
44
|
+
|
45
|
+
def end_diff
|
46
|
+
self.end_table
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'coopy/diff_output_action'
|
2
|
+
|
3
|
+
# this is just a stub, not yet functional
|
4
|
+
class DiffOutputTdiff < DiffOutputAction
|
5
|
+
def begin_diff
|
6
|
+
puts "# tdiff version 0.3"
|
7
|
+
end
|
8
|
+
|
9
|
+
def row_show(rc)
|
10
|
+
rc.active_columns.each do |col|
|
11
|
+
title = col[:title]
|
12
|
+
offset = col[:diff_offset]
|
13
|
+
print "|"
|
14
|
+
print title
|
15
|
+
print "="
|
16
|
+
print rc.cells[offset][:txt]
|
17
|
+
unless rc.cells[offset][:new_value].nil?
|
18
|
+
print "->"
|
19
|
+
print rc.cells[offset][:new_value]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
puts "|"
|
23
|
+
end
|
24
|
+
|
25
|
+
def row_insert(rc)
|
26
|
+
print "+ "
|
27
|
+
row_show(rc)
|
28
|
+
end
|
29
|
+
|
30
|
+
def row_delete(rc)
|
31
|
+
print "- "
|
32
|
+
row_show(rc)
|
33
|
+
end
|
34
|
+
|
35
|
+
def row_update(rc)
|
36
|
+
print "= "
|
37
|
+
row_show(rc)
|
38
|
+
end
|
39
|
+
|
40
|
+
def row_skip(rc)
|
41
|
+
puts "* ||"
|
42
|
+
end
|
43
|
+
|
44
|
+
def row_context(rc)
|
45
|
+
print "* "
|
46
|
+
row_show(rc)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'coopy/diff_output'
|
2
|
+
require 'csv'
|
3
|
+
|
4
|
+
class DiffParser
|
5
|
+
def initialize(fname)
|
6
|
+
@rows = CSV.read(fname)
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_output(output)
|
10
|
+
@diff_output = output
|
11
|
+
end
|
12
|
+
|
13
|
+
def apply_row_main(rc,columns)
|
14
|
+
rc.columns = columns
|
15
|
+
@diff_output.apply_row(rc)
|
16
|
+
end
|
17
|
+
|
18
|
+
def apply
|
19
|
+
rows = @rows
|
20
|
+
render = @diff_output
|
21
|
+
return if render.nil?
|
22
|
+
render.begin_diff
|
23
|
+
rcs = []
|
24
|
+
columns = DiffColumns.new
|
25
|
+
rows.each_with_index do |row, r|
|
26
|
+
row_mode = ""
|
27
|
+
open = false
|
28
|
+
next if row.length == 0
|
29
|
+
txt = row[0]
|
30
|
+
txt = "" if txt.nil?
|
31
|
+
if txt=="@" or txt=="@@"
|
32
|
+
row_mode = "@@"
|
33
|
+
columns.title_row = row
|
34
|
+
columns.update
|
35
|
+
elsif txt=="!" or txt=="+++" or txt=="---" or txt=="..." or txt.include? "->"
|
36
|
+
row_mode = txt
|
37
|
+
columns.change_row = row if txt=="!"
|
38
|
+
else
|
39
|
+
open = true
|
40
|
+
end
|
41
|
+
cmd = txt
|
42
|
+
cells = []
|
43
|
+
row.each_with_index do |val, c|
|
44
|
+
next if c == 0
|
45
|
+
nval = nil
|
46
|
+
txt = ""
|
47
|
+
txt = val.to_s unless val.nil?
|
48
|
+
txt = "" if txt=="NULL"
|
49
|
+
cell_mode = ""
|
50
|
+
separator = ""
|
51
|
+
if open and !columns.change_row.nil?
|
52
|
+
change = columns.change_row[c]
|
53
|
+
if change=="+++" or change == "---"
|
54
|
+
cell_mode = change
|
55
|
+
end
|
56
|
+
end
|
57
|
+
if cmd.to_s.include? "->"
|
58
|
+
if txt.include? cmd
|
59
|
+
cell_mode = "->"
|
60
|
+
separator = cmd
|
61
|
+
b = txt.index(cmd)
|
62
|
+
val = txt[0,b]
|
63
|
+
nval = txt[b+cmd.length,txt.length]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
cells << {
|
67
|
+
:txt => txt,
|
68
|
+
:value => val,
|
69
|
+
:new_value => nval,
|
70
|
+
:cell_mode => cell_mode,
|
71
|
+
:separator => separator
|
72
|
+
}
|
73
|
+
end
|
74
|
+
rc = RowChange.new(row_mode,cells)
|
75
|
+
unless columns.title_row.nil?
|
76
|
+
rcs.each { |rc| self.apply_row_main(rc,columns) }
|
77
|
+
rcs = []
|
78
|
+
self.apply_row_main(rc,columns)
|
79
|
+
else
|
80
|
+
rcs << rc
|
81
|
+
end
|
82
|
+
end
|
83
|
+
rcs.each { |rc| self.apply_row_main(rc,columns) }
|
84
|
+
render.end_diff
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_string
|
88
|
+
return diff_output.to_string unless diff_output.nil?
|
89
|
+
""
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'coopy/diff_output_table'
|
2
|
+
require 'csv'
|
3
|
+
|
4
|
+
class DiffRenderCsv < DiffOutputTable
|
5
|
+
def initialize(fname = nil)
|
6
|
+
@txt = ""
|
7
|
+
@csv = CSV.open(fname,'w') if fname
|
8
|
+
end
|
9
|
+
|
10
|
+
def begin_row(row_mode)
|
11
|
+
@line = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def insert_cell(txt,mode,separator)
|
15
|
+
@line << txt
|
16
|
+
end
|
17
|
+
|
18
|
+
def end_row
|
19
|
+
if @csv
|
20
|
+
@csv.add_row(@line)
|
21
|
+
else
|
22
|
+
@txt << @line.to_csv
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_string
|
27
|
+
@txt
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'coopy/diff_output_table'
|
2
|
+
|
3
|
+
class DiffRenderHtml < DiffOutputTable
|
4
|
+
def initialize
|
5
|
+
@text_to_insert = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def insert(str)
|
9
|
+
@text_to_insert << str
|
10
|
+
end
|
11
|
+
|
12
|
+
def begin_table
|
13
|
+
self.insert "<table class='csv_sheet'>\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
def begin_row(mode)
|
17
|
+
@td_open = '<td';
|
18
|
+
@td_close = '</td>';
|
19
|
+
@row_color = "";
|
20
|
+
@open = false;
|
21
|
+
case mode
|
22
|
+
when "@@"
|
23
|
+
@td_open = "<th"
|
24
|
+
@td_close = "</th>"
|
25
|
+
when "!"
|
26
|
+
@row_color = "#aaaaaa"
|
27
|
+
when "+++"
|
28
|
+
@row_color = "#7fff7f";
|
29
|
+
when "---"
|
30
|
+
@row_color = "#ff7f7f";
|
31
|
+
else
|
32
|
+
@open = true
|
33
|
+
end
|
34
|
+
tr = "<tr>";
|
35
|
+
row_decorate = ""
|
36
|
+
if @row_color!=""
|
37
|
+
row_decorate = " bgcolor=\"" + @row_color + "\" style=\"background-color: " + @row_color + ";\""
|
38
|
+
tr = "<tr" + row_decorate + ">"
|
39
|
+
end
|
40
|
+
self.insert(tr)
|
41
|
+
end
|
42
|
+
|
43
|
+
def insert_cell(txt,mode,separator)
|
44
|
+
cell_decorate = ""
|
45
|
+
case mode
|
46
|
+
when "+++"
|
47
|
+
cell_decorate = " bgcolor=\"#7fff7f\" style=\"background-color: #7fff7f;\""
|
48
|
+
when "---"
|
49
|
+
cell_decorate = " bgcolor=\"#ff7f7f\" style=\"background-color: #ff7f7f;\""
|
50
|
+
when "->"
|
51
|
+
cell_decorate = " bgcolor=\"#7f7fff\" style=\"background-color: #7f7fff;\""
|
52
|
+
end
|
53
|
+
self.insert @td_open+cell_decorate+">"
|
54
|
+
self.insert txt
|
55
|
+
self.insert @td_close
|
56
|
+
end
|
57
|
+
|
58
|
+
def end_row
|
59
|
+
self.insert "</tr>\n"
|
60
|
+
end
|
61
|
+
|
62
|
+
def end_table
|
63
|
+
self.insert "</table>\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
def html
|
67
|
+
@text_to_insert.join ''
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_string
|
71
|
+
html
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'diff_output_table'
|
2
|
+
|
3
|
+
class DiffRenderLog < DiffOutputTable
|
4
|
+
def initialize
|
5
|
+
@r = 0
|
6
|
+
@c = 0
|
7
|
+
@row_mode = ""
|
8
|
+
@row_log = []
|
9
|
+
@cell_log = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def begin_table
|
13
|
+
end
|
14
|
+
|
15
|
+
def begin_row(mode)
|
16
|
+
@row_mode = mode
|
17
|
+
@row_log << [@r, mode]
|
18
|
+
@c = 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def insert_cell(txt,mode,separator)
|
22
|
+
@cell_log << {
|
23
|
+
:col => @c,
|
24
|
+
:row => @r,
|
25
|
+
:txt => txt,
|
26
|
+
:cell_mode => mode,
|
27
|
+
:row_mode => @row_mode,
|
28
|
+
:separator => separator
|
29
|
+
}
|
30
|
+
@c = @c + 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def end_row
|
34
|
+
@r = @r + 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def end_table
|
38
|
+
end
|
39
|
+
|
40
|
+
def log
|
41
|
+
txt = ""
|
42
|
+
@cell_log.each do |v|
|
43
|
+
txt << v[:col].to_s + "," + v[:row].to_s + " [" + v[:cell_mode] + "/" +
|
44
|
+
v[:row_mode] + "] " + v[:separator] + " : " + v[:txt].to_s + "\n"
|
45
|
+
end
|
46
|
+
txt
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_string
|
50
|
+
log
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class RowChange
|
2
|
+
attr_accessor :row_mode
|
3
|
+
attr_accessor :cells
|
4
|
+
attr_accessor :columns
|
5
|
+
attr_accessor :key
|
6
|
+
|
7
|
+
def initialize(row_mode,cells)
|
8
|
+
@row_mode = row_mode
|
9
|
+
@cells = cells
|
10
|
+
@key = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def active_columns
|
14
|
+
return [] if @columns.nil?
|
15
|
+
@columns.column_by_offset
|
16
|
+
end
|
17
|
+
|
18
|
+
def value_at(column)
|
19
|
+
@cells[column[:in_offset]][:value]
|
20
|
+
end
|
21
|
+
|
22
|
+
def new_value_at(column)
|
23
|
+
@cells[column[:in_offset]][:new_value]
|
24
|
+
end
|
25
|
+
end
|