示例#1
0
        /// <summary>
        /// Initialize new datafile with header page + lock reserved area zone
        /// </summary>
        public static void CreateDatabase(Stream stream, string password = null)
        {
            // create a new header page in bytes (keep second page empty)
            var header = new HeaderPage()
            {
                LastPageID = 1
            };

            if (password != null)
            {
                header.Password = AesEncryption.HashSHA1(password);
                header.Salt     = AesEncryption.Salt();
            }

            // point to begin file
            stream.Seek(0, SeekOrigin.Begin);

            // get header page in bytes
            var buffer = header.WritePage();

            stream.Write(buffer, 0, BasePage.PAGE_SIZE);

            // write second page empty just to use as lock control
            stream.Write(new byte[BasePage.PAGE_SIZE], 0, BasePage.PAGE_SIZE);
        }
示例#2
0
        /// <summary>
        /// Create new database - empty header with password
        /// </summary>
        public override void CreateNew()
        {
            var header = new HeaderPage();

            header.DbParams.Password = _password;
            this.WritePage(0, header.WritePage());
        }
示例#3
0
        /// <summary>
        /// Read page bytes from disk
        /// </summary>
        public virtual byte[] ReadPage(uint pageID)
        {
            // if stream are not initialized but need header, create new header
            if (_stream == null && pageID == 0)
            {
                var header = new HeaderPage
                {
                    LastPageID = 1
                };

                return(header.WritePage());
            }
            else if (_stream == null)
            {
                this.InternalInitialize();
            }

            var buffer   = new byte[BasePage.PAGE_SIZE];
            var position = BasePage.GetSizeOfPages(pageID);

            // position cursor
            if (_stream.Position != position)
            {
                _stream.Seek(position, SeekOrigin.Begin);
            }

            // read bytes from data file
            _stream.Read(buffer, 0, BasePage.PAGE_SIZE);

            return(buffer);
        }
        public void Initialize(Logger log, string password)
        {
            // get log instance to disk
            _log = log;

            // if stream are empty, create header page and save to stream
            if (_stream.Length == 0)
            {
                _log.Write(Logger.DISK, "initialize new datafile");

                // create a new header page in bytes
                var header = new HeaderPage();

                if (password != null)
                {
                    _log.Write(Logger.DISK, "datafile encrypted");

                    header.Password = AesEncryption.HashSHA1(password);
                    header.Salt     = AesEncryption.Salt();
                }

                // write bytes on page
                this.WritePage(0, header.WritePage());
            }
        }
示例#5
0
 public static void Dump(this HeaderPage page, StringBuilder sb)
 {
     sb.AppendFormat("Change: {0}, FreeEmptyPageID: {1}, LastPageID: {2}",
                     page.ChangeID,
                     page.FreeEmptyPageID.Dump(),
                     page.LastPageID.Dump());
 }
示例#6
0
        public void Initialize(Logger log, string password)
        {
            // get log instance to disk
            _log = log;

            // if stream are empty, create header page and save to stream
            if (_stream.Length == 0)
            {
                _log.Write(Logger.DISK, "initialize new datafile");

                // create a new header page in bytes
                var header = new HeaderPage();

                if(password != null)
                {
                    _log.Write(Logger.DISK, "datafile encrypted");

                    header.Password = AesEncryption.HashSHA1(password);
                    header.Salt = AesEncryption.Salt();
                }

                // write bytes on page
                this.WritePage(0, header.WritePage());
            }
        }
示例#7
0
 public static void Dump(this HeaderPage page, StringBuilder sb)
 {
     sb.AppendFormat("Change: {0}, Version: {1}, FreeEmptyPageID: {2}, LastPageID: {3}, ColID: {4}",
                     page.ChangeID,
                     page.UserVersion,
                     page.FreeEmptyPageID.Dump(),
                     page.LastPageID.Dump(),
                     page.FirstCollectionPageID.Dump());
 }
