/* ** Add a single file named zName to the VFILE table with vid. ** ** Omit any file whose name is pOmit. */ static int add_one_file( const char *zPath, /* Tree-name of file to add. */ int vid, /* Add to this VFILE */ int caseSensitive /* True if filenames are case sensitive */ ){ const char *zCollate = caseSensitive ? "binary" : "nocase"; if( !file_is_simple_pathname(zPath) ){ fossil_fatal("filename contains illegal characters: %s", zPath); } if( db_exists("SELECT 1 FROM vfile" " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){ db_multi_exec("UPDATE vfile SET deleted=0" " WHERE pathname=%Q COLLATE %s", zPath, zCollate); }else{ char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); db_multi_exec( "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe,islink)" "VALUES(%d,0,0,0,%Q,%d,%d)", vid, zPath, file_wd_isexe(zFullname), file_wd_islink(zFullname)); fossil_free(zFullname); } if( db_changes() ){ fossil_print("ADDED %s\n", zPath); return 1; }else{ fossil_print("SKIP %s\n", zPath); return 0; } }
/* ** Update an entry of the TICKET table according to the information ** in the control file given in p. Attempt to create the appropriate ** TICKET table entry if createFlag is true. If createFlag is false, ** that means we already know the entry exists and so we can save the ** work of trying to create it. ** ** Return TRUE if a new TICKET entry was created and FALSE if an ** existing entry was revised. */ int ticket_insert(const Manifest *p, int createFlag, int rid){ Blob sql; Stmt q; int i; const char *zSep; int rc = 0; getAllTicketFields(); if( createFlag ){ db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) " "VALUES(%Q, 0)", p->zTicketUuid); rc = db_changes(); } blob_zero(&sql); blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime"); zSep = "SET"; for(i=0; i<p->nField; i++){ const char *zName = p->aField[i].zName; if( zName[0]=='+' ){ zName++; if( fieldId(zName)<0 ) continue; blob_appendf(&sql,", %s=coalesce(%s,'') || %Q", zName, zName, p->aField[i].zValue); }else{ if( fieldId(zName)<0 ) continue; blob_appendf(&sql,", %s=%Q", zName, p->aField[i].zValue); } if( rid>0 ){ wiki_extract_links(p->aField[i].zValue, rid, 1, p->rDate, i==0, 0); } } blob_appendf(&sql, " WHERE tkt_uuid='%s' AND tkt_mtime<:mtime", p->zTicketUuid); db_prepare(&q, "%s", blob_str(&sql)); db_bind_double(&q, ":mtime", p->rDate); db_step(&q); db_finalize(&q); blob_reset(&sql); return rc; }
/* fossil bundle purge BUNDLE ** ** Try to undo a prior "bundle import BUNDLE". ** ** If the --force option is omitted, then this will only work if ** there have been no check-ins or tags added that use the import. ** ** This routine never removes content that is not already in the bundle ** so the bundle serves as a backup. The purge can be undone using ** "fossil bundle import BUNDLE". */ static void bundle_purge_cmd(void){ int bForce = find_option("force",0,0)!=0; int bTest = find_option("test",0,0)!=0; /* Undocumented --test option */ const char *zFile = g.argv[3]; verify_all_options(); if ( g.argc!=4 ) usage("purge BUNDLE ?OPTIONS?"); bundle_attach_file(zFile, "b1", 0); db_begin_transaction(); /* Find all check-ins of the bundle */ db_multi_exec( "CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY);" "INSERT OR IGNORE INTO ok SELECT blob.rid FROM bblob, blob, plink" " WHERE bblob.uuid=blob.uuid" " AND plink.cid=blob.rid;" ); /* Check to see if new check-ins have been committed to check-ins in ** the bundle. Do not allow the purge if that is true and if --force ** is omitted. */ if( !bForce ){ Stmt q; int n = 0; db_prepare(&q, "SELECT cid FROM plink WHERE pid IN ok AND cid NOT IN ok" ); while( db_step(&q)==SQLITE_ROW ){ whatis_rid(db_column_int(&q,0),0); fossil_print("%.78c\n", '-'); n++; } db_finalize(&q); if( n>0 ){ fossil_fatal("check-ins above are derived from check-ins in the bundle."); } } /* Find all files associated with those check-ins that are used ** nowhere else. */ find_checkin_associates("ok", 1); /* Check to see if any associated files are not in the bundle. Issue ** an error if there are any, unless --force is used. */ if( !bForce ){ db_multi_exec( "CREATE TEMP TABLE err1(rid INTEGER PRIMARY KEY);" "INSERT INTO err1 " " SELECT blob.rid FROM ok CROSS JOIN blob" " WHERE blob.rid=ok.rid" " AND blob.uuid NOT IN (SELECT uuid FROM bblob);" ); if( db_changes() ){ describe_artifacts_to_stdout("IN err1", 0); fossil_fatal("artifacts above associated with bundle check-ins " " are not in the bundle"); }else{ db_multi_exec("DROP TABLE err1;"); } } if( bTest ){ describe_artifacts_to_stdout( "IN (SELECT blob.rid FROM ok, blob, bblob" " WHERE blob.rid=ok.rid AND blob.uuid=bblob.uuid)", "Purged artifacts found in the bundle:"); describe_artifacts_to_stdout( "IN (SELECT blob.rid FROM ok, blob" " WHERE blob.rid=ok.rid " " AND blob.uuid NOT IN (SELECT uuid FROM bblob))", "Purged artifacts NOT in the bundle:"); describe_artifacts_to_stdout( "IN (SELECT blob.rid FROM bblob, blob" " WHERE blob.uuid=bblob.uuid " " AND blob.rid NOT IN ok)", "Artifacts in the bundle but not purged:"); }else{ purge_artifact_list("ok",0,0); } db_end_transaction(0); }