| | @@ -1187,16 +1187,18 @@ |
| 1187 | 1187 | /* |
| 1188 | 1188 | ** Add a single entry to the mlink table. Also add the filename to |
| 1189 | 1189 | ** the filename table if it is not there already. |
| 1190 | 1190 | */ |
| 1191 | 1191 | static void add_one_mlink( |
| 1192 | + int pmid, /* The parent manifest */ |
| 1193 | + const char *zFromUuid, /* UUID for content in parent */ |
| 1192 | 1194 | int mid, /* The record ID of the manifest */ |
| 1193 | | - const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */ |
| 1194 | | - const char *zToUuid, /* UUID for the mlink.fid. "" to delete */ |
| 1195 | + const char *zToUuid, /* UUID for content in child */ |
| 1195 | 1196 | const char *zFilename, /* Filename */ |
| 1196 | 1197 | const char *zPrior, /* Previous filename. NULL if unchanged */ |
| 1197 | 1198 | int isPublic, /* True if mid is not a private manifest */ |
| 1199 | + int isPrimary, /* pmid is the primary parent of mid */ |
| 1198 | 1200 | int mperm /* 1: exec, 2: symlink */ |
| 1199 | 1201 | ){ |
| 1200 | 1202 | int fnid, pfnid, pid, fid; |
| 1201 | 1203 | static Stmt s1; |
| 1202 | 1204 | |
| | @@ -1216,19 +1218,21 @@ |
| 1216 | 1218 | }else{ |
| 1217 | 1219 | fid = uuid_to_rid(zToUuid, 1); |
| 1218 | 1220 | if( isPublic ) content_make_public(fid); |
| 1219 | 1221 | } |
| 1220 | 1222 | db_static_prepare(&s1, |
| 1221 | | - "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)" |
| 1222 | | - "VALUES(:m,:p,:f,:n,:pfn,:mp)" |
| 1223 | + "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)" |
| 1224 | + "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)" |
| 1223 | 1225 | ); |
| 1224 | 1226 | db_bind_int(&s1, ":m", mid); |
| 1225 | | - db_bind_int(&s1, ":p", pid); |
| 1226 | 1227 | db_bind_int(&s1, ":f", fid); |
| 1228 | + db_bind_int(&s1, ":pm", pmid); |
| 1229 | + db_bind_int(&s1, ":p", pid); |
| 1227 | 1230 | db_bind_int(&s1, ":n", fnid); |
| 1228 | 1231 | db_bind_int(&s1, ":pfn", pfnid); |
| 1229 | 1232 | db_bind_int(&s1, ":mp", mperm); |
| 1233 | + db_bind_int(&s1, ":isaux", isPrimary==0); |
| 1230 | 1234 | db_exec(&s1); |
| 1231 | 1235 | if( pid && fid ){ |
| 1232 | 1236 | content_deltify(pid, fid, 0); |
| 1233 | 1237 | } |
| 1234 | 1238 | } |
| | @@ -1342,24 +1346,29 @@ |
| 1342 | 1346 | ** |
| 1343 | 1347 | ** Deleted files have mlink.fid=0. |
| 1344 | 1348 | ** Added files have mlink.pid=0. |
| 1345 | 1349 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1346 | 1350 | */ |
| 1347 | | -static void add_mlink(int pid, Manifest *pParent, int cid, Manifest *pChild){ |
| 1351 | +static void add_mlink( |
| 1352 | + int pmid, Manifest *pParent, /* Parent check-in */ |
| 1353 | + int mid, Manifest *pChild, /* The child check-in */ |
| 1354 | + int isPrim /* TRUE if pmid is the primary parent of mid */ |
| 1355 | +){ |
| 1348 | 1356 | Blob otherContent; |
| 1349 | 1357 | int otherRid; |
| 1350 | 1358 | int i, rc; |
| 1351 | 1359 | ManifestFile *pChildFile, *pParentFile; |
| 1352 | 1360 | Manifest **ppOther; |
| 1353 | 1361 | static Stmt eq; |
| 1354 | 1362 | int isPublic; /* True if pChild is non-private */ |
| 1355 | 1363 | |
| 1356 | | - /* If mlink table entires are already set for cid, then abort early |
| 1357 | | - ** doing no work. |
| 1364 | + /* If mlink table entires are already exist for the pmid-to-mid transition, |
| 1365 | + ** then abort early doing no work. |
| 1358 | 1366 | */ |
| 1359 | | - db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid"); |
| 1360 | | - db_bind_int(&eq, ":mid", cid); |
| 1367 | + db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid AND pmid=:pmid"); |
| 1368 | + db_bind_int(&eq, ":mid", mid); |
| 1369 | + db_bind_int(&eq, ":pmid", pmid); |
| 1361 | 1370 | rc = db_step(&eq); |
| 1362 | 1371 | db_reset(&eq); |
| 1363 | 1372 | if( rc==SQLITE_ROW ) return; |
| 1364 | 1373 | |
| 1365 | 1374 | /* Compute the value of the missing pParent or pChild parameter. |
| | @@ -1366,14 +1375,14 @@ |
| 1366 | 1375 | ** Fetch the baseline checkins for both. |
| 1367 | 1376 | */ |
| 1368 | 1377 | assert( pParent==0 || pChild==0 ); |
| 1369 | 1378 | if( pParent==0 ){ |
| 1370 | 1379 | ppOther = &pParent; |
| 1371 | | - otherRid = pid; |
| 1380 | + otherRid = pmid; |
| 1372 | 1381 | }else{ |
| 1373 | 1382 | ppOther = &pChild; |
| 1374 | | - otherRid = cid; |
| 1383 | + otherRid = mid; |
| 1375 | 1384 | } |
| 1376 | 1385 | if( (*ppOther = manifest_cache_find(otherRid))==0 ){ |
| 1377 | 1386 | content_get(otherRid, &otherContent); |
| 1378 | 1387 | if( blob_size(&otherContent)==0 ) return; |
| 1379 | 1388 | *ppOther = manifest_parse(&otherContent, otherRid, 0); |
| | @@ -1381,20 +1390,20 @@ |
| 1381 | 1390 | } |
| 1382 | 1391 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1383 | 1392 | manifest_destroy(*ppOther); |
| 1384 | 1393 | return; |
| 1385 | 1394 | } |
| 1386 | | - isPublic = !content_is_private(cid); |
| 1395 | + isPublic = !content_is_private(mid); |
| 1387 | 1396 | |
| 1388 | 1397 | /* Try to make the parent manifest a delta from the child, if that |
| 1389 | 1398 | ** is an appropriate thing to do. For a new baseline, make the |
| 1390 | 1399 | ** previous baseline a delta from the current baseline. |
| 1391 | 1400 | */ |
| 1392 | 1401 | if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ |
| 1393 | | - content_deltify(pid, cid, 0); |
| 1402 | + content_deltify(pmid, mid, 0); |
| 1394 | 1403 | }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ |
| 1395 | | - content_deltify(pParent->pBaseline->rid, cid, 0); |
| 1404 | + content_deltify(pParent->pBaseline->rid, mid, 0); |
| 1396 | 1405 | } |
| 1397 | 1406 | |
| 1398 | 1407 | /* Remember all children less than a few seconds younger than their parent, |
| 1399 | 1408 | ** as we might want to fudge the times for those children. |
| 1400 | 1409 | */ |
| | @@ -1414,31 +1423,32 @@ |
| 1414 | 1423 | int mperm = manifest_file_mperm(pChildFile); |
| 1415 | 1424 | if( pChildFile->zPrior ){ |
| 1416 | 1425 | pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0); |
| 1417 | 1426 | if( pParentFile ){ |
| 1418 | 1427 | /* File with name change */ |
| 1419 | | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1420 | | - pChildFile->zName, pChildFile->zPrior, isPublic, mperm); |
| 1428 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1429 | + pChildFile->zName, pChildFile->zPrior, |
| 1430 | + isPublic, isPrim, mperm); |
| 1421 | 1431 | }else{ |
| 1422 | 1432 | /* File name changed, but the old name is not found in the parent! |
| 1423 | 1433 | ** Treat this like a new file. */ |
| 1424 | | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1425 | | - isPublic, mperm); |
| 1434 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1435 | + isPublic, isPrim, mperm); |
| 1426 | 1436 | } |
| 1427 | 1437 | }else{ |
| 1428 | 1438 | pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0); |
| 1429 | 1439 | if( pParentFile==0 ){ |
| 1430 | 1440 | if( pChildFile->zUuid ){ |
| 1431 | 1441 | /* A new file */ |
| 1432 | | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1433 | | - isPublic, mperm); |
| 1442 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1443 | + isPublic, isPrim, mperm); |
| 1434 | 1444 | } |
| 1435 | 1445 | }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 |
| 1436 | 1446 | || manifest_file_mperm(pParentFile)!=mperm ){ |
| 1437 | 1447 | /* Changes in file content or permissions */ |
| 1438 | | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1439 | | - pChildFile->zName, 0, isPublic, mperm); |
| 1448 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1449 | + pChildFile->zName, 0, isPublic, isPrim, mperm); |
| 1440 | 1450 | } |
| 1441 | 1451 | } |
| 1442 | 1452 | } |
| 1443 | 1453 | if( pParent->zBaseline && pChild->zBaseline ){ |
| 1444 | 1454 | /* Both parent and child are delta manifests. Look for files that |
| | @@ -1450,22 +1460,22 @@ |
| 1450 | 1460 | pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0); |
| 1451 | 1461 | if( pChildFile==0 ){ |
| 1452 | 1462 | /* The child file reverts to baseline. Show this as a change */ |
| 1453 | 1463 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1454 | 1464 | if( pChildFile ){ |
| 1455 | | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1456 | | - pChildFile->zName, 0, isPublic, |
| 1465 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1466 | + pChildFile->zName, 0, isPublic, isPrim, |
| 1457 | 1467 | manifest_file_mperm(pChildFile)); |
| 1458 | 1468 | } |
| 1459 | 1469 | } |
| 1460 | 1470 | }else{ |
| 1461 | 1471 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1462 | 1472 | if( pChildFile ){ |
| 1463 | 1473 | /* File resurrected in the child after having been deleted in |
| 1464 | 1474 | ** the parent. Show this as an added file. */ |
| 1465 | | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1466 | | - isPublic, manifest_file_mperm(pChildFile)); |
| 1475 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1476 | + isPublic, isPrim, manifest_file_mperm(pChildFile)); |
| 1467 | 1477 | } |
| 1468 | 1478 | } |
| 1469 | 1479 | } |
| 1470 | 1480 | }else if( pChild->zBaseline==0 ){ |
| 1471 | 1481 | /* pChild is a baseline. Look for files that are present in pParent |
| | @@ -1472,12 +1482,12 @@ |
| 1472 | 1482 | ** but are missing from pChild and mark them as having been deleted. */ |
| 1473 | 1483 | manifest_file_rewind(pParent); |
| 1474 | 1484 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1475 | 1485 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1476 | 1486 | if( pChildFile==0 && pParentFile->zUuid!=0 ){ |
| 1477 | | - add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0, |
| 1478 | | - isPublic, 0); |
| 1487 | + add_one_mlink(pmid, pParentFile->zUuid, mid, 0, pParentFile->zName, 0, |
| 1488 | + isPublic, isPrim, 0); |
| 1479 | 1489 | } |
| 1480 | 1490 | } |
| 1481 | 1491 | } |
| 1482 | 1492 | manifest_cache_insert(*ppOther); |
| 1483 | 1493 | } |
| | @@ -1781,45 +1791,33 @@ |
| 1781 | 1791 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d", |
| 1782 | 1792 | uuid_to_rid(p->zBaseline,1)); |
| 1783 | 1793 | }else{ |
| 1784 | 1794 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL"); |
| 1785 | 1795 | } |
| 1786 | | - (void)db_schema_is_outofdate(); /* Make sure g.zAuxSchema is initialized */ |
| 1787 | 1796 | for(i=0; i<p->nParent; i++){ |
| 1788 | 1797 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1789 | | - if( strcmp(g.zAuxSchema,"2014-11-24 20:35")>=0 ){ |
| 1790 | | - /* Support for PLINK.BASEID added on 2014-11-24 */ |
| 1791 | | - db_multi_exec( |
| 1792 | | - "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1793 | | - "VALUES(%d, %d, %d, %.17g, %s)", |
| 1794 | | - pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1795 | | - }else{ |
| 1796 | | - /* Continue to work with older schema to avoid an unnecessary |
| 1797 | | - ** rebuild */ |
| 1798 | | - db_multi_exec( |
| 1799 | | - "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)" |
| 1800 | | - "VALUES(%d, %d, %d, %.17g)", |
| 1801 | | - pid, rid, i==0, p->rDate); |
| 1802 | | - } |
| 1803 | | - if( i==0 ){ |
| 1804 | | - add_mlink(pid, 0, rid, p); |
| 1805 | | - parentid = pid; |
| 1806 | | - } |
| 1807 | | - } |
| 1808 | | - db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid); |
| 1798 | + db_multi_exec( |
| 1799 | + "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1800 | + "VALUES(%d, %d, %d, %.17g, %s)", |
| 1801 | + pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1802 | + add_mlink(pid, 0, rid, p, i); |
| 1803 | + if( i==0 ) parentid = pid; |
| 1804 | + } |
| 1805 | + db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid); |
| 1809 | 1806 | while( db_step(&q)==SQLITE_ROW ){ |
| 1810 | 1807 | int cid = db_column_int(&q, 0); |
| 1811 | | - add_mlink(rid, p, cid, 0); |
| 1808 | + int isprim = db_column_int(&q, 1); |
| 1809 | + add_mlink(rid, p, cid, 0, isprim); |
| 1812 | 1810 | } |
| 1813 | 1811 | db_finalize(&q); |
| 1814 | 1812 | if( p->nParent==0 ){ |
| 1815 | 1813 | /* For root files (files without parents) add mlink entries |
| 1816 | 1814 | ** showing all content as new. */ |
| 1817 | 1815 | int isPublic = !content_is_private(rid); |
| 1818 | 1816 | for(i=0; i<p->nFile; i++){ |
| 1819 | | - add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0, |
| 1820 | | - isPublic, manifest_file_mperm(&p->aFile[i])); |
| 1817 | + add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0, |
| 1818 | + isPublic, 1, manifest_file_mperm(&p->aFile[i])); |
| 1821 | 1819 | } |
| 1822 | 1820 | } |
| 1823 | 1821 | db_multi_exec( |
| 1824 | 1822 | "REPLACE INTO event(type,mtime,objid,user,comment," |
| 1825 | 1823 | "bgcolor,euser,ecomment,omtime)" |
| 1826 | 1824 | |