daff 1.2.6 → 1.3.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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -6
  3. data/bin/daff.rb +0 -0
  4. data/lib/daff.rb +6 -0
  5. data/lib/lib/coopy/alignment.rb +146 -169
  6. data/lib/lib/coopy/cell_builder.rb +1 -1
  7. data/lib/lib/coopy/cell_info.rb +2 -1
  8. data/lib/lib/coopy/column_change.rb +16 -0
  9. data/lib/lib/coopy/compare_flags.rb +33 -5
  10. data/lib/lib/coopy/compare_table.rb +219 -99
  11. data/lib/lib/coopy/coopy.rb +205 -99
  12. data/lib/lib/coopy/csv.rb +17 -22
  13. data/lib/lib/coopy/diff_render.rb +16 -8
  14. data/lib/lib/coopy/flat_cell_builder.rb +11 -8
  15. data/lib/lib/coopy/highlight_patch.rb +363 -63
  16. data/lib/lib/coopy/highlight_patch_unit.rb +1 -1
  17. data/lib/lib/coopy/index.rb +21 -8
  18. data/lib/lib/coopy/index_item.rb +7 -3
  19. data/lib/lib/coopy/index_pair.rb +13 -10
  20. data/lib/lib/coopy/merger.rb +3 -3
  21. data/lib/lib/coopy/meta.rb +17 -0
  22. data/lib/lib/coopy/mover.rb +7 -5
  23. data/lib/lib/coopy/ndjson.rb +2 -2
  24. data/lib/lib/coopy/nested_cell_builder.rb +7 -7
  25. data/lib/lib/coopy/ordering.rb +6 -2
  26. data/lib/lib/coopy/property_change.rb +16 -0
  27. data/lib/lib/coopy/row.rb +1 -0
  28. data/lib/lib/coopy/row_change.rb +42 -0
  29. data/lib/lib/coopy/row_stream.rb +11 -0
  30. data/lib/lib/coopy/simple_table.rb +84 -30
  31. data/lib/lib/coopy/simple_view.rb +8 -8
  32. data/lib/lib/coopy/sparse_sheet.rb +1 -1
  33. data/lib/lib/coopy/sql_column.rb +22 -10
  34. data/lib/lib/coopy/sql_compare.rb +397 -85
  35. data/lib/lib/coopy/sql_database.rb +2 -0
  36. data/lib/lib/coopy/sql_helper.rb +5 -0
  37. data/lib/lib/coopy/sql_table.rb +122 -19
  38. data/lib/lib/coopy/sql_table_name.rb +1 -1
  39. data/lib/lib/coopy/sqlite_helper.rb +250 -3
  40. data/lib/lib/coopy/table.rb +1 -0
  41. data/lib/lib/coopy/table_diff.rb +643 -464
  42. data/lib/lib/coopy/table_io.rb +19 -6
  43. data/lib/lib/coopy/table_modifier.rb +1 -1
  44. data/lib/lib/coopy/table_stream.rb +102 -0
  45. data/lib/lib/coopy/terminal_diff_render.rb +4 -3
  46. data/lib/lib/coopy/unit.rb +22 -2
  47. data/lib/lib/coopy/viterbi.rb +4 -4
  48. data/lib/lib/haxe/ds/int_map.rb +1 -1
  49. data/lib/lib/haxe/ds/string_map.rb +1 -1
  50. data/lib/lib/haxe/format/json_parser.rb +1 -1
  51. data/lib/lib/haxe/format/json_printer.rb +1 -1
  52. data/lib/lib/haxe/io/bytes.rb +2 -2
  53. data/lib/lib/haxe/io/eof.rb +1 -1
  54. data/lib/lib/haxe/io/output.rb +1 -1
  55. data/lib/lib/hx_overrides.rb +1 -1
  56. data/lib/lib/hx_sys.rb +9 -5
  57. data/lib/lib/lambda.rb +3 -3
  58. data/lib/lib/list.rb +1 -1
  59. data/lib/lib/rb/ruby_iterator.rb +2 -2
  60. data/lib/lib/reflect.rb +1 -1
  61. data/lib/lib/sys/io/file_output.rb +1 -1
  62. data/lib/lib/sys/io/hx_file.rb +1 -1
  63. data/lib/lib/x_list/list_iterator.rb +2 -2
  64. metadata +29 -25
  65. data/lib/lib/coopy/table_text.rb +0 -26
  66. data/lib/lib/haxe/io/bytes_buffer.rb +0 -19
  67. data/lib/lib/haxe/io/bytes_input.rb +0 -13
  68. data/lib/lib/haxe/io/bytes_output.rb +0 -33
  69. data/lib/lib/haxe/io/input.rb +0 -11
