Ticket Hash: | b30dcd10afbe52050b6ab2ef07b90cb14608e9b3 | |||
Title: | Error when loading an extension... | |||
Status: | Closed | Type: | Incident | |
Severity: | Important | Priority: | Medium | |
Subsystem: | Connection | Resolution: | Works_As_Designed | |
Last Modified: | 2016-10-31 01:38:12 | |||
Version Found In: | 1.0.103 | |||
User Comments: | ||||
anonymous added on 2016-09-15 15:36:03:
(text/x-fossil-plain)
LoadExtension("SQLite.Interop.dll", "sqlite3_fts_init"); System.Data.SQLite.SQLiteException occurred HResult=-2147467259 Message=SQL logic error or missing database error during initialization: Source=System.Data.SQLite ErrorCode=1 StackTrace: at System.Data.SQLite.SQLite3.LoadExtension(String fileName, String procName) at ApplicationServices.Factories.ConnectionDataFactory.<CreateConnectionAsync>d__9.MoveNext() in C:\Dropbox\SoftLAnd\Project\VS13\TOTKSilverlight\Goods\ApplicationServices\Factories\ConnectionDataFactory.cs:line 111 InnerException: anonymous added on 2016-09-15 15:43:26: (text/x-fossil-plain) connection.Pooling = true; recreateconnection mistachkin added on 2016-09-15 19:52:13: (text/x-fossil-plain) I'm a bit confused about this ticket. First, when calling the LoadExtension method, you will almost certainly need to pass the fully qualified path to the "SQLite.Interop.dll" file. Also, I have a couple questions: 1. Which extension are you trying to load? 2. Are you actually using connection pooling? anonymous added on 2016-09-15 20:22:43: (text/x-fossil-plain) Example defect code. using System; using System.Linq; using System.Data.SQLite; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var cs = "data source=:memory:;pooling=True;"; var path = Environment.Is64BitProcess ? "x64" : "x86"; var dllFullFileName = Path.Combine(path, "SQLite.Interop.dll"); foreach (var i in Enumerable.Range(0, 10)) { using (var connection = new SQLiteConnection(cs)) { connection.Open(); connection.EnableExtensions(true); connection.LoadExtension(dllFullFileName, "sqlite3_fts5_init"); connection.EnableExtensions(false); } } } } } mistachkin added on 2016-09-16 03:14:55: (text/x-fossil-plain) Off hand, I can tell you that connection pooling does not interact well with the load extension mechanism. I think System.Data.SQLite prevents connections that use extensions from entering (or re-entering) the pool. mistachkin added on 2016-09-16 03:20:13: (text/x-fossil-plain) Ok, I appear to be wrong. It's CreateModule that disables the pool. mistachkin added on 2016-09-16 03:37:40: (text/x-fossil-plain) Thanks for the example code. Reproduced the error message locally. mistachkin added on 2016-09-16 03:44:41: (text/x-fossil-plain) The root cause of the error is trying to load an extension into a connection that already has it (i.e. due to it being from the pool). To be specific: 1. Connection #1 is opened fresh. 2. Connection #1 loads the FTS5 extension. 3. Connection #1 is closed -AND- added to the connection pool. 4. Connection #2 is opened from the pool (with FTS5 already loaded). 5. An attempt is made to load the FTS5 extension into Connection #2. 6. Exception is thrown. mistachkin added on 2016-09-16 03:47:45: (text/x-fossil-plain) I see three workarounds to this issue: 1. Avoid using Pooling=True when you plan to load extensions. 2. Check if an extension is already loaded prior to calling LoadExtension (e.g. by trying to use something that it adds to the connection). 3. Wrap the LoadExtension calls in a try/catch and ignore exceptions (this is the most problematic workaround because LoadExtension can fail for reasons other than the extension already being loaded). |