/// <summary> /// Delete an page using pageID - transform them in Empty Page and add to EmptyPageList /// If you delete a page, you can using same old instance of page - page will be converter to EmptyPage /// If need deleted page, use GetPage again /// </summary> public void DeletePage(uint pageID, bool addSequence = false) { // get all pages in sequence or a single one var pages = addSequence ? GetSeqPages <BasePage>(pageID).ToArray() : new BasePage[] { GetPage <BasePage>(pageID) }; // get my header page var header = GetPage <HeaderPage>(0); // adding all pages to FreeList foreach (var page in pages) { // create a new empty page based on a normal page var empty = new EmptyPage(page.PageID); // add empty page to cache (with now EmptyPage type) and mark as dirty SetDirty(empty); // add to empty free list AddOrRemoveToFreeList(true, empty, header, ref header.FreeEmptyPageID); } }
//public void Dispose() //{ // // dispose datafile and journal file // _disk.Dispose(); // // dispose crypto // if (_crypto != null) _crypto.Dispose(); //} /// <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); // create crypto class if has password var crypto = password != null ? new AesEncryption(password, header.Salt) : null; // 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 }; var bytes = empty.WritePage(); if (password != null) { bytes = crypto.Encrypt(bytes); } stream.Write(bytes, 0, BasePage.PAGE_SIZE); } } if (crypto != null) { crypto.Dispose(); } }