@@ -13,6 +13,8 @@ module Coopy
13
13
  def end() puts "Abstract SqlDatabase.end called" end
14
14
  def width() puts "Abstract SqlDatabase.width called" end
15
15
  def rowid() puts "Abstract SqlDatabase.rowid called" end
16
+ def getHelper() puts "Abstract SqlDatabase.getHelper called" end
17
+ def getNameForAttachment() puts "Abstract SqlDatabase.getNameForAttachment called" end
16
18
  haxe_me ["coopy", "SqlDatabase"]
17
19
  end
18
20
 
@@ -6,6 +6,11 @@ module Coopy
6
6
  def getTableNames(db) puts "Abstract SqlHelper.getTableNames called" end
7
7
  def countRows(db,name) puts "Abstract SqlHelper.countRows called" end
8
8
  def getRowIDs(db,name) puts "Abstract SqlHelper.getRowIDs called" end
9
+ def insert(db,name,vals) puts "Abstract SqlHelper.insert called" end
10
+ def delete(db,name,conds) puts "Abstract SqlHelper.delete called" end
11
+ def update(db,name,conds,vals) puts "Abstract SqlHelper.update called" end
12
+ def attach(db,tag,resource_name) puts "Abstract SqlHelper.attach called" end
13
+ def alterColumns(db,name,columns) puts "Abstract SqlHelper.alterColumns called" end
9
14
  haxe_me ["coopy", "SqlHelper"]
10
15
  end
11
16
 
@@ -8,6 +8,7 @@ module Coopy
8
8
  @db = db
9
9
  @name = name
10
10
  @helper = helper
11
+ @helper = db.get_helper if helper == nil
11
12
  @cache = {}
12
13
  @h = -1
13
14
  @id2rid = nil
@@ -57,7 +58,7 @@ module Coopy
57
58
  result.push(col.get_name)
58
59
  end
59
60
  end
60
- return result
61
+ result
61
62
  end
62
63
 
63
64
  def get_all_but_primary_key
@@ -73,28 +74,30 @@ module Coopy
73
74
  result.push(col.get_name)
74
75
  end
75
76
  end
76
- return result
77
+ result
77
78
  end
78
79
 
79
80
  def get_column_names
80
81
  self.get_columns
81
- return @column_names
82
+ @column_names
82
83
  end
83
84
 
84
85
  def get_quoted_table_name
85
86
  return @quoted_table_name if @quoted_table_name != nil
86
87
  @quoted_table_name = @db.get_quoted_table_name(@name)
87
- return @quoted_table_name
88
+ @quoted_table_name
88
89
  end
89
90
 
90
91
  def get_quoted_column_name(name)
91
- return @db.get_quoted_column_name(name)
92
+ @db.get_quoted_column_name(name)
92
93
  end
93
94
 
94
95
  def get_cell(x,y)
95
96
  if @h >= 0
96
97
  y = y - 1
97
98
  y = @id2rid[y] if y >= 0
99
+ elsif y == 0
100
+ y = -1
98
101
  end
99
102
  if y < 0
100
103
  self.get_columns
@@ -129,7 +132,7 @@ module Coopy
129
132
  end
130
133
  begin
131
134
  this1 = @cache[y]
132
- return this1.get(x)
135
+ this1.get(x)
133
136
  end
134
137
  end
135
138
 
@@ -158,30 +161,30 @@ module Coopy
158
161
  end
159
162
 
160
163
  def get_cell_view
161
- return ::Coopy::SimpleView.new
164
+ ::Coopy::SimpleView.new
162
165
  end
163
166
 
164
167
  def is_resizable
165
- return false
168
+ false
166
169
  end
167
170
 
168
171
  def resize(w,h)
169
- return false
172
+ false
170
173
  end
171
174
 
172
175
  def clear
173
176
  end
174
177
 
175
178
  def insert_or_delete_rows(fate,hfate)
176
- return false
179
+ false
177
180
  end
178
181
 
179
182
  def insert_or_delete_columns(fate,wfate)
180
- return false
183
+ false
181
184
  end
182
185
 
183
186
  def trim_blank
184
- return false
187
+ false
185
188
  end
186
189
 
187
190
  def height() get_height end
@@ -191,23 +194,123 @@ module Coopy
191
194
 
192
195
  def get_width
