Ejemplo n.º 1
0
        /// <summary>
        /// Method to create and connect to a SQLite database.
        /// </summary>
        /// <param name="database">The database file name.</param>
        /// <param name="createFile">Create file if not exists ?</param>
        /// <param name="scheme">The path to the database scheme.</param>
        /// <exception cref="FileNotFoundException"></exception>
        /// <exception cref="SQLiteException"></exception>
        public void CreateConnection(string database, bool createFile = false, string scheme = "")
        {
            try
            {
                log.Debug(@"WPFSQLitePCL connecting : Data Source=" + database + ";Version=3;FailIfMissing=False;UTF8Encoding=True;");

                Db = new SQLiteConnection(new SQLitePlatformWin32(), @"Data Source=" + database + ";Version=3;FailIfMissing=False;UTF8Encoding=True;", SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.ProtectionNone);

                if (createFile)
                {
                    CreateDatabase(scheme);
                    InitializeSetting();
                }
            }
            catch (FileNotFoundException e)
            {
                string message = string.Format(CultureInfo.InvariantCulture, "Database file not found : {0}", database);
                log.Fatal(string.Format(message));
                log.Fatal(e);
                throw new Exception("Database file not found : " + database, e);
            }
            catch (SQLiteException e)
            {
                string message = string.Format(CultureInfo.InvariantCulture, "Database file not found : {0}", database);
                log.Fatal(string.Format(message));
                log.Fatal(e);
                throw SQLiteException.New(e.Result, e.Message);
            }
        }
