public static RC sqlite3OsCloseFree(VirtualFile id) { var rc = RC.OK; Debug.Assert(id != null); rc = sqlite3OsClose(id); return rc; }
private static RC readMasterJournal(VirtualFile pJrnl, byte[] zMaster, uint nMaster) { int len = 0; // Length in bytes of master journal name long szJ = 0; // Total size in bytes of journal file pJrnl uint cksum = 0; // MJ checksum value read from journal zMaster[0] = 0; var aMagic = new byte[8]; // A buffer to hold the magic header RC rc; if (RC.OK != (rc = pJrnl.FileSize(ref szJ)) || szJ < 16 || RC.OK != (rc = pJrnl.ReadByte((int)(szJ - 16), ref len)) || len >= nMaster || RC.OK != (rc = pJrnl.ReadByte(szJ - 12, ref cksum)) || RC.OK != (rc = pJrnl.Read(aMagic, 8, szJ - 8)) || ArrayEx.Compare(aMagic, aJournalMagic, 8) != 0 || RC.OK != (rc = pJrnl.Read(zMaster, len, (long)(szJ - 16 - len)))) return rc; // See if the checksum matches the master journal name for (var u = 0; u < len; u++) cksum -= zMaster[u]; if (cksum != 0) // If the checksum doesn't add up, then one or more of the disk sectors containing the master journal filename is corrupted. This means // definitely roll back, so just return SQLITE.OK and report a (nul) master-journal filename. len = 0; if (len == 0) zMaster[0] = 0; return RC.OK; }
public RC xOpen(string zName, VirtualFile pFile, OPEN flags, out OPEN pOutFlags) { pOutFlags = 0; // If argument zPath is a NULL pointer, this function is required to open a temporary file. Use this buffer to store the file name in. //var zTmpname = new StringBuilder(MAX_PATH + 1); // Buffer used to create temp filename var rc = RC.OK; var eType = (OPEN)((int)flags & 0xFFFFFF00); // Type of file to open var isExclusive = (flags & OPEN.EXCLUSIVE) != 0; var isDelete = (flags & OPEN.DELETEONCLOSE) != 0; var isCreate = (flags & OPEN.CREATE) != 0; var isReadonly = (flags & OPEN.READONLY) != 0; var isReadWrite = (flags & OPEN.READWRITE) != 0; var isOpenJournal = (isCreate && (eType == OPEN.MASTER_JOURNAL || eType == OPEN.MAIN_JOURNAL || eType == OPEN.WAL)); // Check the following statements are true: // (a) Exactly one of the READWRITE and READONLY flags must be set, and // (b) if CREATE is set, then READWRITE must also be set, and // (c) if EXCLUSIVE is set, then CREATE must also be set. // (d) if DELETEONCLOSE is set, then CREATE must also be set. Debug.Assert((!isReadonly || !isReadWrite) && (isReadWrite || isReadonly)); Debug.Assert(!isCreate || isReadWrite); Debug.Assert(!isExclusive || isCreate); Debug.Assert(!isDelete || isCreate); // The main DB, main journal, WAL file and master journal are never automatically deleted. Nor are they ever temporary files. //Debug.Assert((!isDelete && !string.IsNullOrEmpty(zName)) || eType != OPEN.MAIN_DB); Debug.Assert((!isDelete && !string.IsNullOrEmpty(zName)) || eType != OPEN.MAIN_JOURNAL); Debug.Assert((!isDelete && !string.IsNullOrEmpty(zName)) || eType != OPEN.MASTER_JOURNAL); Debug.Assert((!isDelete && !string.IsNullOrEmpty(zName)) || eType != OPEN.WAL); // Assert that the upper layer has set one of the "file-type" flags. Debug.Assert(eType == OPEN.MAIN_DB || eType == OPEN.TEMP_DB || eType == OPEN.MAIN_JOURNAL || eType == OPEN.TEMP_JOURNAL || eType == OPEN.SUBJOURNAL || eType == OPEN.MASTER_JOURNAL || eType == OPEN.TRANSIENT_DB || eType == OPEN.WAL); pFile.S = null; // If the second argument to this function is NULL, generate a temporary file name to use if (string.IsNullOrEmpty(zName)) { Debug.Assert(isDelete && !isOpenJournal); zName = Path.GetRandomFileName(); } // Convert the filename to the system encoding. if (zName.StartsWith("/") && !zName.StartsWith("//")) zName = zName.Substring(1); var dwDesiredAccess = (isReadWrite ? FileAccess.Read | FileAccess.Write : FileAccess.Read); // SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is created. SQLite doesn't use it to indicate "exclusive access" as it is usually understood. FileMode dwCreationDisposition; if (isExclusive) // Creates a new file, only if it does not already exist. */ If the file exists, it fails. dwCreationDisposition = FileMode.CreateNew; else if (isCreate) // Open existing file, or create if it doesn't exist dwCreationDisposition = FileMode.OpenOrCreate; else // Opens a file, only if it exists. dwCreationDisposition = FileMode.Open; var dwShareMode = FileShare.Read | FileShare.Write; #if !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE) FileOptions dwFlagsAndAttributes; #endif if (isDelete) #if !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE) dwFlagsAndAttributes = FileOptions.DeleteOnClose; #endif else #if !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE) dwFlagsAndAttributes = FileOptions.None; #endif // Reports from the internet are that performance is always better if FILE_FLAG_RANDOM_ACCESS is used. FileStream fs = null; if (Environment.OSVersion.Platform >= PlatformID.Win32NT) { // retry opening the file a few times; this is because of a racing condition between a delete and open call to the FS var retries = 3; while (fs == null && retries > 0) try { retries--; #if WINDOWS_PHONE || SQLITE_SILVERLIGHT fs = new IsolatedStorageFileStream(zConverted, dwCreationDisposition, dwDesiredAccess, dwShareMode, IsolatedStorageFile.GetUserStoreForApplication()); #elif !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE) fs = new FileStream(zName, dwCreationDisposition, dwDesiredAccess, dwShareMode, 4096, dwFlagsAndAttributes); #else fs = new FileStream(zName, dwCreationDisposition, dwDesiredAccess, dwShareMode, 4096); #endif #if DEBUG SysEx.OSTRACE("OPEN {0} ({1})", fs.GetHashCode(), fs.Name); #endif } catch (Exception) { Thread.Sleep(100); } } SysEx.OSTRACE("OPEN {0} {1} 0x{2:x} {3}", pFile.GetHashCode(), zName, dwDesiredAccess, fs == null ? "failed" : "ok"); if (fs == null || #if !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE) fs.SafeFileHandle.IsInvalid #else !fs.CanRead #endif ) { #if SQLITE_SILVERLIGHT pFile.lastErrno = 1; #else pFile.LastErrno = (uint)Marshal.GetLastWin32Error(); #endif VirtualFile.winLogError(RC.CANTOPEN, "winOpen", zName); return (isReadWrite ? xOpen(zName, pFile, ((flags | OPEN.READONLY) & ~(OPEN.CREATE | OPEN.READWRITE)), out pOutFlags) : SysEx.SQLITE_CANTOPEN_BKPT()); } pOutFlags = (isReadWrite ? OPEN.READWRITE : OPEN.READONLY); pFile.Clear(); pFile.IsOpen = true; pFile.S = fs; pFile.LastErrno = 0; pFile.Vfs = this; pFile.Shm = null; pFile.Path = zName; pFile.SectorSize = (uint)getSectorSize(zName); return rc; }
private RC pagerOpentemp(ref VirtualFile pFile, VFSOPEN vfsFlags) { vfsFlags |= VFSOPEN.READWRITE | VFSOPEN.CREATE | VFSOPEN.EXCLUSIVE | VFSOPEN.DELETEONCLOSE; VFSOPEN dummy = 0; var rc = FileEx.sqlite3OsOpen(this.pVfs, null, pFile, vfsFlags, ref dummy); Debug.Assert(rc != RC.OK || pFile.IsOpen); return rc; }
private static int FILEHANDLEID(VirtualFile fd) { return fd.GetHashCode(); }
private static void TestVFS() { var vfs = FileEx.sqlite3_vfs_find(null); VirtualFileSystem.OPEN flagOut = 0; VirtualFile file = new VirtualFile(); var rc = FileEx.sqlite3OsOpen(vfs, @"Test", file, VirtualFileSystem.OPEN.CREATE, ref flagOut); }
public static RC sqlite3OsOpen(VirtualFileSystem pVfs, string zPath, VirtualFile pFile, VirtualFileSystem.OPEN flags, ref VirtualFileSystem.OPEN pFlagsOut) { // 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed down into the VFS layer. Some SQLITE_OPEN_ flags (for example, // SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before reaching the VFS. var rc = pVfs.xOpen(zPath, pFile, (VirtualFileSystem.OPEN)((int)flags & 0x87f3f), out pFlagsOut); Debug.Assert(rc == RC.OK || !pFile.IsOpen); return rc; }
//internal static int sqlite3OsRandomness(VirtualFileSystem pVfs, int nByte, byte[] zBufOut) { return pVfs.xRandomness(nByte, zBufOut); } //internal static int sqlite3OsSleep(VirtualFileSystem pVfs, int nMicro) { return pVfs.xSleep(nMicro); } //internal static SQLITE sqlite3OsCurrentTimeInt64(VirtualFileSystem pVfs, ref long pTimeOut) //{ // // IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() method to get the current date and time if that method is available // // (if iVersion is 2 or greater and the function pointer is not NULL) and will fall back to xCurrentTime() if xCurrentTimeInt64() is unavailable. // SQLITE rc; // if (pVfs.iVersion >= 2) // rc = pVfs.xCurrentTimeInt64(ref pTimeOut); // else // { // double r = 0; // rc = pVfs.xCurrentTime(ref r); // pTimeOut = (long)(r * 86400000.0); // } // return rc; //} internal static RC sqlite3OsOpenMalloc(ref VirtualFileSystem pVfs, string zFile, ref VirtualFile ppFile, VirtualFileSystem.OPEN flags, ref VirtualFileSystem.OPEN pOutFlags) { var rc = RC.NOMEM; var pFile = new VirtualFile(); if (pFile != null) { rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, ref pOutFlags); if (rc != RC.OK) pFile = null; else ppFile = pFile; } return rc; }
// was:sqlite3WalOpen internal static RC Open(VirtualFileSystem x, VirtualFile y, string z) { return RC.OK; }
private RC pager_delmaster(string zMaster) { //string zMasterJournal = null; /* Contents of master journal file */ //long nMasterJournal; /* Size of master journal file */ //string zJournal; /* Pointer to one journal within MJ file */ //string zMasterPtr; /* Space to hold MJ filename from a journal file */ //int nMasterPtr; /* Amount of space allocated to zMasterPtr[] */ // Allocate space for both the pJournal and pMaster file descriptors. If successful, open the master journal file for reading. var pMaster = new VirtualFile();// Malloc'd master-journal file descriptor var pJournal = new VirtualFile();// Malloc'd child-journal file descriptor var pVfs = this.pVfs; VFSOPEN iDummy = 0; var rc = FileEx.sqlite3OsOpen(pVfs, zMaster, pMaster, VFSOPEN.READONLY | VFSOPEN.MASTER_JOURNAL, ref iDummy); if (rc != RC.OK) goto delmaster_out; Debugger.Break(); //TODO -- // Load the entire master journal file into space obtained from sqlite3_malloc() and pointed to by zMasterJournal. Also obtain // sufficient space (in zMasterPtr) to hold the names of master journal files extracted from regular rollback-journals. //rc = sqlite3OsFileSize(pMaster, &nMasterJournal); //if (rc != SQLITE.OK) goto delmaster_out; //nMasterPtr = pVfs.mxPathname + 1; // zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1); // if ( !zMasterJournal ) // { // rc = SQLITE_NOMEM; // goto delmaster_out; // } // zMasterPtr = &zMasterJournal[nMasterJournal+1]; // rc = sqlite3OsRead( pMaster, zMasterJournal, (int)nMasterJournal, 0 ); // if ( rc != SQLITE.OK ) goto delmaster_out; // zMasterJournal[nMasterJournal] = 0; // zJournal = zMasterJournal; // while ( ( zJournal - zMasterJournal ) < nMasterJournal ) // { // int exists; // rc = sqlite3OsAccess( pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists ); // if ( rc != SQLITE.OK ) // goto delmaster_out; // if ( exists ) // { // // One of the journals pointed to by the master journal exists. Open it and check if it points at the master journal. If // // so, return without deleting the master journal file. // int c; // int flags = ( SQLITE_OPEN_READONLY | SQLITE_OPEN_MAIN_JOURNAL ); // rc = sqlite3OsOpen( pVfs, zJournal, pJournal, flags, 0 ); // if ( rc != SQLITE.OK ) // goto delmaster_out; // rc = readMasterJournal( pJournal, zMasterPtr, nMasterPtr ); // sqlite3OsClose( pJournal ); // if ( rc != SQLITE.OK ) // goto delmaster_out; // c = zMasterPtr[0] != 0 && strcmp( zMasterPtr, zMaster ) == 0; // if ( c ) // // We have a match. Do not delete the master journal file. // goto delmaster_out; // } // zJournal += ( sqlite3Strlen30( zJournal ) + 1 ); // } // //sqlite3OsClose(pMaster); //rc = sqlite3OsDelete( pVfs, zMaster, 0 ); goto delmaster_out; delmaster_out: if (pMaster != null) { FileEx.sqlite3OsClose(pMaster); Debug.Assert(!pJournal.IsOpen); } return rc; }
public static RC sqlite3OsClose(VirtualFile id) { var rc = RC.OK; if (id.IsOpen) { rc = id.Close(); id.IsOpen = false; } return rc; }