Giter VIP home page Giter VIP logo

sqlitepcl.raw's Introduction

SQLitePCLRaw

SQLitePCLRaw is a Portable Class Library (PCL) for low-level (raw) access to SQLite. License: Apache License v2.

Version 2.0

SQLitePCLRaw 2.0 is a major release. See the release notes for more information.

Compatibility

As of version 2.0, SQLitePCLRaw requires NetStandard2.0:

  • Xamarin.Android
  • Xamarin.iOS
  • UWP
  • .NET Framework 4.6.1 or higher, preferably 4.7.2
  • Linux with Mono
  • MacOS with Mono
  • .NET Core 3.1, .NET 5.x and up, etc
  • NetStandard 2.0

How the packaging works

The main assembly is SQLitePCLRaw.core. A portable library project would need to only take a dep on this one. All the other packages deal with initialization and the question of which instance of the native SQLite library is involved.

Many different native SQLite libraries

In some cases, apps use a SQLite library which is externally provided. In other cases, an instance of the SQLite library is bundled with the app.

  • On iOS, there is a SQLite library provided with the operating system, and apps are allowed to use it.

  • Android also has a SQLite library, and prior to Android N, apps were allowed to use it.

  • Recent versions of Windows 10 have a SQLite library.

  • In some cases, people want to use SQLCipher as their SQLite library.

  • Sometimes people want to compile and bundle their own custom SQLite library.

SQLitePCLRaw supports any of these cases.

Providers

In this context, a "provider" is the piece of code which tells SQLitePCLRaw which instance of the native code to use.

More specifically, a "provider" is an implementation of the ISQLite3Provider interface. It is necessary to call SQLitePCL.raw.SetProvider() to initialize things.

The SQLitePCLRaw.core package contains no providers.

All the various providers are in packages with ids of the form SQLitePCLRaw.provider.*.

Provider names

There is a dynamic provider which does not use a hard-coded DllImport string. This one is used as often as possible.

The DllImport-based providers are named for the exact string which is used for DllImport (pinvoke).

For example:

[DllImport("foo")]
public static extern int whatever();

This pinvoke will look for a library called "foo".

  • On Windows, that means "foo.dll".
  • On Unix, "libfoo.so"
  • On MacOS, "libfoo.dylib"

(The actual rules are more complicated than this.)

So, a provider where all the DllImport attributes were using "foo", would have "foo" in its package id and in its class name.

Included providers

SQLitePCLRaw includes the following providers:

  • "dynamic" -- Uses dynamic loading of the native library instead of DllImport attributes.

  • "e_sqlite3" -- This is the name of all SQLite builds provided as part of this project.

  • "e_sqlcipher" -- This is the name of the unofficial and unsupported SQLCipher builds which are provided as part of this project.

  • "sqlite3" -- This matches the name of the system-provided SQLite on iOS (which is fine), and Android (which is not allowed). And it matches the official name of builds provided at sqlite.org.

  • "sqlcipher" -- Intended to be used for official SQLCipher builds from Zetetic.

  • "winsqlite3" -- Matches the name of the library provided by recent builds of Windows 10.

SQLitePCLRaw.lib

A provider is the bridge between the core assembly and the native code, but the provider does not contain the native code itself.

In some cases (like "winsqlite3") this is because it does not need to. The provider is merely a bridge to a SQLite library instance which is known (or assumed) to be somewhere else.

But in cases where the app is going to be bundling the native code library, those bits need to make it into your build output somehow.

Packages with ids named "SQLitePCLRaw.lib.*" contain native code. This project distributes two kinds of these packages:

  • "e_sqlite3" -- These are builds of the SQLite library provided for the convenience of SQLitePCLRaw users. I try to keep them reasonably current with respect to SQLite itself (www.sqlite.org). The build configuration is the same for every platform, and includes full-text-search. If you are building an app on multiple platforms and you want to use the same recent version of SQLite on each platform, e_sqlite3 should be a good choice.

  • "e_sqlcipher" -- These are unofficial and unsupported builds of the open source SQLCipher code.

The build scripts for both of the above are in the ericsink/cb repo.

A trio of packages

So, using SQLitePCLRaw means you need to add two packages:

  • SQLitePCLRaw.core
  • SQLitePCLRaw.provider.whatever

And in many cases one of these as well:

  • SQLitePCLRaw.lib.whatever

And in your platform-specific code, you need to call:

SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_whatever());

But the word "whatever" is different on each platform. For example, on Android, using e_sqlite3, you need:

  • SQLitePCLRaw.core
  • SQLitePCLRaw.provider.e_sqlite3.android
  • SQLitePCLRaw.lib.e_sqlite3.android

and you need to call:

SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_e_sqlite3());

Bundles

To make things easier, SQLitePCLRaw includes "bundle" packages. These packages automatically bring in the right dependencies for each platform. They also provide a single Init() call that is the same for all platforms.

Think of a bundle as way of giving a "batteries included" experience.

So for example, SQLitePCLRaw.bundle_e_sqlite3 is a bundle that uses e_sqlite3 in all cases. Just add this package, and call:

SQLitePCL.Batteries_V2.Init();

SQLitePCLRaw.bundle_green is a bundle that uses e_sqlite3 everywhere except iOS, where the system-provided SQLite is used.

The purpose of the bundles is to make things easier by taking away flexibility and control. You don't have to use them.

How do I build this?

Requirements

  • Install the t4 cli tool with dotnet tool install --global dotnet-t4
  • Clone the cb repository in the same directory as you cloned this SQLitePCL.raw repository
  • Make sure that the Mobile development with.NET workload is installed

Then, from a Developer Command Prompt for Visual Studio 2017 or 2019:

cd build
dotnet run

Can this library be used to write a mobile app?

Technically, yes, but that's not what you want to do. This is not the sort of SQLite library you would use to write an app. It is a very thin C# wrapper around the C API for SQLite. It's "raw".

Consequently, as much as possible, this library follows the stylistic conventions of SQLite, not those of the .NET/C# world.

For example, the C function for opening a SQLite file is sqlite3\_open(), so this API provides a method called sqlite3\_open(), not Sqlite3Open().

Similarly, the functions in this API return integer error codes rather than throwing .NET exceptions, because that's how the SQLite C API works.

As a library for app developers, this library is downright hostile. It feels like using C. Intentionally.

So if this library is so unfriendly, why does it exist at all?

