| OLD | NEW | 
 | (Empty) | 
|    1 /* |  | 
|    2 ** 2006 June 14 |  | 
|    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 ** Test extension for testing the sqlite3_load_extension() function. |  | 
|   13 ** |  | 
|   14 ** $Id: test_loadext.c,v 1.3 2008/08/02 03:50:39 drh Exp $ |  | 
|   15 */ |  | 
|   16 #include <string.h> |  | 
|   17 #include "sqlite3ext.h" |  | 
|   18 SQLITE_EXTENSION_INIT1 |  | 
|   19  |  | 
|   20 /* |  | 
|   21 ** The half() SQL function returns half of its input value. |  | 
|   22 */ |  | 
|   23 static void halfFunc( |  | 
|   24   sqlite3_context *context, |  | 
|   25   int argc, |  | 
|   26   sqlite3_value **argv |  | 
|   27 ){ |  | 
|   28   sqlite3_result_double(context, 0.5*sqlite3_value_double(argv[0])); |  | 
|   29 } |  | 
|   30  |  | 
|   31 /* |  | 
|   32 ** SQL functions to call the sqlite3_status function and return results. |  | 
|   33 */ |  | 
|   34 static void statusFunc( |  | 
|   35   sqlite3_context *context, |  | 
|   36   int argc, |  | 
|   37   sqlite3_value **argv |  | 
|   38 ){ |  | 
|   39   int op, mx, cur, resetFlag, rc; |  | 
|   40   if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){ |  | 
|   41     op = sqlite3_value_int(argv[0]); |  | 
|   42   }else if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){ |  | 
|   43     int i; |  | 
|   44     const char *zName; |  | 
|   45     static const struct { |  | 
|   46       const char *zName; |  | 
|   47       int op; |  | 
|   48     } aOp[] = { |  | 
|   49       { "MEMORY_USED",         SQLITE_STATUS_MEMORY_USED         }, |  | 
|   50       { "PAGECACHE_USED",      SQLITE_STATUS_PAGECACHE_USED      }, |  | 
|   51       { "PAGECACHE_OVERFLOW",  SQLITE_STATUS_PAGECACHE_OVERFLOW  }, |  | 
|   52       { "SCRATCH_USED",        SQLITE_STATUS_SCRATCH_USED        }, |  | 
|   53       { "SCRATCH_OVERFLOW",    SQLITE_STATUS_SCRATCH_OVERFLOW    }, |  | 
|   54       { "MALLOC_SIZE",         SQLITE_STATUS_MALLOC_SIZE         }, |  | 
|   55     }; |  | 
|   56     int nOp = sizeof(aOp)/sizeof(aOp[0]); |  | 
|   57     zName = (const char*)sqlite3_value_text(argv[0]); |  | 
|   58     for(i=0; i<nOp; i++){ |  | 
|   59       if( strcmp(aOp[i].zName, zName)==0 ){ |  | 
|   60         op = aOp[i].op; |  | 
|   61         break; |  | 
|   62       } |  | 
|   63     } |  | 
|   64     if( i>=nOp ){ |  | 
|   65       char *zMsg = sqlite3_mprintf("unknown status property: %s", zName); |  | 
|   66       sqlite3_result_error(context, zMsg, -1); |  | 
|   67       sqlite3_free(zMsg); |  | 
|   68       return; |  | 
|   69     } |  | 
|   70   }else{ |  | 
|   71     sqlite3_result_error(context, "unknown status type", -1); |  | 
|   72     return; |  | 
|   73   } |  | 
|   74   if( argc==2 ){ |  | 
|   75     resetFlag = sqlite3_value_int(argv[1]); |  | 
|   76   }else{ |  | 
|   77     resetFlag = 0; |  | 
|   78   } |  | 
|   79   rc = sqlite3_status(op, &cur, &mx, resetFlag); |  | 
|   80   if( rc!=SQLITE_OK ){ |  | 
|   81     char *zMsg = sqlite3_mprintf("sqlite3_status(%d,...) returns %d", op, rc); |  | 
|   82     sqlite3_result_error(context, zMsg, -1); |  | 
|   83     sqlite3_free(zMsg); |  | 
|   84     return; |  | 
|   85   }  |  | 
|   86   if( argc==2 ){ |  | 
|   87     sqlite3_result_int(context, mx); |  | 
|   88   }else{ |  | 
|   89     sqlite3_result_int(context, cur); |  | 
|   90   } |  | 
|   91 } |  | 
|   92  |  | 
|   93 /* |  | 
|   94 ** Extension load function. |  | 
|   95 */ |  | 
|   96 int testloadext_init( |  | 
|   97   sqlite3 *db,  |  | 
|   98   char **pzErrMsg,  |  | 
|   99   const sqlite3_api_routines *pApi |  | 
|  100 ){ |  | 
|  101   int nErr = 0; |  | 
|  102   SQLITE_EXTENSION_INIT2(pApi); |  | 
|  103   nErr |= sqlite3_create_function(db, "half", 1, SQLITE_ANY, 0, halfFunc, 0, 0); |  | 
|  104   nErr |= sqlite3_create_function(db, "sqlite3_status", 1, SQLITE_ANY, 0, |  | 
|  105                           statusFunc, 0, 0); |  | 
|  106   nErr |= sqlite3_create_function(db, "sqlite3_status", 2, SQLITE_ANY, 0, |  | 
|  107                           statusFunc, 0, 0); |  | 
|  108   return nErr ? SQLITE_ERROR : SQLITE_OK; |  | 
|  109 } |  | 
|  110  |  | 
|  111 /* |  | 
|  112 ** Another extension entry point. This one always fails. |  | 
|  113 */ |  | 
|  114 int testbrokenext_init( |  | 
|  115   sqlite3 *db,  |  | 
|  116   char **pzErrMsg,  |  | 
|  117   const sqlite3_api_routines *pApi |  | 
|  118 ){ |  | 
|  119   char *zErr; |  | 
|  120   SQLITE_EXTENSION_INIT2(pApi); |  | 
|  121   zErr = sqlite3_mprintf("broken!"); |  | 
|  122   *pzErrMsg = zErr; |  | 
|  123   return 1; |  | 
|  124 } |  | 
| OLD | NEW |