@@ -28,9 +28,9 @@
#include <assert.h>
#if INTERFACE
/*
-** A parsed manifest
+** A parsed manifest or cluster.
*/
struct Manifest {
Blob content; /* The original content blob */
char *zComment; /* Decoded comment */
@@ -45,8 +45,11 @@
} *aFile;
int nParent; /* Number of parents */
int nParentAlloc; /* Slots allocated in azParent[] */
char **azParent; /* UUIDs of parents */
+ int nCChild; /* Number of cluster children */
+ int nCChildAlloc; /* Number of closts allocated in azCChild[] */
+ char **azCChild; /* UUIDs of referenced objects in a cluster */
};
#endif
@@ -56,8 +59,9 @@
void manifest_clear(Manifest *p){
blob_reset(&p->content);
free(p->aFile);
free(p->azParent);
+ free(p->azCChild);
memset(p, 0, sizeof(*p));
}
/*
@@ -141,8 +145,26 @@
if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
zDate = blob_terminate(&a1);
p->rDate = db_double(0.0, "SELECT julianday(%Q)", zDate);
+ }else if( z[0]=='M' ){
+ char *zUuid;
+ md5sum_step_text(blob_buffer(&line), blob_size(&line));
+ if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
+ zUuid = blob_terminate(&a1);
+ if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error;
+ if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
+ if( p->nCChild>=p->nCChildAlloc ){
+ p->nCChildAlloc = p->nCChildAlloc*2 + 10;
+ p->azCChild =
+ realloc(p->azCChild, p->nCChildAlloc*sizeof(p->azCChild[0]) );
+ if( p->azCChild==0 ) fossil_panic("out of memory");
+ }
+ i = p->nCChild++;
+ p->azCChild[i] = zUuid;
+ if( i>0 && strcmp(p->azCChild[i-1], zUuid)>=0 ){
+ goto manifest_syntax_error;
+ }
}else if( z[0]=='U' ){
md5sum_step_text(blob_buffer(&line), blob_size(&line));
if( p->zUser!=0 ) goto manifest_syntax_error;
if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
@@ -292,8 +314,12 @@
/*
** Scan record rid/pContent to see if it is a manifest. If
** it is a manifest, then populate the mlink, plink,
** filename, and event tables with cross-reference information.
+**
+** (Later:) Also check to see if pContent is a cluster. If it
+** is a cluster then remove all referenced elements from the
+** unclustered table and create phantoms for any unknown elements.
*/
int manifest_crosslink(int rid, Blob *pContent){
int i;
Manifest m;
@@ -322,9 +348,16 @@
"INSERT INTO event(type,mtime,objid,user,comment)"
"VALUES('ci',%.17g,%d,%Q,%Q)",
m.rDate, rid, m.zUser, m.zComment
);
+ }
+ for(i=0; i<m.nCChild; i++){
+ int rid;
+ rid = uuid_to_rid(m.azCChild[i], 1);
+ if( rid>0 ){
+ db_multi_exec("DELETE FROM unclustered WHERE rid=%d", rid);
+ }
}
db_end_transaction(0);
manifest_clear(&m);
return 1;
}