Bug 652 - There is no way to call sqlite3_config() in the Mono.Data.Sqlite library.
Summary: There is no way to call sqlite3_config() in the Mono.Data.Sqlite library.
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 4.x
Hardware: Other Other
: --- enhancement
Target Milestone: Untriaged
Assignee: Sebastien Pouliot
Depends on:
Reported: 2011-09-06 13:55 UTC by zachbarth
Modified: 2011-12-16 08:26 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

updated assembly (165.50 KB, application/octet-stream)
2011-09-19 10:56 UTC, Sebastien Pouliot
updated assembly with fix (165.50 KB, application/octet-stream)
2011-09-24 10:02 UTC, Sebastien Pouliot

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description zachbarth 2011-09-06 13:55:09 UTC
There is currently no way to call sqlite3_config() in the Mono.Data.Sqlite library. This prevents programs from being able to set the threading mode to SQLITE_CONFIG_SERIALIZED.

This is a different library than what Mono.Data.Sqlite is based on, but here is a similar bug and fix: 


Comment 1 Sebastien Pouliot 2011-09-12 17:15:57 UTC
I'll look at adding it (it's more a testing than a coding task) for future version of MonoTouch. 

However this should not block you (or your application) since you can copy/paste the same few lines into your own application (it does not require any internal handle to be called) and call it before opening your database.
Comment 2 zachbarth 2011-09-13 17:01:17 UTC
The workaround mentioned above works perfectly. Thanks!
Comment 3 Sebastien Pouliot 2011-09-18 10:18:40 UTC
In Mono.Data.Sqlite.dll the base class (SQLiteBase and SQLiteBase) are internals. Would adding a SetConfig in SqliteConnection (as a static method) makes sense to you ? or would be it easier to discover elsewhere ? 

E.g. > Mono.Data.Sqlite.SqliteConnection.SetConfig (Mono.Data.Sqlite.SQLiteConfig.Serialized);

If this seems coorect then I'll attach an assembly with the extra method (including the earlier fix for bug #233) so you might be able to test it with your application.
Comment 4 zachbarth 2011-09-18 13:06:24 UTC
The first place I looked for this functionality was in the Mono.Data.Sqlite namespace to see if a static class existed purely for this purpose. The second place I looked was in SqliteConnection. I think either would be fine?
Comment 5 Sebastien Pouliot 2011-09-19 10:56:47 UTC
Created attachment 425 [details]
updated assembly

Please try this assembly and let me know if it works like you expected. If so I'll push my changes to GIT so this will become part of future MT (and Mono) releases. Thanks!

note: this assembly includes the previous changes from #233
Comment 6 zachbarth 2011-09-19 12:37:21 UTC
The sqlite3_config() function returns an error code indicating whether it was successful or not, which is particularly relevant if you don't know when sqlite3_initialize() is being called behind the scenes (http://www.sqlite.org/c3ref/config.html). The SetConfig() function in this assembly does not return anything. Since the problem we were seeing that required access to this function was a non-deterministic database corruption, checking this return value for success is the best way to verify that the function works as expected (since the rest is up to the underlying sqlite3 library and is assumed to work).

Also, I don't think that SQLiteConfig.None (which maps to 0) corresponds to a real configuration option (at least, according to http://www.sqlite.org/c3ref/c_config_getmalloc.html).
Comment 7 Sebastien Pouliot 2011-09-22 20:11:10 UTC
Good point. I was not surehow common it would be and it seems many (most?) of the error code returned by sqlite3_* functions are turned into SqliteException (or ignored) with something like:

      if (n > 0) throw new SqliteException(n, SQLiteLastError());

Throwing one means you would get an SqliteException you know you could not set the configuration to your liking. Would that be better ?

> Also, I don't think that SQLiteConfig.None (which maps to 0)

No, it does not exists. I added it (by second nature) because of: "CA1008: Enums should have zero value", ref: http://msdn.microsoft.com/en-us/library/ms182149(v=VS.100).aspx

I can drop it since it would (at least) need an extra check in the SetConfig call (to avoid errors) and (anyway) it's not a terrible API mistake :-)
Comment 8 zachbarth 2011-09-23 14:00:45 UTC
If the other sqlite3_* functions convert non-zero error codes into Exceptions then it makes sense to do that for sqlite3_config as well. This seems like a good change!
Comment 9 Sebastien Pouliot 2011-09-24 10:02:31 UTC
Created attachment 484 [details]
updated assembly with fix
Comment 10 Sebastien Pouliot 2011-09-24 10:03:58 UTC
Fixed in mono 'master', 'mono-2-10' and monotouch 'mobile-master'
Comment 11 René Ruppert 2011-12-16 08:11:16 UTC
I tried the assembly. I can call the SetConfig(), I don't get an exception but it does not solve my multithreading issue either. I still get a lock exception while trying to update a row form a table that is currently being read by a reader. I also tried to invoke directly and get a "21" as return value, that indicates "Incorrect usage of Library". I assume the same is happening with this assembly. Any ideas?
Comment 12 Sebastien Pouliot 2011-12-16 08:26:21 UTC
Have a look at http://www.sqlite.org/c3ref/config.html

<quote>Furthermore, sqlite3_config() may only be invoked prior to library initialization using sqlite3_initialize() or after shutdown by sqlite3_shutdown(). If sqlite3_config() is called after sqlite3_initialize() and before sqlite3_shutdown() then it will return SQLITE_MISUSE.</quote>

This means you should call this method as soon as possible inside your application. Once initialized SQLite won't change its mind.