/// <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); }
/// <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()); }
/// <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()); } }
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()); }
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()); } }
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()); }
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 }
/// <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); } } }
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); }); } }
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); }); } }
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); }
/// <summary> /// Empty cache and header page /// </summary> public void Clear(HeaderPage newHeaderPage) { _header = newHeaderPage; _cache.Clear(); }