dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Copyright (c) 2007 D. Richard Hipp dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This program is free software; you can redistribute it and/or dbda8d6ce9 2007-07-21 drh: ** modify it under the terms of the GNU General Public dbda8d6ce9 2007-07-21 drh: ** License version 2 as published by the Free Software Foundation. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This program is distributed in the hope that it will be useful, dbda8d6ce9 2007-07-21 drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of dbda8d6ce9 2007-07-21 drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dbda8d6ce9 2007-07-21 drh: ** General Public License for more details. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** You should have received a copy of the GNU General Public dbda8d6ce9 2007-07-21 drh: ** License along with this library; if not, write to the dbda8d6ce9 2007-07-21 drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, dbda8d6ce9 2007-07-21 drh: ** Boston, MA 02111-1307, USA. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** Author contact information: dbda8d6ce9 2007-07-21 drh: ** drh@hwaci.com dbda8d6ce9 2007-07-21 drh: ** http://www.hwaci.com/drh/ dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ******************************************************************************* dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This file contains code used to rebuild the database. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: #include "config.h" dbda8d6ce9 2007-07-21 drh: #include "rebuild.h" dbda8d6ce9 2007-07-21 drh: #include <assert.h> dbda8d6ce9 2007-07-21 drh: e00384d26d 2007-08-29 aku: /* 62f37c9722 2007-11-26 drh: ** Schema changes 62f37c9722 2007-11-26 drh: */ 62f37c9722 2007-11-26 drh: static const char zSchemaUpdates[] = 62f37c9722 2007-11-26 drh: @ -- Index on the delta table 62f37c9722 2007-11-26 drh: @ -- f088412c49 2007-11-28 drh: @ CREATE INDEX IF NOT EXISTS delta_i1 ON delta(srcid); 62f37c9722 2007-11-26 drh: @ 62f37c9722 2007-11-26 drh: @ -- Artifacts that should not be processed are identified in the 62f37c9722 2007-11-26 drh: @ -- "shun" table. Artifacts that are control-file forgeries or 62f37c9722 2007-11-26 drh: @ -- spam can be shunned in order to prevent them from contaminating 62f37c9722 2007-11-26 drh: @ -- the repository. 62f37c9722 2007-11-26 drh: @ -- 62f37c9722 2007-11-26 drh: @ CREATE TABLE IF NOT EXISTS shun(uuid UNIQUE); 62f37c9722 2007-11-26 drh: @ 62f37c9722 2007-11-26 drh: @ -- An entry in this table describes a database query that generates a 62f37c9722 2007-11-26 drh: @ -- table of tickets. 62f37c9722 2007-11-26 drh: @ -- 62f37c9722 2007-11-26 drh: @ CREATE TABLE IF NOT EXISTS reportfmt( 62f37c9722 2007-11-26 drh: @ rn integer primary key, -- Report number 62f37c9722 2007-11-26 drh: @ owner text, -- Owner of this report format (not used) 62f37c9722 2007-11-26 drh: @ title text, -- Title of this report 62f37c9722 2007-11-26 drh: @ cols text, -- A color-key specification 62f37c9722 2007-11-26 drh: @ sqlcode text -- An SQL SELECT statement for this report 62f37c9722 2007-11-26 drh: @ ); 62f37c9722 2007-11-26 drh: ; dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* e00384d26d 2007-08-29 aku: ** Core function to rebuild the infomration in the derived tables of a e00384d26d 2007-08-29 aku: ** fossil repository from the blobs. This function is shared between e00384d26d 2007-08-29 aku: ** 'rebuild_database' ('rebuild') and 'reconstruct_cmd' e00384d26d 2007-08-29 aku: ** ('reconstruct'), both of which have to regenerate this information e00384d26d 2007-08-29 aku: ** from scratch. dbda8d6ce9 2007-07-21 drh: ** ce1c1a2907 2007-09-21 drh: ** If the randomize parameter is true, then the BLOBs are deliberately ce1c1a2907 2007-09-21 drh: ** extracted in a random order. This feature is used to test the ce1c1a2907 2007-09-21 drh: ** ability of fossil to accept records in any order and still ce1c1a2907 2007-09-21 drh: ** construct a sane repository. dbda8d6ce9 2007-07-21 drh: */ e38fc922a5 2007-10-11 drh: int rebuild_db(int randomize, int ttyOutput){ dbda8d6ce9 2007-07-21 drh: Stmt s; e00384d26d 2007-08-29 aku: int errCnt = 0; dbda8d6ce9 2007-07-21 drh: char *zTable; e38fc922a5 2007-10-11 drh: int cnt = 0; dbda8d6ce9 2007-07-21 drh: 62f37c9722 2007-11-26 drh: db_multi_exec(zSchemaUpdates); dbda8d6ce9 2007-07-21 drh: for(;;){ dbda8d6ce9 2007-07-21 drh: zTable = db_text(0, dbda8d6ce9 2007-07-21 drh: "SELECT name FROM sqlite_master" dbda8d6ce9 2007-07-21 drh: " WHERE type='table'" 70d5cc86b7 2007-10-05 drh: " AND name NOT IN ('blob','delta','rcvfrom','user','config','shun')"); dbda8d6ce9 2007-07-21 drh: if( zTable==0 ) break; dbda8d6ce9 2007-07-21 drh: db_multi_exec("DROP TABLE %Q", zTable); dbda8d6ce9 2007-07-21 drh: free(zTable); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_multi_exec(zRepositorySchema2); fb358ca492 2007-11-24 drh: ticket_create_table(0); dbda8d6ce9 2007-07-21 drh: ba486fec5a 2007-09-03 drh: db_multi_exec("INSERT INTO unclustered SELECT rid FROM blob"); ba486fec5a 2007-09-03 drh: db_multi_exec( 70d5cc86b7 2007-10-05 drh: "DELETE FROM unclustered" 70d5cc86b7 2007-10-05 drh: " WHERE rid IN (SELECT rid FROM shun JOIN blob USING(uuid))" 70d5cc86b7 2007-10-05 drh: ); ce1c1a2907 2007-09-21 drh: db_multi_exec( ba486fec5a 2007-09-03 drh: "DELETE FROM config WHERE name IN ('remote-code', 'remote-maxid')" ba486fec5a 2007-09-03 drh: ); ce1c1a2907 2007-09-21 drh: db_prepare(&s, 70d5cc86b7 2007-10-05 drh: "SELECT rid, size FROM blob %s" 70d5cc86b7 2007-10-05 drh: " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)", ce1c1a2907 2007-09-21 drh: randomize ? "ORDER BY random()" : "" ce1c1a2907 2007-09-21 drh: ); dbda8d6ce9 2007-07-21 drh: while( db_step(&s)==SQLITE_ROW ){ dbda8d6ce9 2007-07-21 drh: int rid = db_column_int(&s, 0); 73bddaebb9 2007-08-09 drh: int size = db_column_int(&s, 1); 73bddaebb9 2007-08-09 drh: if( size>=0 ){ 73bddaebb9 2007-08-09 drh: Blob content; e38fc922a5 2007-10-11 drh: if( ttyOutput ){ e38fc922a5 2007-10-11 drh: cnt++; e38fc922a5 2007-10-11 drh: printf("%d...\r", cnt); e38fc922a5 2007-10-11 drh: fflush(stdout); e38fc922a5 2007-10-11 drh: } 73bddaebb9 2007-08-09 drh: content_get(rid, &content); 73bddaebb9 2007-08-09 drh: manifest_crosslink(rid, &content); 73bddaebb9 2007-08-09 drh: blob_reset(&content); 73bddaebb9 2007-08-09 drh: }else{ e1c1877c99 2007-09-08 drh: db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid); 73bddaebb9 2007-08-09 drh: } 73bddaebb9 2007-08-09 drh: } e38fc922a5 2007-10-11 drh: db_finalize(&s); e38fc922a5 2007-10-11 drh: if( ttyOutput ){ e38fc922a5 2007-10-11 drh: printf("\n"); dbda8d6ce9 2007-07-21 drh: } e00384d26d 2007-08-29 aku: return errCnt; e00384d26d 2007-08-29 aku: } 6607844a01 2007-08-18 drh: 6607844a01 2007-08-18 drh: /* 6607844a01 2007-08-18 drh: ** COMMAND: rebuild 6607844a01 2007-08-18 drh: ** 6607844a01 2007-08-18 drh: ** Usage: %fossil rebuild REPOSITORY 6607844a01 2007-08-18 drh: ** 6607844a01 2007-08-18 drh: ** Reconstruct the named repository database from the core 6607844a01 2007-08-18 drh: ** records. Run this command after updating the fossil 6607844a01 2007-08-18 drh: ** executable in a way that changes the database schema. 6607844a01 2007-08-18 drh: */ 6607844a01 2007-08-18 drh: void rebuild_database(void){ 6607844a01 2007-08-18 drh: int forceFlag; ce1c1a2907 2007-09-21 drh: int randomizeFlag; e00384d26d 2007-08-29 aku: int errCnt; dbda8d6ce9 2007-07-21 drh: 6607844a01 2007-08-18 drh: forceFlag = find_option("force","f",0)!=0; ce1c1a2907 2007-09-21 drh: randomizeFlag = find_option("randomize", 0, 0)!=0; 6607844a01 2007-08-18 drh: if( g.argc!=3 ){ 6607844a01 2007-08-18 drh: usage("REPOSITORY-FILENAME"); 6607844a01 2007-08-18 drh: } 6607844a01 2007-08-18 drh: db_open_repository(g.argv[2]); 6607844a01 2007-08-18 drh: db_begin_transaction(); e38fc922a5 2007-10-11 drh: errCnt = rebuild_db(randomizeFlag, 1); dbda8d6ce9 2007-07-21 drh: if( errCnt && !forceFlag ){ dbda8d6ce9 2007-07-21 drh: printf("%d errors. Rolling back changes. Use --force to force a commit.\n", dbda8d6ce9 2007-07-21 drh: errCnt); dbda8d6ce9 2007-07-21 drh: db_end_transaction(1); dbda8d6ce9 2007-07-21 drh: }else{ dbda8d6ce9 2007-07-21 drh: db_end_transaction(0); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: }