| | @@ -79,61 +79,81 @@ |
| 79 | 79 | ** (i) ATTACHMENT |
| 80 | 80 | ** (j) TICKETCHNG |
| 81 | 81 | ** (7) If any ticket artifacts were removed (6j) then rebuild the |
| 82 | 82 | ** corresponding ticket entries. Possibly remove entries from |
| 83 | 83 | ** the ticket table. |
| 84 | +** |
| 85 | +** Stops 1-4 (saving the purged artifacts into the graveyard) are only |
| 86 | +** undertaken if the moveToGraveyard flag is true. |
| 84 | 87 | */ |
| 85 | 88 | int purge_artifact_list( |
| 86 | 89 | const char *zTab, /* TEMP table containing list of RIDS to be purged */ |
| 87 | | - const char *zNote /* Text of the purgeevent.pnotes field */ |
| 90 | + const char *zNote, /* Text of the purgeevent.pnotes field */ |
| 91 | + int moveToGraveyard /* Move purged artifacts into the graveyard */ |
| 88 | 92 | ){ |
| 89 | 93 | int peid = 0; /* New purgeevent ID */ |
| 90 | 94 | Stmt q; /* General-use prepared statement */ |
| 91 | 95 | |
| 92 | 96 | assert( g.repositoryOpen ); /* Main database must already be open */ |
| 93 | 97 | db_begin_transaction(); |
| 98 | + |
| 99 | + /* Make sure we are not removing a manifest that is the baseline of some |
| 100 | + ** manifest that is being left behind. This step is not strictly necessary. |
| 101 | + ** is is just a safety check. */ |
| 94 | 102 | if( purge_baseline_out_from_under_delta(zTab) ){ |
| 95 | 103 | fossil_fatal("attempt to purge a baseline manifest without also purging " |
| 96 | 104 | "all of its deltas"); |
| 97 | 105 | } |
| 98 | | - db_multi_exec(zPurgeInit /*works-like:"%w%w"*/, |
| 99 | | - db_name("repository"), db_name("repository")); |
| 100 | | - db_multi_exec( |
| 101 | | - "INSERT INTO purgeevent(ctime,pnotes) VALUES(now(),%Q)", zNote |
| 102 | | - ); |
| 103 | | - peid = db_last_insert_rowid(); |
| 106 | + |
| 107 | + /* Make sure that no delta that is left behind requires a purged artifact |
| 108 | + ** as its basis. If such artifacts exist, go ahead and undelta them now. |
| 109 | + */ |
| 104 | 110 | db_prepare(&q, "SELECT rid FROM delta WHERE srcid IN \"%w\"" |
| 105 | 111 | " AND rid NOT IN \"%w\"", zTab, zTab); |
| 106 | 112 | while( db_step(&q)==SQLITE_ROW ){ |
| 107 | 113 | int rid = db_column_int(&q, 0); |
| 108 | 114 | content_undelta(rid); |
| 109 | 115 | verify_before_commit(rid); |
| 110 | 116 | } |
| 111 | 117 | db_finalize(&q); |
| 112 | | - db_prepare(&q, "SELECT rid FROM delta WHERE rid IN \"%w\"" |
| 113 | | - " AND srcid NOT IN \"%w\"", zTab, zTab); |
| 114 | | - while( db_step(&q)==SQLITE_ROW ){ |
| 115 | | - int rid = db_column_int(&q, 0); |
| 116 | | - content_undelta(rid); |
| 117 | | - } |
| 118 | | - db_finalize(&q); |
| 119 | | - db_multi_exec( |
| 120 | | - "INSERT INTO purgeitem(peid,orid,uuid,sz,isPrivate,data)" |
| 121 | | - " SELECT %d, rid, uuid, size," |
| 122 | | - " EXISTS(SELECT 1 FROM private WHERE private.rid=blob.rid)," |
| 123 | | - " content" |
| 124 | | - " FROM blob WHERE rid IN \"%w\"", |
| 125 | | - peid, zTab |
| 126 | | - ); |
| 127 | | - db_multi_exec( |
| 128 | | - "UPDATE purgeitem" |
| 129 | | - " SET srcid=(SELECT piid FROM purgeitem px, delta" |
| 130 | | - " WHERE px.orid=delta.srcid" |
| 131 | | - " AND delta.rid=purgeitem.orid)" |
| 132 | | - " WHERE peid=%d", |
| 133 | | - peid |
| 134 | | - ); |
| 118 | + |
| 119 | + /* Construct the graveyard and copy the artifacts to be purged into the |
| 120 | + ** graveyard */ |
| 121 | + if( moveToGraveyard ){ |
| 122 | + db_multi_exec(zPurgeInit /*works-like:"%w%w"*/, |
| 123 | + db_name("repository"), db_name("repository")); |
| 124 | + db_multi_exec( |
| 125 | + "INSERT INTO purgeevent(ctime,pnotes) VALUES(now(),%Q)", zNote |
| 126 | + ); |
| 127 | + peid = db_last_insert_rowid(); |
| 128 | + db_prepare(&q, "SELECT rid FROM delta WHERE rid IN \"%w\"" |
| 129 | + " AND srcid NOT IN \"%w\"", zTab, zTab); |
| 130 | + while( db_step(&q)==SQLITE_ROW ){ |
| 131 | + int rid = db_column_int(&q, 0); |
| 132 | + content_undelta(rid); |
| 133 | + } |
| 134 | + db_finalize(&q); |
| 135 | + db_multi_exec( |
| 136 | + "INSERT INTO purgeitem(peid,orid,uuid,sz,isPrivate,data)" |
| 137 | + " SELECT %d, rid, uuid, size," |
| 138 | + " EXISTS(SELECT 1 FROM private WHERE private.rid=blob.rid)," |
| 139 | + " content" |
| 140 | + " FROM blob WHERE rid IN \"%w\"", |
| 141 | + peid, zTab |
| 142 | + ); |
| 143 | + db_multi_exec( |
| 144 | + "UPDATE purgeitem" |
| 145 | + " SET srcid=(SELECT piid FROM purgeitem px, delta" |
| 146 | + " WHERE px.orid=delta.srcid" |
| 147 | + " AND delta.rid=purgeitem.orid)" |
| 148 | + " WHERE peid=%d", |
| 149 | + peid |
| 150 | + ); |
| 151 | + } |
| 152 | + |
| 153 | + /* Remove the artifacts being purged. Also remove all references to those |
| 154 | + ** artifacts from the secondary tables. */ |
| 135 | 155 | db_multi_exec("DELETE FROM blob WHERE rid IN \"%w\"", zTab); |
| 136 | 156 | db_multi_exec("DELETE FROM delta WHERE rid IN \"%w\"", zTab); |
| 137 | 157 | db_multi_exec("DELETE FROM delta WHERE srcid IN \"%w\"", zTab); |
| 138 | 158 | db_multi_exec("DELETE FROM event WHERE objid IN \"%w\"", zTab); |
| 139 | 159 | db_multi_exec("DELETE FROM private WHERE rid IN \"%w\"", zTab); |
| | @@ -160,10 +180,12 @@ |
| 160 | 180 | while( db_step(&q)==SQLITE_ROW ){ |
| 161 | 181 | ticket_rebuild_entry(db_column_text(&q, 0)); |
| 162 | 182 | } |
| 163 | 183 | db_finalize(&q); |
| 164 | 184 | db_multi_exec("DROP TABLE \"%w_tickets\"", zTab); |
| 185 | + |
| 186 | + /* Mission accomplished */ |
| 165 | 187 | db_end_transaction(0); |
| 166 | 188 | return peid; |
| 167 | 189 | } |
| 168 | 190 | |
| 169 | 191 | /* |
| | @@ -476,18 +498,12 @@ |
| 476 | 498 | db_begin_transaction(); |
| 477 | 499 | i = strncmp(zSubcmd,"checkin",n)==0 ? 3 : 2; |
| 478 | 500 | if( i>=g.argc ) usage("[checkin] TAGS... [--explain]"); |
| 479 | 501 | db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); |
| 480 | 502 | for(; i<g.argc; i++){ |
| 481 | | - int r = symbolic_name_to_rid(g.argv[i], "br"); |
| 482 | | - if( r>0 ){ |
| 483 | | - compute_descendants(r, 1000000000); |
| 484 | | - }else if( r==0 ){ |
| 485 | | - fossil_fatal("not found: %s", g.argv[i]); |
| 486 | | - }else{ |
| 487 | | - fossil_fatal("ambiguous: %s\n", g.argv[i]); |
| 488 | | - } |
| 503 | + int r = name_to_typed_rid(g.argv[i], "br"); |
| 504 | + compute_descendants(r, 1000000000); |
| 489 | 505 | } |
| 490 | 506 | vid = db_lget_int("checkout",0); |
| 491 | 507 | if( db_exists("SELECT 1 FROM ok WHERE rid=%d",vid) ){ |
| 492 | 508 | fossil_fatal("cannot purge the current checkout"); |
| 493 | 509 | } |
| | @@ -501,13 +517,13 @@ |
| 501 | 517 | if( i++ > 0 ) fossil_print("%.78c\n",'-'); |
| 502 | 518 | whatis_rid(db_column_int(&q,0), 0); |
| 503 | 519 | } |
| 504 | 520 | db_finalize(&q); |
| 505 | 521 | }else{ |
| 506 | | - int peid = purge_artifact_list("ok",""); |
| 522 | + int peid = purge_artifact_list("ok","",1); |
| 507 | 523 | fossil_print("%d checkins and %d artifacts purged.\n", nCkin, nArtifact); |
| 508 | 524 | fossil_print("undoable using \"%s purge undo %d\".\n", |
| 509 | 525 | g.nameOfExe, peid); |
| 510 | 526 | } |
| 511 | 527 | db_end_transaction(explainOnly||dryRun); |
| 512 | 528 | } |
| 513 | 529 | } |
| 514 | 530 | |