193
196
  self.get_columns
194
- return @columns.length
197
+ @columns.length
195
198
  end
196
199
 
197
200
  def get_height
198
201
  return @h if @h >= 0
199
- return -1 if @helper == nil
200
- @id2rid = @helper.get_row_ids(@db,@name)
201
- @h = @id2rid.length + 1
202
- return @h
202
+ -1
203
203
  end
204
204
 
205
205
  def get_data
206
- return nil
206
+ nil
207
207
  end
208
208
 
209
209
  def clone
210
- return nil
210
+ nil
211
+ end
212
+
213
+ def get_meta
214
+ self
215
+ end
216
+
217
+ def alter_columns(columns)
218
+ result = @helper.alter_columns(@db,@name,columns)
219
+ @columns = nil
220
+ result
221
+ end
222
+
223
+ def change_row(rc)
224
+ if @helper == nil
225
+ puts "No sql helper"
226
+ return false
227
+ end
228
+ if rc.action == "+++"
229
+ return @helper.insert(@db,@name,rc.val)
230
+ elsif rc.action == "---"
231
+ return @helper._delete(@db,@name,rc.cond)
232
+ elsif rc.action == "->"
233
+ return @helper.update(@db,@name,rc.cond,rc.val)
234
+ end
235
+ false
236
+ end
237
+
238
+ def as_table
239
+ pct = 3
240
+ self.get_columns
241
+ w = @column_names.length
242
+ mt = ::Coopy::SimpleTable.new(w + 1,pct)
243
+ mt.set_cell(0,0,"@")
244
+ mt.set_cell(0,1,"type")
245
+ mt.set_cell(0,2,"pkey")
246
+ begin
247
+ _g = 0
248
+ while(_g < w)
249
+ x = _g
250
+ _g+=1
251
+ i = x + 1
252
+ mt.set_cell(i,0,@column_names[x])
253
+ mt.set_cell(i,1,@columns[x].type_value)
254
+ mt.set_cell(i,2,((@columns[x].primary) ? 1 : 0))
255
+ end
256
+ end
257
+ mt
258
+ end
259
+
260
+ def use_for_column_changes
261
+ true
262
+ end
263
+
264
+ def use_for_row_changes
265
+ true
266
+ end
267
+
268
+ def clone_meta(table = nil)
269
+ nil
270
+ end
271
+
272
+ def apply_flags(flags)
273
+ false
274
+ end
275
+
276
+ def get_database
277
+ @db
278
+ end
279
+
280
+ def get_row_stream
281
+ self.get_columns
282
+ @db._begin("SELECT * FROM " + _hx_str(self.get_quoted_table_name) + " ORDER BY ?",[@db.rowid],@column_names)
283
+ self
284
+ end
285
+
286
+ def fetch_row
287
+ if @db.read
288
+ row = {}
289
+ begin
290
+ _g1 = 0
291
+ _g = @column_names.length
292
+ while(_g1 < _g)
293
+ i = _g1
294
+ _g1+=1
295
+ begin
296
+ v = @db.get(i)
297
+ begin
298
+ value = v
299
+ row[@column_names[i]] = value
300
+ end
301
+ v
302
+ end
303
+ end
304
+ end
305
+ return row
306
+ end
307
+ @db._end
308
+ nil
309
+ end
310
+
311
+ def fetch_columns
312
+ self.get_columns
313
+ @column_names
211
314
  end
212
315
 
213
316
  haxe_me ["coopy", "SqlTable"]
@@ -14,7 +14,7 @@ module Coopy
14
14
 
15
15
  def to_s
16
16
  return @name if @prefix == ""
17
- return _hx_str(@prefix) + "." + _hx_str(@name)
17
+ _hx_str(@prefix) + "." + _hx_str(@name)
18
18
  end
19
19
 
20
20
  haxe_me ["coopy", "SqlTableName"]
@@ -15,7 +15,7 @@ module Coopy
15
15
  names.push(db.get(0))
16
16
  end
17
17
  db._end
18
- return names
18
+ names
19
19
  end
20
20
 
21
21
  def count_rows(db,name)
@@ -26,7 +26,7 @@ module Coopy
26
26
  ct = db.get(0)
27
27
  end
28
28
  db._end
29
- return ct
29
+ ct
30
30
  end
31
31
 
32
32
  def get_row_ids(db,name)
@@ -38,7 +38,254 @@ module Coopy
38
38
  result.push(c)
39
39
  end
40
40
  db._end