示例#8
0
        public void Initialize(Logger log, string password)
        {
            // get log instance to disk
            _log = log;

            // if is readonly, journal must be disabled
            if (_options.FileMode == FileMode.ReadOnly)
            {
                _options.Journal = false;
            }

            // open/create file using readonly/exclusive options
            _stream = new FileStream(_filename,
                                     _options.FileMode == FileMode.ReadOnly ? System.IO.FileMode.Open : System.IO.FileMode.OpenOrCreate,
                                     _options.FileMode == FileMode.ReadOnly ? FileAccess.Read : FileAccess.ReadWrite,
                                     _options.FileMode == FileMode.Exclusive ? FileShare.None : FileShare.ReadWrite,
                                     BasePage.PAGE_SIZE);

            // if file is new, initialize
            if (_stream.Length == 0)
            {
                _log.Write(Logger.DISK, "initialize new datafile");

                // set datafile initial size
                _stream.SetLength(_options.InitialSize);

                // create a new header page in bytes (keep second page empty)
                var header = new HeaderPage()
                {
                    LastPageID = 1
                };

                if (password != null)
                {
                    _log.Write(Logger.DISK, "datafile encrypted");

                    header.Password = AesEncryption.HashSHA1(password);
                    header.Salt     = AesEncryption.Salt();
                }

                // write bytes on page
                this.WritePage(0, header.WritePage());

                // write second page empty just to use as lock control
                this.WritePage(1, new byte[BasePage.PAGE_SIZE]);
            }

#if !NET35
            // there is no Lock in NetStandard (1.x) - no shared mode
            if (_options.FileMode == FileMode.Shared)
            {
                _options.FileMode = FileMode.Exclusive;
            }
#endif
        }
示例#9
0
        /// <summary>
        /// Initialize new datafile with header page + lock reserved area zone
        /// </summary>
        public static void CreateDatabase(Stream stream, string password = null, long initialSize = 0)
        {
            // calculate how many empty pages will be added on disk
            var emptyPages = initialSize == 0 ? 0 : (initialSize - (2 * BasePage.PAGE_SIZE)) / BasePage.PAGE_SIZE;

            // if too small size (less than 2 pages), assume no initial size
            if (emptyPages < 0)
            {
                emptyPages = 0;
            }

            // create a new header page in bytes (keep second page empty)
            var header = new HeaderPage
            {
                LastPageID      = initialSize == 0 ? 1 : (uint)emptyPages + 1,
                FreeEmptyPageID = initialSize == 0 ? uint.MaxValue : 2
            };

            if (password != null)
            {
                header.Password = AesEncryption.HashSHA1(password);
                header.Salt     = AesEncryption.Salt();
            }

            // point to begin file
            stream.Seek(0, SeekOrigin.Begin);

            // get header page in bytes
            var buffer = header.WritePage();

            stream.Write(buffer, 0, BasePage.PAGE_SIZE);

            // write second page as an empty AREA (it's not a page) just to use as lock control
            stream.Write(new byte[BasePage.PAGE_SIZE], 0, BasePage.PAGE_SIZE);

            // if initial size is defined, lets create empty pages in a linked list
            if (emptyPages > 0)
            {
                stream.SetLength(initialSize);

                var pageID = 1u;

                while (++pageID < (emptyPages + 2))
                {
                    var empty = new EmptyPage(pageID)
                    {
                        PrevPageID = pageID == 2 ? 0 : pageID - 1,
                        NextPageID = pageID == emptyPages + 1 ? uint.MaxValue : pageID + 1
                    };

                    stream.Write(empty.WritePage(), 0, BasePage.PAGE_SIZE);
                }
            }
        }
