coopy 0.6.4.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/CHANGELOG.md +7 -0
  5. data/Gemfile +7 -0
  6. data/LICENSE.md +22 -0
  7. data/README.md +59 -0
  8. data/Rakefile +4 -6
  9. data/coopy.gemspec +26 -0
  10. data/lib/coopy.rb +32 -175
  11. data/lib/coopy/alignment.rb +260 -0
  12. data/lib/coopy/bag.rb +17 -0
  13. data/lib/coopy/cell_info.rb +24 -0
  14. data/lib/coopy/change_type.rb +10 -0
  15. data/lib/coopy/compare_flags.rb +62 -0
  16. data/lib/coopy/compare_table.rb +327 -0
  17. data/lib/coopy/coopy.rb +22 -0
  18. data/lib/coopy/cross_match.rb +10 -0
  19. data/lib/coopy/csv_table.rb +51 -0
  20. data/lib/coopy/diff_render.rb +307 -0
  21. data/lib/coopy/index.rb +73 -0
  22. data/lib/coopy/index_item.rb +17 -0
  23. data/lib/coopy/index_pair.rb +72 -0
  24. data/lib/coopy/mover.rb +123 -0
  25. data/lib/coopy/ordering.rb +27 -0
  26. data/lib/coopy/row.rb +9 -0
  27. data/lib/coopy/simple_cell.rb +15 -0
  28. data/lib/coopy/simple_table.rb +144 -0
  29. data/lib/coopy/simple_view.rb +36 -0
  30. data/lib/coopy/table.rb +44 -0
  31. data/lib/coopy/table_comparison_state.rb +33 -0
  32. data/lib/coopy/table_diff.rb +634 -0
  33. data/lib/coopy/table_text.rb +14 -0
  34. data/lib/coopy/table_view.rb +31 -0
  35. data/lib/coopy/unit.rb +53 -0
  36. data/lib/coopy/version.rb +3 -0
  37. data/lib/coopy/view.rb +34 -0
  38. data/spec/fixtures/bridges.html +10 -0
  39. data/spec/fixtures/bridges_diff.csv +8 -0
  40. data/spec/fixtures/bridges_new.csv +9 -0
  41. data/spec/fixtures/bridges_old.csv +9 -0
  42. data/spec/fixtures/planetary_bodies.html +22 -0
  43. data/spec/fixtures/planetary_bodies_diff.csv +19 -0
  44. data/spec/fixtures/planetary_bodies_new.csv +20 -0
  45. data/spec/fixtures/planetary_bodies_old.csv +19 -0
  46. data/spec/fixtures/quote_me.csv +10 -0
  47. data/spec/fixtures/quote_me2.csv +11 -0
  48. data/spec/integration/table_diff_spec.rb +57 -0
  49. data/spec/libs/compare_flags_spec.rb +40 -0
  50. data/spec/libs/coopy_spec.rb +14 -0
  51. data/spec/libs/ordering_spec.rb +28 -0
  52. data/spec/libs/unit_spec.rb +31 -0
  53. data/spec/spec_helper.rb +29 -0
  54. metadata +153 -46
  55. data/bin/sqlite_diff +0 -4
  56. data/bin/sqlite_patch +0 -4
  57. data/bin/sqlite_rediff +0 -4
  58. data/lib/coopy/dbi_sql_wrapper.rb +0 -89
  59. data/lib/coopy/diff_apply_sql.rb +0 -35
  60. data/lib/coopy/diff_columns.rb +0 -33
  61. data/lib/coopy/diff_output.rb +0 -21
  62. data/lib/coopy/diff_output_action.rb +0 -34
  63. data/lib/coopy/diff_output_group.rb +0 -40
  64. data/lib/coopy/diff_output_raw.rb +0 -17
  65. data/lib/coopy/diff_output_stats.rb +0 -45
  66. data/lib/coopy/diff_output_table.rb +0 -49
  67. data/lib/coopy/diff_output_tdiff.rb +0 -48
  68. data/lib/coopy/diff_parser.rb +0 -92
  69. data/lib/coopy/diff_render_csv.rb +0 -29
  70. data/lib/coopy/diff_render_html.rb +0 -74
  71. data/lib/coopy/diff_render_log.rb +0 -52
  72. data/lib/coopy/row_change.rb +0 -25
  73. data/lib/coopy/scraperwiki_sql_wrapper.rb +0 -8
  74. data/lib/coopy/scraperwiki_utils.rb +0 -23
  75. data/lib/coopy/sequel_sql_wrapper.rb +0 -73
  76. data/lib/coopy/sql_compare.rb +0 -222
  77. data/lib/coopy/sql_wrapper.rb +0 -34
  78. data/lib/coopy/sqlite_sql_wrapper.rb +0 -143
  79. data/test/test_coopy.rb +0 -126
