/// <summary> /// Creates a new log file for reading and writing and populates it with the specified message set. /// Throws an exception, if the file exists already. /// </summary> /// <param name="path">Log file to open/create.</param> /// <param name="purpose"> /// Purpose of the log file determining whether the log file is primarily used for recording or for analysis /// (does not have any effect, if the log file exists already). /// </param> /// <param name="writeMode">Write mode determining whether to open the log file in 'robust' or 'fast' mode.</param> /// <exception cref="LogFileException">Opening the log file failed (see message and inner exception for details).</exception> private LogFile( string path, LogFilePurpose purpose, LogFileWriteMode writeMode) : this(path, true, false, purpose, writeMode, false, null, null) { mMessageCollection = new FileBackedLogMessageCollection(this); }
/// <summary> /// Creates a new log file. /// </summary> /// <param name="path">Log file to create.</param> /// <param name="purpose">Purpose of the log file determining whether the log file is primarily used for recording or for analysis.</param> /// <param name="writeMode">Write mode determining whether to open the log file in 'robust' or 'fast' mode.</param> /// <param name="messages">Messages to populate the log file with.</param> /// <exception cref="LogFileException">Opening the log file failed (see message and inner exception for details).</exception> private LogFile( string path, LogFilePurpose purpose, LogFileWriteMode writeMode, IEnumerable <ILogMessage> messages) : this(path, true, true, purpose, writeMode, false, null, messages) { mMessageCollection = new FileBackedLogMessageCollection(this); }
/// <summary> /// Opens an existing log file for reading only. /// Throws an exception, if the file does not exist. /// </summary> /// <param name="path">Log file to open.</param> /// <exception cref="FileNotFoundException">The specified file does not exist.</exception> /// <exception cref="LogFileException">Opening the log file failed (see message and inner exception for details).</exception> private LogFile(string path) : this(path, false, false, LogFilePurpose.NotSpecified, LogFileWriteMode.Fast, true, null, null) { mMessageCollection = new FileBackedLogMessageCollection(this); }
/// <summary> /// Constructor providing functionality common to other constructors (for internal use only). /// </summary> /// <param name="path">Log file to open/create.</param> /// <param name="createIfNotExist"> /// true to create the specified log file, if it does not exist, yet; /// false to throw an exception, if the file does not exist. /// </param> /// <param name="fileMustNotExist"> /// <c>true</c> if the specified file must not exist; otherwise <c>false</c>. /// </param> /// <param name="purpose">Purpose of the log file determining whether the log file is primarily used for recording or for analysis.</param> /// <param name="writeMode">Write mode determining whether to open the log file in 'robust' or 'fast' mode.</param> /// <param name="isReadOnly"> /// true to open the log file in read-only mode; /// false to open the log file in read/write mode. /// </param> /// <param name="collection">Collection that works upon the log file.</param> /// <param name="messages">Messages to put into the log file (should only be used for new files).</param> /// <exception cref="FileNotFoundException"><paramref name="createIfNotExist"/> is <c>false</c> and the specified file does not exist.</exception> /// <exception cref="LogFileException">Opening/Creating the log file failed.</exception> internal LogFile( string path, bool createIfNotExist, bool fileMustNotExist, LogFilePurpose purpose, LogFileWriteMode writeMode, bool isReadOnly, FileBackedLogMessageCollection collection, IEnumerable <ILogMessage> messages) { if (path == null) { throw new ArgumentNullException(nameof(path)); } // initialize information about the operating mode mFilePath = Path.GetFullPath(path); mMessageCollection = collection; // check whether the log file exists already bool fileExists = File.Exists(mFilePath); // abort, if the file does not exist and creating a new file is not allowed if (!fileExists && !createIfNotExist) { throw new FileNotFoundException($"Log file ({path}) does not exist."); } // abort, if the file exists, but the caller expects it does not if (fileExists && fileMustNotExist) { throw new LogFileException("Log file ({path}) exists already, but it should not."); } // abort, if the file exists, but an initial message set is specified (internal error) if (fileExists && messages != null) { throw new InvalidOperationException("Log file ({path}) exists already, but it should not as an initial message set is specified."); } SQLiteConnection connection = null; try { // open database file (creates a new one, if it does not exist) connection = new SQLiteConnection($"Data Source={mFilePath};Version=3;Read Only={isReadOnly}"); connection.Open(); // open/create the database if (fileExists) { // check application id ulong applicationId = DatabaseAccessor.GetApplicationId(connection); if (applicationId != DatabaseAccessor.LogFileApplicationId) { throw new InvalidLogFileFormatException($"Application id in the sqlite database is 0x{applicationId:08x}, expecting not 0x{DatabaseAccessor.LogFileApplicationId:08x}"); } // check user version // (indicates its purpose, directly corresponds to the database schema) ulong userVersion = DatabaseAccessor.GetSchemaVersion(connection); switch (userVersion) { case 1: mDatabaseAccessor = new RecordingDatabaseAccessor(connection, writeMode, isReadOnly, false); break; case 2: mDatabaseAccessor = new AnalysisDatabaseAccessor(connection, writeMode, isReadOnly, false); break; default: throw new FileVersionNotSupportedException(); } } else { switch (purpose) { case LogFilePurpose.Recording: mDatabaseAccessor = new RecordingDatabaseAccessor(connection, writeMode, isReadOnly, true, messages); break; case LogFilePurpose.Analysis: mDatabaseAccessor = new AnalysisDatabaseAccessor(connection, writeMode, isReadOnly, true, messages); break; default: throw new NotSupportedException($"The specified purpose ({purpose}) is not supported."); } } } catch (SQLiteException ex) { Dispose(); connection?.Dispose(); throw new LogFileException( $"Opening/Creating the log file failed: {ex.Message}", ex); } catch (Exception) { Dispose(); connection?.Dispose(); throw; } }