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
|
** 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, exists FROM undo WHERE pathname=%Q AND redoflag=%d",
zPathname, redoFlag
);
if( db_step(&q)==SQLITE_ROW ){
int old_exists;
int new_exists;
Blob current;
Blob new;
zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname);
new_exists = file_size(zFullname)>=0;
if( new_exists ){
blob_read_from_file(¤t, zFullname);
}else{
blob_zero(¤t);
}
blob_zero(&new);
old_exists = db_column_int(&q, 1);
if( old_exists ){
db_ephemeral_blob(&q, 0, &new);
}
printf("%sdo changes to %s\n", redoFlag ? "Re" : "Un", zPathname);
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);
|
|
<
|
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
|
** 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",
zPathname, redoFlag
);
if( db_step(&q)==SQLITE_ROW ){
int old_exists;
int new_exists;
Blob current;
Blob new;
zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname);
new_exists = file_size(zFullname)>=0;
if( new_exists ){
blob_read_from_file(¤t, zFullname);
}else{
blob_zero(¤t);
}
blob_zero(&new);
old_exists = db_column_int(&q, 1);
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);
|
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
}
/*
** Undo or redo all undoable or redoable changes.
*/
static void undo_all(int redoFlag){
Stmt q;
db_prepare(&q, "SELECT pathname FROM undo WHERE redoflag=%d"
" ORDER BY +pathname", redoFlag);
while( db_step(&q) ){
const char *zPathname = db_column_text(&q, 0);
undo_one(zPathname, redoFlag);
}
db_finalize(&q);
db_multi_exec(
"CREATE TEMP TABLE undo_vfile_2 AS SELECT * FROM vfile;"
"DELETE FROM vfile;"
"INSERT INTO vfile SELECT * FROM undo_vfile;"
"DELETE FROM undo_vfile;"
"INSERT INTO undo_vfile SELECT * FROM undo_vfile_2;"
"DROP TABLE undo_vfile_2;"
"CREATE TEMP TABLE undo_vmerge_2 AS SELECT * FROM vmerge;"
"DELETE FROM vmerge;"
"INSERT INTO vmerge SELECT * FROM undo_vmerge;"
"DELETE FROM undo_vmerge;"
"INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
"DROP TABLE undo_vmerge_2;"
);
}
/*
** Reset the the undo memory.
*/
void undo_reset(void){
static const char zSql[] =
@ DROP TABLE IF EXISTS undo;
@ DROP TABLE IF EXISTS undo_vfile;
@ DROP TABLE IF EXISTS undo_vmerge;
;
db_multi_exec(zSql);
db_lset_int("undo_available", 0);
}
/*
** Begin capturing a snapshot that can be undone.
*/
void undo_begin(void){
static const char zSql[] =
@ CREATE TABLE undo(
@ pathname TEXT UNIQUE, -- Name of the file
@ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
@ existsflag BOOLEAN, -- True if the file exists
@ content BLOB -- Saved content
@ );
@ CREATE TABLE undo_vfile AS SELECT * FROM vfile;
@ CREATE TABLE undo_vfile AS SELECT * FROM vmerge;
;
undo_reset();
db_multi_exec(zSql);
db_lset_int("undo_available", 1);
}
/*
** Save the current content of the file zPathname so that it
** will be undoable. The name is relative to the root of the
** tree.
|
>
>
|
>
>
>
>
>
>
|
>
>
|
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
}
/*
** Undo or redo all undoable or redoable changes.
*/
static void undo_all(int redoFlag){
Stmt q;
int ucid;
int ncid;
db_prepare(&q, "SELECT pathname FROM undo WHERE redoflag=%d"
" ORDER BY +pathname", redoFlag);
while( db_step(&q)==SQLITE_ROW ){
const char *zPathname = db_column_text(&q, 0);
undo_one(zPathname, redoFlag);
}
db_finalize(&q);
db_multi_exec(
"CREATE TEMP TABLE undo_vfile_2 AS SELECT * FROM vfile;"
"DELETE FROM vfile;"
"INSERT INTO vfile SELECT * FROM undo_vfile;"
"DELETE FROM undo_vfile;"
"INSERT INTO undo_vfile SELECT * FROM undo_vfile_2;"
"DROP TABLE undo_vfile_2;"
"CREATE TEMP TABLE undo_vmerge_2 AS SELECT * FROM vmerge;"
"DELETE FROM vmerge;"
"INSERT INTO vmerge SELECT * FROM undo_vmerge;"
"DELETE FROM undo_vmerge;"
"INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
"DROP TABLE undo_vmerge_2;"
);
ncid = db_lget_int("undo_checkout", 0);
ucid = db_lget_int("checkout", 0);
db_lset_int("undo_checkout", ucid);
db_lset_int("checkout", ncid);
}
/*
** Reset the the undo memory.
*/
void undo_reset(void){
static const char zSql[] =
@ DROP TABLE IF EXISTS undo;
@ DROP TABLE IF EXISTS undo_vfile;
@ DROP TABLE IF EXISTS undo_vmerge;
;
db_multi_exec(zSql);
db_lset_int("undo_available", 0);
db_lset_int("undo_checkout", 0);
}
/*
** Begin capturing a snapshot that can be undone.
*/
void undo_begin(void){
int cid;
static const char zSql[] =
@ CREATE TABLE undo(
@ pathname TEXT UNIQUE, -- Name of the file
@ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
@ existsflag BOOLEAN, -- True if the file exists
@ content BLOB -- Saved content
@ );
@ CREATE TABLE undo_vfile AS SELECT * FROM vfile;
@ CREATE TABLE undo_vmerge AS SELECT * FROM vmerge;
;
undo_reset();
db_multi_exec(zSql);
cid = db_lget_int("checkout", 0);
db_lset_int("undo_checkout", cid);
db_lset_int("undo_available", 1);
}
/*
** Save the current content of the file zPathname so that it
** will be undoable. The name is relative to the root of the
** tree.
|
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
if( existsFlag ){
blob_read_from_file(&content, zFullname);
db_bind_blob(&q, ":c", &content);
}
free(zFullname);
db_step(&q);
db_finalize(&q);
blob_reset(&content);
}
/*
** COMMAND: undo
**
** Usage: %fossil undo ?FILENAME...?
**
|
>
|
>
|
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
if( existsFlag ){
blob_read_from_file(&content, zFullname);
db_bind_blob(&q, ":c", &content);
}
free(zFullname);
db_step(&q);
db_finalize(&q);
if( existsFlag ){
blob_reset(&content);
}
}
/*
** COMMAND: undo
**
** Usage: %fossil undo ?FILENAME...?
**
|