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 find decendents of a version dbda8d6ce9 2007-07-21 drh: ** or leaves of a version tree. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: #include "config.h" dbda8d6ce9 2007-07-21 drh: #include "descendents.h" dbda8d6ce9 2007-07-21 drh: #include <assert.h> dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Create a temporary table named "leaves" if it does not dbda8d6ce9 2007-07-21 drh: ** already exist. Load this table with the RID of all dbda8d6ce9 2007-07-21 drh: ** versions that are leaves are which are decended from dbda8d6ce9 2007-07-21 drh: ** version iBase. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void compute_leaves(int iBase){ dbda8d6ce9 2007-07-21 drh: int generation = 0; dbda8d6ce9 2007-07-21 drh: int chngCnt = 0; dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: db_multi_exec( dbda8d6ce9 2007-07-21 drh: "CREATE TEMP TABLE IF NOT EXISTS leaves(" dbda8d6ce9 2007-07-21 drh: " rid INTEGER PRIMARY KEY," dbda8d6ce9 2007-07-21 drh: " generation INTEGER" dbda8d6ce9 2007-07-21 drh: ");" dbda8d6ce9 2007-07-21 drh: "DELETE FROM leaves;" dbda8d6ce9 2007-07-21 drh: "INSERT INTO leaves VALUES(%d,0);", dbda8d6ce9 2007-07-21 drh: iBase dbda8d6ce9 2007-07-21 drh: ); dbda8d6ce9 2007-07-21 drh: do{ dbda8d6ce9 2007-07-21 drh: db_multi_exec( dbda8d6ce9 2007-07-21 drh: "INSERT OR IGNORE INTO leaves(rid,generation) " dbda8d6ce9 2007-07-21 drh: "SELECT cid, %d FROM plink" dbda8d6ce9 2007-07-21 drh: " WHERE pid IN (SELECT rid FROM leaves WHERE generation=%d)", dbda8d6ce9 2007-07-21 drh: generation+1, generation dbda8d6ce9 2007-07-21 drh: ); dbda8d6ce9 2007-07-21 drh: generation++; dbda8d6ce9 2007-07-21 drh: chngCnt = db_changes(); dbda8d6ce9 2007-07-21 drh: }while( chngCnt>0 ); dbda8d6ce9 2007-07-21 drh: db_multi_exec( dbda8d6ce9 2007-07-21 drh: "DELETE FROM leaves" dbda8d6ce9 2007-07-21 drh: " WHERE EXISTS(SELECT 1 FROM plink WHERE pid=rid)" 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: leaves dbda8d6ce9 2007-07-21 drh: ** afcdc7ec97 2007-08-01 drh: ** Find all leaf descendents of the current version or of the afcdc7ec97 2007-08-01 drh: ** specified version. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: void leaves_cmd(void){ dbda8d6ce9 2007-07-21 drh: Stmt q; dbda8d6ce9 2007-07-21 drh: int base; dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: db_must_be_within_tree(); dbda8d6ce9 2007-07-21 drh: if( g.argc==2 ){ dbda8d6ce9 2007-07-21 drh: base = db_lget_int("checkout", 0); dbda8d6ce9 2007-07-21 drh: }else{ dbda8d6ce9 2007-07-21 drh: base = name_to_rid(g.argv[2]); dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: if( base==0 ) return; dbda8d6ce9 2007-07-21 drh: compute_leaves(base); dbda8d6ce9 2007-07-21 drh: db_prepare(&q, dbda8d6ce9 2007-07-21 drh: "SELECT uuid, datetime(event.mtime,'localtime'), comment" dbda8d6ce9 2007-07-21 drh: " FROM leaves, blob, event" dbda8d6ce9 2007-07-21 drh: " WHERE blob.rid=leaves.rid" dbda8d6ce9 2007-07-21 drh: " AND event.objid=leaves.rid" dbda8d6ce9 2007-07-21 drh: " ORDER BY event.mtime DESC" dbda8d6ce9 2007-07-21 drh: ); dbda8d6ce9 2007-07-21 drh: print_timeline(&q, 20); dbda8d6ce9 2007-07-21 drh: db_finalize(&q); afcdc7ec97 2007-08-01 drh: } afcdc7ec97 2007-08-01 drh: afcdc7ec97 2007-08-01 drh: /* afcdc7ec97 2007-08-01 drh: ** COMMAND: branches afcdc7ec97 2007-08-01 drh: ** afcdc7ec97 2007-08-01 drh: ** Find leaves of all branches. afcdc7ec97 2007-08-01 drh: */ afcdc7ec97 2007-08-01 drh: void branches_cmd(void){ afcdc7ec97 2007-08-01 drh: Stmt q; afcdc7ec97 2007-08-01 drh: int base; afcdc7ec97 2007-08-01 drh: afcdc7ec97 2007-08-01 drh: db_must_be_within_tree(); afcdc7ec97 2007-08-01 drh: if( g.argc==2 ){ afcdc7ec97 2007-08-01 drh: base = db_lget_int("checkout", 0); afcdc7ec97 2007-08-01 drh: }else{ afcdc7ec97 2007-08-01 drh: base = name_to_rid(g.argv[2]); afcdc7ec97 2007-08-01 drh: } afcdc7ec97 2007-08-01 drh: if( base==0 ) return; afcdc7ec97 2007-08-01 drh: db_prepare(&q, afcdc7ec97 2007-08-01 drh: "SELECT blob.uuid, datetime(event.mtime,'localtime'), event.comment" afcdc7ec97 2007-08-01 drh: " FROM blob, event" afcdc7ec97 2007-08-01 drh: " WHERE blob.rid IN" afcdc7ec97 2007-08-01 drh: " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)" afcdc7ec97 2007-08-01 drh: " AND event.objid=blob.rid" afcdc7ec97 2007-08-01 drh: " ORDER BY event.mtime DESC" afcdc7ec97 2007-08-01 drh: ); afcdc7ec97 2007-08-01 drh: print_timeline(&q, 20); afcdc7ec97 2007-08-01 drh: db_finalize(&q); afcdc7ec97 2007-08-01 drh: } afcdc7ec97 2007-08-01 drh: afcdc7ec97 2007-08-01 drh: /* afcdc7ec97 2007-08-01 drh: ** WEBPAGE: leaves afcdc7ec97 2007-08-01 drh: ** afcdc7ec97 2007-08-01 drh: ** Find leaves of all branches. afcdc7ec97 2007-08-01 drh: */ afcdc7ec97 2007-08-01 drh: void branches_page(void){ afcdc7ec97 2007-08-01 drh: Stmt q; afcdc7ec97 2007-08-01 drh: afcdc7ec97 2007-08-01 drh: login_check_credentials(); afcdc7ec97 2007-08-01 drh: if( !g.okRead ){ login_needed(); return; } afcdc7ec97 2007-08-01 drh: afcdc7ec97 2007-08-01 drh: style_header("Leaves"); afcdc7ec97 2007-08-01 drh: db_prepare(&q, afcdc7ec97 2007-08-01 drh: "SELECT blob.uuid, datetime(event.mtime,'localtime')," afcdc7ec97 2007-08-01 drh: " event.comment, event.user" afcdc7ec97 2007-08-01 drh: " FROM blob, event" afcdc7ec97 2007-08-01 drh: " WHERE blob.rid IN" afcdc7ec97 2007-08-01 drh: " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)" afcdc7ec97 2007-08-01 drh: " AND event.objid=blob.rid" afcdc7ec97 2007-08-01 drh: " ORDER BY event.mtime DESC" afcdc7ec97 2007-08-01 drh: ); afcdc7ec97 2007-08-01 drh: www_print_timeline(&q); afcdc7ec97 2007-08-01 drh: db_finalize(&q); afcdc7ec97 2007-08-01 drh: style_footer(); dbda8d6ce9 2007-07-21 drh: }