/ Check-in [931201f6]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Change zipfile to be a WITHOUT ROWID virtual table and table-valued function.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 931201f64e04247ed613a0301fcc86c3a337c2ed162c6370a80c67a1dd919e7c
User & Date: dan 2018-01-11 17:33:48
Context
2018-01-11
18:15
Add the sqlite3_vtab_nochange() interface. Test cases are in TH3. check-in: a5d09dfa user: drh tags: trunk
17:33
Change zipfile to be a WITHOUT ROWID virtual table and table-valued function. check-in: 931201f6 user: dan tags: trunk
16:16
Add test cases for running multiple RBU operations within the same process concurrently. check-in: 407b5ed3 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/misc/zipfile.c.

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
...
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
...
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
....
1247
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257

1258
1259
1260
1261
1262
1263
1264
typedef unsigned short u16;
typedef unsigned long u32;
#define MIN(a,b) ((a)<(b) ? (a) : (b))
#endif

static const char ZIPFILE_SCHEMA[] = 
  "CREATE TABLE y("
    "name,"              /* 0: Name of file in zip archive */
    "mode,"              /* 1: POSIX mode for file */
    "mtime,"             /* 2: Last modification time (secs since 1970)*/
    "sz,"                /* 3: Size of object */
    "rawdata,"           /* 4: Raw data */
    "data,"              /* 5: Uncompressed data */
    "method,"            /* 6: Compression method (integer) */
    "file HIDDEN"        /* 7: Name of zip file */
  ");";

#define ZIPFILE_F_COLUMN_IDX 7    /* Index of column "file" in the above */
#define ZIPFILE_BUFFER_SIZE (64*1024)


/*
** Magic numbers used to read and write zip files.
................................................................................
  u16 nFile;
  u16 nExtra;
};

typedef struct ZipfileEntry ZipfileEntry;
struct ZipfileEntry {
  char *zPath;               /* Path of zipfile entry */
  i64 iRowid;                /* Rowid for this value if queried */
  u8 *aCdsEntry;             /* Buffer containing entire CDS entry */
  int nCdsEntry;             /* Size of buffer aCdsEntry[] in bytes */
  int bDeleted;              /* True if entry has been deleted */
  ZipfileEntry *pNext;       /* Next element in in-memory CDS */
};

/* 
................................................................................
  return SQLITE_OK;
}

/*
** Return the rowid for the current row.
*/
static int zipfileRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
  if( pCsr->pCurrent ){
    *pRowid = pCsr->pCurrent->iRowid;
  }else{
    *pRowid = pCsr->cds.iOffset;
  }
  return SQLITE_OK;
}

/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
................................................................................
** 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){
  assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
  assert( pNew->pNext==0 );
  if( pTab->pFirstEntry==0 ){
    pNew->iRowid = 1;
    pTab->pFirstEntry = pTab->pLastEntry = pNew;
  }else{
    assert( pTab->pLastEntry->pNext==0 );
    pNew->iRowid = pTab->pLastEntry->iRowid+1;
    pTab->pLastEntry->pNext = pNew;
    pTab->pLastEntry = pNew;
  }
}

static int zipfileLoadDirectory(ZipfileTab *pTab){
  ZipfileEOCD eocd;
................................................................................
  assert( pTab->zFile );
  assert( pTab->pWriteFd );

  if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
    if( nVal>1 ){
      return SQLITE_CONSTRAINT;
    }else{
      i64 iDelete = sqlite3_value_int64(apVal[0]);

      ZipfileEntry *p;
      for(p=pTab->pFirstEntry; p; p=p->pNext){
        if( p->iRowid==iDelete ){

          p->bDeleted = 1;
          break;
        }
      }
      return SQLITE_OK;
    }
  }







|







|







 







<







 







|
<
<
<
<
<







 







<



<







 







|
>


<
>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
...
219
220
221
222
223
224
225

226
227
228
229
230
231
232
...
825
826
827
828
829
830
831
832





833
834
835
836
837
838
839
...
989
990
991
992
993
994
995