示例#10
0
        public void Initialize(Logger log, string password)
        {
            // get log instance to disk
            _log = log;

            // if file not exists, just create empty file
            if (!File.Exists(_filename))
            {
                // readonly
                if (_options.ReadOnly)
                {
                    throw LiteException.ReadOnlyDatabase();
                }

                // open file as create mode
                _stream = new FileStream(_filename,
                                         FileMode.CreateNew,
                                         FileAccess.ReadWrite,
                                         FileShare.Read,
                                         BasePage.PAGE_SIZE);

                _log.Write(Logger.DISK, "initialize new datafile");

                // set datafile initial size
                _stream.SetLength(_options.InitialSize);

                // create a new header page in bytes
                var header = new HeaderPage();

                if (password != null)
                {
                    _log.Write(Logger.DISK, "datafile encrypted");

                    header.Password = AesEncryption.HashSHA1(password);
                    header.Salt     = AesEncryption.Salt();
                }

                // write bytes on page
                this.WritePage(0, header.WritePage());
            }
            else
            {
                // try open file in exclusive mode
                TryExec(() =>
                {
                    _stream = new FileStream(_filename,
                                             FileMode.Open,
                                             _options.ReadOnly ? FileAccess.Read : FileAccess.ReadWrite,
                                             _options.ReadOnly ? FileShare.ReadWrite : FileShare.Read,
                                             BasePage.PAGE_SIZE);
                });
            }
        }
 /// <summary>
 /// Create new database - empty header with password
 /// </summary>
 public override void CreateNew()
 {
     var header = new HeaderPage();
     header.DbParams.Password = _password;
     this.WritePage(0, header.WritePage());
 }
示例#12
0
        public void Initialize(Logger log, string password)
        {
            // get log instance to disk
            _log = log;

            // if file not exists, just create empty file
            if (!File.Exists(_filename))
            {
                // readonly
                if (_options.ReadOnly) throw LiteException.ReadOnlyDatabase();

                // open file as create mode
                _stream = new FileStream(_filename,
                    FileMode.CreateNew,
                    FileAccess.ReadWrite,
                    FileShare.Read,
                    BasePage.PAGE_SIZE);

                _log.Write(Logger.DISK, "initialize new datafile");

                // set datafile initial size
                _stream.SetLength(_options.InitialSize);

                // create a new header page in bytes
                var header = new HeaderPage();

                if(password != null)
                {
                    _log.Write(Logger.DISK, "datafile encrypted");

                    header.Password = AesEncryption.HashSHA1(password);
                    header.Salt = AesEncryption.Salt();
                }

                // write bytes on page
                this.WritePage(0, header.WritePage());
            }
            else
            {
                // try open file in exclusive mode
                TryExec(() =>
                {
                    _stream = new FileStream(_filename,
                        FileMode.Open,
                        _options.ReadOnly ? FileAccess.Read : FileAccess.ReadWrite,
                        _options.ReadOnly ? FileShare.ReadWrite : FileShare.Read,
                        BasePage.PAGE_SIZE);
                });
            }
        }
示例#13
0
        private static Dictionary <uint, string> RecoveryCollectionPages(LiteEngine engine, HeaderPage header, StringBuilder log)
        {
            var result = new Dictionary <uint, string>();

            // get collection page
            foreach (var col in header.CollectionPages)
            {
                CollectionPage colPage = null;

                try
                {
                    // read collection page
                    var buffer = engine._disk.ReadPage(col.Value);
                    var page   = BasePage.ReadPage(buffer);

                    if (page.PageType != PageType.Collection)
                    {
                        continue;
                    }

                    colPage = page as CollectionPage;
                }
                catch (Exception ex)
                {
                    log.AppendLine($"Page {col.Value} (Collection) Error: {ex.Message}");
                    continue;
                }

                // get all pageID from all valid indexes
                var pagesID = new HashSet <uint>(colPage.Indexes.Where(x => x.IsEmpty == false && x.HeadNode.PageID != uint.MaxValue).Select(x => x.HeadNode.PageID));

                // load all dataPages from this initial index pageIDs
                var dataPages = RecoveryDetectCollectionByIndexPages(engine, pagesID, log);

                // populate resultset with this collection name/data page
                foreach (var page in dataPages)
                {
                    result[page] = col.Key;
                }
            }

            return(result);
        }
示例#14
0
 /// <summary>
 /// Empty cache and header page
 /// </summary>
 public void Clear(HeaderPage newHeaderPage)
 {
     _header = newHeaderPage;
     _cache.Clear();
 }