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 push, pull, and sync a repository dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: #include "config.h" dbda8d6ce9 2007-07-21 drh: #include "sync.h" dbda8d6ce9 2007-07-21 drh: #include <assert.h> dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** COMMAND: pull dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** Pull changes in a remote repository into the local repository dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void pull_cmd(void){ dbda8d6ce9 2007-07-21 drh: if( g.argc!=3 ){ dbda8d6ce9 2007-07-21 drh: usage("FILE-OR-URL"); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: url_parse(g.argv[2]); dbda8d6ce9 2007-07-21 drh: db_must_be_within_tree(); dbda8d6ce9 2007-07-21 drh: user_select(); dbda8d6ce9 2007-07-21 drh: if( g.urlIsFile ){ dbda8d6ce9 2007-07-21 drh: Stmt q; dbda8d6ce9 2007-07-21 drh: char *zRemote = g.urlName; dbda8d6ce9 2007-07-21 drh: if( !file_isfile(zRemote) ){ dbda8d6ce9 2007-07-21 drh: zRemote = mprintf("%s/_FOSSIL_"); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: if( !file_isfile(zRemote) ){ dbda8d6ce9 2007-07-21 drh: fossil_panic("no such repository: %s", zRemote); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_multi_exec("ATTACH DATABASE %Q AS other", zRemote); dbda8d6ce9 2007-07-21 drh: db_begin_transaction(); dbda8d6ce9 2007-07-21 drh: db_prepare(&q, dbda8d6ce9 2007-07-21 drh: "SELECT rid FROM other.blob WHERE NOT EXISTS" dbda8d6ce9 2007-07-21 drh: " (SELECT 1 FROM blob WHERE uuid=other.blob.uuid)" dbda8d6ce9 2007-07-21 drh: ); dbda8d6ce9 2007-07-21 drh: while( db_step(&q)==SQLITE_ROW ){ dbda8d6ce9 2007-07-21 drh: int nrid; dbda8d6ce9 2007-07-21 drh: int rid = db_column_int(&q, 0); dbda8d6ce9 2007-07-21 drh: Blob rec; dbda8d6ce9 2007-07-21 drh: content_get_from_db(rid, &rec, "other"); dbda8d6ce9 2007-07-21 drh: nrid = content_put(&rec, 0); dbda8d6ce9 2007-07-21 drh: manifest_crosslink(nrid, &rec); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_finalize(&q); dbda8d6ce9 2007-07-21 drh: db_end_transaction(0); dbda8d6ce9 2007-07-21 drh: }else{ dbda8d6ce9 2007-07-21 drh: client_sync(0,1,0); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** COMMAND: push dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** Push changes in the local repository over into a remote repository dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void push_cmd(void){ dbda8d6ce9 2007-07-21 drh: if( g.argc!=3 ){ dbda8d6ce9 2007-07-21 drh: usage("FILE-OR-URL"); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: url_parse(g.argv[2]); dbda8d6ce9 2007-07-21 drh: db_must_be_within_tree(); dbda8d6ce9 2007-07-21 drh: if( g.urlIsFile ){ dbda8d6ce9 2007-07-21 drh: Blob remote; dbda8d6ce9 2007-07-21 drh: char *zRemote; dbda8d6ce9 2007-07-21 drh: file_canonical_name(g.urlName, &remote); dbda8d6ce9 2007-07-21 drh: zRemote = blob_str(&remote); dbda8d6ce9 2007-07-21 drh: if( file_isdir(zRemote)!=1 ){ dbda8d6ce9 2007-07-21 drh: int i = strlen(zRemote); dbda8d6ce9 2007-07-21 drh: while( i>0 && zRemote[i]!='/' ){ i--; } dbda8d6ce9 2007-07-21 drh: zRemote[i] = 0; dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: if( chdir(zRemote) ){ dbda8d6ce9 2007-07-21 drh: fossil_panic("unable to change the working directory to %s", zRemote); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: db_close(); dbda8d6ce9 2007-07-21 drh: g.argv[2] = g.zLocalRoot; dbda8d6ce9 2007-07-21 drh: pull_cmd(); dbda8d6ce9 2007-07-21 drh: }else{ dbda8d6ce9 2007-07-21 drh: client_sync(1,0,0); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** COMMAND: sync dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** Synchronize the local repository with a remote repository dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void sync_cmd(void){ dbda8d6ce9 2007-07-21 drh: if( g.argc!=3 ){ dbda8d6ce9 2007-07-21 drh: usage("FILE-OR-URL"); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: url_parse(g.argv[2]); dbda8d6ce9 2007-07-21 drh: if( g.urlIsFile ){ dbda8d6ce9 2007-07-21 drh: pull_cmd(); dbda8d6ce9 2007-07-21 drh: db_close(); dbda8d6ce9 2007-07-21 drh: push_cmd(); dbda8d6ce9 2007-07-21 drh: }else{ dbda8d6ce9 2007-07-21 drh: db_must_be_within_tree(); dbda8d6ce9 2007-07-21 drh: client_sync(1,1,0); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: }