Fossil

Diff
Login

Differences From Artifact [615528bf6d]:

To Artifact [dcc00132ae]:


28
29
30
31
32
33
34
35


36
37
38
39
40


41
42
43
44
45
46

47
48

49
50
51

52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70


71
72

73
74
75
76
77
78
79
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79

80
81
82
83
84
85
86
87







-
+
+





+
+






+


+



+










+








-
+
+

-
+







** true the redo a change.  If there is nothing to undo (or redo) then
** this routine is a noop.
*/
static void undo_one(const char *zPathname, int redoFlag){
  Stmt q;
  char *zFullname;
  db_prepare(&q,
    "SELECT content, existsflag FROM undo WHERE pathname=%Q AND redoflag=%d",
    "SELECT content, existsflag, isExe FROM undo"
    " WHERE pathname=%Q AND redoflag=%d",
     zPathname, redoFlag
  );
  if( db_step(&q)==SQLITE_ROW ){
    int old_exists;
    int new_exists;
    int old_exe;
    int new_exe;
    Blob current;
    Blob new;
    zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname);
    new_exists = file_size(zFullname)>=0;
    if( new_exists ){
      blob_read_from_file(&current, zFullname);
      new_exe = file_isexe(zFullname);
    }else{
      blob_zero(&current);
      new_exe = 0;
    }
    blob_zero(&new);
    old_exists = db_column_int(&q, 1);
    old_exe = db_column_int(&q, 2);
    if( old_exists ){
      db_ephemeral_blob(&q, 0, &new);
    }
    if( old_exists ){
      if( new_exists ){
        printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
      }else{
        printf("NEW %s\n", zPathname);
      }
      blob_write_to_file(&new, zFullname);
      file_setexe(zFullname, old_exe);
    }else{
      printf("DELETE %s\n", zPathname);
      unlink(zFullname);
    }
    blob_reset(&new);
    free(zFullname);
    db_finalize(&q);
    db_prepare(&q, 
       "UPDATE undo SET content=:c, existsflag=%d, redoflag=NOT redoflag"
       "UPDATE undo SET content=:c, existsflag=%d, isExe=%d,"
             " redoflag=NOT redoflag"
       " WHERE pathname=%Q",
       new_exists, zPathname
       new_exists, new_exe, zPathname
    );
    if( new_exists ){
      db_bind_blob(&q, ":c", &current);
    }
    db_step(&q);
    blob_reset(&current);
  }
198
199
200
201
202
203
204

205
206
207
208
209
210
211
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220







+







  int cid;
  const char *zDb = db_name("localdb");
  static const char zSql[] = 
    @ CREATE TABLE %s.undo(
    @   pathname TEXT UNIQUE,             -- Name of the file
    @   redoflag BOOLEAN,                 -- 0 for undoable.  1 for redoable
    @   existsflag BOOLEAN,               -- True if the file exists
    @   isExe BOOLEAN,                    -- True if the file is executable
    @   content BLOB                      -- Saved content
    @ );
    @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
    @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
  ;
  if( undoDisable ) return;
  undo_reset();
244
245
246
247
248
249
250
251
252
253



254
255
256
257
258
259
260
253
254
255
256
257
258
259



260
261
262
263
264
265
266
267
268
269







-
-
-
+
+
+







  int existsFlag;
  Stmt q;

  if( !undoActive ) return;
  zFullname = mprintf("%s%s", g.zLocalRoot, zPathname);
  existsFlag = file_size(zFullname)>=0;
  db_prepare(&q,
    "INSERT OR IGNORE INTO undo(pathname,redoflag,existsflag,content)"
    " VALUES(%Q,0,%d,:c)",
    zPathname, existsFlag
    "INSERT OR IGNORE INTO undo(pathname,redoflag,existsflag,isExe,content)"
    " VALUES(%Q,0,%d,%d,:c)",
    zPathname, existsFlag, file_isexe(zFullname)
  );
  if( existsFlag ){
    blob_read_from_file(&content, zFullname);
    db_bind_blob(&q, ":c", &content);
  }
  free(zFullname);
  db_step(&q);