/ Check-in [d5c17d1a]
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:Add an extension that implements compress() and uncompress() SQL functions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d5c17d1a423321f766616d82c9b27ef87c1d5afd
User & Date: drh 2014-06-13 13:08:21
Context
2014-06-13
13:43
Add the fileio.c loadable extension, that implements readfile() and writefile() SQL functions. check-in: 0ca104d8 user: drh tags: trunk
13:08
Add an extension that implements compress() and uncompress() SQL functions. check-in: d5c17d1a user: drh tags: trunk
2014-06-12
17:10
Increase the WAL-mode SQLITE_PROTOCOL timeout to 10 seconds. check-in: 2aeacf81 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added ext/misc/compress.c.

            1  +/*
            2  +** 2014-06-13
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This SQLite extension implements SQL compression functions
           14  +** compress() and uncompress() using ZLIB.
           15  +*/
           16  +#include "sqlite3ext.h"
           17  +SQLITE_EXTENSION_INIT1
           18  +#include <zlib.h>
           19  +
           20  +/*
           21  +** Implementation of the "compress(X)" SQL function.  The input X is
           22  +** compressed using zLib and the output is returned.
           23  +**
           24  +** The output is a BLOB that begins with a variable-length integer that
           25  +** is the input size in bytes (the size of X before compression).  The
           26  +** variable-length integer is implemented as 1 to 5 bytes.  There are
           27  +** seven bits per integer stored in the lower seven bits of each byte.
           28  +** More significant bits occur first.  The most significant bit (0x80)
           29  +** is a flag to indicate the end of the integer.
           30  +*/
           31  +static void compressFunc(
           32  +  sqlite3_context *context,
           33  +  int argc,
           34  +  sqlite3_value **argv
           35  +){
           36  +  const unsigned char *pIn;
           37  +  unsigned char *pOut;
           38  +  unsigned int nIn;
           39  +  unsigned long int nOut;
           40  +  unsigned char x[8];
           41  +  int i, j;
           42  +
           43  +  pIn = sqlite3_value_blob(argv[0]);
           44  +  nIn = sqlite3_value_bytes(argv[0]);
           45  +  nOut = 13 + nIn + (nIn+999)/1000;
           46  +  pOut = sqlite3_malloc( nOut+5 );
           47  +  for(i=4; i>=0; i--){
           48  +    x[i] = (nIn >> (7*(4-i)))&0x7f;
           49  +  }
           50  +  for(i=0; i<4 && x[i]==0; i++){}
           51  +  for(j=0; i<=4; i++, j++) pOut[j] = x[i];
           52  +  pOut[j-1] |= 0x80;
           53  +  compress(&pOut[j], &nOut, pIn, nIn);
           54  +  sqlite3_result_blob(context, pOut, nOut+j, sqlite3_free);
           55  +}
           56  +
           57  +/*
           58  +** Implementation of the "uncompress(X)" SQL function.  The argument X
           59  +** is a blob which was obtained from compress(Y).  The output will be
           60  +** the value Y.
           61  +*/
           62  +static void uncompressFunc(
           63  +  sqlite3_context *context,
           64  +  int argc,
           65  +  sqlite3_value **argv
           66  +){
           67  +  const unsigned char *pIn;
           68  +  unsigned char *pOut;
           69  +  unsigned int nIn;
           70  +  unsigned long int nOut;
           71  +  int rc;
           72  +  int i;
           73  +
           74  +  pIn = sqlite3_value_blob(argv[0]);
           75  +  nIn = sqlite3_value_bytes(argv[0]);
           76  +  nOut = 0;
           77  +  for(i=0; i<nIn && i<5; i++){
           78  +    nOut = (nOut<<7) | (pIn[i]&0x7f);
           79  +    if( (pIn[i]&0x80)!=0 ){ i++; break; }
           80  +  }
           81  +  pOut = sqlite3_malloc( nOut+1 );
           82  +  rc = uncompress(pOut, &nOut, &pIn[i], nIn-i);
           83  +  if( rc==Z_OK ){
           84  +    sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
           85  +  }
           86  +}
           87  +
           88  +
           89  +#ifdef _WIN32
           90  +__declspec(dllexport)
           91  +#endif
           92  +int sqlite3_compress_init(
           93  +  sqlite3 *db, 
           94  +  char **pzErrMsg, 
           95  +  const sqlite3_api_routines *pApi
           96  +){
           97  +  int rc = SQLITE_OK;
           98  +  SQLITE_EXTENSION_INIT2(pApi);
           99  +  (void)pzErrMsg;  /* Unused parameter */
          100  +  rc = sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0,
          101  +                               compressFunc, 0, 0);
          102  +  if( rc==SQLITE_OK ){
          103  +    rc = sqlite3_create_function(db, "uncompress", 1, SQLITE_UTF8, 0,
          104  +                                 uncompressFunc, 0, 0);
          105  +  }
          106  +  return rc;
          107  +}