996
997
998

999
1000
1001
1002
1003
1004
1005
....
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249

1250
1251
1252
1253
1254
1255
1256
1257
typedef unsigned short u16;
typedef unsigned long u32;
#define MIN(a,b) ((a)<(b) ? (a) : (b))
#endif

static const char ZIPFILE_SCHEMA[] = 
  "CREATE TABLE y("
    "name PRIMARY KEY,"  /* 0: Name of file in zip archive */
    "mode,"              /* 1: POSIX mode for file */
    "mtime,"             /* 2: Last modification time (secs since 1970)*/
    "sz,"                /* 3: Size of object */
    "rawdata,"           /* 4: Raw data */
    "data,"              /* 5: Uncompressed data */
    "method,"            /* 6: Compression method (integer) */
    "file HIDDEN"        /* 7: Name of zip file */
  ") WITHOUT ROWID;";

#define ZIPFILE_F_COLUMN_IDX 7    /* Index of column "file" in the above */
#define ZIPFILE_BUFFER_SIZE (64*1024)


/*
** Magic numbers used to read and write zip files.
................................................................................
  u16 nFile;
  u16 nExtra;
};

typedef struct ZipfileEntry ZipfileEntry;
struct ZipfileEntry {
  char *zPath;               /* Path of zipfile entry */

  u8 *aCdsEntry;             /* Buffer containing entire CDS entry */
  int nCdsEntry;             /* Size of buffer aCdsEntry[] in bytes */
  int bDeleted;              /* True if entry has been deleted */
  ZipfileEntry *pNext;       /* Next element in in-memory CDS */
};

/* 
................................................................................
  return SQLITE_OK;
}

/*
** Return the rowid for the current row.
*/
static int zipfileRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
  assert( 0 );





  return SQLITE_OK;
}

/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
................................................................................
** 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){
  assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
  assert( pNew->pNext==0 );
  if( pTab->pFirstEntry==0 ){

    pTab->pFirstEntry = pTab->pLastEntry = pNew;
  }else{
    assert( pTab->pLastEntry->pNext==0 );

    pTab->pLastEntry->pNext = pNew;
    pTab->pLastEntry = pNew;
  }
}

static int zipfileLoadDirectory(ZipfileTab *pTab){
  ZipfileEOCD eocd;
................................................................................
  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;
        }
      }
      return SQLITE_OK;
    }
  }

Changes to test/zipfile.test.

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
156
157
158
159
160
161
162




163
164
165
}

forcedelete test.zip
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE temp.zz USING zipfile('test.zip');
  PRAGMA table_info(zz);
} {
  0 name {} 0 {} 0 
  1 mode {} 0 {} 0 
  2 mtime {} 0 {} 0 
  3 sz {} 0 {} 0 
  4 rawdata {} 0 {} 0
  5 data {} 0 {} 0
  6 method {} 0 {} 0
}
................................................................................
    INSERT INTO x1(name, data) VALUES($fname || '/', NULL);
  } {1 {constraint failed}}
  do_catchsql_test 3.1.$tn.2 {
    INSERT INTO x1(name, data) VALUES($fname, 'abcd');
  } {1 {constraint failed}}
}






finish_test








|







 







>
>
>
>



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
}

forcedelete test.zip
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE temp.zz USING zipfile('test.zip');
  PRAGMA table_info(zz);
} {
  0 name {} 1 {} 1 
  1 mode {} 0 {} 0 
  2 mtime {} 0 {} 0 
  3 sz {} 0 {} 0 
  4 rawdata {} 0 {} 0
  5 data {} 0 {} 0
  6 method {} 0 {} 0
}
................................................................................
    INSERT INTO x1(name, data) VALUES($fname || '/', NULL);
  } {1 {constraint failed}}
  do_catchsql_test 3.1.$tn.2 {
    INSERT INTO x1(name, data) VALUES($fname, 'abcd');
  } {1 {constraint failed}}
}

do_catchsql_test 3.2 {
  SELECT rowid FROM x1
} {1 {no such column: rowid}}


finish_test