예제 #1
0
 public static RC sqlite3OsCloseFree(VirtualFile id)
 {
     var rc = RC.OK;
     Debug.Assert(id != null);
     rc = sqlite3OsClose(id);
     return rc;
 }
예제 #2
0
 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;
 }
예제 #3
0
 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;
 }
예제 #4
0
 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;
 }
예제 #5
0
 private static int FILEHANDLEID(VirtualFile fd)
 {
     return fd.GetHashCode();
 }
예제 #6
0
 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);
 }
예제 #7
0
 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;
 }
예제 #8
0
 //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;
 }
예제 #9
0
 // was:sqlite3WalOpen
 internal static RC Open(VirtualFileSystem x, VirtualFile y, string z) { return RC.OK; }
예제 #10
0
 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;
 }
예제 #11
0
 public static RC sqlite3OsClose(VirtualFile id)
 {
     var rc = RC.OK;
     if (id.IsOpen) { rc = id.Close(); id.IsOpen = false; }
     return rc;
 }