coopy 0.6.4.1 → 1.0.0

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