1 /*
2 ** 2020-01-11
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 various SQL functions used to access
14 ** the following SQLite C-language APIs:
15 **
16 ** sqlite3_uri_parameter()
17 ** sqlite3_uri_boolean()
18 ** sqlite3_uri_int64()
19 ** sqlite3_uri_key()
20 ** sqlite3_filename_database()
21 ** sqlite3_filename_journal()
22 ** sqlite3_filename_wal()
23 ** sqlite3_db_filename()
24 **
25 ** These SQL functions are for testing and demonstration purposes only.
26 **
27 **
28 */
29 #include "sqlite3ext.h"
30 SQLITE_EXTENSION_INIT1
31 #include <assert.h>
32 #include <string.h>
33
34 /*
35 ** SQL function: sqlite3_db_filename(SCHEMA)
36 **
37 ** Return the filename corresponding to SCHEMA.
38 */
func_db_filename(sqlite3_context * context,int argc,sqlite3_value ** argv)39 static void func_db_filename(
40 sqlite3_context *context,
41 int argc,
42 sqlite3_value **argv
43 ){
44 const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
45 sqlite3 *db = sqlite3_context_db_handle(context);
46 const char *zFile = sqlite3_db_filename(db, zSchema);
47 sqlite3_result_text(context, zFile, -1, SQLITE_TRANSIENT);
48 }
49
50 /*
51 ** SQL function: sqlite3_uri_parameter(SCHEMA,NAME)
52 **
53 ** Return the value of the NAME query parameter to the database for SCHEMA
54 */
func_uri_parameter(sqlite3_context * context,int argc,sqlite3_value ** argv)55 static void func_uri_parameter(
56 sqlite3_context *context,
57 int argc,
58 sqlite3_value **argv
59 ){
60 const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
61 sqlite3 *db = sqlite3_context_db_handle(context);
62 const char *zName = (const char*)sqlite3_value_text(argv[1]);
63 const char *zFile = sqlite3_db_filename(db, zSchema);
64 const char *zRes = sqlite3_uri_parameter(zFile, zName);
65 sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
66 }
67
68 /*
69 ** SQL function: sqlite3_uri_boolean(SCHEMA,NAME,DEFAULT)
70 **
71 ** Return the boolean value of the NAME query parameter to
72 ** the database for SCHEMA
73 */
func_uri_boolean(sqlite3_context * context,int argc,sqlite3_value ** argv)74 static void func_uri_boolean(
75 sqlite3_context *context,
76 int argc,
77 sqlite3_value **argv
78 ){
79 const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
80 sqlite3 *db = sqlite3_context_db_handle(context);
81 const char *zName = (const char*)sqlite3_value_text(argv[1]);
82 const char *zFile = sqlite3_db_filename(db, zSchema);
83 int iDflt = sqlite3_value_int(argv[2]);
84 int iRes = sqlite3_uri_boolean(zFile, zName, iDflt);
85 sqlite3_result_int(context, iRes);
86 }
87
88 /*
89 ** SQL function: sqlite3_uri_key(SCHEMA,N)
90 **
91 ** Return the name of the Nth query parameter
92 */
func_uri_key(sqlite3_context * context,int argc,sqlite3_value ** argv)93 static void func_uri_key(
94 sqlite3_context *context,
95 int argc,
96 sqlite3_value **argv
97 ){
98 const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
99 sqlite3 *db = sqlite3_context_db_handle(context);
100 int N = sqlite3_value_int(argv[1]);
101 const char *zFile = sqlite3_db_filename(db, zSchema);
102 const char *zRes = sqlite3_uri_key(zFile, N);
103 sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
104 }
105
106 /*
107 ** SQL function: sqlite3_uri_int64(SCHEMA,NAME,DEFAULT)
108 **
109 ** Return the int64 value of the NAME query parameter to
110 ** the database for SCHEMA
111 */
func_uri_int64(sqlite3_context * context,int argc,sqlite3_value ** argv)112 static void func_uri_int64(
113 sqlite3_context *context,
114 int argc,
115 sqlite3_value **argv
116 ){
117 const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
118 sqlite3 *db = sqlite3_context_db_handle(context);
119 const char *zName = (const char*)sqlite3_value_text(argv[1]);
120 const char *zFile = sqlite3_db_filename(db, zSchema);
121 sqlite3_int64 iDflt = sqlite3_value_int64(argv[2]);
122 sqlite3_int64 iRes = sqlite3_uri_int64(zFile, zName, iDflt);
123 sqlite3_result_int64(context, iRes);
124 }
125
126 /*
127 ** SQL function: sqlite3_filename_database(SCHEMA)
128 **
129 ** Return the database filename for SCHEMA
130 */
func_filename_database(sqlite3_context * context,int argc,sqlite3_value ** argv)131 static void func_filename_database(
132 sqlite3_context *context,
133 int argc,
134 sqlite3_value **argv
135 ){
136 const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
137 sqlite3 *db = sqlite3_context_db_handle(context);
138 const char *zFile = sqlite3_db_filename(db, zSchema);
139 const char *zRes = zFile ? sqlite3_filename_database(zFile) : 0;
140 sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
141 }
142
143 /*
144 ** SQL function: sqlite3_filename_journal(SCHEMA)
145 **
146 ** Return the rollback journal filename for SCHEMA
147 */
func_filename_journal(sqlite3_context * context,int argc,sqlite3_value ** argv)148 static void func_filename_journal(
149 sqlite3_context *context,
150 int argc,
151 sqlite3_value **argv
152 ){
153 const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
154 sqlite3 *db = sqlite3_context_db_handle(context);
155 const char *zFile = sqlite3_db_filename(db, zSchema);
156 const char *zRes = zFile ? sqlite3_filename_journal(zFile) : 0;
157 sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
158 }
159
160 /*
161 ** SQL function: sqlite3_filename_wal(SCHEMA)
162 **
163 ** Return the WAL filename for SCHEMA
164 */
func_filename_wal(sqlite3_context * context,int argc,sqlite3_value ** argv)165 static void func_filename_wal(
166 sqlite3_context *context,
167 int argc,
168 sqlite3_value **argv
169 ){
170 const char *zSchema = (const char*)sqlite3_value_text(argv[0]);
171 sqlite3 *db = sqlite3_context_db_handle(context);
172 const char *zFile = sqlite3_db_filename(db, zSchema);
173 const char *zRes = zFile ? sqlite3_filename_wal(zFile) : 0;
174 sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
175 }
176
177 #ifdef _WIN32
178 __declspec(dllexport)
179 #endif
sqlite3_urifuncs_init(sqlite3 * db,char ** pzErrMsg,const sqlite3_api_routines * pApi)180 int sqlite3_urifuncs_init(
181 sqlite3 *db,
182 char **pzErrMsg,
183 const sqlite3_api_routines *pApi
184 ){
185 static const struct {
186 const char *zFuncName;
187 int nArg;
188 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
189 } aFunc[] = {
190 { "sqlite3_db_filename", 1, func_db_filename },
191 { "sqlite3_uri_parameter", 2, func_uri_parameter },
192 { "sqlite3_uri_boolean", 3, func_uri_boolean },
193 { "sqlite3_uri_int64", 3, func_uri_int64 },
194 { "sqlite3_uri_key", 2, func_uri_key },
195 { "sqlite3_filename_database", 1, func_filename_database },
196 { "sqlite3_filename_journal", 1, func_filename_journal },
197 { "sqlite3_filename_wal", 1, func_filename_wal },
198 };
199 int rc = SQLITE_OK;
200 int i;
201 SQLITE_EXTENSION_INIT2(pApi);
202 (void)pzErrMsg; /* Unused parameter */
203 for(i=0; rc==SQLITE_OK && i<sizeof(aFunc)/sizeof(aFunc[0]); i++){
204 rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg,
205 SQLITE_UTF8, 0,
206 aFunc[i].xFunc, 0, 0);
207 }
208 return rc;
209 }
210