This library is designed to be the common portable layer upon which friendlier wrappers can be built. Before this existed, every C# SQLite library was writing their own P/Invoke and COM and marshaling and stuff. Building on this library instead allows folks to focus more on the upper layer and its goal of providing a pleasant, easy-to-use API for app developers.

How does this compare to Microsoft.Data.Sqlite?

Microsoft.Data.Sqlite is an ADO.NET-style SQLite wrapper which is part of Entity Framework Core. It uses SQLitePCLRaw.

How does this compare to sqlite-net?

sqlite-net is a very popular SQLite wrapper by Frank Krueger (@praeclarum). Unlike SQLitePCLRaw, it is designed to make writing apps easier. It even includes a lightweight ORM, and some basic support for LINQ.

The sqlite-net-pcl package uses SQLitePCLRaw:

https://www.nuget.org/packages/sqlite-net-pcl/

How does this compare to System.Data.SQLite?

System.Data.SQLite is an ADO.NET-style SQLite wrapper developed by the core SQLite team. It is very full-featured, supporting LINQ and Entity Framework. And for obvious reasons, it does a fantastic job of the SQLite side of things. But it is not at all mobile-friendly.

Why is this called SQLitePCLRaw?

SQLitePCL was a SQLite Portable Class Library released on Codeplex by MS Open Tech.

This library is a fork of that code. Sort of.

It is a fork in the 2007 sense of the word. I made significant use of the code. I preserved copyright notices.

However, this is not the the sort of fork which is created for the purpose of producing a pull request. The changes I've made are so extensive that I do not plan to submit a pull request unless one is requested. I plan to maintain this code going forward.

What is SQLitePCL.Ugly?

Well, it's a bunch of extension methods, a layer that provides method call syntax. It also switches the error handling model from integer return codes to exception throwing.

For example, the sqlite3_stmt class represents a statement handle, but you still have to do things like this:

int rc;

sqlite3 db;
rc = raw.sqlite3_open(":memory:", out db);
if (rc != raw.SQLITE_OK)
{
    error
}
sqlite3_stmt stmt;
rc = raw.sqlite3_prepare(db, "CREATE TABLE foo (x int)", out stmt);
if (rc != raw.SQLITE_OK)
{
    error
}
rc = raw.sqlite3_step(stmt);
if (rc == raw.SQLITE_DONE)
{
    whatever
}
else
{
    error
}
raw.sqlite3_finalize(stmt);

The Ugly layer allows me to do things like this:

using (sqlite3 db = ugly.open(":memory:"))
{
    sqlite3_stmt stmt = db.prepare("CREATE TABLE foo (x int)");
    stmt.step();
}

This exception-throwing wrapper exists so that I can have something easier against which to write tests. It retains all the "lower-case and underscores" ugliness of the layer(s) below.
It does not do things "The C# Way". As such, this is not a wrapper intended for public consumption.

sqlitepcl.raw's People

Contributors

0xced avatar alexandertaeschner avatar alhad-deshpande avatar anaisbetts avatar bordoley avatar bricelam avatar cyrusnajmabadi avatar dalexsoto avatar ericsink avatar farzonl avatar filipnavara avatar ghuntley avatar kant2002 avatar nberardi avatar pavel-faltynek avatar prollin avatar sharwell avatar softlion avatar therzok avatar trinitek avatar utelle avatar uweigand avatar wzchua avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sqlitepcl.raw's Issues

Assemblies should be strong-name signed

The assemblies built in this project are not strong-name signed. This makes them unconsumable on .NET Framework from assemblies that are themselves strong-name signed.

If you strong-name sign, your assemblies work everywhere.
If you don't strong-name sign, your assemblies only work for folks who don't strong-name sign.

sqlite3 for Windows 10 Universal apps

Hi,

I'm migrating my app to run on Windows 10 and I'm having issues with sqlite3.dll.

I've downloaded the latest libraries from the official website and replace it and it's working now, at least on x86.

Any change you could update this libraries for x86 and x64 on NuGet?

Thanks

System.IndexOutOfRangeException: Index was outside the bounds of the array.

