1

I have created a xamarin.forms application and ship a sqlite database with the application, im getting the following error:

database disk image is malformed.

This is the stacktrace:

SQLite3.Prepare2 (SQLitePCL.sqlite3 db, System.String query)
SQLiteCommand.Prepare ()
SQLiteCommand+<ExecuteDeferredQuery>d__12`1[T].MoveNext ()
List`1[T].AddEnumerable (System.Collections.Generic.IEnumerable`1[T] enumerable)
System.Collections.Generic.List`1[T]..ctor (System.Collections.Generic.IEnumerable`1[T] collection) [0x00062] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
Enumerable.ToList[TSource] (System.Collections.Generic.IEnumerable`1[T] source)
SQLiteCommand.ExecuteQuery[T] ()
SQLiteConnection.Query[T] (System.String query, System.Object[] args)
SQLiteAsyncConnection+<>c__DisplayClass28_0`1[T].<QueryAsync>b__0 ()
Task`1[TResult].InnerInvoke ()
Task.Execute ()
MyApp+<LoadDocFromDB>d__18.MoveNext ()
VolumeView+<VolumesListView_ItemSelected>d__13.MoveNext ()
AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state)
SyncContext+<>c__DisplayClass2_0.<Post>b__0 ()
Thread+RunnableImplementor.Run ()
IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) System.Object.17(intptr,intptr)

this is happening on both Xamarin iOS and Xamarin Android.

the xamarin forms versions i use are: 4.3.0.947036

i use the following sqlite packages: SQLiteNetExtensions version 2.1.0 SQLiteNetExtensions.Async version 2.1.0

this is the following code that is crashing:

public static async Task LoadDocFromDB(string volume, int chapterNr)
{
    if(dbPath == null)
    {
        dbPath = await DependencyService.Get<IDatabaseAccess>().DatabasePathAsync(false,"Data");
    }
    var connection = new SQLiteAsyncConnection(dbPath, SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.ReadWrite);
    IRepository<Doc> repository = new DocRepository<Doc>(connection);
    try
    {
        var docMetadata = await repository.QueryAsync($"SELECT * FROM [Docs] WHERE [volume] == '{volume}' AND [chapterNr] == '{chapterNr}'");
        LoadedDoc = await repository.GetWithChildrenAsync(docMetadata.First().chapterID);
        await repository.DisposeDbConnectionAsync();
    }
    catch (Exception ex)
    {
        throw;
    }
    await Task.FromResult(0);
}

this is the DisposeDbConnectionAsync() method implementation:

public async Task DisposeDbConnectionAsync()
        {
            using (await _mutex.LockAsync()) //from the Nito.AsyncEx library
            {
                if (dbConnection != null)
                {
                    dbConnection.GetConnection().Close();
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    dbConnection.GetConnection().Dispose();
                    SQLite.SQLiteAsyncConnection.ResetPool();
                    dbConnection = null;
                }
            }
        }

This seem to happen sometimes, any clue what might be causing this?

I have also run a Pragma integrity check on the database and its was ok, no issues.

thanks for all the help!

2
  • I've never seen that, but I assume that the sqlite database must be corrupt Commented Dec 14, 2019 at 23:12
  • I think one it might be some data in database file such as migrations table is missing. Commented Dec 15, 2019 at 8:49

2 Answers 2

2

I had the same problem, after a lot research, the problem was related with the SQL file saving checks. I recommend you do the following checks:

  • Always check if already exists a SQL file before overwrite;
  • Always delete the SQL file before save new one with the same name;
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks i will try this as well!
1

I have not found the solution for this exception, however i solved it in my application by catching the exception and then in the catch clause removing the corrupt database from the specialfolders, and copy in a new copy of the database to the special folders, this solved the issue and the app stopped crashing at least.

The exception might have been caused by some corruption during an initial copy of the database. Hope this helps anyone facing the same issue!

2 Comments

How do you ensure your copy is not also corrupt? do you always have a copy of the database on hand to use for when it gets corrupted? Any sample code would be appreciated/helpful. :)
Yes i keep a copy of the database since i need to copy the database over to special folders the first time the application is started after someone installs the app. I will try to share some sample code as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.