File Annotation
Not logged in
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: 
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: 
eea381f416 2007-08-09       drh:   db_multi_exec(
eea381f416 2007-08-09       drh:     "CREATE INDEX IF NOT EXISTS delta_i1 ON delta(srcid);"
70d5cc86b7 2007-10-05       drh:     "CREATE TABLE IF NOT EXISTS shun(uuid UNIQUE);"
eea381f416 2007-08-09       drh:   );
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: }