@@ -0,0 +1,72 @@
1
+ module Coopy
2
+ class IndexPair
3
+
4
+ def initialize
5
+ @ia = Index.new
6
+ @ib = Index.new
7
+ @quality = 0
8
+ end
9
+
10
+ def add_column(i)
11
+ @ia.add_column i
12
+ @ib.add_column i
13
+ end
14
+
15
+ def add_columns(ca, cb)
16
+ @ia.add_column ca
17
+ @ib.add_column cb
18
+ end
19
+
20
+ def index_tables(a, b)
21
+ @ia.index_table a
22
+ @ib.index_table b
23
+ # calculate
24
+ # P(present and unique within a AND present and unique with b)
25
+ # for rows in a
26
+ good = 0
27
+ @ia.items.keys.each do |key|
28
+ item_a = @ia.items[key]
29
+ spot_a = item_a.lst.length
30
+ item_b = @ib.items[key]
31
+ spot_b = 0;
32
+ spot_b = item_b.lst.length if item_b
33
+ if spot_a == 1 && spot_b == 1
34
+ good += 1
35
+ end
36
+ end
37
+ @quality = good / [1.0,a.height].max
38
+ end
39
+
40
+ def query_by_key(ka)
41
+ result = CrossMatch.new
42
+ result.item_a = @ia.items[ka]
43
+ result.item_b = @ib.items[ka]
44
+ result.spot_a = result.spot_b = 0
45
+ if ka != ""
46
+ result.spot_a = result.item_a.lst.length if result.item_a
47
+ result.spot_b = result.item_b.lst.length if result.item_b
48
+ end
49
+ result
50
+ end
51
+
52
+ def query_by_content(row)
53
+ ka = @ia.to_key_by_content(row)
54
+ query_by_key ka
55
+ end
56
+
57
+ def query_local(row)
58
+ ka = @ia.to_key(@ia.get_table,row)
59
+ query_by_key ka
60
+ end
61
+
62
+ def get_top_freq
63
+ [@ib.top_freq, @ia.top_freq].max
64
+ end
65
+
66
+ def get_quality
67
+ @quality
68
+ end
69
+
70
+ end
71
+ end
72
+
@@ -0,0 +1,123 @@
1
+ module Coopy
2
+ class Mover
3
+
4
+ def self.move_units(units)
5
+ isrc = []
6
+ idest = []
7
+ len = units.length
8
+ ltop = -1.0
9
+ rtop = -1
10
+ in_src = {}
11
+ in_dest = {}
12
+ (0..len-1).each do |i|
13
+ unit = units[i]
14
+ if (unit.l>=0 && unit.r>=0)
15
+ ltop = unit.l if (ltop<unit.l)
16
+ rtop = unit.r if (rtop<unit.r)
17
+ in_src[unit.l] = i
18
+ in_dest[unit.r] = i
19
+ end
20
+ end
21
+ v = nil
22
+ (0...ltop+1).each do |i|
23
+ v = in_src[i]
24
+ isrc.push(v) if v
25
+ end
26
+ (0...rtop+1).each do |i|
27
+ v = in_dest[i]
28
+ idest.push(v) if v
29
+ end
30
+ return move_without_extras(isrc,idest)
31
+ end
32
+
33
+ def self.move_with_extras(isrc, idest)
34
+ # First pass: eliminate non-overlapping elements (inserts+deletes)
35
+ len = isrc.length
36
+ len2 = idest.length
37
+ in_src = {}
38
+ in_dest = {}
39
+ (0..len-1).each do |i|
40
+ in_src[isrc[i]] = i
41
+ end
42
+ (0..len2-1).each do |i|
43
+ in_dest[idest[i]] = i
44
+ end
45
+ src = []
46
+ dest = []
47
+ v = nil
48
+ (0..len-1).each do |i|
49
+ v = isrc[i]
50
+ src << v if (in_dest.has_key?(v))
51
+ end
52
+ (0..len2-1).each do |i|
53
+ v = idest[i]
54
+ dest << v if (in_src.has_key?(v))
55
+ end
56
+ return move_without_extras(src,dest)
57
+ end
58
+
59
+ def self.move_without_extras(src, dest)
60
+ return nil if (src.length!=dest.length)
61
+ return [] if (src.length<=1)
62
+
63
+ len = src.length
64
+ in_src = {}
65
+ blk_len = {}
66
+ blk_src_loc = {}
67
+ blk_dest_loc = {}
68
+ (0...len).each do |i|
69
+ in_src[src[i]] = i
70
+ end
71
+ ct = 0
72
+ in_cursor = -2
73
+ out_cursor = 0
74
+ nxt = nil
75
+ blk = -1
76
+ v = nil
77
+ while (out_cursor<len)
78
+ v = dest[out_cursor]
79
+ nxt = in_src[v]
80
+ if (nxt != in_cursor+1)
81
+ blk = v
82
+ ct = 1
83
+ blk_src_loc[blk] = nxt
84
+ blk_dest_loc[blk] = out_cursor
85
+ else
86
+ ct+=1
87
+ end
88
+ blk_len[blk] = ct
89
+ in_cursor = nxt
90
+ out_cursor+=1
91
+ end
92
+
93
+ blks = blk_len.keys
94
+ blks.sort!{ |a,b| blk_len[a] <=> blk_len[b] }
95
+
96
+ moved = []
97
+
98
+ while (blks.length>0)
99
+ blk = blks.shift
100
+ blen = blks.length
101
+ ref_src_loc = blk_src_loc[blk]
102
+ ref_dest_loc = blk_dest_loc[blk]
103
+ i = blen-1
104
+ while (i>=0)
105
+ blki = blks[i]
106
+ blki_src_loc = blk_src_loc[blki]
107
+ to_left_src = blki_src_loc < ref_src_loc
108
+ to_left_dest = blk_dest_loc[blki] < ref_dest_loc
109
+ if (to_left_src!=to_left_dest)
110
+ ct = blk_len[blki]
111
+ (0..ct-1).each do |j|
112
+ moved.push(src[blki_src_loc])
113
+ blki_src_loc+=1
114
+ end
115
+ blks.splice(i,1)
116
+ end
117
+ i-=1
118
+ end
119
+ end
120
+ return moved
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,27 @@
1
+ module Coopy
2
+ class Ordering
3
+
4
+ def initialize
5
+ @order = []
6
+ @ignore_parent = false
7
+ end
8
+
9
+ def add(l, r, p = -2)
10
+ p = -2 if @ignore_parent
11
+ @order << Coopy::Unit.new(l,r,p)
12
+ end
13
+
14
+ def get_list
15
+ @order
16
+ end
17
+
18
+ def to_s
19
+ @order.map{|x| x.to_s}.join(", ")
20
+ end
21
+
22
+ def ignore_parent
23
+ @ignore_parent = true;
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ module Coopy
2
+ module Row
3
+
4
+ def get_row_string(c)
5
+ raise NotImplementedError
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module Coopy
2
+ class SimpleCell
3
+
4
+ attr_accessor :datum
5
+
6
+ def initialize(datum = nil)
7
+ @datum = datum
8
+ end
9
+
10
+ def to_s
11
+ @datum.to_s
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,144 @@
1
+ module Coopy
2
+ class SimpleTable
3
+
4
+ include Coopy::Table
5
+
6
+ def initialize(w, h)
7
+ @data = {} # Map<Int,Dynamic>
8
+ @width = w
9
+ @height = h
10
+ end
11
+
12
+ def get_table
13
+ self
14
+ end
15
+
16
+ attr_accessor :size
17
+
18
+ def get_size
19
+ @height
20
+ end
21
+
22
+ def get_cell(x, y)
23
+ @data[x+y*@width]
24
+ end
25
+
26
+ def set_cell(x, y, c)
27
+ @data[x+y*@width] = c
28
+ end
29
+
30
+ def to_s
31
+ table_to_string(self)
32
+ end
33
+
34
+ def table_to_string(tab)
35
+ x = ""
36
+ (0..tab.height-1).each do |i|
37
+ (0..tab.width-1).each do |j|
38
+ x += " " if (j>0)
39
+ x += tab.get_cell(j,i).to_s
40
+ end
41
+ x += "\n"
42
+ end
43
+ return x
44
+ end
45
+
46
+ def get_cell_view
47
+ Coopy::SimpleView.new
48
+ end
49
+
50
+ def is_resizable?
51
+ true
52
+ end
53
+
54
+ def resize(w, h)
55
+ @width = w
56
+ @height = h
57
+ true
58
+ end
59
+
60
+ def clear
61
+ @data = {}
62
+ end
63
+
64
+ def insert_or_delete_rows(fate, hfate)
65
+ data2 = {}
66
+ (0..fate.length-1).each do |i|
67
+ j = fate[i]
68
+ if (j!=-1)
69
+ (0..@width-1).each do |c|
70
+ idx = i*@width+c;
71
+ idxf (@data.has_key?(idx))
72
+ data2[j*@width+c] = @data.get(idx)
73
+ end
74
+ end
75
+ end
76
+ @h = hfate
77
+ @data = data2
78
+ return true
79
+ end
80
+
81
+ def insert_or_delete_columns(fate, wfate)
82
+ data2 = {}
83
+ (0..fate.length-1).each do |i|
84
+ j = fate[i]
85
+ if (j!=-1)
86
+ (0..@height-1).each do |r|
87
+ idx = r*@width+i
88
+ if (data.has_key?(idx))
89
+ data2[r*wfate+j] = data.get(idx)
90
+ end
91
+ end
92
+ end
93
+ end
94
+ @width = wfate
95
+ @data = data2
96
+ return true
97
+ end
98
+
99
+ def trim_blank
100
+ return true if (h==0)
101
+ h_test = @height
102
+ h_test = 3 if (h_test>=3)
103
+ view = get_cell_view
104
+ space = view.to_datum("")
105
+ more = true
106
+ while (more)
107
+ (0..width-1).each do |i|
108
+ c = get_cell(i,@height-1)
109
+ if (!(view.equals(c,space)||c==nil))
110
+ more = false
111
+ break
112
+ end
113
+ end
114
+ h-=1 if (more)
115
+ end
116
+ more = true
117
+ nw = @width
118
+ while (more)
119
+ break if (@width==0)
120
+ (0..h_test-1).each do |i|
121
+ c = get_cell(nw-1,i)
122
+ if (!(view.equals(c,space)||c==nil))
123
+ more = false
124
+ break
125
+ end
126
+ end
127
+ nw -=1 if (more)
128
+ end
129
+ return true if (nw==w)
130
+ data2 = {}
131
+ (0..nw-1).each do |i|
132
+ (0..h-1).each do |r|
133
+ idx = r*@width+i;
134
+ if (@data.exists(idx))
135
+ data2[r*nw+i] = @data.get(idx)
136
+ end
137
+ end
138
+ end
139
+ @width = nw
140
+ @data = data2
141
+ return true
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,36 @@
1
+ module Coopy
2
+ class SimpleView
3
+
4
+ include Coopy::View
5
+
6
+ def to_s(d)
7
+ return nil if (d==nil)
8
+ return d.to_s
9
+ end
10
+
11
+ def get_bag(d)
12
+ nil
13
+ end
14
+
15
+ def get_table(d)
16
+ nil
17
+ end
18
+
19
+ def has_structure(d)
20
+ false
21
+ end
22
+
23
+ def equals(d1, d2)
24
+ #trace("Comparing " + d1 + " and " + d2 + " -- " + (("" + d1) == ("" + d2)));
25
+ return true if (d1==nil && d2==nil)
26
+ return true if (d1==nil && d2.to_s=="")
27
+ return true if (d1.to_s=="" && d2==nil)
28
+ return d1.to_s == d2.to_s
29
+ end
30
+
31
+ def to_datum(str)
32
+ return nil if (str==nil)
33
+ return SimpleCell.new(str)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ module Coopy
2
+ module Table
3
+
4
+ attr_reader :height # integer
5
+ attr_reader :width # integer
6
+
7
+ def get_cell(x, y)
8
+ raise NotImplementedError
9
+ end
10
+
11
+ def set_cell(x, y, cell)
12
+ raise NotImplementedError
13
+ end
14
+
15
+ def get_cell_view
16
+ raise NotImplementedError
17
+ end
18
+
19
+ def is_resizable?
20
+ raise NotImplementedError
21
+ end
22
+
23
+ def resize(w, h)
24
+ raise NotImplementedError
25
+ end
26
+
27
+ def clear
28
+ raise NotImplementedError
29
+ end
30
+
31
+ def insert_or_delete_rows(fate, hfate)
32
+ raise NotImplementedError
33
+ end
34
+
35
+ def insert_or_delete_columns(fate, wfate)
36
+ raise NotImplementedError
37
+ end
38
+
39
+ def trim_blank
40
+ raise NotImplementedError
41
+ end
42
+
43
+ end
44
+ end