예제 #1
0
        /// <summary>
        /// Test if cache still valid (if datafile was changed by another process reset cache)
        /// Returns true if file was changed
        /// [Thread Safe]
        /// </summary>
        private bool DetectDatabaseChanges()
        {
            // if disk are exclusive don't need check dirty read
            if (_disk.IsExclusive)
            {
                return(false);
            }

            // empty cache? just exit
            if (_cache.CleanUsed == 0)
            {
                return(false);
            }

            _log.Write(Logger.CACHE, "checking disk to detect database changes from another process");

            // get ChangeID from cache
            var header   = _cache.GetPage(0) as HeaderPage;
            var changeID = header == null ? 0 : header.ChangeID;

            // and get header from disk
            var disk = BasePage.ReadPage(_disk.ReadPage(0)) as HeaderPage;

            // if disk header are in recovery mode, throw exception to datafile re-open and recovery pages
            if (disk.Recovery)
            {
                _log.Write(Logger.ERROR, "datafile in recovery mode, need re-open database");

                throw LiteException.NeedRecover();
            }

            // if header change, clear cache and add new header to cache
            if (disk.ChangeID != changeID)
            {
                _log.Write(Logger.CACHE, "file changed from another process, cleaning all cache pages");

                _cache.ClearPages();
                _cache.AddPage(disk);
                return(true);
            }

            return(false);
        }