Ejemplo n.º 2
0
        public void InitOrCreateDatabase(Boolean AutoCreateDB)
        {
            // create a DbMetadataProvider
            _DBMetadataProvider = new SQLiteMetadataProvider();
            _DBMetadataProvider.AutoCreateDB = AutoCreateDB;

            SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder(_DBAccess.DBConnectStr);

            try
            {
                // Let caller know about anything we logged to this point
                LogMessage(TraceLevel.Verbose, "Attempting database connection...", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);
                _DBAccess.TryDBConnection();
                LogMessage(TraceLevel.Verbose, "  Connection successful. (DataSource: " + builder.DataSource + ")", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);
            }
            catch (Exception loExcept)
            {
                LogMessage(TraceLevel.Error, "  Connection Failed! (DataSource: " + builder.DataSource + ")", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);

                // Let caller know about anything we logged to this point
                if (loExcept is SQLiteException)
                {
                    SQLiteException loSQLError = (loExcept as SQLiteException);
                    LogMessage(TraceLevel.Error, loSQLError.Message + "; ErrorCode = " + loSQLError.ErrorCode.ToString(),
                               System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);
                }
                else
                {
                    LogMessage(TraceLevel.Error, loExcept.Message, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId);
                }

                // re-throw the error
                throw loExcept;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Method to create a new database base on a file of scheme.
        /// </summary>
        /// <param name="scheme">An application relative path to the database scheme to create.</param>
        /// <exception cref="FileNotFoundException"></exception>
        /// <exception cref="SQLiteException"></exception>
        protected void CreateDatabase(string scheme)
        {
            string query = "";
            string path  = Path.Combine(Environment.CurrentDirectory, scheme);

            try
            {
                query = File.ReadAllText(path);
            }
            catch (Exception e)
            {
                string message = string.Format(CultureInfo.InvariantCulture, "Database scheme file not found : {0}", scheme);
                log.Fatal(string.Format(message));
                log.Fatal(e);
                throw new FileNotFoundException(message, e);
            }

            try
            {
                Db.RunInTransaction(() => { Db.Execute(query); });
            }
            catch (SQLiteException e)
            {
                string message = string.Format(CultureInfo.InvariantCulture, "Failed to create database scheme : {0}", scheme);
                log.Fatal(string.Format(message));
                log.Fatal(e);
                throw SQLiteException.New(e.Result, message);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets a message from an exception raised by the connector.
        /// Removes the initial #{number} and the ending dot.
        /// </summary>
        /// <param name="e">Exception.</param>
        /// <returns>The message.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="e"/> is a <B>null</B> reference.</exception>
        public override string GetExceptionMessage(Exception /*!*/ e)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }

            SQLiteException mye = e as SQLiteException;

            if (mye == null || mye.Message.Length == 0)
            {
                return(e.Message);
            }

            string msg = StripErrorNumber(mye.Message);

            // skip last dot:
            int j = msg.Length;

            if (msg[j - 1] == '.')
            {
                j--;
            }

            return(String.Format("{0} (error {1})", msg.Substring(0, j), mye.ErrorCode));
        }
Ejemplo n.º 5
0
        public override T ExecuteScalar <T>()
        {
            T val = default(T);

            var stmt = Prepare();

            try
            {
                var r = SQLite3.Step(stmt);
                if (r == SQLite3.Result.Row)
                {
                    var colType = SQLite3.ColumnType(stmt, 0);
                    var colval  = ReadCol(stmt, 0, colType, typeof(T));
                    if (colval != null)
                    {
                        val = (T)colval;
                    }
                }
                else if (r == SQLite3.Result.Done)
                {
                }
                else
                {
                    throw SQLiteException.New(r, SQLite3.GetErrmsg(_conn.Handle));
                }
            }
            finally
            {
                Finalize(stmt);
            }

            return(val);
        }
Ejemplo n.º 6
0
        public int ExecuteNonQuery()
        {
            if (_conn.Trace)
            {
                Debug.WriteLine("Executing: " + this);
            }

            var r    = SQLite3.Result.OK;
            var stmt = Prepare();

            r = SQLite3.Step(stmt);
            Finalize(stmt);
            if (r == SQLite3.Result.Done)
            {
                int rowsAffected = SQLite3.Changes(_conn.Handle);
                return(rowsAffected);
            }
            else if (r == SQLite3.Result.Error)
            {
                string msg = SQLite3.GetErrmsg(_conn.Handle);
                throw SQLiteException.New(r, msg);
            }
            else if (r == SQLite3.Result.Constraint)
            {
                if (SQLite3.ExtendedErrCode(_conn.Handle) == SQLite3.ExtendedResult.ConstraintNotNull)
                {
                    throw NotNullConstraintViolationException.New(r, SQLite3.GetErrmsg(_conn.Handle));
                }
            }

            throw SQLiteException.New(r, r.ToString());
        }
Ejemplo n.º 7
0
        public T ExecuteScalar <T>()
        {
            if (_conn.Trace)
            {
                Debug.WriteLine("Executing Query: " + this);
            }

            T val = default(T);

            var stmt = Prepare();

            try
            {
                var r = SQLite3.Step(stmt);
                if (r == SQLite3.Result.Row)
                {
                    var colType = SQLite3.ColumnType(stmt, 0);
                    val = (T)ReadCol(stmt, 0, colType, typeof(T));
                }
                else if (r == SQLite3.Result.Done)
                {
                }
                else
                {
                    throw SQLiteException.New(r, SQLite3.GetErrmsg(_conn.Handle));
                }
            }
            finally
            {
                Finalize(stmt);
            }

            return(val);
        }
Ejemplo n.º 8
0
 private ActionResult Handle(SQLiteException exception)
 {
     //todo: some logic handle sqlite exception
     return(new ViewResult {
         ViewName = "CustomError",
         ViewData = { Model = new FriendlyUserErrorMessage("Error", exception.Message, "contact to support") }
     });
 }
Ejemplo n.º 9
0
 private void HandleSQLite_Exception(SQLiteException e)
 {
     switch (e.ResultCode)
     {
     case SQLiteErrorCode.Constraint:
         throw new SQL_Exception(SQL_Exception_Type.Unique_Failed);
     }
 }
        //        protected static UserError Handle(Win32Exception ex, string action) {
        //            return ex.NativeErrorCode == Win32ErrorCodes.ERROR_CANCELLED_ELEVATION
        //                ? new CanceledUserError(action, innerException: ex)
        //                : Handle((Exception) ex, action);
        //        }

        protected static UserErrorModel Handle(SQLiteException ex, string action)
        {
            var message =
                $"There appears to be a problem with your database. If the problem persists, you can delete the databases from:\n{Common.Paths.LocalDataPath} and {Common.Paths.DataPath}" +
                "\nError message: " + ex.Message;
            var title = "An error has occured while trying to '" + action + "'";

            return(new UserErrorModel(title, message, innerException: ex));
        }
        public int ExecuteNonQuery(object[] source)
        {
            if (Initialized && Statement == NullStatement)
            {
                throw new ObjectDisposedException(nameof(PreparedSqlLiteInsertCommand));
            }
            if (Connection.IsClosed)
            {
                Connection.RenewConnection();
            }

            var r = SQLite3.Result.OK;

            if (!Initialized)
            {
                Statement   = SQLite3.Prepare2(Connection.Handle, CommandText);
                Initialized = true;
            }

            //bind the values.
            if (source != null)
            {
                for (int i = 0; i < source.Length; i++)
                {
                    SQLiteCommand.BindParameter(Statement, i + 1, source[i], Connection.StoreDateTimeAsTicks, Connection.DateTimeStringFormat, Connection.StoreTimeSpanAsTicks);
                }
            }
            r = SQLite3.Step(Statement);

            if (r == SQLite3.Result.Done)
            {
                int rowsAffected = SQLite3.Changes(Connection.Handle);
                SQLite3.Reset(Statement);
                return(rowsAffected);
            }
            else if (r == SQLite3.Result.Error)
            {
                string msg = SQLite3.GetErrmsg(Connection.Handle);
                SQLite3.Reset(Statement);
                throw SQLiteException.New(r, msg);
            }
            else if (r == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode(Connection.Handle) == SQLite3.ExtendedResult.ConstraintNotNull)
            {
                SQLite3.Reset(Statement);
                throw NotNullConstraintViolationException.New(r, SQLite3.GetErrmsg(Connection.Handle));
            }
            else if (r == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode(Connection.Handle) == SQLite3.ExtendedResult.ConstraintUnique)
            {
                SQLite3.Reset(Statement);
                throw NotNullConstraintViolationException.New(r, SQLite3.GetErrmsg(Connection.Handle));
            }
            else
            {
                SQLite3.Reset(Statement);
                throw SQLiteException.New(r, SQLite3.GetErrmsg(Connection.Handle));
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// 在qqlite控制台输出异常信息
        /// </summary>
        /// <param name="funcName">执行的函数名</param>
        /// <param name="E">异常</param>
        private static void PrintErrorMessage(string funcName, SQLiteException E)
        {
            string errorString = string.Format("Message:{0}\nSource:{1}\nTargetSite:{2}\nStackTrace:{3}",
                                               E.Message, E.Source, E.TargetSite.ToString(), E.StackTrace);

            QQLog.WriteLog(DbBase.RobotQQ, string.Format("{0} Error Begin", funcName));
            QQLog.WriteLog(DbBase.RobotQQ, errorString);
            QQLog.WriteLog(DbBase.RobotQQ, string.Format("{0} Error End", funcName));
        }
Ejemplo n.º 13
0
        public static IDbStatement Prepare2(IDbHandle db, string query)
        {
            IDbStatement stmt;
            var          r = Prepare2(db, query, query.Length, out stmt, IntPtr.Zero);

            if (r != Result.OK)
            {
                throw SQLiteException.New(r, GetErrmsg(db));
            }
            return(stmt);
        }
Ejemplo n.º 14
0
        public IDbStatement Prepare2(IDbHandle db, string query)
        {
            var internalDbHandle = (DbHandle)db;
            var r = SQLiteApiGenericInternal.sqlite3_prepare16_v2(internalDbHandle.DbPtr, query, -1, out IntPtr stmt, IntPtr.Zero);

            if (r != Result.OK)
            {
                throw SQLiteException.New(r, Errmsg16(internalDbHandle));
            }
            return(new DbStatement(stmt));
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Gets last error number.
        /// </summary>
        /// <returns>The error number it is known, -1 if unknown error occured, or zero on success.</returns>
        public override int GetLastErrorNumber()
        {
            if (LastException == null)
            {
                return(0);
            }

            SQLiteException e = LastException as SQLiteException;

            return((e != null) ? (int)e.ErrorCode : -1);
        }
Ejemplo n.º 16
0
        public static IntPtr Prepare2(IntPtr db, string query)
        {
            IntPtr stmt;
            var    r = Prepare2(db, query, query.Length, out stmt, IntPtr.Zero);

            if (r != SQLite3.Result.OK)
            {
                throw SQLiteException.New(r, GetErrmsg(db));
            }
            return(stmt);
        }
Ejemplo n.º 17
0
        public void Issue604_RecoversFromFailedCommit()
        {
            db.Trace = true;
            var initialCount = db.Table <TestObj> ().Count();

            //
            // Well this is an issue because there is an internal variable called _transactionDepth
            // that tries to track if we are in an active transaction.
            // The problem is, _transactionDepth is set to 0 and then commit is executed on the database.
            // Well, the commit fails and "When COMMIT fails in this way, the transaction remains active and
            // the COMMIT can be retried later after the reader has had a chance to clear"
            //
            var rollbacks = 0;

            db.Tracer = m => {
                if (m == "Executing: commit")
                {
                    throw SQLiteException.New(SQLite3.Result.Busy, "Make commit fail");
                }
                if (m == "Executing: rollback")
                {
                    rollbacks++;
                }
            };
            db.BeginTransaction();
            db.Insert(new TestObj());
            try {
                db.Commit();
                Assert.Fail("Should have thrown");
            }
            catch (SQLiteException ex) when(ex.Result == SQLite3.Result.Busy)
            {
                db.Tracer = null;
            }
            Assert.False(db.IsInTransaction);
            Assert.AreEqual(1, rollbacks);

            //
            // The catch statements in the RunInTransaction family of functions catch this and call rollback,
            // but since _transactionDepth is 0, the transaction isn't actually rolled back.
            //
            // So the next time begin transaction is called on the same connection,
            // sqlite-net attempts to begin a new transaction (because _transactionDepth is 0),
            // which promptly fails because there is still an active transaction on the connection.
            //
            // Well now we are in big trouble because _transactionDepth got set to 1,
            // and when begin transaction fails in this manner, the transaction isn't rolled back
            // (which would have set _transactionDepth to 0)
            //
            db.BeginTransaction();
            db.Insert(new TestObj());
            db.Commit();
            Assert.AreEqual(initialCount + 1, db.Table <TestObj> ().Count());
        }
Ejemplo n.º 18
0
        protected override bool IsTransactionFailure(Exception exception)
        {
            SQLiteException localException = exception as SQLiteException;

            if (localException != null)
            {
                return(IsTransactionFailure(localException.ErrorCode));
            }

            return(false);
        }
Ejemplo n.º 19
0
        public IDbStatement Prepare2(IDbHandle db, string query)
        {
            var dbHandle = (DbHandle)db;
            var stmt     = default(Sqlite3Statement);
            var r        = SQLite3.Prepare2(dbHandle.InternalDbHandle, query, query.Length, out stmt, IntPtr.Zero);

            if (r != Result.OK)
            {
                throw SQLiteException.New(r, SQLite3.GetErrmsg(dbHandle.InternalDbHandle));
            }
            return(new DbStatement(stmt));
        }
        private static InjectOutcomePolicy CreateRetryChaos(IPolicies policies)
        {
            var fault = new SQLiteException(
                (SQLiteErrorCode)ChaosPolicyShared.GetRandomEnum <RetryableSqlErrors>(),
                "Policy chaos testing");

            return(MonkeyPolicy.InjectException(with =>
                                                with.Fault(fault)
                                                .InjectionRate((context, token) => ChaosPolicyShared.InjectionRate(context, RetryConstants.RetryCount, RetryAttempts))
                                                .Enabled(policies.EnableChaos)
                                                ));
        }
Ejemplo n.º 21
0
        /// <summary>
        ///  Logs SQLiteExceptions
        /// </summary>
        /// <param name="sqlex">SQLiteException </param>
        private static void LogException(SQLiteException sqlex)
        {
            LogFile log = new LogFile();

            string errorMessage;

            errorMessage = "Exception Number : " + sqlex.ErrorCode +
                           "(" + sqlex.Message + ") has occurred";


            log.Create(errorMessage);
        }
Ejemplo n.º 22
0
        public IDbStatement Prepare2(IDbHandle db, string query)
        {
            var    internalDbHandle = (DbHandle)db;
            IntPtr stmt;
            Result r = SQLiteApiIOSInternal.sqlite3_prepare_v2(internalDbHandle.DbPtr, query, query.Length, out stmt, IntPtr.Zero);

            if (r != Result.OK)
            {
                throw SQLiteException.New(r, Errmsg16(internalDbHandle));
            }
            return(new DbStatement(stmt));
        }
Ejemplo n.º 23
0
        public IDbStatement Prepare2(IDbHandle db, string query)
        {
            var dbHandle = (DbHandle)db;
            var stmt     = new Sqlite3.Vdbe();

            int r = Sqlite3.sqlite3_prepare_v2(dbHandle.InternalDbHandle, query, -1, ref stmt, 0);

            if (r != 0)
            {
                throw SQLiteException.New((Result)r, GetErrmsg(db));
            }
            return(new DbStatement(stmt));
        }
Ejemplo n.º 24
0
            public static IntPtr Prepare2(IntPtr db, string query)
            {
                IntPtr stmt;

                byte[] queryBytes = Encoding.UTF8.GetBytes(query);
                var    r          = Prepare2(db, queryBytes, queryBytes.Length, out stmt, IntPtr.Zero);

                if (r != Result.OK)
                {
                    throw SQLiteException.New(r, GetErrmsg(db));
                }
                return(stmt);
            }
Ejemplo n.º 25
0
        private async Task RunIntegrityCheckAsync(Context context)
        {
            try
            {
                System.IO.FileInfo dbFileInfo = new System.IO.FileInfo(DatabaseFilePath.Path);
                Tracer.RecordSQLiteDatabaseSize(context, dbFileInfo.Length);

                // Getting file stats is supposed to be safe and should not interfere
                // with future file opens and reads.
            }
            catch (Exception exception)
            {
                Tracer.Error(context, exception, "Could not get file size of master DB");
            }

            try
            {
                Tracer.SQLiteIntegrityCheckStart(context);
                var integrityCheckWatch = Stopwatch.StartNew();
                await ExecuteReaderAsync(string.Empty, "PRAGMA integrity_check", reader =>
                {
                    const string integrityCheckOk = "ok";
                    var result = (string)reader[0];  // The reader should always have something to read, by design
                    if (result != integrityCheckOk)
                    {
                        integrityCheckWatch.Stop();
                        SQLiteException sqle = new SQLiteException(
                            SQLiteErrorCode.Corrupt,
                            $"Sqlite integrity check result expected to be [{integrityCheckOk}] but is instead [{result}]");
                        Tracer.SQLiteIntegrityCheckStopAtFailure(context, sqle, integrityCheckWatch.Elapsed);
                        throw sqle;
                    }

                    integrityCheckWatch.Stop();
                    Tracer.SQLiteIntegrityCheckStopAtSuccess(context, integrityCheckWatch.Elapsed);
                    return(ReadResponse.StopReadingIgnoreFurther);
                });
            }
            catch (Exception exception)
            {
                SQLiteException sqle = exception as SQLiteException;
                if (sqle != null && sqle.ResultCode == SQLiteErrorCode.Corrupt)
                {
                    throw sqle;
                }

                // else ignore and continue. Treat other exceptions as a failure to perform the check and not
                // a real integrity check failure.
                Tracer.Error(context, exception, "Unable to perform an integrity check");
            }
        }
Ejemplo n.º 26
0
        public async Task RecreateCorruptedDatabaseOnInnerCorruptException()
        {
            var mockStorageAdapter = Mock.Of <IStorageAdapter>();

            using (var storage = new Microsoft.AppCenter.Storage.Storage(mockStorageAdapter))
            {
                var exception = new StorageException(SQLiteException.New(SQLite3.Result.Corrupt, "Corrupt"));
                Mock.Get(mockStorageAdapter).Setup(adapter => adapter.InsertAsync(It.IsAny <LogEntry>())).Throws(exception);
                await Assert.ThrowsExceptionAsync <StorageException>(() => storage.PutLog(StorageTestChannelName, TestLog.CreateTestLog()));

                Mock.Get(mockStorageAdapter).Verify(adapter => adapter.DeleteDatabaseFileAsync());
                Mock.Get(mockStorageAdapter).Verify(adapter => adapter.InitializeStorageAsync(), Times.Exactly(2));
            }
        }
        public int ExecuteNonQuery(object[] source)
        {
            if (Connection.Trace)
            {
                Debug.WriteLine("Executing: " + CommandText);
            }

            var r = SQLite3.Result.OK;

            if (!Initialized)
            {
                Statement   = Prepare();
                Initialized = true;
            }

            //bind the values.
            if (source != null)
            {
                for (int i = 0; i < source.Length; i++)
                {
                    // TODO: Handle null case
                    var sqlType = SQLite3.GetSQLiteType(source[i].GetType());
                    sqlType.Bind(Statement, i + 1, source[i], Connection.StoreDateTimeAsTicks);
                }
            }
            r = SQLite3.Step(Statement);

            if (r == SQLite3.Result.Done)
            {
                int rowsAffected = SQLite3.Changes(Connection.Handle);
                SQLite3.Reset(Statement);
                return(rowsAffected);
            }
            else if (r == SQLite3.Result.Error)
            {
                string msg = SQLite3.GetErrmsg(Connection.Handle);
                SQLite3.Reset(Statement);
                throw SQLiteException.New(r, msg);
            }
            else if (r == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode(Connection.Handle) == SQLite3.ExtendedResult.ConstraintNotNull)
            {
                SQLite3.Reset(Statement);
                throw NotNullConstraintViolationException.New(r, SQLite3.GetErrmsg(Connection.Handle));
            }
            else
            {
                SQLite3.Reset(Statement);
                throw SQLiteException.New(r, r.ToString());
            }
        }
Ejemplo n.º 28
0
        public IDbStatement Prepare2(IDbHandle db, string query)
        {
            var dbHandle = (DbHandle)db;
            var stmt     = default(Sqlite3Statement);

            int queryByteCount = Encoding.UTF8.GetByteCount(query);
            int r = (int)NativeMethods.Prepare2(dbHandle.InternalDbHandle, query, queryByteCount, out stmt, default(IntPtr));

            if (r != 0)
            {
                throw SQLiteException.New((Result)r, GetErrmsg(db));
            }
            return(new DbStatement(stmt));
        }
Ejemplo n.º 29
0
        //
        // WriteToEventLog
        //   A helper function that writes exception detail to the event log. Exceptions
        // are written to the event log as a security measure to avoid private database
        // details from being returned to the browser. If a method does not return a status
        // or boolean indicating the action succeeded or failed, a generic exception is also
        // thrown by the caller.
        //


        private void WriteToEventLog(SQLiteException e, string action)
        {
            EventLog log = new EventLog();

            log.Source = eventSource;
            log.Log    = eventLog;

            string message = exceptionMessage + "\n\n";

            message += "Action: " + action + "\n\n";
            message += "Exception: " + e.ToString();

            log.WriteEntry(message);
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Executes the statement
        /// </summary>
        public static void ExecutePreparedNonQuery(this IDbStatement me, bool reuse = true)
        {
            var sqlite3 = ApplicationContext.Current.GetService <ISQLitePlatform>().SQLiteApi;
            var r       = sqlite3.Step(me);

            if (r != Result.Done)
            {
                throw SQLiteException.New(r, "Error executing SQLite prepared statement");
            }
            if (reuse)
            {
                sqlite3.Reset(me);
            }
        }
        public void TestReadOnlyDB()
        {
            Exception exception = null;
            var numRecords = this.rnd.Next(1, 11);

            var insertedRecords = new List<Tuple<int, long, string, double>>(numRecords);
            var queriedRecords = new List<Tuple<int, long, string, double>>(numRecords);

            for (var i = 0; i < numRecords; i++)
            {
                insertedRecords.Add(new Tuple<int, long, string, double>(i, this.GetRandomInteger(), this.GetRandomString(), this.GetRandomReal()));
            }

            using (var connection = new SQLiteConnection(this.databaseRelativePath, SQLiteOpen.READWRITE))
            {
                using (var statement = connection.Prepare("DROP TABLE IF EXISTS TestReadOnlyDB;"))
                {
                    statement.Step();
                }

                using (var statement = connection.Prepare("CREATE TABLE TestReadOnlyDB(id INTEGER, i INTEGER, t TEXT, r REAL);"))
                {
                    statement.Step();
                }

                foreach (var record in insertedRecords)
                {
                    var command = "INSERT INTO TestReadOnlyDB(id, i, t, r) VALUES(" + record.Item1.ToString(this.invClt) + "," + record.Item2.ToString(this.invClt)
                        + ",'" + record.Item3 + "'," + record.Item4.ToString(this.invClt) + ");";

                    using (var statement = connection.Prepare(command))
                    {
                        statement.Step();
                    }
                }
            }

            using (var connection = new SQLiteConnection(this.databaseRelativePath, SQLiteOpen.READONLY))
            {
                foreach (var record in insertedRecords)
                {
                    var command = "SELECT id, i, t, r FROM TestReadOnlyDB WHERE id = " + record.Item1.ToString(this.invClt) + " AND i = " + record.Item2.ToString(this.invClt)
                        + " AND t = '" + record.Item3 + "' AND r = " + record.Item4.ToString(this.invClt) + ";";

                    using (var statement = connection.Prepare(command))
                    {
                        while (statement.Step() == SQLiteResult.ROW)
                        {
                            var id = (long)statement[0];
                            var i = (long)statement[1];
                            var t = (string)statement[2];
                            var r = (double)statement[3];

                            queriedRecords.Add(new Tuple<int, long, string, double>((int)id, i, t, r));
                        }
                    }
                }

                using (var statement = connection.Prepare("DROP TABLE TestReadOnlyDB;"))
                {
                    var result = statement.Step();

                    if (result == SQLiteResult.READONLY)
                    {
                        exception = new SQLiteException(connection.ErrorMessage());
                    }
                    else
                    {
                        throw new SQLiteException(connection.ErrorMessage());
                    }
                }
            }

            using (var connection = new SQLiteConnection(this.databaseRelativePath, SQLiteOpen.READWRITE))
            {
                using (var statement = connection.Prepare("DROP TABLE TestReadOnlyDB;"))
                {
                    var result = statement.Step();

                    if (result != SQLiteResult.DONE)
                    {
                        throw new SQLiteException(connection.ErrorMessage());
                    }
                }
            }

            Assert.AreEqual(insertedRecords.Count, queriedRecords.Count);

            insertedRecords.Sort((x, y) => { return x.Item1 - y.Item1; });
            queriedRecords.Sort((x, y) => { return x.Item1 - y.Item1; });

            for (var i = 0; i < insertedRecords.Count; i++)
            {
                var insertedRecord = insertedRecords[i];
                var queriedRecord = queriedRecords[i];

                Assert.AreEqual(insertedRecord.Item1, queriedRecord.Item1);
                Assert.AreEqual(insertedRecord.Item2, queriedRecord.Item2);
                Assert.AreEqual(insertedRecord.Item3, queriedRecord.Item3);
                Assert.IsTrue(Math.Abs(insertedRecord.Item4 - queriedRecord.Item4) <= Math.Abs(insertedRecord.Item4 * 0.0000001));
            }

            Assert.IsNotNull(exception);
        }
        //        protected static UserError Handle(Win32Exception ex, string action) {
        //            return ex.NativeErrorCode == Win32ErrorCodes.ERROR_CANCELLED_ELEVATION
        //                ? new CanceledUserError(action, innerException: ex)
        //                : Handle((Exception) ex, action);
        //        }

        protected static UserErrorModel Handle(SQLiteException ex, string action) {
            var message =
                $"There appears to be a problem with your database. If the problem persists, you can delete the databases from:\n{Common.Paths.LocalDataPath} and {Common.Paths.DataPath}" +
                "\nError message: " + ex.Message;
            var title = "An error has occured while trying to '" + action + "'";
            return new UserErrorModel(title, message, innerException: ex);
        }