Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
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
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.
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:
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.
The workaround mentioned above works perfectly. Thanks!
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.
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?
Created attachment 425 [details]
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
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).
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 :-)
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!
Created attachment 484 [details]
updated assembly with fix
Fixed in mono 'master', 'mono-2-10' and monotouch 'mobile-master'
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?
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.