Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Instead of just the frame number, store frame sizes and offsets in zonefile shadow table %_shadow_idx. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | zonefile |
Files: | files | file ages | folders |
SHA3-256: |
56801c461c5d19cf96146fe0fa7f725c |
User & Date: | dan 2018-02-20 18:47:24.294 |
Context
2018-02-20
| ||
19:25 | Fix a problem with reading the "file" column of a zonefile virtual table. (check-in: d8d0bdcb40 user: dan tags: zonefile) | |
18:47 | Instead of just the frame number, store frame sizes and offsets in zonefile shadow table %_shadow_idx. (check-in: 56801c461c user: dan tags: zonefile) | |
2018-02-19
| ||
21:07 | Add support for invoking encryption hooks to zonefile. And mock encryption method "xor" for testing. (check-in: 55cf920c5a user: dan tags: zonefile) | |
Changes
Changes to ext/zonefile/zonefile.c.
︙ | ︙ | |||
499 500 501 502 503 504 505 | #define ZONEFILE_SCHEMA \ "CREATE TABLE z1(" \ " k INTEGER PRIMARY KEY," \ " v BLOB," \ | < < | | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | #define ZONEFILE_SCHEMA \ "CREATE TABLE z1(" \ " k INTEGER PRIMARY KEY," \ " v BLOB," \ " file TEXT," \ " sz INTEGER" \ ")" #define ZONEFILE_FILES_SCHEMA \ "CREATE TABLE z2(" \ " filename TEXT," \ " ekey BLOB," \ |
︙ | ︙ | |||
1594 1595 1596 1597 1598 1599 1600 | int nKey; /* Size of buffer aKey[] in bytes */ int i; rc = zonefileLoadIndex(&hdr, pFd, &aKey, &nKey, &pTab->base.zErrMsg); if( rc==SQLITE_OK && pTab->pInsertIdx==0 ){ rc = zonefilePrepare(pTab->db, &pTab->pInsertIdx, &pTab->base.zErrMsg, | | | > > > > > > > > > > > > > > > | | > > > > | > | 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 | int nKey; /* Size of buffer aKey[] in bytes */ int i; rc = zonefileLoadIndex(&hdr, pFd, &aKey, &nKey, &pTab->base.zErrMsg); if( rc==SQLITE_OK && pTab->pInsertIdx==0 ){ rc = zonefilePrepare(pTab->db, &pTab->pInsertIdx, &pTab->base.zErrMsg, "INSERT INTO %Q.'%q_shadow_idx'(k, fileid, fofst, fsz, ofst, sz)" "VALUES(?,?,?,?,?,?)", pTab->zDb, pTab->zBase ); } for(i=0; i<hdr.numKeys && rc==SQLITE_OK; i++){ u8 *aEntry = &aKey[4*hdr.numFrames + ZONEFILE_SZ_KEYOFFSETS_ENTRY * i]; int iFrame = zonefileGet32(&aEntry[8]); i64 iFrameOff = 0; /* Offset of frame */ int szFrame; /* Compressed size of frame */ i64 iOff; /* Offset of blob within uncompressed frame */ int sz; /* Size of blob within uncompressed frame */ szFrame = zonefileGet32(&aKey[iFrame*4]); if( iFrame>0 ){ iFrameOff = zonefileGet32(&aKey[(iFrame-1)*4]); szFrame -= iFrameOff; } iFrameOff += hdr.byteOffsetFrames; iOff = (i64)zonefileGet32(&aEntry[12]); sz = (int)zonefileGet32(&aEntry[16]); sqlite3_bind_int64(pTab->pInsertIdx, 1, (i64)zonefileGet64(&aEntry[0])); sqlite3_bind_int64(pTab->pInsertIdx, 2, iFileid); if( hdr.encryptionType || hdr.compressionTypeContent ){ sqlite3_bind_int64(pTab->pInsertIdx, 5, iOff); sqlite3_bind_int(pTab->pInsertIdx, 6, sz); }else{ iFrameOff += iOff; szFrame = sz; } sqlite3_bind_int64(pTab->pInsertIdx, 3, iFrameOff); sqlite3_bind_int(pTab->pInsertIdx, 4, szFrame); sqlite3_step(pTab->pInsertIdx); rc = sqlite3_reset(pTab->pInsertIdx); if( rc!=SQLITE_OK ){ pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); } } |
︙ | ︙ | |||
1804 1805 1806 1807 1808 1809 1810 | p->zDb = &p->zName[nName+1]; memcpy(p->zDb, zDb, nDb+1); p->db = db; p->pGlobal = (ZonefileGlobal*)pAux; if( bCreate ){ char *zSql = sqlite3_mprintf( | | > | | 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 | p->zDb = &p->zName[nName+1]; memcpy(p->zDb, zDb, nDb+1); p->db = db; p->pGlobal = (ZonefileGlobal*)pAux; if( bCreate ){ char *zSql = sqlite3_mprintf( "CREATE TABLE %Q.'%q_shadow_idx'(" " k INTEGER PRIMARY KEY," " fileid INTEGER," " fofst INTEGER," " fsz INTEGER," " ofst INTEGER," " sz INTEGER" ");" "CREATE TABLE %Q.'%q_shadow_file'(" " filename TEXT," " fileid INTEGER PRIMARY KEY" ");" |
︙ | ︙ | |||
1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 | */ static int zonefileDestroy(sqlite3_vtab *pVtab){ ZonefileTab *pTab = (ZonefileTab*)pVtab; int rc = SQLITE_OK; char *zSql = sqlite3_mprintf( "DROP TABLE IF EXISTS %Q.'%q_shadow_idx';" "DROP TABLE IF EXISTS %Q.'%q_shadow_file';" "DROP TABLE IF EXISTS %Q.'%q_files';", pTab->zDb, pTab->zName, pTab->zDb, pTab->zName, pTab->zDb, pTab->zName ); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0); | > | 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 | */ static int zonefileDestroy(sqlite3_vtab *pVtab){ ZonefileTab *pTab = (ZonefileTab*)pVtab; int rc = SQLITE_OK; char *zSql = sqlite3_mprintf( "DROP TABLE IF EXISTS %Q.'%q_shadow_idx';" "DROP TABLE IF EXISTS %Q.'%q_shadow_file';" "DROP TABLE IF EXISTS %Q.'%q_shadow_frame';" "DROP TABLE IF EXISTS %Q.'%q_files';", pTab->zDb, pTab->zName, pTab->zDb, pTab->zName, pTab->zDb, pTab->zName ); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0); |
︙ | ︙ | |||
2049 2050 2051 2052 2053 2054 2055 | if( idxNum & 0x02 ) { z1 = "k < ?"; } if( idxNum & 0x04 ) { z1 = "k <= ?"; } if( idxNum & 0x08 ) { if( z1 ) z2 = "k > ?"; else z1 = "k > ?"; } if( idxNum & 0x10 ) { if( z1 ) z2 = "k <= ?"; else z1 = "k <= ?"; } } rc = zonefilePrepare(pTab->db, &pCsr->pSelect, &pTab->base.zErrMsg, | | | 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 | if( idxNum & 0x02 ) { z1 = "k < ?"; } if( idxNum & 0x04 ) { z1 = "k <= ?"; } if( idxNum & 0x08 ) { if( z1 ) z2 = "k > ?"; else z1 = "k > ?"; } if( idxNum & 0x10 ) { if( z1 ) z2 = "k <= ?"; else z1 = "k <= ?"; } } rc = zonefilePrepare(pTab->db, &pCsr->pSelect, &pTab->base.zErrMsg, "SELECT k, fileid, fofst, fsz, ofst, sz FROM %Q.'%q_shadow_idx'%s%s%s%s", pTab->zDb, pTab->zName, z1 ? " WHERE " : "", z1, z2 ? " AND " : "", z2 ); if( z1 ) sqlite3_bind_value(pCsr->pSelect, 1, argv[0]); if( z2 ) sqlite3_bind_value(pCsr->pSelect, 2, argv[1]); |
︙ | ︙ | |||
2115 2116 2117 2118 2119 2120 2121 | return pKey->nKey; } } return 0; } | | > > > > < < < < < < < | < < < < < < < < | < | < | > > > > | > > > > > > > > > > > > > | > > > > | > > | > | | | 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 | return pKey->nKey; } } return 0; } static int zonefileGetFile( sqlite3_context *pCtx, /* Leave error message here */ ZonefileCsr *pCsr, /* Cursor object */ const char **pzFile /* OUT: Pointer to current file */ ){ ZonefileTab *pTab = (ZonefileTab*)pCsr->base.pVtab; int rc = SQLITE_OK; i64 iFileid; if( pTab->pIdToName==0 ){ rc = zonefilePrepare(pTab->db, &pTab->pIdToName, &pTab->base.zErrMsg, "SELECT filename FROM %Q.'%q_shadow_file' WHERE fileid=?", pTab->zDb, pTab->zName ); if( rc!=SQLITE_OK ){ zonefileTransferError(pCtx); return SQLITE_ERROR; } } iFileid = sqlite3_column_int64(pCsr->pSelect,1); sqlite3_bind_int64(pTab->pIdToName, 1, iFileid); if( SQLITE_ROW==sqlite3_step(pTab->pIdToName) ){ *pzFile = (const char*)sqlite3_column_text(pTab->pIdToName, 0); }else{ rc = sqlite3_reset(pTab->pIdToName); if( rc==SQLITE_OK ){ rc = SQLITE_CORRUPT_VTAB; }else{ zonefileTransferError(pCtx); } } return rc; } static void zonefileReleaseFile(ZonefileCsr *pCsr){ ZonefileTab *pTab = (ZonefileTab*)pCsr->base.pVtab; sqlite3_reset(pTab->pIdToName); } static int zonefileGetValue(sqlite3_context *pCtx, ZonefileCsr *pCsr){ ZonefileTab *pTab = (ZonefileTab*)pCsr->base.pVtab; const char *zFile = 0; char *zErr = 0; FILE *pFd = 0; int rc = SQLITE_OK; ZonefileHeader hdr; ZonefileCompress *pCmpMethod = 0; ZonefileCodec *pCodec = 0; void *pCmp = 0; /* Open the file to read the blob from */ rc = zonefileGetFile(pCtx, pCsr, &zFile); if( rc==SQLITE_OK ){ pFd = zonefileFileOpen(zFile, 0, &zErr); if( pFd==0 ) rc = SQLITE_ERROR; } /* Read the zonefile header */ if( rc==SQLITE_OK ){ rc = zonefileReadHeader(pFd, zFile, &hdr, &zErr); } /* Find the compression method and open the compressor handle. */ if( rc==SQLITE_OK ){ rc = zfFindCompress(hdr.compressionTypeContent, &pCmpMethod, &zErr); } if( pCmpMethod ){ int nDict = 0; u8 *aDict = 0; assert( rc==SQLITE_OK ); |
︙ | ︙ | |||
2191 2192 2193 2194 2195 2196 2197 2198 | } if( rc==SQLITE_OK ){ rc = pCmpMethod->xOpen(&pCmp, aDict, nDict); } sqlite3_free(aDict); } if( hdr.encryptionType ){ | > | | | < < < < < < < < < < < < < < < < < < < < < < < < < < | < | < < | < | < < | | < < < < < < < < < < < < < < < < | > | > > > > > > > | > > > > | > > > > > > | > > > > | > | 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 | } if( rc==SQLITE_OK ){ rc = pCmpMethod->xOpen(&pCmp, aDict, nDict); } sqlite3_free(aDict); } /* Find the encryption method and key. */ if( hdr.encryptionType ){ const char *z= 0; int nKey = zonefileFindKey(pTab, sqlite3_column_int64(pCsr->pSelect,1), &z); if( nKey==0 ){ zErr = sqlite3_mprintf("missing encryption key for file \"%s\"", zFile); rc = SQLITE_ERROR; }else{ rc = zonefileCodecCreate(hdr.encryptionType,(u8*)z, nKey, &pCodec, &zErr); } } /* Read some data into memory. If the data is uncompressed, then just ** the required record is read. Otherwise, the entire frame is read ** into memory. */ if( rc==SQLITE_OK ){ i64 iFrameOff = sqlite3_column_int64(pCsr->pSelect, 2); int szFrame = sqlite3_column_int(pCsr->pSelect, 3); u8 *aBuf = sqlite3_malloc(szFrame); if( aBuf==0 ){ rc = SQLITE_NOMEM; }else{ rc = zonefileFileRead(pFd, aBuf, szFrame, iFrameOff); if( rc!=SQLITE_OK ){ zErr = sqlite3_mprintf( "failed to read %d bytes at offset %d from file \"%s\"", szFrame, iFrameOff, zFile ); } } if( rc==SQLITE_OK ){ if( pCodec==0 && pCmpMethod==0 ){ sqlite3_result_blob(pCtx, aBuf, szFrame, zonefileFree); aBuf = 0; }else{ i64 iOff = sqlite3_column_int64(pCsr->pSelect, 4); int sz = sqlite3_column_int(pCsr->pSelect, 5); /* Decrypt the data if necessary */ if( pCodec ){ zonefileCodecDecode(pCodec, aBuf, szFrame); szFrame -= zonefileCodecNonceSize(pCodec); } if( pCmpMethod ){ rc = zonefileCtxUncompress( pCtx, pCmpMethod, pCmp, aBuf, szFrame, iOff, sz ); }else{ sqlite3_result_blob(pCtx, &aBuf[iOff], sz, SQLITE_TRANSIENT); } } } sqlite3_free(aBuf); } zonefileReleaseFile(pCsr); if( zErr ){ assert( rc!=SQLITE_OK ); sqlite3_result_error(pCtx, zErr, -1); sqlite3_free(zErr); } zonefileFileClose(pFd); zonefileCodecDestroy(pCodec); |
︙ | ︙ | |||
2301 2302 2303 2304 2305 2306 2307 | switch( i ){ case 0: /* k */ sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pSelect, 0)); break; case 1: /* v */ rc = zonefileGetValue(pCtx, pCsr); break; | | | < < | | > | < > > | > | 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 | switch( i ){ case 0: /* k */ sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pSelect, 0)); break; case 1: /* v */ rc = zonefileGetValue(pCtx, pCsr); break; case 2: /* file */ sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pSelect, 1)); break; default: { /* sz */ int iCol; if( sqlite3_column_type(pCsr->pSelect, 5)==SQLITE_NULL ){ iCol = 3; }else{ iCol = 5; } sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pSelect, iCol)); break; } } return rc; } /* ** zonefile virtual table module xRowid method. */ |
︙ | ︙ |
Changes to ext/zonefile/zonefile1.test.
︙ | ︙ | |||
43 44 45 46 47 48 49 | json_extract(header, '$.numKeys') FROM z1_files; } {test.zonefile 1179332920 1 3} do_execsql_test 1.4 { SELECT count(*) FROM z1_shadow_idx } 3 do_execsql_test 1.5.1 { SELECT k FROM z1 } {1 2 3} | | | > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | json_extract(header, '$.numKeys') FROM z1_files; } {test.zonefile 1179332920 1 3} do_execsql_test 1.4 { SELECT count(*) FROM z1_shadow_idx } 3 do_execsql_test 1.5.1 { SELECT k FROM z1 } {1 2 3} do_execsql_test 1.5.2 { SELECT file FROM z1 } { test.zonefile test.zonefile test.zonefile } do_execsql_test 1.5.4 { SELECT sz FROM z1 } {100 100 100} exit do_execsql_test 1.5.5 { SELECT zz.v==z1.v FROM zz, z1 WHERE zz.k=z1.k } {1 1 1} do_execsql_test 1.5 { DELETE FROM z1_files; |
︙ | ︙ |