OLD | NEW |
| (Empty) |
1 /* | |
2 ** 2008 Jan 22 | |
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 file contains code that modified the OS layer in order to simulate | |
14 ** different device types (by overriding the return values of the | |
15 ** xDeviceCharacteristics() and xSectorSize() methods). | |
16 */ | |
17 #if SQLITE_TEST /* This file is used for testing only */ | |
18 | |
19 #include "sqlite3.h" | |
20 #include "sqliteInt.h" | |
21 | |
22 /* | |
23 ** Maximum pathname length supported by the devsym backend. | |
24 */ | |
25 #define DEVSYM_MAX_PATHNAME 512 | |
26 | |
27 /* | |
28 ** Name used to identify this VFS. | |
29 */ | |
30 #define DEVSYM_VFS_NAME "devsym" | |
31 | |
32 typedef struct devsym_file devsym_file; | |
33 struct devsym_file { | |
34 sqlite3_file base; | |
35 sqlite3_file *pReal; | |
36 }; | |
37 | |
38 /* | |
39 ** Method declarations for devsym_file. | |
40 */ | |
41 static int devsymClose(sqlite3_file*); | |
42 static int devsymRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); | |
43 static int devsymWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); | |
44 static int devsymTruncate(sqlite3_file*, sqlite3_int64 size); | |
45 static int devsymSync(sqlite3_file*, int flags); | |
46 static int devsymFileSize(sqlite3_file*, sqlite3_int64 *pSize); | |
47 static int devsymLock(sqlite3_file*, int); | |
48 static int devsymUnlock(sqlite3_file*, int); | |
49 static int devsymCheckReservedLock(sqlite3_file*, int *); | |
50 static int devsymFileControl(sqlite3_file*, int op, void *pArg); | |
51 static int devsymSectorSize(sqlite3_file*); | |
52 static int devsymDeviceCharacteristics(sqlite3_file*); | |
53 static int devsymShmLock(sqlite3_file*,int,int,int); | |
54 static int devsymShmMap(sqlite3_file*,int,int,int, void volatile **); | |
55 static void devsymShmBarrier(sqlite3_file*); | |
56 static int devsymShmUnmap(sqlite3_file*,int); | |
57 | |
58 /* | |
59 ** Method declarations for devsym_vfs. | |
60 */ | |
61 static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); | |
62 static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir); | |
63 static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *); | |
64 static int devsymFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); | |
65 #ifndef SQLITE_OMIT_LOAD_EXTENSION | |
66 static void *devsymDlOpen(sqlite3_vfs*, const char *zFilename); | |
67 static void devsymDlError(sqlite3_vfs*, int nByte, char *zErrMsg); | |
68 static void (*devsymDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void); | |
69 static void devsymDlClose(sqlite3_vfs*, void*); | |
70 #endif /* SQLITE_OMIT_LOAD_EXTENSION */ | |
71 static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut); | |
72 static int devsymSleep(sqlite3_vfs*, int microseconds); | |
73 static int devsymCurrentTime(sqlite3_vfs*, double*); | |
74 | |
75 static sqlite3_vfs devsym_vfs = { | |
76 2, /* iVersion */ | |
77 sizeof(devsym_file), /* szOsFile */ | |
78 DEVSYM_MAX_PATHNAME, /* mxPathname */ | |
79 0, /* pNext */ | |
80 DEVSYM_VFS_NAME, /* zName */ | |
81 0, /* pAppData */ | |
82 devsymOpen, /* xOpen */ | |
83 devsymDelete, /* xDelete */ | |
84 devsymAccess, /* xAccess */ | |
85 devsymFullPathname, /* xFullPathname */ | |
86 #ifndef SQLITE_OMIT_LOAD_EXTENSION | |
87 devsymDlOpen, /* xDlOpen */ | |
88 devsymDlError, /* xDlError */ | |
89 devsymDlSym, /* xDlSym */ | |
90 devsymDlClose, /* xDlClose */ | |
91 #else | |
92 0, /* xDlOpen */ | |
93 0, /* xDlError */ | |
94 0, /* xDlSym */ | |
95 0, /* xDlClose */ | |
96 #endif /* SQLITE_OMIT_LOAD_EXTENSION */ | |
97 devsymRandomness, /* xRandomness */ | |
98 devsymSleep, /* xSleep */ | |
99 devsymCurrentTime, /* xCurrentTime */ | |
100 0, /* xGetLastError */ | |
101 0 /* xCurrentTimeInt64 */ | |
102 }; | |
103 | |
104 static sqlite3_io_methods devsym_io_methods = { | |
105 2, /* iVersion */ | |
106 devsymClose, /* xClose */ | |
107 devsymRead, /* xRead */ | |
108 devsymWrite, /* xWrite */ | |
109 devsymTruncate, /* xTruncate */ | |
110 devsymSync, /* xSync */ | |
111 devsymFileSize, /* xFileSize */ | |
112 devsymLock, /* xLock */ | |
113 devsymUnlock, /* xUnlock */ | |
114 devsymCheckReservedLock, /* xCheckReservedLock */ | |
115 devsymFileControl, /* xFileControl */ | |
116 devsymSectorSize, /* xSectorSize */ | |
117 devsymDeviceCharacteristics, /* xDeviceCharacteristics */ | |
118 devsymShmMap, /* xShmMap */ | |
119 devsymShmLock, /* xShmLock */ | |
120 devsymShmBarrier, /* xShmBarrier */ | |
121 devsymShmUnmap /* xShmUnmap */ | |
122 }; | |
123 | |
124 struct DevsymGlobal { | |
125 sqlite3_vfs *pVfs; | |
126 int iDeviceChar; | |
127 int iSectorSize; | |
128 }; | |
129 struct DevsymGlobal g = {0, 0, 512}; | |
130 | |
131 /* | |
132 ** Close an devsym-file. | |
133 */ | |
134 static int devsymClose(sqlite3_file *pFile){ | |
135 devsym_file *p = (devsym_file *)pFile; | |
136 return sqlite3OsClose(p->pReal); | |
137 } | |
138 | |
139 /* | |
140 ** Read data from an devsym-file. | |
141 */ | |
142 static int devsymRead( | |
143 sqlite3_file *pFile, | |
144 void *zBuf, | |
145 int iAmt, | |
146 sqlite_int64 iOfst | |
147 ){ | |
148 devsym_file *p = (devsym_file *)pFile; | |
149 return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst); | |
150 } | |
151 | |
152 /* | |
153 ** Write data to an devsym-file. | |
154 */ | |
155 static int devsymWrite( | |
156 sqlite3_file *pFile, | |
157 const void *zBuf, | |
158 int iAmt, | |
159 sqlite_int64 iOfst | |
160 ){ | |
161 devsym_file *p = (devsym_file *)pFile; | |
162 return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); | |
163 } | |
164 | |
165 /* | |
166 ** Truncate an devsym-file. | |
167 */ | |
168 static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){ | |
169 devsym_file *p = (devsym_file *)pFile; | |
170 return sqlite3OsTruncate(p->pReal, size); | |
171 } | |
172 | |
173 /* | |
174 ** Sync an devsym-file. | |
175 */ | |
176 static int devsymSync(sqlite3_file *pFile, int flags){ | |
177 devsym_file *p = (devsym_file *)pFile; | |
178 return sqlite3OsSync(p->pReal, flags); | |
179 } | |
180 | |
181 /* | |
182 ** Return the current file-size of an devsym-file. | |
183 */ | |
184 static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ | |
185 devsym_file *p = (devsym_file *)pFile; | |
186 return sqlite3OsFileSize(p->pReal, pSize); | |
187 } | |
188 | |
189 /* | |
190 ** Lock an devsym-file. | |
191 */ | |
192 static int devsymLock(sqlite3_file *pFile, int eLock){ | |
193 devsym_file *p = (devsym_file *)pFile; | |
194 return sqlite3OsLock(p->pReal, eLock); | |
195 } | |
196 | |
197 /* | |
198 ** Unlock an devsym-file. | |
199 */ | |
200 static int devsymUnlock(sqlite3_file *pFile, int eLock){ | |
201 devsym_file *p = (devsym_file *)pFile; | |
202 return sqlite3OsUnlock(p->pReal, eLock); | |
203 } | |
204 | |
205 /* | |
206 ** Check if another file-handle holds a RESERVED lock on an devsym-file. | |
207 */ | |
208 static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){ | |
209 devsym_file *p = (devsym_file *)pFile; | |
210 return sqlite3OsCheckReservedLock(p->pReal, pResOut); | |
211 } | |
212 | |
213 /* | |
214 ** File control method. For custom operations on an devsym-file. | |
215 */ | |
216 static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){ | |
217 devsym_file *p = (devsym_file *)pFile; | |
218 return sqlite3OsFileControl(p->pReal, op, pArg); | |
219 } | |
220 | |
221 /* | |
222 ** Return the sector-size in bytes for an devsym-file. | |
223 */ | |
224 static int devsymSectorSize(sqlite3_file *pFile){ | |
225 return g.iSectorSize; | |
226 } | |
227 | |
228 /* | |
229 ** Return the device characteristic flags supported by an devsym-file. | |
230 */ | |
231 static int devsymDeviceCharacteristics(sqlite3_file *pFile){ | |
232 return g.iDeviceChar; | |
233 } | |
234 | |
235 /* | |
236 ** Shared-memory methods are all pass-thrus. | |
237 */ | |
238 static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ | |
239 devsym_file *p = (devsym_file *)pFile; | |
240 return sqlite3OsShmLock(p->pReal, ofst, n, flags); | |
241 } | |
242 static int devsymShmMap( | |
243 sqlite3_file *pFile, | |
244 int iRegion, | |
245 int szRegion, | |
246 int isWrite, | |
247 void volatile **pp | |
248 ){ | |
249 devsym_file *p = (devsym_file *)pFile; | |
250 return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp); | |
251 } | |
252 static void devsymShmBarrier(sqlite3_file *pFile){ | |
253 devsym_file *p = (devsym_file *)pFile; | |
254 sqlite3OsShmBarrier(p->pReal); | |
255 } | |
256 static int devsymShmUnmap(sqlite3_file *pFile, int delFlag){ | |
257 devsym_file *p = (devsym_file *)pFile; | |
258 return sqlite3OsShmUnmap(p->pReal, delFlag); | |
259 } | |
260 | |
261 | |
262 | |
263 /* | |
264 ** Open an devsym file handle. | |
265 */ | |
266 static int devsymOpen( | |
267 sqlite3_vfs *pVfs, | |
268 const char *zName, | |
269 sqlite3_file *pFile, | |
270 int flags, | |
271 int *pOutFlags | |
272 ){ | |
273 int rc; | |
274 devsym_file *p = (devsym_file *)pFile; | |
275 p->pReal = (sqlite3_file *)&p[1]; | |
276 rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags); | |
277 if( p->pReal->pMethods ){ | |
278 pFile->pMethods = &devsym_io_methods; | |
279 } | |
280 return rc; | |
281 } | |
282 | |
283 /* | |
284 ** Delete the file located at zPath. If the dirSync argument is true, | |
285 ** ensure the file-system modifications are synced to disk before | |
286 ** returning. | |
287 */ | |
288 static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ | |
289 return sqlite3OsDelete(g.pVfs, zPath, dirSync); | |
290 } | |
291 | |
292 /* | |
293 ** Test for access permissions. Return true if the requested permission | |
294 ** is available, or false otherwise. | |
295 */ | |
296 static int devsymAccess( | |
297 sqlite3_vfs *pVfs, | |
298 const char *zPath, | |
299 int flags, | |
300 int *pResOut | |
301 ){ | |
302 return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut); | |
303 } | |
304 | |
305 /* | |
306 ** Populate buffer zOut with the full canonical pathname corresponding | |
307 ** to the pathname in zPath. zOut is guaranteed to point to a buffer | |
308 ** of at least (DEVSYM_MAX_PATHNAME+1) bytes. | |
309 */ | |
310 static int devsymFullPathname( | |
311 sqlite3_vfs *pVfs, | |
312 const char *zPath, | |
313 int nOut, | |
314 char *zOut | |
315 ){ | |
316 return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut); | |
317 } | |
318 | |
319 #ifndef SQLITE_OMIT_LOAD_EXTENSION | |
320 /* | |
321 ** Open the dynamic library located at zPath and return a handle. | |
322 */ | |
323 static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){ | |
324 return sqlite3OsDlOpen(g.pVfs, zPath); | |
325 } | |
326 | |
327 /* | |
328 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable | |
329 ** utf-8 string describing the most recent error encountered associated | |
330 ** with dynamic libraries. | |
331 */ | |
332 static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ | |
333 sqlite3OsDlError(g.pVfs, nByte, zErrMsg); | |
334 } | |
335 | |
336 /* | |
337 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. | |
338 */ | |
339 static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ | |
340 return sqlite3OsDlSym(g.pVfs, p, zSym); | |
341 } | |
342 | |
343 /* | |
344 ** Close the dynamic library handle pHandle. | |
345 */ | |
346 static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){ | |
347 sqlite3OsDlClose(g.pVfs, pHandle); | |
348 } | |
349 #endif /* SQLITE_OMIT_LOAD_EXTENSION */ | |
350 | |
351 /* | |
352 ** Populate the buffer pointed to by zBufOut with nByte bytes of | |
353 ** random data. | |
354 */ | |
355 static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | |
356 return sqlite3OsRandomness(g.pVfs, nByte, zBufOut); | |
357 } | |
358 | |
359 /* | |
360 ** Sleep for nMicro microseconds. Return the number of microseconds | |
361 ** actually slept. | |
362 */ | |
363 static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){ | |
364 return sqlite3OsSleep(g.pVfs, nMicro); | |
365 } | |
366 | |
367 /* | |
368 ** Return the current time as a Julian Day number in *pTimeOut. | |
369 */ | |
370 static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ | |
371 return g.pVfs->xCurrentTime(g.pVfs, pTimeOut); | |
372 } | |
373 | |
374 | |
375 /* | |
376 ** This procedure registers the devsym vfs with SQLite. If the argument is | |
377 ** true, the devsym vfs becomes the new default vfs. It is the only publicly | |
378 ** available function in this file. | |
379 */ | |
380 void devsym_register(int iDeviceChar, int iSectorSize){ | |
381 if( g.pVfs==0 ){ | |
382 g.pVfs = sqlite3_vfs_find(0); | |
383 devsym_vfs.szOsFile += g.pVfs->szOsFile; | |
384 sqlite3_vfs_register(&devsym_vfs, 0); | |
385 } | |
386 if( iDeviceChar>=0 ){ | |
387 g.iDeviceChar = iDeviceChar; | |
388 }else{ | |
389 g.iDeviceChar = 0; | |
390 } | |
391 if( iSectorSize>=0 ){ | |
392 g.iSectorSize = iSectorSize; | |
393 }else{ | |
394 g.iSectorSize = 512; | |
395 } | |
396 } | |
397 | |
398 #endif | |
OLD | NEW |