test_loadext.c 3.3 KB

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