We are investigating an issue where the sqlite3_stmt is not thread safe and throws IndexOutOfRangeExceptions when put under pressure. Do you have any insight on what may be going on? Would something like ConcurrentDictionary help out in this situation?

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
   at SQLitePCL.sqlite3.add_stmt(sqlite3_stmt stmt)
   at SQLitePCL.sqlite3_stmt..ctor(IntPtr p, sqlite3 db)
   at SQLitePCL.raw.sqlite3_prepare_v2(sqlite3 db, String sql, sqlite3_stmt& stmt, String& tail)
   at SQLitePCL.raw.sqlite3_prepare_v2(sqlite3 db, String sql, sqlite3_stmt& stmt)
   at SQLite.SQLite3.Prepare2(sqlite3 db, String query) in C:\projects\CloudDriveDesktop\src\Amazon.CloudDrive.Shared\Database\SQLite.cs:line 3265
   at SQLite.SQLiteCommand.Prepare() in C:\projects\CloudDriveDesktop\src\Amazon.CloudDrive.Shared\Database\SQLite.cs:line 2261
   at SQLite.SQLiteCommand.<ExecuteDeferredQuery>d__12`1.MoveNext() in C:\projects\CloudDriveDesktop\src\Amazon.CloudDrive.Shared\Database\SQLite.cs:line 2182
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at SQLite.SQLiteCommand.ExecuteQuery[T]() in C:\projects\CloudDriveDesktop\src\Amazon.CloudDrive.Shared\Database\SQLite.cs:line 2151
   at SQLite.TableQuery`1.GetEnumerator() in C:\projects\CloudDriveDesktop\src\Amazon.CloudDrive.Shared\Database\SQLite.cs:line 2952
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at SQLite.TableQuery`1.FirstOrDefault() in C:\projects\CloudDriveDesktop\src\Amazon.CloudDrive.Shared\Database\SQLite.cs:line 2971

Cannot load DLL

Hi there,

We are using CouachDB Lite which has SQLitePCL as dependency. Everything works perfectly locally on my development machine (windows 7). However, when our CI Server (MS Server 2008 box) builds the .net MVC web project and deploy it to our Web Server (MS Server 2012 box), we getting an exception says:

The type initializer for 'Couchbase.Lite.Store.SqliteCouchStore' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'sqlite3': The specified module could not be found.

So I downloaded the latest version of 32bits sqlite3.dll from sqlite.org and dropped it into the folder overriding the one generated at build time, everything works... I don't have much knowledge of PCL libraries but it looks like this might be similar to issue 44? Just wondering if you could shed some light on how to solve this issue? Would referencing VC++ extension SDK in my project solve this issue?

Thanks,
Henry

no support for set_authorizer

I wonder why its not there and not mentioned. I could add it but I am scared off by the dire warning about trying to build it myself

not much as an issue as more a question

Does SQLite.Raw suport multiple statments on execute?

I need to update several records like this: "update x set a=1 where k=0;update x set a=1 where k=2;"

SQLitePCL.raw does not run on Xamarin.Mac Unified

I upgraded a fairly large project to the Xamarin Unified API, without reading the fine print that SQLitePCL.raw runs on Xamarin.iOS Unified, but only .net45 on OSX.

I could try to selectively roll back changes, but thought I'd ask - would it be possible for you to release a build that runs against Xamarin.Mac Unified? Since you've already got iOS Universal working, I imagine this is not too difficult.

Many thanks.

Drop the -beta tag?

I'm working on shipping Akavache 4.0 using the SQLitePCL.Raw binaries, but because of lulznuget and because SQLitePCL.Raw has a -beta tag on it, I have to mark Akavache as prerelease too. Can you create a release that drops the beta tag?

While it might not be Ready For General Consumption Yet™, the subset of features that we use in Akavache work great, so I'm fairly confident that the Beta aspects of SQLitePCL.raw won't be seen by Akavache users

RTree Support

Would it be possible to enable RTree support for this project?

How to use it?

Is there any example available, for this library?
I want to use it on my project but don't know how? any one can provide me the example how to use it?

thread safe? raw.sqlite3_prepare_v2(db, sql, out command);

I am using a package(Couchbase Lite .net) that uses SQLitePCL. I often get hangs on a call to raw.sqlite3_prepare_v2(db, sql, out command); where this function does not return. I think I narrowed it down to this Dictionary in sqlite3 not being thread safe.

Should I expect this to be thread safe? Should the package be making calls to SQLitePCL in a single thread only?

public class sqlite3 : IDisposable
{
    private readonly IntPtr _p;
    private bool _disposed = false;
    private Dictionary<IntPtr, sqlite3_stmt> _stmts = new Dictionary<IntPtr, sqlite3_stmt>();  // thread safe??

Profile 78?

I'm trying to add the SQLitePCL.raw to my own PCL that targets Profile 78 -- but I get the below error when trying to add it (with Xamarin Studio 4.3):

Adding SQLitePCL.raw_needy...
Adding 'SQLitePCL.raw_needy 0.5.0' to client.Core.
Could not install package 'SQLitePCL.raw_needy 0.5.0'. You are trying to install this package into a project that targets 'portable-net45+win+wp80+MonoAndroid10+MonoTouch10', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

It was my understanding from the readme that Profile 78 should be supported. Am I missing something? I'm using mvvmcross, which appears to want Profile 78. I'm fairly new to Xamarin, and C# for that matter, so it could well be that I'm doing something silly on my end.

image

status of 3.8.11.1 in SQLitePCL.raw

Great package and we are using it with praeclarum/sqlite-net. Question for Eric: I know there are a few important issues going on, but will you have time to upgrade the SQLitePCL.raw package to support the SQLite 3.8.11.1 binary and push to Nuget?

And... Does anyone know if the praeclarum/sqlite-net project is still moving? There have not been any updates since January.. Just curious if anyone has any insight. Both are great packages and we really are happy with how it all just works so well with .Net 4.5.2 on the desktop under Win8 64bit WPF.

SQLitePCL.raw and msvcr110.dll

Hi,

I want to avoid install vc++ redistributable on every client machine. But when I try to copy compiled program to another computer I've got error.

The program can't start because MSVCR110.dll is missing from your computer. Try reinstalling the program to fix thix problem.
Exception thrown: 'System.DllNotFoundException' in SQLitePCL.raw.dll

I cannot copy MSVCR110.dll because some computers are Vista and MSVCR110.dll from Windows 7 doesn't work.
Is it possible to exclude this requirments from your library ?

Best regards,
alexiej

Version Used: Latest Stable: 1,1,
,NET Framework used: 4.5.1
Visual Studio 2015

Add a way to configure root path on windows

I would like to have an option where I can configure from where the library will load/search the interop .dlls.

Right now, you are using AppDomain.CurrentDomain.BaseDirectory, but on AppDomains created dynamically, that path returns null.

Xamarin.iOS: Bait assembly incorrectly loaded

I've opened the same issue in the sqlite-net project, but it is more likely a SQLitePCL.raw issue.

My iOS project worked fine with sqlite-net / SQLitePCL.raw previously.

However, with recent builds, the bait PCL assembly is loading instead of the platform-specific one.
I'm not sure when the regression first occurred. I'm using SQLitePCL.raw v0.8.4 with the latest sqlite-net code.

The exception occurs with both Visual Studio 2015 and Xamarin Studio.

My project is completely broken right now, so appreciate any pointers. How exactly does the loading process work?

Should SQLite.raw protect against managed delegates throwing exceptions?

SQLite.raw supports using managed delegates for several sqlite functions:

  • sqlite3_create_function
  • sqlite3_create_collation
  • sqlite3_commit_hook
  • sqlite3_progress_handler (hopefully in a near future release).

As I recall the current code doesn't protect against exceptions being thrown by these functions. Should it? Is there any kind of data corruption risk if an exception goes unhandled, perhaps caught by managed code but crashing the native sqlite code?

Specifically sqlite3_create_function callbacks can call sqlite3_result_error and sqlite3_result_error_code to communicate error cases. Should the library catch exceptions and call these to communicate an error. The downside of course is that the managed exception is swallowed in this case and you would lose the managed stack trace.

RTree not correctly enabled for Android

I noticed in one of your latest commits you enabled RTree by un-commenting the line in gen_build.cs. Unfortunately this won't do anything for Android because the Android.mk file needs to be updated and ndk-build needs to be called again to rebuild the .so's which are referenced in the project.

-DSQLITE_ENABLE_RTREE should be added to the LOCAL_CFLAGS variable in Android.mk and the .so's should be recompiled by calling ndk-build while in the jni directory. This will correctly enable RTree for the Android module.

raw.sqlite3_db_filename returns empty string instead of null for memory db

According to the sqlite documentation I'd expect name in the following example to be null not an empty string. The SQLite documentation states:

If database N is a temporary or in-memory database, then a NULL pointer is returned.
static void Main(string[] args)
{
    sqlite3 db;
    raw.sqlite3_open(":memory:", out db);

    var name = raw.sqlite3_db_filename(db, "main");
    Console.WriteLine(name!= null); // prints true would expect false
    Console.ReadLine();
}

SqlitePCL.raw 0.8.0 on nuget doesn't seem to work with Android

When I include the nuget package into my Android project, it is putting a bait and switch dll in the android references instead, which of course will not run. If I look in the packages folder, all the other libs seem to have a SQLitePCL.raw.dll file in, however, the monodroid folder has a single file called . which is zero bytes.

I have tried with both SQLitePCL.raw and SQLitePCL.raw_basic packages and both seem broken.

Add variants of raw.sqlite3_blob_write/read that accept a start offset in the source/dest arrays

I'm attempting to wrap blob_write/blog_read in a C# Stream. The Stream APIs are:

void Write(byte[] buffer, int offset, int count)
int Read(byte[] buffer, int offset, int count)

Both of these APIs accept offsets into the byte arrays since C# doesn't support zero copy subarrays. The C APIs provided by SQLite for blob_write/blog_read implicitly support subarrays, since the caller can pass any pointer as the byte buffer, however in C# there is no way to do that. I suggest adding variants:

int sqlite3_blob_write(sqlite3_blob blob, byte[] b, int bOffset, int n, int offset)
int sqlite3_blob_read(sqlite3_blob blob, byte[] b, int bOffset int n, int offset)

in order to complete the API.

Format source files with code maid

Pet peeve, but it would be nice if the source files used consistent format conventions throughout. Parts of the code use tabs, others use spaces. Also Visual Studio has a bad habit of reformatting the cpp files, such that I frequently have to fallback to vim on the command line in order to avoid diffs that change the whole source file. Obviously low priority, but it would make contributing a bit easier.

"Sqlite3.dll was not loaded" error when using sqlite.raw in Visual Studio

I have a Visual Studio VSIX that carries SQLite with it. When I try to use it outside VS it works fine. But inside VS, the exception below is always thrown. I have confirmed that these files are available in the expanded VSIX (where the rest of my code is running):
SQLite-net.dll
sqlitepcl.raw.dll
x86\sqlite3.dll
x64\sqlite3.dll

System.TypeInitializationException occurred
HResult=-2146233036
Message=The type initializer for 'NativeMethods' threw an exception.
Source=SQLitePCL.raw
TypeName=NativeMethods
StackTrace:
at SQLitePCL.SQLite3Provider.NativeMethods.sqlite3_open_v2(Byte[] filename, IntPtr& db, Int32 flags, Byte[] vfs)
at SQLitePCL.SQLite3Provider.SQLitePCL.ISQLite3Provider.sqlite3_open_v2(String filename, IntPtr& db, Int32 flags, String vfs)
at SQLitePCL.raw.sqlite3_open_v2(String filename, sqlite3& db, Int32 flags, String vfs)
at SQLite.SQLiteConnection..ctor(String databasePath, SQLiteOpenFlags openFlags, Boolean storeDateTimeAsTicks)
at SQLite.SQLiteConnection..ctor(String databasePath, Boolean storeDateTimeAsTicks)
at Microsoft.VisualStudio.*(String databasePath)
InnerException:
HResult=-2146233088
Message=sqlite3.dll was not loaded.
Source=SQLitePCL.raw
StackTrace:
at SQLitePCL.SQLite3Provider.NativeMethods..cctor()
InnerException:

FileNotFoundException when running on Windows Phone 8.1 Silverlight

Fails when trying to create the database with SQLite-net.PCL, here's the stack trace:

>   SQLitePCL.raw.DLL!SQLitePCL.SQLite3Provider.SQLitePCL.ISQLite3Provider.sqlite3_open(string filename, out System.IntPtr db = {System.IntPtr})    Unknown
    SQLitePCL.raw.DLL!SQLitePCL.SQLite3Provider.SQLite3Provider()   Unknown
    SQLitePCL.raw.DLL!SQLitePCL.raw.raw()   Unknown
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    SQLitePCL.raw.DLL!SQLitePCL.raw.sqlite3_open_v2(string filename = "C:\\Data\\Users\\DefApps\\APPDATA\\Local\\Packages\\5458be8c-a0f5-434c-9f10-b148eade3f75_6pk4qsq6wgqs2\\LocalState\\TaskDB.db3", out SQLitePCL.sqlite3 db = null, int flags = 6, string vfs = null)  Unknown
    SQLite-net.DLL!SQLite.SQLiteConnection.SQLiteConnection(string databasePath, SQLite.SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = true)    Unknown
    SQLite-net.DLL!SQLite.SQLiteConnectionWithLock.SQLiteConnectionWithLock(SQLite.SQLiteConnectionString connectionString, SQLite.SQLiteOpenFlags openFlags)   Unknown
    SQLite-net.DLL!SQLite.SQLiteConnectionPool.Entry.Entry(SQLite.SQLiteConnectionString connectionString, SQLite.SQLiteOpenFlags openFlags)    Unknown
    SQLite-net.DLL!SQLite.SQLiteConnectionPool.GetConnection(SQLite.SQLiteConnectionString connectionString, SQLite.SQLiteOpenFlags openFlags)  Unknown
    SQLite-net.DLL!SQLite.SQLiteAsyncConnection.<>m__0()    Unknown
    mscorlib.ni.dll!System.Threading.Tasks.Task<SQLite.CreateTablesResult>.InnerInvoke()    Unknown
    mscorlib.ni.dll!System.Threading.Tasks.Task.Execute()   Unknown
    mscorlib.ni.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj)    Unknown
    mscorlib.ni.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)    Unknown
    mscorlib.ni.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)    Unknown
    mscorlib.ni.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot = Id = 1, Status = Running, Method = "SQLite.CreateTablesResult <>m__0()", Result = "{Not yet computed}")    Unknown
    mscorlib.ni.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution)  Unknown
    mscorlib.ni.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()  Unknown
    mscorlib.ni.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Unknown
    mscorlib.ni.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()  Unknown

Same code works fine with Xamarin.iOS and Xamarin.Android.

Consider moving unmanaged code out into separate package(s)

Background

Calling SQLite from C#/F#/etc involves two parts:

  1. a wrapper (managed code, a bunch of glue written in C#)
  2. and, SQLite itself (unmanaged code, written in C)

Calling C from managed code is rather complicated, and even more so when dealing with lots of different underlying platforms. Most platforms use the pinvoke mechanism, but they do so in different ways. And the Silverlight-flavored versions of Windows Phone do not support pinvoke, so they have to use C++/CX instead.

The goal of SQLitePCL.raw is to hide all that complexity and present a portable API for calling SQLite.

But the previous sentence makes things sound simpler than they are. Exactly what do we mean by "SQLite"? Obviously, we are referring to some compiled form of the SQLite library. But where does that come from?

  1. We obviously need to get the right CPU, which might be x86, x64, ARM, ARM7, or whatever.
  2. And on iOS and its ilk, we now have LLVM bitcode to deal with, which is kind of like another CPU.
  3. On Windows and its ilk, we care about which version of the C compiler was used, because that determines which version of the C runtime library will be needed. Visual C++ 2010, 2013, and 2015 are all still important, depending on what version(s) of Windows you want to be compatible with.
  4. There are lots of options that can be chosen when SQLite is compiled. Features like full text search and JSON can be turned on or off. Newer versions of SQLite often arrive with more bug fixes or better performance.
  5. Some platforms have SQLite built-in to the OS. We want to give the choice to use that library (to keep the app small, for example) or to use a different SQLite build (to get a more recent SQLite version, for example).
  6. We might want encryption features, which are available as SQLCipher (SQLite with encryption support, maintained by Zetetic, a third party) or SEE (a proprietary encryption feature available from the SQLite authors). These are just different builds of SQLite with more features.
  7. Some platforms (Windows) do not have SQLite built-in to the OS. It is worth providing a good experience for developers on these platforms.
  8. Cross-platform apps might (and probably do) want to be sure that the same version of SQLite is being used on all their platforms.

Giving people choices can be a bad thing. Too many options is the way to paralysis. There is much to be said for something that Just Works without hassle.

So it is tempting to eliminate a bunch of these choices. For example, maybe we should not support the ability to use the SQLite built-in to iOS and just always bundle a newer version with all the optional features turned on?

Alas, my experience in maintaining this library and supporting the developers who use it has taught me that app developers need the ability to choose among these tradeoffs.

Two kinds of SQLite choices

It is worth highlighting at this point that all the complexity of choosing a specific SQLite build can be separated into two categories:

  1. Choosing the right build of SQLite for a given platform, such as CPU, runtime, etc. In all likelihood, the developer wants this to be automatic and never think about it.
  2. Choosing the build of SQLite based on which features are desired, such as full text search or encryption. Some developers don't want to think about this, but some do.

Two cases of developers

It is also worth mentioning that the needs of library developers are a bit different than those of app developers.

If someone is building and deploying an app, they probably care a lot about exactly how SQLite is included and what features it is using.

But if someone is developing a library which calls SQLitePCL.raw, they may not care about much of the stuff above. They probably want to defer those choices to their own users.

And I should also admit that library developers are the primary audience of this library, since it intentionally provides a "raw" API that is low-level, intended to be the foundation for friendlier APIs to be built on top of it.

The Status Quo

As of SQLitePCL.raw version 0.8.6, we have one large NuGet package which tries to solve all these problems.

With the exception of support for Windows 10 Universal apps (the "uap10.0" TFM, added in 0.8.5), the package is based on a NuGet 2.x approach, using none of the new stuff from NuGet 3.x.

The package contains both SQLitePCL.raw.dll (in a bunch of different forms) and compiled SQLite libraries (in a bunch of different forms).

For Windows platforms, the job of copying the correct sqlite3.dll to the build directory is handled by using an msbuild "targets" file, a NuGet feature wherein msbuild code from the NuGet package can be invoked as part of the build process. This targets file chooses the correct sqlite3.dll based on the CPU. On most Windows platforms, SQLitePCL.raw.dll goes into the NuGet "lib" directory, and the "targets" file goes into the NuGet "build" directory.

For the Silverlight-flavored versions of Windows Phone, because pinvoke is not used, the targets file has to do more. Everything goes into the "build" directory.

For iOS and Android, the targets file is not necessary for CPU choice. On iOS, unmanaged code libraries are "fat", containing multiple CPU architectures in a single file. On both iOS and Android, native code gets included by the Xamarin tools by embedding it into a resource within a CLR assembly.

So if we did not care about supporting different builds of SQLite for features (like full text search or encryption), we wouldn't need the targets file for iOS/Android at all. But NuGet doesn't have any way of presenting the sort of config option we would need. So, the SQLitePCL.raw.dll file(s) go into the build directory anyway, and a targets file is used to choose based on the msbuild property "UseSQLiteFrom".

Ignoring the different forms of native code for a moment, the various versions of SQLitePCL.raw.dll itself are actually not that different from each other:

  1. Well, to be honest, the non-pinvoke builds are very different. So let's try to avoid talking about them.
  2. There are "bait" versions. SQLitePCL.raw is a "bait and switch" PCL. The bait versions are designed to be used when another PCL wants to reference SQLitePCL.raw. A bait assembly is just a stand-in that is used at build time. It doesn't contain any functionality.
  3. Some are compiled for different .NET framework versions. For example, there is a net35 build. And there is a compile-time option to choose between the old way of doing reflection and the new way. Stuff like that.
  4. There are little bits of platform-specific code which can be compiled in or out. For example, on iOS, callback functions that are round-tripped through unmanaged code have to decorated with an attribute so the Xamarin AOT compiler can do magic.
  5. Finally, there is the question of what library name is provided to pinvoke. In other words, when the DllImport directive is used to specify a C function to be called by managed code, where does that C function get found? In general, this is the name of a shared library, but iOS doesn't support shared libraries, so things there a little weird.

Other tidbits about the status quo:

  1. Xamarin.iOS classic (not the unified stuff) still has limited support. This toolset does not support targets files, so there is no ability to choose different SQLite builds.
  2. The recently-added support for "uap10.0" is done with a SQLitePCL.raw.dll in "lib" and a targets file in "build". The targets file will add a sqlite3.dll which was built with the v140 toolset (Visual C++ 2015), linked against the Visual C++ 2015 C runtime. Testing so far indicates that this works on Windows 10 desktop as well as Windows 10 Mobile. The special dependencies section is also included in the nuspec, and it gets ignored by older NuGets. There is currently no "dotnet" TFM included. None of the new NuGet 3.x stuff for unmanaged code is being used yet.
  3. There is not yet any support for .NET Core on non-Windows platforms.
  4. The package includes no SQLite builds for Linux.
  5. There is some support for Xamarin.Mac, but it has problems.
  6. The use of the targets file has been fragile, a common source of difficulty for developers using the library. Xamarin.iOS classic doesn't support it. When developers have a problem, they look in the lib directory and find nothing there, so they conclude that the package is corrupt. Remarks from "People Who Know More Than Me" suggest that the targets file mechanism is out of favor and probably headed for deprecation someday.
  7. A previous design attempted to use multiple SQLitePCL.raw packages for different feature options. The intent of this approach was, for example, to have "SQLitePCL.raw_Latest" which included the latest build of SQLite for all platforms, and "SQLitePCL.raw_Cipher", which included the SQLCipher builds of SQLite. No msbuild property (UseSQLiteFrom). Just reference the NuGet package containing the features you wanted. The problem with this approach was with library developers, like Akavache, for example. If you are building a library, you want to reference one SQLitePCL.raw NuGet package and defer the other choices to the users of your library. You certainly do NOT want to end up having multiple NuGet packages, like "Akavache_With_SQLite_Latest" and "Akavache_With_SQLCipher" and so on.
  8. The SQLitePCL.raw NuGet package is around 30 MB, and every time I add support for another platform, it gets bigger. In many cases, developers are downloading a package that contains a bunch of stuff they are not using.
  9. SQLCipher is currently supported only for Android and iOS, not for any of the Windows platforms. And for iOS, it uses the libcrypto from OpenSSL, not the stuff provided by iOS itself. I have a pending pull request from the Couchbase folks to address these issues.
  10. One other edge case is currently supported. On Windows, one of the SQLitePCL.raw builds contains special code to dynamically load the appropriate "sqlite3.dll" after checking whether it is running in 32 bit or 64 bit mode. I implemented this because it was something that EF7 would need, but it turns out that other people have found it helpful.

The change I am considering

I would like to do this differently.

The idea is get all the compiled SQLite libraries out of SQLitePCL.raw itself.

  1. The SQLitePCL.raw NuGet package would contain nothing but the managed code (the wrapper).
  2. There would still be several different builds of SQLitePCL.raw.dll, including bait assemblies and platform-specific builds.
  3. All the SQLitePCL.raw.dll assemblies would go in the NuGet "lib" directory. No more msbuild targets files in the main package.

And the various builds of SQLite (or SQLCipher) itself would go into separate NuGet packages. In other words, if you are using the SQLitePCL.raw package, you would also need to reference something (like another NuGet package) which gives you SQLite itself.

An attractive thing about this idea is that the complexity ends up located very close to the thing that caused it. SQLitePCL.raw itself becomes simple, because it mostly is. And the plethora of SQLite builds will be, er, complicated, but that's just the way things are.

The trick is to design this so that all the flexibility above gets retained.

  1. The SQLitePCL.raw package itself gives you no choices and requires no decisions.
  2. Any decisions about what SQLite library you are using are implicit in which SQLite library package you choose to add.
  3. Library developers reference SQLitePCL.raw only. App developers are the ones who need to somehow add SQLite itself.

The key question in all of this is: In SQLitePCL.raw.dll, what name is provided to DllImport (pinvoke)?

(Let's ignore the non-pinvoke platforms for now.)

The simple answer is to just use "sqlite3":

  1. The pinvoke mechanism will look for a shared library called "sqlite3" in whatever fashion makes the most sense on the platform.
  2. The nice thing about this approach is that it fits the convention of how the SQLite library is named in its various official forms. By referencing "sqlite3" in DllImport, you give the developer the ability to use the OS-provided SQLite or a custom SQLite build from almost any source. The SQLite provided by iOS or Android would Just Work. The SQLite vsix extenson SDK would Just Work.
  3. The bad thing about this approach is that it fits the convention of how SQLite is named, so it risks referencing a SQLite library that you were not intending to use. If you want to use a custom SQLite build, you have to give it the same name as the one provided by the OS and trust that the library you want will get used.
  4. On iOS, this approach will always end up referencing the SQLite dynamic library provided by the OS. The option to use a more recent build or a custom build or a SQLCipher build would not be available. iOS does not allow apps to provide shared libraries.
  5. On Android, this approach will find the libsqlite.so library provided by the OS. How would we support the use of other SQLite builds? If the app provides a libsqlite.so of its own, which one will get chosen? I honestly don't know the answer to this. For the moment, let's suppose I ran some tests and found that the app's libsqlite.so is preferred over the one from the OS. Would I trust this to be true for every version of Android? (Do I trust anything to be true for every version of Android?) Would I trust that this behavior cannot be changed by fiddling with LD_LIBRARY_PATH?
  6. On Windows, this approach will look for sqlite3.dll wherever it can be found. Some of the same concerns about ambiguity would apply here, except of course that most (or all?) Windows platforms do not have SQLite as part of the OS. (I heard rumors of this changing on Windows 10, or maybe just on Windows 10 Mobile?)
  7. Some developers want to always use the OS-provided SQLite or a SQLite build that is reasonably "official". The previous sentence might even be correct if I replace "Some" with "Most". For those developers, passing "sqlite3" to DllImport is the preferred answer, because it is simple. But I don't want to eliminate "developers who need more control" from the audience of this package.

So, using "sqlite3" with DllImport is problematic. What are the alternatives?

  1. For iOS, the only other option is to use "__Internal". This is a special feature of Mono (upon which Xamarin.iOS is based). Quoting directly from mono-project.com: /The “__Internal” library name will instruct Mono not to look this up in an external library, but to try to satisfy the symbol referenced (DoSomething) in the current executable image./ Basically, since iOS does not allow apps to use shared libraries, this is what we have to use.
  2. For all the other platforms, the alternative is to reference a library name that we would have to provide. For example, instead of DllImport with "sqlite3", we could use "z_sqlite3".
  3. This approach makes the use of a custom SQLite build possible. The bad news is that it also makes the use of a customer SQLite build necessary. SQLitePCL.raw.dll will always look for a shared library called "z_sqlite3", so that's what will be required.
  4. So, all the SQLite and SQLCipher builds that are currently inside the SQLitePCL.raw NuGet package would instead be published in separate NuGet packages that provide them under the name "z_sqlite3".
  5. For example, we could have a package called Z_SQLite_Latest, which includes the latest copy of the SQLite code, in a library called "z_sqlite3". Another one might be called "Z_SQLite_SQLCipher".
  6. These packages would not contain any managed code.
  7. These packages would not, in general, be useful for anyone who is not using SQLitePCL.raw.
  8. For the use case where people want to just use the SQLite that is installed with iOS or Android, we would need to publish a bridge package that includes a "z_sqlite3" that passes everything through to "sqlite3". We might call this Z_SQLite_Shim.
  9. Some platforms will continue to need msbuild targets files in the Z_SQLite package. For NuGet 3.x cases, we can use its new features for native code.
  10. It should be possible (at least for NuGet 3.x) to separate these builds into separate packages. For example, instead of having one big NuGet package which contains builds for every platform, we could have separate NuGet packages for each platform, and perhaps also a package which uses platform-specific dependencies to route to the proper one.
  11. The SQLitePCL.raw NuGet package would require one of the z_sqlite3 packages, but it would not contain a dependency on any of the z_sqlite3 packages, because any such dependency would require a decision to be made about which one, and the goal is to not make that decision.
  12. All the complexity of multiple SQLite builds would stay in the z_sqlite3 side of things, without the need to affect SQLitePCL.raw itself.
  13. It is unfortunate that as a project, SQLitePCL.raw will go from publishing one or two NuGet packages to publishing many more. Flooding nuget.org with packages causes confusion. OTOH, looking at the quantity of packages now being provided by Microsoft itself, it would seem that this ship has already sailed.
  14. FWIW, I have verified that this model will work for iOS. In other words, I was concerned that having one assembly that does a DllImport from "__Internal" might not work if the actual bundled native library resources were coming from a separate assembly. But it does. I still need to verify this with Xamarin.Android, but I am less concerned about that one.

So, DllImport("sqlite3") is simple but inflexible. And DllImport("custom name") is flexible but complicated.

I have made various attempts to find a way to allow this decision to be made at runtime, without success. If such a solution were to exist, I would set things up such that "sqlite3" would be used by default and provide a way to override.

Moving forward

I have not yet decided how to proceed. I am publishing this (lengthy and tedious) writeup to solicit feedback. If you have made it all the way to the end, please accept my thanks for your attention. All comments would be welcomed.

SQLitePCL.native.sqlite3.v110_xp.0.9.0 seems to look for esqlite3 in the wrong package directory

Just installed the 0.9.0 stuff and then installed the native/plugin tools for a .net 4.5.2 unit test project and started getting this error

Severity Code Description Project File Line Source Suppression State
Error Could not copy the file "\packages\build\native\sqlite3\v110_xp\x64\esqlite3.dll" because it was not found.

I checked the targets file and it's

<Content Include="$(MSBuildThisFileDirectory)..\..\build\native\sqlite3\v110_xp\x86\esqlite3.dll">

If I change it to
<Content Include="$(MSBuildThisFileDirectory)..\build\native\sqlite3\v110_xp\x86\esqlite3.dll">
or
<Content Include="$(MSBuildThisFileDirectory)native\sqlite3\v110_xp\x86\esqlite3.dll">

Then it all works super

I'm running this from an MSunit test which maybe changes the dynamics of things

MethodAccessException for Concurrent.ConcurrentDictionary.ctor

I get the following exception when attempting to run 0.8.6 on a Windows Phone 8.1 (winrt) project.

{"Attempt by method 'SQLitePCL.sqlite3..ctor(IntPtr)' to access method 'System.Collections.Concurrent.ConcurrentDictionary'2<System.IntPtr,System.__Canon>..ctor()' failed."}

.Net 4.6.1 support & verison

Eric,
I may have overlooked this, but does SQLitePCL.raw currently support .Net 4.6.1 64 bit on Windows 10 desktop? I thought the current version (not -pre) only supported up to .Net 4.5.2 on the desktop. We would like to upgrade our WPF application to 4.6.1 and I wanted to check with you first.

And... will the v0.9.0 release ship with the latest SQLite 3.12.2 build? Several bugs fixed in the latest.

Thanks for the great work!

Cannot have AnyCPU Win8/UWP class libs

I'm trying to use SQLitePCL.raw in a Win8.1 class library but because of the generated targets, I cannot have my class library as AnyCPU:

<?xml version="1.0" encoding="utf-8"?>
<!--Automatically generated-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <SDKReference Include="Microsoft.VCLibs, Version=12.0" />
  </ItemGroup>
  <Target Name="InjectReference_9c3053de-7f64-49f0-b4f3-7d7f750b02d0" BeforeTargets="ResolveAssemblyReferences" Condition=" '$(UseSQLiteFrom.ToLower())' != 'elsewhere' ">
    <ItemGroup Condition=" '$(Platform.ToLower())' == 'arm' ">
      <Content Include="$(MSBuildThisFileDirectory)..\..\build\native\sqlite3_dynamic\v120\arm\sqlite3.dll">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
    </ItemGroup>
    <ItemGroup Condition=" '$(Platform.ToLower())' == 'x64' ">
      <Content Include="$(MSBuildThisFileDirectory)..\..\build\native\sqlite3_dynamic\v120\x64\sqlite3.dll">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
    </ItemGroup>
    <ItemGroup Condition=" '$(Platform.ToLower())' == 'x86' ">
      <Content Include="$(MSBuildThisFileDirectory)..\..\build\native\sqlite3_dynamic\v120\x86\sqlite3.dll">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
    </ItemGroup>
  </Target>
</Project>

The issue is that it adds the <SDKReference Include="Microsoft.VCLibs, Version=12.0" /> and that ref requires me to choose a platform. What would work is a variable that lets me disable that SDKReference include in that case. The SDKReference will get added to the app when the package is added there, so in the end it works out.

Add pretty interface?

I put together what I think is the for the most part a pretty, yet raw interface on top of SQLitePCL.raw. For now i put it up on github as a separate project (https://github.com/bordoley/SQLitePCL.pretty) but I was wondering if you would be interested in merging it into the main SQLitePCL.raw project as a companion to the ugly interface.

Most of the API is a fairly non-controversial translation of the SQLite APIs to .NET idioms. The main points of interest I suppose are the following:

  1. Bind variables indexed starting at 0 instead of 1.
  2. .NET implementation of the SQLiteValue object. I needed these in order to make the interface for create_function (DatabaseConnection.RegisterFunction in the API) clean.

Other than that, I support the whole SQLitePCL.raw API with the exception of the following APIs:

  • sqlite3__vfs__delete : Didn't see a benefit of wrapping this
  • sqlite3_column_decltype
  • sqlite3_db_handle
  • sqlite3_exec (the semantics are supported, but implemented using stmt, so that an exception is thrown when a sql string is supplied that has more than one statement in it).

Anyway, let me know your thoughts. Thanks,

Dave

Suggestion: Use double checking on locks

You have several locks before accessing dictionaries. That's a lot of contention. I would replace that in all methods by a double checking (one check outside the lock, another inside).

Like for example:

internal static info getOrCreateFor(IntPtr db)
{
    info i;
    if (_hooks_by_db.TryGetValue(db, out i))
    {
        return i;
    }

    lock (_hooks_by_db)
    {
        if (_hooks_by_db.TryGetValue(db, out i))
        {
            return i;
        }

        return _hooks_by_db[db] = new info();
    }
}

Is the lib\Xamarin.iOS10 missing in the latest 0.8.0.0 version on purpose?

I'm guessing I'm just not seeing a readme somewhere about this change and how to make it work

I'm using Akavache from @paulcbetts and noticed that my project stopped running on ios complaining that it couldn't find SQLitePCL.raw version 0.6.1.0...

Project runs fine on Android and Windows

I noticed for the nuget package the
lib\Xamarin.iOS10
folder is empty for version 0.8.0.0 so I downgraded the project to 0.7.1.0 (because it's not empty in that version) and now it's all running without any issues

Am I missing something about how to make version 0.8 work?

WinRT not working?

Great project. It runs successfully on Windows desktop, but in a WinRT project, it throws:

Unable to load 'sqlite3' - the specified module could not be found.

The lib folder also doesn't have any folder that looks like it would work for WinRT:

MonoAndroid
MonoTouch
net45
netcore45
netcore451
portable-net45+netcore45+wp8+MonoAndroid10+MonoTouch10+Xamarin.iOS10
portable-net45+netcore45+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10
portable-net45+netcore45+wpa81+wp8+MonoAndroid10+MonoTouch10+Xamarin.iOS10
portable-net45+sl5+netcore45+wp8+MonoAndroid10+MonoTouch10+Xamarin.iOS10
wp8
wp81
wpa81
Xamarin.iOS10

Any ideas?

Can we talk?

I use a custom build of SQLite and I need to make some additions to this for use in MvvmCross.

SQLitePCL.raw not being included in TFSBuild

We have a strange issue that I hope you can help me with.

We have a Xamarin project that uses SQLitePCL (and by virtue, SQLitePCL.raw). One of the builds is for WinPhone (8.0) and we are experiencing build issues with this version.

When we build the ARM/Release version on a developer machine, it all works fine. SQLite works, and the app works as intended.

When we build the ARM/Release version using TFSBuild, the SQLitePCL.raw.dll is not included, and the app crashes on startup as the DLL is not included in the XAP file. It is literally the same code, taken from the same branch in TFS.

We cannot work out what is different between the developer machines and the build server that makes it behave differently. All the same installs are present (SDK's etc), and the build is successful, but when we looks in the logs, SQLitePCL.raw.dll is not being packaged up.

I know from many google searches that there may be some shenanigans with Microsoft.Bcl.Build but its not apparent if this is the problem or its something else.

We are using SQLitePCL nuget package v1.1.1 (https://github.com/praeclarum/sqlite-net) and this is targeting SQLitePCL.raw 0.8.6 (https://github.com/ericsink/SQLitePCL.raw)

If you could give me any pointers as to what might be causing this issue, it would be appreciated.

I can provide snippets from build logs if this would help.

.NET 3.5 support

This is a feature request for .NET 3.5 support so that Couchbase Lite can use this library without compiling it ourselves. There is very minimal work that needs to be done for source changes (they are all included in the first commit of my SQLCipher PR). The majority of the work comes from generating a .NET 3.5 target for raw and ugly. Please let me know if this is a possibility.

create_collation bug with multiple connections (iOS)

When using multiple connections I have to call raw.sqlite3_create_collation for every connection to register the collation functions. Doing so I get random NullPointer exceptions from SQLite3Provider.collation_hook_bridge_impl at a later point.

I think I narrowed the problem down to the following (correct me if I'm wrong):
The SQLite3Provider class is implemented as a singleton (static member _imp of class raw) which contains a Dictionary _collation_hooks. Now every time create_collation is called (regardless of the connection or db object) the old collation hook of the _collation_hooks dictionary is released and a new one is created.
So when first connection1 and then connection2 are created and the collations are registered in this order, connection1 contains a collation hook which was released and is therefore unusable.

Another thought: As you do not lock the _collation_hooks dictionary in a critical section, have you tested opening multiple connections simultaneously from different threads? This might produce race conditions...

DllNotFound Access violation on upgrade

Our Windows desktop C# 4.5.2 WPF x64 app works great with SQLitePCL.raw 0.8.6 so I thought I would test the latest with a simple in place upgrade to 0.9.0-pre8. After running Nuget to update to the latest pre-release we now get System.DllNotFoundException and the Access violation. Attaching screen shots. I am thinking maybe the location of files have moved in the 0.9.0 release and there will be some new docs telling us where to find the dll but I wanted to share this "breaking" update issue, as you cannot do an in place update now and keep things working. We are compiling with .Net 4.5.2 and CPU is set to x64.

capture1
capture2

How do I use my own copy of sqlite3.dll

I have purchased the Sqlite Encryption Extensions which allows me to build a version of the sqlite3.dll which encrypts the contents of the database.

I wan to use this sqlite.dll to replace the version of sqlite used by iOS and Android.

How do I go about doing this?

  • Update - Looking through the code, I see static libraries esqlite.a for iOS. Do I just have to build the sqlite3 library as a static library, and overwrite this file, and the application will use this version of sqlite rather than the one installed on iOS? I assume it is a similar process for Android?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.