41
- return result
41
+ result
42
+ end
43
+
44
+ def update(db,name,conds,vals)
45
+ q = "UPDATE " + _hx_str(db.get_quoted_table_name(name)) + " SET "
46
+ lst = Array.new
47
+ _it = ::Rb::RubyIterator.new(vals.keys)
48
+ while(_it.has_next) do
49
+ k = _it._next
50
+ q += ", " if lst.length > 0
51
+ q += db.get_quoted_column_name(k)
52
+ q += " = ?"
53
+ lst.push(vals[k])
54
+ end
55
+ val_len = lst.length
56
+ q += " WHERE "
57
+ _it2 = ::Rb::RubyIterator.new(conds.keys)
58
+ while(_it2.has_next) do
59
+ k1 = _it2._next
60
+ q += " and " if lst.length > val_len
61
+ q += db.get_quoted_column_name(k1)
62
+ q += " = ?"
63
+ lst.push(conds[k1])
64
+ end
65
+ if !db._begin(q,lst,[])
66
+ puts "Problem with database update"
67
+ return false
68
+ end
69
+ db._end
70
+ true
71
+ end
72
+
73
+ def _delete(db,name,conds)
74
+ q = "DELETE FROM " + _hx_str(db.get_quoted_table_name(name)) + " WHERE "
75
+ lst = Array.new
76
+ _it = ::Rb::RubyIterator.new(conds.keys)
77
+ while(_it.has_next) do
78
+ k = _it._next
79
+ q += " and " if lst.length > 0
80
+ q += db.get_quoted_column_name(k)
81
+ q += " = ?"
82
+ lst.push(conds[k])
83
+ end
84
+ if !db._begin(q,lst,[])
85
+ puts "Problem with database delete"
86
+ return false
87
+ end
88
+ db._end
89
+ true
90
+ end
91
+
92
+ def insert(db,name,vals)
93
+ q = "INSERT INTO " + _hx_str(db.get_quoted_table_name(name)) + " ("
94
+ lst = Array.new
95
+ _it = ::Rb::RubyIterator.new(vals.keys)
96
+ while(_it.has_next) do
97
+ k = _it._next
98
+ q += "," if lst.length > 0
99
+ q += db.get_quoted_column_name(k)
100
+ lst.push(vals[k])
101
+ end
102
+ q += ") VALUES("
103
+ need_comma = false
104
+ _it2 = ::Rb::RubyIterator.new(vals.keys)
105
+ while(_it2.has_next) do
106
+ k1 = _it2._next
107
+ q += "," if need_comma
108
+ q += "?"
109
+ need_comma = true
110
+ end
111
+ q += ")"
112
+ if !db._begin(q,lst,[])
113
+ puts "Problem with database insert"
114
+ return false
115
+ end
116
+ db._end
117
+ true
118
+ end
119
+
120
+ def attach(db,tag,resource_name)
121
+ if !db._begin("ATTACH ? AS `" + _hx_str(tag) + "`",[resource_name],[])
122
+ puts "Failed to attach " + _hx_str(resource_name) + " as " + _hx_str(tag)
123
+ return false
124
+ end
125
+ db._end
126
+ true
127
+ end
128
+
129
+ protected
130
+
131
+ def column_list_sql(x)
132
+ x.join(",")
133
+ end
134
+
135
+ def fetch_schema(db,name)
136
+ tname = db.get_quoted_table_name(name)
137
+ query = "select sql from sqlite_master where name = '" + _hx_str(tname) + "'"
138
+ if !db._begin(query,nil,["sql"])
139
+ puts "Cannot find schema for table " + _hx_str(tname)
140
+ return nil
141
+ end
142
+ sql = ""
143
+ sql = db.get(0) if db.read
144
+ db._end
145
+ sql
146
+ end
147
+
148
+ def split_schema(db,name,sql)
149
+ preamble = ""
150
+ parts = Array.new
151
+ double_quote = false
152
+ single_quote = false
153
+ token = ""
154
+ nesting = 0
155
+ begin
156
+ _g1 = 0
157
+ _g = sql.length
158
+ while(_g1 < _g)
159
+ i = _g1
160
+ _g1+=1
161
+ ch = sql[i]
162
+ if double_quote || single_quote
163
+ if double_quote
164
+ double_quote = false if ch == "\""
165
+ end
166
+ if single_quote
167
+ single_quote = false if ch == "'"
168
+ end
169
+ token += ch
170
+ next
171
+ end
172
+ brk = false
173
+ if ch == "("
174
+ nesting+=1
175
+ brk = true if nesting == 1
176
+ elsif ch == ")"
177
+ nesting-=1
178
+ brk = true if nesting == 0
179
+ end
180
+ if ch == ","
181
+ brk = true
182
+ if nesting == 1
183
+ end
184
+ end
185
+ if brk
186
+ token = token[1,token.length] if token[0] == " "
187
+ if preamble == ""
188
+ preamble = token
189
+ else
190
+ parts.push(token)
191
+ end
192
+ token = ""
193
+ else
194
+ token += ch
195
+ end
196
+ end
197
+ end
198
+ cols = db.get_columns(name)
199
+ name2part = {}
200
+ name2col = {}
201
+ begin
202
+ _g11 = 0
203
+ _g2 = cols.length
204
+ while(_g11 < _g2)
205
+ i1 = _g11
206
+ _g11+=1
207
+ col = cols[i1]
208
+ name2part[col.name] = parts[i1]
209
+ name2col[col.name] = cols[i1]
210
+ end
211
+ end
212
+ { preamble: preamble, parts: parts, name2part: name2part, columns: cols, name2column: name2col}
213
+ end
214
+
215
+ def exec(db,query)
216
+ if !db._begin(query)
217
+ puts "database problem"
218
+ return false
219
+ end
220
+ db._end
221
+ true
222
+ end
223
+
224
+ public
225
+
226
+ def alter_columns(db,name,columns)
227
+ not_blank = lambda {|x|
228
+ return false if x == nil || x == "" || x == "null"
229
+ true
230
+ }
231
+ sql = self.fetch_schema(db,name)
232
+ schema = self.split_schema(db,name,sql)
233
+ parts = schema[:parts]
234
+ nparts = Array.new
235
+ new_column_list = Array.new
236
+ ins_column_list = Array.new
237
+ sel_column_list = Array.new
238
+ meta = schema[:columns]
239
+ begin
240
+ _g1 = 0
241
+ _g = columns.length
242
+ while(_g1 < _g)
243
+ i = _g1
244
+ _g1+=1
245
+ c = columns[i]
246
+ if c.name != nil
247
+ if c.prev_name != nil
248
+ sel_column_list.push(c.prev_name)
249
+ ins_column_list.push(c.name)
250
+ end
251
+ orig_type = ""
252
+ orig_primary = false
253
+ if schema[:name2column].include?(c.name)
254
+ m = schema[:name2column][c.name]
255
+ orig_type = m.type_value
256
+ orig_primary = m.primary
257
+ end
258
+ next_type = orig_type
259
+ next_primary = orig_primary
260
+ if c.props != nil
261
+ _g2 = 0
262
+ _g3 = c.props
263
+ while(_g2 < _g3.length)
264
+ p = _g3[_g2]
265
+ _g2+=1
266
+ next_type = p.val if p.name == "type"
267
+ next_primary = "" + _hx_str(p.val.to_s) == "1" if p.name == "pkey"
268
+ end
269
+ end
270
+ part = "" + _hx_str(c.name)
271
+ part += " " + _hx_str(next_type) if not_blank.call(next_type)
272
+ part += " PRIMARY KEY" if next_primary
273
+ nparts.push(part)
274
+ new_column_list.push(c.name)
275
+ end
276
+ end
277
+ end
278
+ return false if !self.exec(db,"BEGIN TRANSACTION")
279
+ c1 = self.column_list_sql(ins_column_list)
280
+ tname = db.get_quoted_table_name(name)
281
+ return false if !self.exec(db,"CREATE TEMPORARY TABLE __coopy_backup(" + _hx_str(c1) + ")")
282
+ return false if !self.exec(db,"INSERT INTO __coopy_backup (" + _hx_str(c1) + ") SELECT " + _hx_str(c1) + " FROM " + _hx_str(tname))
283
+ return false if !self.exec(db,"DROP TABLE " + _hx_str(tname))
284
+ return false if !self.exec(db,_hx_str(schema[:preamble]) + "(" + _hx_str(nparts.join(", ")) + ")")
285
+ return false if !self.exec(db,"INSERT INTO " + _hx_str(tname) + " (" + _hx_str(c1) + ") SELECT " + _hx_str(c1) + " FROM __coopy_backup")
286
+ return false if !self.exec(db,"DROP TABLE __coopy_backup")
287
+ return false if !self.exec(db,"COMMIT")
288
+ true
42
289
  end
43
290
 
44
291
  haxe_me ["coopy", "SqliteHelper"]