Artifact 238e2858a9bf1dcd84b20f8a7044f4b97e60f099
File
src/construct.c
part of check-in
[ce1c1a2907]
- Add the --randomize parameter to the rebuild command. Used for
testing.
by
drh on
2007-09-21 18:33:13.
/*
** Copyright (c) 2007 Andreas Kupries
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public
** License version 2 as published by the Free Software Foundation.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public
** License along with this library; if not, write to the
** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
** Boston, MA 02111-1307, USA.
**
** Author contact information:
** akupries@shaw.ca
**
**
*******************************************************************************
**
** This file contains code used to de- and reconstruct a repository
** into and from an indicated directory.
*/
#include "config.h"
#include "construct.h"
#include <assert.h>
#include <sys/types.h>
#include <dirent.h>
/* This function recursively scans the directory hierarchy starting at
** zOrigin and enters all found files into the repository. The uuid is
** generated from the file contents, and not taken from the, possibly
** modified, file name. While function is able to handle the directory
** structure created by 'deconstruct' it can actually much more.
*/
static int import_origin(const char* zOrigin){
DIR *d;
int count = 0;
const char *zFormat;
const char *zDir = zOrigin;
struct dirent *pEntry;
if( zDir[0]==0 ){
zDir = ".";
zFormat = "%s%s";
}else{
zFormat = "%s/%s";
}
d = opendir(zDir);
if( d ){
while( (pEntry=readdir(d))!=0 ){
char *zPath;
if( pEntry->d_name[0]=='.' ) continue;
zPath = mprintf(zFormat, zOrigin, pEntry->d_name);
if( file_isdir(zPath)==1 ){
count += import_origin(zPath);
}else if( file_isfile(zPath) ){
Blob zIn;
blob_read_from_file (&zIn,zPath);
content_put (&zIn, 0, 0);
blob_reset (&zIn);
count++;
}
free (zPath);
}
}
closedir(d);
return count;
}
/*
** COMMAND: deconstruct
** Usage %fossil deconstruct ?-R|--repository REPOSITORY? DESTINATION
**
** Populates the indicated DESTINATION directory with copies of all
** files contained within the repository. Files are named AA/bbbbb
** where AA is the first 2 characters of the uuid and bbbbb is the
** remaining 38 characters.
*/
void deconstruct_cmd(void){
const char* zDestination;
Blob zOut;
Stmt q;
if( (g.argc != 3) && (g.argc != 5) ){
usage ("?-R|--repository REPOSITORY? DESTINATION");
}
db_find_and_open_repository ();
zDestination = g.argv[g.argc-1];
if( !file_isdir (zDestination) ){
fossil_panic("not a directory: %s", zDestination);
}
/* Iterate over all blobs in the repository, retrieve their
* contents, and write them to a file with a name based on their
* uuid. Note: Non-writable destination causes bail-out in the first
* call of blob_write_to_file.
*/
db_prepare(&q, "SELECT rid,uuid FROM blob");
while( db_step(&q)==SQLITE_ROW ){
int rid = db_column_int (&q, 0);
const char *zUuid = db_column_text(&q, 1);
char *zFile = mprintf ("%s/%.2s/%s", zDestination, zUuid, zUuid + 2);
content_get (rid,&zOut);
blob_write_to_file (&zOut,zFile);
blob_reset (&zOut);
free(zFile);
}
db_finalize(&q);
}
/*
** COMMAND: reconstruct
** Usage %fossil reconstruct REPOSITORY ORIGIN
**
** Creates the REPOSITORY and populates it with the files in the
** indicated ORIGIN directory.
*/
void reconstruct_cmd(void){
const char* zOrigin;
const char* zRepository;
int fileCnt;
int errCnt;
if( g.argc != 4 ){
usage ("REPOSITORY ORIGIN");
}
zRepository = g.argv[2];
zOrigin = g.argv[3];
if( !file_isdir (zOrigin) ){
fossil_panic("not a directory: %s", zOrigin);
}
/* Create the foundation */
db_create_repository(zRepository);
db_open_repository(zRepository);
db_open_config();
db_begin_transaction();
db_initial_setup(0);
printf("project-id: %s\n", db_get("project-code", 0));
printf("server-id: %s\n", db_get("server-code", 0));
printf("admin-user: %s (no password set yet!)\n", g.zLogin);
printf("baseline: %s\n", db_text(0, "SELECT uuid FROM blob"));
/* Scan origin and insert all files found inside */
fileCnt = import_origin (zOrigin);
printf("imported: %d %s\n", fileCnt, fileCnt == 1 ?
"file" : "files");
/* Finalize the repository, rebuild the derived tables */
errCnt = rebuild_db(0);
if( errCnt ){
printf("%d %s. Rolling back changes.\n", errCnt, errCnt == 1 ?
"error" : "errors");
db_end_transaction(1);
}else{
db_end_transaction(0);
}
}