SQLitePCL.raw: Unable to use the new "SQLitePCL.raw.sqlite3_config()" to set threading mode

Steps to reproduce

  1. Create a new solution with a PCL project (in my case profile 259).
  2. Add a platform specific project with a dependency to the PCL (in my case Android).
  3. Add necessary packages to those projects to use the bundle green edition.
  4. From the PCL code, configure SQLite in serialized mode:
SQLitePCL.Batteries.Init();
var result = SQLitePCL.raw.sqlite3_config(SQLitePCL.raw.SQLITE_CONFIG_SERIALIZED);
if (result != SQLitePCL.raw.SQLITE_OK)
{
    System.Diagnostics.Debug.WriteLine($"Unable to set SQLIte in Serialized mode (error code = {result})");
}

Expected result As I am understanding that bundles and providers are used to inject platform specific bits from the PCL by using bait/switch, this should be considered a possible case.

Actual result Config call is failing and returning a SQLITE_MISUSE error.

Remarks SQLite serialized mode cannot be set after SQLitePCL.Batteries.Init() or SQLitePCL.raw.SetProvider() as this last call try to open then close the DB which internally init the SQLite library. Once SQLite has been initialized, this is no longer permitted to use config to set the threading mode and result in a misuse error. Even by doing so at the platform level, SQLitePCL.raw.sqlite3_config() still requires to call Init or SetProvider first, which prevent usage.

I am not sufficiently experienced with SQLite and your libraries to determine if there is an other way to validate the lib injection other than by opening/closing it…

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 16 (7 by maintainers)

Most upvoted comments

The pre-release of 1.1.1 (now on nuget.org) addresses this issue.

raw.SetProvider() no longer calls open/close, so sqlite3_initialize() should not end up getting called.

For WinRT-ish platforms, we still have the problem that the pinvoke provider constructor calls sqlite3_win32_set_directory(), and I can’t remove those calls without breaking apps. The workaround for that is to call sqlite3_shutdown(), then sqlite3_config(), then re-call sqlite3_win32_set_directory, which is now made available for that purpose.

@EnglishDave OK, but just to clarify, as of 1.1.1, released today, SetProvider() no longer indirectly calls sqlite3_initialize(), so Batteries.Init() does not either.

Unrelated to whether this should work, I’m curious why you are electing to use SQLite’s serialized thread mode, as opposed to doing explicit locking in your application, or using a higher level library that guarantees thread safety?

A given SQLite connection isn’t really meant to be used from multiple threads at the same time, hence the thread safe mode adds locks to all api calls. In this mode you need to be careful not to make SQLite calls from the mainloop of your application (assuming this is a mobile app), to avoid blocking the UI. To avoid this issue, Akavache, SQLite-net, and SQLitePCL.pretty all use variants of an internal scheduler to queue and schedule work for a given SQLite DB connection, dispatched to a task pool thread.