Richard Hipp or Igor Tadetnik, Here is the C# code for Microsoft.Data.Sqlite.dll, designed for .NET users on Ubuntu Linux and Windows, I am using the latest version of libsqlite3.so compiled as follows;
gcc -shared -g -o libsqlite3.so -fPIC sqlite3.c I was able to get sqlite3_exec running properly calling it from an C# DLLImport when I run mono Program.exe However, I am getting the following exception which says the return value is being returned by slqite3_prepare_v2 is incorrect: --- End of inner exception stack trace --- at Microsoft.Data.Sqlite.Interop.MarshalEx.ThrowExceptionForRC (Int32 rc, Microsoft.Data.Sqlite.Interop.Sqlite3Handle db) <0x414bfb70 + 0x0008f> in <filename unknown>:0 at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader (CommandBehavior behavior) <0x414c09e0 + 0x0022f> in <filename unknown>:0 at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader () <0x414c09b0 + 0x00015> in <filename unknown>:0 at Microsoft.Data.Sqlite.SqliteCommand.ExecuteNonQuery () <0x414c0860 + 0x0005e> in <filename unknown>:0 at Microsoft.Data.Sqlite.Tests.Program.ManagedWrapperMainOne (System.String Name) <0x414bbea0 + 0x0019b> in <filename unknown>:0 at Microsoft.Data.Sqlite.Tests.Program.Main () <0x414bbd50 + 0x00013> in <filename unknown>:0 public static int sqlite3_prepare_v2(Sqlite3Handle db, string zSql, out Sqlite3StmtHandle ppStmt, out string pzTail) { int nByte; var zSqlPtr = MarshalEx.StringToHGlobalUTF8(zSql, out nByte); try { // TODO: Something fancy with indexes? IntPtr pzTailPtr; var rc = sqlite3_prepare_v2(db, zSqlPtr, nByte, out ppStmt, out pzTailPtr); pzTail = MarshalEx.PtrToStringUTF8(pzTailPtr); return rc; } finally { Marshal.FreeHGlobal(zSqlPtr); } } public new virtual SqliteDataReader ExecuteReader(CommandBehavior behavior) { if ((behavior & ~(CommandBehavior.Default | CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection)) != 0) { throw new ArgumentException(Strings.FormatInvalidCommandBehavior(behavior)); } if (Connection == null || Connection.State != ConnectionState.Open) { throw new InvalidOperationException(Strings.FormatCallRequiresOpenConnection("ExecuteReader")); } if (string.IsNullOrEmpty(CommandText)) { throw new InvalidOperationException(Strings.FormatCallRequiresSetCommandText("ExecuteReader")); } if (Transaction != Connection.Transaction) { throw new InvalidOperationException( Transaction == null ? Strings.TransactionRequired : Strings.TransactionConnectionMismatch); } //TODO not necessary to call every time a command is executed. Only on first command or when timeout changes NativeMethods.sqlite3_busy_timeout(Connection.DbHandle, CommandTimeout * 1000); var hasChanges = false; var changes = 0; var stmts = new Queue<Tuple<Sqlite3StmtHandle, bool>>(); var tail = CommandText; do { Sqlite3StmtHandle stmt; var rc = NativeMethods.sqlite3_prepare_v2( Connection.DbHandle, tail, out stmt, out tail); MarshalEx.ThrowExceptionForRC(rc, Connection.DbHandle); // Statement was empty, white space, or a comment if (stmt.IsInvalid) { if (!string.IsNullOrEmpty(tail)) { continue; } break; } var boundParams = 0; if (_parameters.IsValueCreated) { boundParams = _parameters.Value.Bind(stmt); } var expectedParams = NativeMethods.sqlite3_bind_parameter_count(stmt); if (expectedParams != boundParams) { var unboundParams = new List<string>(); for (var i = 1; i <= expectedParams; i++) { var name = NativeMethods.sqlite3_bind_parameter_name(stmt, i); if (_parameters.IsValueCreated || !_parameters.Value.Cast<SqliteParameter>().Any(p => p.ParameterName == name)) { unboundParams.Add(name); } } throw new InvalidOperationException(Strings.FormatMissingParameters(string.Join(", ", unboundParams))); } try { var timer = Stopwatch.StartNew(); while (SQLITE_LOCKED == (rc = NativeMethods.sqlite3_step(stmt))) { if (timer.ElapsedMilliseconds >= CommandTimeout * 1000) { break; } NativeMethods.sqlite3_reset(stmt); } MarshalEx.ThrowExceptionForRC(rc, Connection.DbHandle); } catch { stmt.Dispose(); throw; } // NB: This is only a heuristic to separate SELECT statements from INSERT/UPDATE/DELETE statements. It will result // in unexpected corner cases, but it's the best we can do without re-parsing SQL if (NativeMethods.sqlite3_stmt_readonly(stmt) != 0) { stmts.Enqueue(Tuple.Create(stmt, rc != SQLITE_DONE)); } else { hasChanges = true; changes += NativeMethods.sqlite3_changes(Connection.DbHandle); stmt.Dispose(); } } while (!string.IsNullOrEmpty(tail)); var closeConnection = (behavior & CommandBehavior.CloseConnection) != 0; return new SqliteDataReader(Connection, stmts, hasChanges ? changes : -1, closeConnection); } Here is my SQL statement: var connMaryStr = new SqliteConnectionStringBuilder() { DataSource = new Uri("file:db.sqlite",UriKind.Relative).ToString() }; SqliteConnection connection = new SqliteConnection (connMaryStr.ConnectionString); //"Filename=/home/venkat/Sandbox/mydb.db"); connection.Open(); var insertCommand = new SqliteCommand("INSERT INTO message ( text ) VALUES (\"Hello World!\")",connection); insertCommand.ExecuteNonQuery(); insertCommand.Close(); Any help is greatly appreciated. 3:28 AM (2 minutes ago)