From: dan Date: Sat, 13 Jan 2018 19:08:24 +0000 (+0000) Subject: Support UPDATE statements against zipfile virtual tables. X-Git-Tag: version-3.22.0~36 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f42884c307241c46994b05915e356c7931c352bc;p=thirdparty%2Fsqlite.git Support UPDATE statements against zipfile virtual tables. FossilOrigin-Name: f2d2a5df4f29b47212fd2411eae6545087b901a270655640c87ceb472e02a24c --- diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index 7ec8a222e7..88b7403f82 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -464,10 +464,47 @@ static u8* zipfileCsrBuffer(ZipfileCsr *pCsr){ /* ** Magic numbers used to read CDS records. */ -#define ZIPFILE_CDS_FIXED_SZ 46 -#define ZIPFILE_CDS_NFILE_OFF 28 +#define ZIPFILE_CDS_FIXED_SZ 46 +#define ZIPFILE_CDS_NFILE_OFF 28 -static int zipfileReadCDS(ZipfileCsr *pCsr){ +/* +** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR +** if the record is not well-formed, or SQLITE_OK otherwise. +*/ +static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){ + u8 *aRead = aBuf; + u32 sig = zipfileRead32(aRead); + int rc = SQLITE_OK; + if( sig!=ZIPFILE_SIGNATURE_CDS ){ + rc = SQLITE_ERROR; + }else{ + pCDS->iVersionMadeBy = zipfileRead16(aRead); + pCDS->iVersionExtract = zipfileRead16(aRead); + pCDS->flags = zipfileRead16(aRead); + pCDS->iCompression = zipfileRead16(aRead); + pCDS->mTime = zipfileRead16(aRead); + pCDS->mDate = zipfileRead16(aRead); + pCDS->crc32 = zipfileRead32(aRead); + pCDS->szCompressed = zipfileRead32(aRead); + pCDS->szUncompressed = zipfileRead32(aRead); + assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); + pCDS->nFile = zipfileRead16(aRead); + pCDS->nExtra = zipfileRead16(aRead); + pCDS->nComment = zipfileRead16(aRead); + pCDS->iDiskStart = zipfileRead16(aRead); + pCDS->iInternalAttr = zipfileRead16(aRead); + pCDS->iExternalAttr = zipfileRead32(aRead); + pCDS->iOffset = zipfileRead32(aRead); + assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] ); + } + + return rc; +} + +/* +** Read the CDS record for the current entry from disk into pCsr->cds. +*/ +static int zipfileCsrReadCDS(ZipfileCsr *pCsr){ char **pzErr = &pCsr->base.pVtab->zErrMsg; u8 *aRead; int rc = SQLITE_OK; @@ -485,41 +522,19 @@ static int zipfileReadCDS(ZipfileCsr *pCsr){ } if( rc==SQLITE_OK ){ - u32 sig = zipfileRead32(aRead); - if( sig!=ZIPFILE_SIGNATURE_CDS ){ + rc = zipfileReadCDS(aRead, &pCsr->cds); + if( rc!=SQLITE_OK ){ assert( pCsr->pCurrent==0 ); zipfileSetErrmsg(pCsr,"failed to read CDS at offset %lld",pCsr->iNextOff); - rc = SQLITE_ERROR; }else{ int nRead; - pCsr->cds.iVersionMadeBy = zipfileRead16(aRead); - pCsr->cds.iVersionExtract = zipfileRead16(aRead); - pCsr->cds.flags = zipfileRead16(aRead); - pCsr->cds.iCompression = zipfileRead16(aRead); - pCsr->cds.mTime = zipfileRead16(aRead); - pCsr->cds.mDate = zipfileRead16(aRead); - pCsr->cds.crc32 = zipfileRead32(aRead); - pCsr->cds.szCompressed = zipfileRead32(aRead); - pCsr->cds.szUncompressed = zipfileRead32(aRead); - assert( pCsr->pCurrent - || aRead==zipfileCsrBuffer(pCsr)+ZIPFILE_CDS_NFILE_OFF - ); - pCsr->cds.nFile = zipfileRead16(aRead); - pCsr->cds.nExtra = zipfileRead16(aRead); - pCsr->cds.nComment = zipfileRead16(aRead); - pCsr->cds.iDiskStart = zipfileRead16(aRead); - pCsr->cds.iInternalAttr = zipfileRead16(aRead); - pCsr->cds.iExternalAttr = zipfileRead32(aRead); - pCsr->cds.iOffset = zipfileRead32(aRead); - assert( pCsr->pCurrent - || aRead==zipfileCsrBuffer(pCsr)+ZIPFILE_CDS_FIXED_SZ - ); - if( pCsr->pCurrent==0 ){ nRead = pCsr->cds.nFile + pCsr->cds.nExtra; aRead = zipfileCsrBuffer(pCsr); pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ; rc = zipfileReadData(pCsr->pFile, aRead, nRead, pCsr->iNextOff, pzErr); + }else{ + aRead = &aRead[ZIPFILE_CDS_FIXED_SZ]; } if( rc==SQLITE_OK ){ @@ -570,37 +585,47 @@ static FILE *zipfileGetFd(ZipfileCsr *pCsr){ return ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd; } -static int zipfileReadLFH(ZipfileCsr *pCsr){ - FILE *pFile = zipfileGetFd(pCsr); - char **pzErr = &pCsr->base.pVtab->zErrMsg; +static int zipfileReadLFH( + FILE *pFd, + i64 iOffset, + u8 *aTmp, + ZipfileLFH *pLFH, + char **pzErr +){ + u8 *aRead = aTmp; static const int szFix = ZIPFILE_LFH_FIXED_SZ; - u8 *aRead = zipfileCsrBuffer(pCsr); int rc; - rc = zipfileReadData(pFile, aRead, szFix, pCsr->cds.iOffset, pzErr); + rc = zipfileReadData(pFd, aRead, szFix, iOffset, pzErr); if( rc==SQLITE_OK ){ u32 sig = zipfileRead32(aRead); if( sig!=ZIPFILE_SIGNATURE_LFH ){ - zipfileSetErrmsg(pCsr, "failed to read LFH at offset %d", - (int)pCsr->cds.iOffset - ); + *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", (int)iOffset); rc = SQLITE_ERROR; }else{ - pCsr->lfh.iVersionExtract = zipfileRead16(aRead); - pCsr->lfh.flags = zipfileRead16(aRead); - pCsr->lfh.iCompression = zipfileRead16(aRead); - pCsr->lfh.mTime = zipfileRead16(aRead); - pCsr->lfh.mDate = zipfileRead16(aRead); - pCsr->lfh.crc32 = zipfileRead32(aRead); - pCsr->lfh.szCompressed = zipfileRead32(aRead); - pCsr->lfh.szUncompressed = zipfileRead32(aRead); - pCsr->lfh.nFile = zipfileRead16(aRead); - pCsr->lfh.nExtra = zipfileRead16(aRead); - assert( aRead==zipfileCsrBuffer(pCsr)+szFix ); - pCsr->iDataOff = pCsr->cds.iOffset+szFix+pCsr->lfh.nFile+pCsr->lfh.nExtra; + pLFH->iVersionExtract = zipfileRead16(aRead); + pLFH->flags = zipfileRead16(aRead); + pLFH->iCompression = zipfileRead16(aRead); + pLFH->mTime = zipfileRead16(aRead); + pLFH->mDate = zipfileRead16(aRead); + pLFH->crc32 = zipfileRead32(aRead); + pLFH->szCompressed = zipfileRead32(aRead); + pLFH->szUncompressed = zipfileRead32(aRead); + pLFH->nFile = zipfileRead16(aRead); + pLFH->nExtra = zipfileRead16(aRead); + assert( aRead==&aTmp[szFix] ); } } + return rc; +} +static int zipfileCsrReadLFH(ZipfileCsr *pCsr){ + FILE *pFile = zipfileGetFd(pCsr); + char **pzErr = &pCsr->base.pVtab->zErrMsg; + u8 *aRead = zipfileCsrBuffer(pCsr); + int rc = zipfileReadLFH(pFile, pCsr->cds.iOffset, aRead, &pCsr->lfh, pzErr); + pCsr->iDataOff = pCsr->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; + pCsr->iDataOff += pCsr->lfh.nFile+pCsr->lfh.nExtra; return rc; } @@ -629,9 +654,9 @@ static int zipfileNext(sqlite3_vtab_cursor *cur){ } if( pCsr->bEof==0 ){ - rc = zipfileReadCDS(pCsr); + rc = zipfileCsrReadCDS(pCsr); if( rc==SQLITE_OK ){ - rc = zipfileReadLFH(pCsr); + rc = zipfileCsrReadLFH(pCsr); } } @@ -770,6 +795,9 @@ static int zipfileColumn( ){ ZipfileCsr *pCsr = (ZipfileCsr*)cur; int rc = SQLITE_OK; + if( i>=3 && sqlite3_vtab_nochange(ctx) ){ + return SQLITE_OK; + } switch( i ){ case 0: /* name */ sqlite3_result_text(ctx, pCsr->cds.zFile, -1, SQLITE_TRANSIENT); @@ -989,15 +1017,26 @@ static int zipfileBestIndex( ** Add object pNew to the end of the linked list that begins at ** ZipfileTab.pFirstEntry and ends with pLastEntry. */ -static void zipfileAddEntry(ZipfileTab *pTab, ZipfileEntry *pNew){ +static void zipfileAddEntry( + ZipfileTab *pTab, + ZipfileEntry *pBefore, + ZipfileEntry *pNew +){ assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) ); assert( pNew->pNext==0 ); - if( pTab->pFirstEntry==0 ){ - pTab->pFirstEntry = pTab->pLastEntry = pNew; + if( pBefore==0 ){ + if( pTab->pFirstEntry==0 ){ + pTab->pFirstEntry = pTab->pLastEntry = pNew; + }else{ + assert( pTab->pLastEntry->pNext==0 ); + pTab->pLastEntry->pNext = pNew; + pTab->pLastEntry = pNew; + } }else{ - assert( pTab->pLastEntry->pNext==0 ); - pTab->pLastEntry->pNext = pNew; - pTab->pLastEntry = pNew; + ZipfileEntry **pp; + for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext)); + pNew->pNext = pBefore; + *pp = pNew; } } @@ -1044,7 +1083,7 @@ static int zipfileLoadDirectory(ZipfileTab *pTab){ pNew->aCdsEntry = (u8*)&pNew->zPath[nFile+1]; pNew->nCdsEntry = ZIPFILE_CDS_FIXED_SZ+nFile+nExtra+nComment; memcpy(pNew->aCdsEntry, aRec, pNew->nCdsEntry); - zipfileAddEntry(pTab, pNew); + zipfileAddEntry(pTab, 0, pNew); } iOff += ZIPFILE_CDS_FIXED_SZ+nFile+nExtra+nComment; @@ -1168,7 +1207,7 @@ static int zipfileGetMode( u32 mode = 0; if( z==0 ){ mode = defaultMode; - }else if( z[0]>=0 && z[0]<=9 ){ + }else if( z[0]>='0' && z[0]<='9' ){ mode = (unsigned int)sqlite3_value_int(pVal); }else{ const char zTemplate[11] = "-rwxrwxrwx"; @@ -1231,79 +1270,104 @@ static int zipfileUpdate( u8 *pFree = 0; /* Free this */ char *zFree = 0; /* Also free this */ ZipfileCDS cds; /* New Central Directory Structure entry */ - + ZipfileEntry *pOld = 0; int bIsDir = 0; - int mNull; - assert( pTab->zFile ); assert( pTab->pWriteFd ); if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ - if( nVal>1 ){ - return SQLITE_CONSTRAINT; - }else{ - const char *zDelete = (const char*)sqlite3_value_text(apVal[0]); - int nDelete = strlen(zDelete); - ZipfileEntry *p; - for(p=pTab->pFirstEntry; p; p=p->pNext){ - if( zipfileComparePath(p->zPath, zDelete, nDelete)==0 ){ - p->bDeleted = 1; - break; - } + const char *zDelete = (const char*)sqlite3_value_text(apVal[0]); + int nDelete = strlen(zDelete); + for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){ + if( pOld->bDeleted ) continue; + if( zipfileComparePath(pOld->zPath, zDelete, nDelete)==0 ){ + pOld->bDeleted = 1; + break; } - return SQLITE_OK; + assert( pOld->pNext ); } + if( nVal==1 ) return SQLITE_OK; } - mNull = (sqlite3_value_type(apVal[5])==SQLITE_NULL ? 0x0 : 0x8) /* sz */ - + (sqlite3_value_type(apVal[6])==SQLITE_NULL ? 0x0 : 0x4) /* rawdata */ - + (sqlite3_value_type(apVal[7])==SQLITE_NULL ? 0x0 : 0x2) /* data */ - + (sqlite3_value_type(apVal[8])==SQLITE_NULL ? 0x0 : 0x1); /* method */ - if( mNull==0x00 ){ - /* All four are NULL - this must be a directory */ - bIsDir = 1; - } - else if( mNull==0x2 || mNull==0x3 ){ - /* Value specified for "data", and possibly "method". This must be - ** a regular file or a symlink. */ - const u8 *aIn = sqlite3_value_blob(apVal[7]); - int nIn = sqlite3_value_bytes(apVal[7]); - int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL; - - iMethod = sqlite3_value_int(apVal[8]); - sz = nIn; - if( iMethod!=0 && iMethod!=8 ){ - rc = SQLITE_CONSTRAINT; - }else if( bAuto || iMethod ){ - rc = zipfileDeflate(pTab, aIn, nIn, &pFree, &nData); + if( sqlite3_value_nochange(apVal[5]) && sqlite3_value_nochange(apVal[6]) + && sqlite3_value_nochange(apVal[7]) && sqlite3_value_nochange(apVal[8]) + ){ + /* Reuse the data from the existing entry. */ + FILE *pFile = pTab->pWriteFd; + ZipfileCDS cds; + zipfileReadCDS(pOld->aCdsEntry, &cds); + + bIsDir = ((cds.iExternalAttr>>16) & S_IFDIR) ? 1 : 0; + sz = cds.szUncompressed; + iMethod = cds.iCompression; + if( sz>0 ){ + char **pzErr = &pTab->base.zErrMsg; + ZipfileLFH lfh; + rc = zipfileReadLFH(pFile, cds.iOffset, pTab->aBuffer, &lfh, pzErr); if( rc==SQLITE_OK ){ - if( iMethod || nData65535 ){ - pTab->base.zErrMsg = sqlite3_mprintf( - "zipfile: invalid compression method: %d", iMethod - ); - rc = SQLITE_ERROR; + }else{ + int mNull; + mNull = (sqlite3_value_type(apVal[5])==SQLITE_NULL ? 0x0 : 0x8) /* sz */ + + (sqlite3_value_type(apVal[6])==SQLITE_NULL ? 0x0 : 0x4) /* rawdata */ + + (sqlite3_value_type(apVal[7])==SQLITE_NULL ? 0x0 : 0x2) /* data */ + + (sqlite3_value_type(apVal[8])==SQLITE_NULL ? 0x0 : 0x1); /* method */ + if( mNull==0x00 ){ + /* All four are NULL - this must be a directory */ + bIsDir = 1; + } + else if( mNull==0x2 || mNull==0x3 ){ + /* Value specified for "data", and possibly "method". This must be + ** a regular file or a symlink. */ + const u8 *aIn = sqlite3_value_blob(apVal[7]); + int nIn = sqlite3_value_bytes(apVal[7]); + int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL; + + iMethod = sqlite3_value_int(apVal[8]); + sz = nIn; + pData = aIn; + nData = nIn; + if( iMethod!=0 && iMethod!=8 ){ + rc = SQLITE_CONSTRAINT; + }else if( bAuto || iMethod ){ + int nCmp; + rc = zipfileDeflate(pTab, aIn, nIn, &pFree, &nCmp); + if( rc==SQLITE_OK ){ + if( iMethod || nCmp65535 ){ + pTab->base.zErrMsg = sqlite3_mprintf( + "zipfile: invalid compression method: %d", iMethod + ); + rc = SQLITE_ERROR; + } + } + else{ + rc = SQLITE_CONSTRAINT; } - } - else{ - rc = SQLITE_CONSTRAINT; } if( rc==SQLITE_OK ){ @@ -1344,6 +1408,7 @@ static int zipfileUpdate( if( rc==SQLITE_OK ){ ZipfileEntry *p; for(p=pTab->pFirstEntry; p; p=p->pNext){ + if( p->bDeleted ) continue; if( zipfileComparePath(p->zPath, zPath, nPath)==0 ){ rc = SQLITE_CONSTRAINT; break; @@ -1368,7 +1433,7 @@ static int zipfileUpdate( if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ - zipfileAddEntry(pTab, pNew); + zipfileAddEntry(pTab, pOld, pNew); } } @@ -1377,6 +1442,9 @@ static int zipfileUpdate( rc = zipfileAppendEntry(pTab, &cds, zPath, nPath, pData, nData, (u32)mTime); } + if( rc!=SQLITE_OK && pOld ){ + pOld->bDeleted = 0; + } sqlite3_free(pFree); sqlite3_free(zFree); return rc; diff --git a/manifest b/manifest index 8cef8f94b4..5633e43082 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fully\sinitialize\sthe\sMem\sobject\sfor\sserial-type\s10,\sin\scase\ssuch\sa\nserial-type\sis\sfound\sin\sa\scorrupt\sdatabase\sfile. -D 2018-01-13T14:28:00.767 +C Support\sUPDATE\sstatements\sagainst\szipfile\svirtual\stables. +D 2018-01-13T19:08:24.877 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 38f84f301cbef443b2d269f67a74b8cc536469831f70df7c3e912acc04932cc2 @@ -303,7 +303,7 @@ F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178 F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 -F ext/misc/zipfile.c e42d3ae79511ee86545bed07e9e5e7321f8139b55cdf73f60849352070bf12ad +F ext/misc/zipfile.c fd05292abc98fb9ad84ffc24ac8f39a25472c992f81d3ea6f3379e0df36ef4a1 F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842 F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee @@ -1600,7 +1600,7 @@ F test/wordcount.c cb589cec469a1d90add05b1f8cee75c7210338d87a5afd65260ed5c0f4bbf F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc -F test/zipfile.test a5cd98e91aebf343e21a32b97fadd6aefe02d249d5c6a1a3c2e624b88d7bdbe2 +F test/zipfile.test 61c6daf74f71f6d0c4d925cd7e23eb9ffe642491f8927b26aebba476d3244e50 F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 @@ -1699,7 +1699,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6bedc7435d26c1f21c0d1b3a52daa0169fa5416b690a99347328dcafdcd78740 -R a7ff4a80a5a33de73167133f07814a11 -U drh -Z 940a381e739a90351c545fb8067ae8cb +P bd70a07d819a54346cb6c40fab681424c5af0dfb6bf29321a3de9fc99d285376 +R 353db64d08ace436e64659cf45ce290c +U dan +Z 6cc524f643589f82fe6965a2f7fe8556 diff --git a/manifest.uuid b/manifest.uuid index b60772254f..f828d42ddb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd70a07d819a54346cb6c40fab681424c5af0dfb6bf29321a3de9fc99d285376 \ No newline at end of file +f2d2a5df4f29b47212fd2411eae6545087b901a270655640c87ceb472e02a24c \ No newline at end of file diff --git a/test/zipfile.test b/test/zipfile.test index fe1ad89c55..e766cb31bf 100644 --- a/test/zipfile.test +++ b/test/zipfile.test @@ -76,12 +76,79 @@ do_execsql_test 1.5.1 { do_execsql_test 1.5.2 { SELECT name FROM zz; } {f.txt g.txt h.txt i.txt} +do_execsql_test 1.5.3 { + SELECT data FROM zz WHERE name='i.txt'; +} {zxcvb} do_execsql_test 1.6.0 { DELETE FROM zz WHERE name='g.txt'; SELECT name FROM zz; } {f.txt h.txt i.txt} +do_execsql_test 1.6.1 { + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + f.txt 33188 1000000000 abcde 0 + h.txt 33188 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 1000000006 zxcvb 0 +} + +do_execsql_test 1.6.2 { + UPDATE zz SET mtime=4 WHERE name='i.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + f.txt 33188 1000000000 abcde 0 + h.txt 33188 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +} + +do_execsql_test 1.6.3 { + UPDATE zz SET mode='-rw-r--r-x' WHERE name='h.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + f.txt 33188 1000000000 abcde 0 + h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +} + +do_execsql_test 1.6.4 { + UPDATE zz SET name = 'blue.txt' WHERE name='f.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + blue.txt 33188 1000000000 abcde 0 + h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +} + +do_execsql_test 1.6.5 { + UPDATE zz SET data = 'edcba' WHERE name='blue.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + blue.txt 33188 1000000000 edcba 0 + h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +} + +do_execsql_test 1.6.6 { + UPDATE zz SET mode=NULL, data = NULL WHERE name='blue.txt'; + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + blue.txt/ 16877 1000000000 {} 0 + h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +} + +do_catchsql_test 1.6.7 { + UPDATE zz SET data=NULL WHERE name='i.txt' +} {1 {constraint failed}} +do_execsql_test 1.6.8 { + SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); +} { + blue.txt/ 16877 1000000000 {} 0 + h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 + i.txt 33188 4 zxcvb 0 +} + #------------------------------------------------------------------------- db close forcedelete test.zip @@ -104,11 +171,11 @@ do_execsql_test 2.2 { do_catchsql_test 2.3 { UPDATE zzz SET name = 'dirname3' WHERE name = 'dirname/'; -} {1 {constraint failed}} +} {0 {}} do_execsql_test 2.4 { SELECT name, mode, data FROM zzz; } { - dirname/ 16877 {} + dirname3/ 16877 {} dirname2/ 16877 {} dirname2/file1.txt 33188 abcdefghijklmnop } @@ -118,11 +185,11 @@ do_execsql_test 2.4 { if {$::tcl_platform(platform)=="unix"} { do_test 2.5.1 { forcedelete dirname - forcedelete dirname2 - set rc [catch { exec unzip test.zip > /dev/null } msg] - list $rc $msg + forcedelete dirname2 + set rc [catch { exec unzip test.zip > /dev/null } msg] + list $rc $msg } {0 {}} - do_test 2.5.2 { file isdir dirname } 1 + do_test 2.5.2 { file isdir dirname3 } 1 do_test 2.5.3 { file isdir dirname2 } 1 do_test 2.5.4 { file isdir dirname2/file1.txt } 0 do_test 2.5.5 {