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