Skip to content

Using multiple libraries that use SQLitePCL.raw

Eric Sink edited this page Jan 4, 2017 · 1 revision

TL;DR

In some cases, you can get problems when using multiple packages that use SQLitePCL.raw (such as Akavache, sqlite-net-pcl, Azure Mobile Services offline sync, etc).

When this happens, add these two lines somewhere in your app initialization, before any of those packages get a chance to do anything:

SQLitePCL.Batteries_V2.Init();
SQLitePCL.raw.FreezeProvider();

Details

The SQLitePCL.raw library needs to be initialized by calling SQLitePCL.raw.SetProvider().

(In practice, this is usually done by calling SQLitePCL.Batteries_V2.Init(). SetProvider() is the low-level init call. The higher-level call comes from the so-called "batteries included" bundle packages which are more convenient to use.)

(Batteries_V2.Init() does exactly the same thing as the original Batteries.Init(), but the V2 version is preferred because it supports bait-and-switch across different bundle types.)

SetProvider() wants to be called only once, during the app initialization. If you call SetProvider(), and then use the SQLitePCL.raw library to do some stuff, and then call SetProvider() again, your app might do something bad. Like crash.

SQLitePCL.raw is used by a number of other packages. Such packages could choose to take a dependency on the SQLitePCL.raw core library and document the need to initialize it. But in most cases, the maintainers of those packages prefer to spare their users the burden of initializing SQLitePCL.raw. So they take a dep on a bundle package and call its batteries init() function. And if there are two such packages in play, SQLitePCL.raw can get initialized twice.

Which is often not a problem. If both init calls happen early, before anything else, it doesn't matter.

But in cases where this is a problem...

The solution is for you, the app developer, to initialize SQLitePCL.raw yourself, and then call SQLitePCL.raw.FreezeProvider(), which means "ignore all future calls to SetProvider()".

BTW

If you maintain a library which uses SQLitePCL.raw, you should not call FreezeProvider(). This method is only there to give ultimate control over SQLitePCL.raw initialization to the app.