Skip to content
This repository was archived by the owner on Nov 1, 2018. It is now read-only.

Use SQLitePCL.raw #320

Merged
merged 1 commit into from
Feb 14, 2017
Merged

Use SQLitePCL.raw #320

merged 1 commit into from
Feb 14, 2017

Conversation

bricelam
Copy link
Contributor

@bricelam bricelam commented Feb 10, 2017

Changes:

Other notes:

  • If a SQLitePCL.raw bundle is installed, Microsoft.Data.Sqlite.Core with auto-initialize it

Resolves #21, resolves #255

<PackageTags>SQLite;Data;ADO.NET</PackageTags>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)$(MSBuildProjectName).ruleset</CodeAnalysisRuleSet>
<IncludeSymbols>true</IncludeSymbols>
<Description>Metapackage that includes Microsoft.Data.Sqlite.Core and SQLitePCLRaw.bundle_green.</Description>
Copy link
Contributor Author

@bricelam bricelam Feb 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @rowanmiller (I wasn't sure what to put here.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SQLite ADO.NET provider, packaged for most common use cases

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep the description the same? The fact that it is a metapackage is an implementation detail that 99% of people won't care about.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my view the term "metapackage" is a bit nerdy so I agree that's somewhat of an implementation detail. The most interesting things to put in the description are: 1. What is this thing? 2. Why do I need/want it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will keep the same. I debated doing that, but wanted emphasize that one includes SQLite while the other doesn't, but it probably doesn't actually matter.

@ErikEJ
Copy link
Contributor

ErikEJ commented Feb 10, 2017

Wonder if the newer required runtime version will cause issue on non MS OSes - I recall a number of issues already with the current required version

@bricelam
Copy link
Contributor Author

@ErikEJ It was a problem before we started distributing SQLite on OSX and Linux. You can still hit issues, but only if you step outside of the default bundle_green experience or are deploying to older iOS devices.

Copy link
Contributor

@natemcmaster natemcmaster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of my comments are questions. I'm not familiar with SQlitePCL, but want to make sure we've done the due diligence to ensure it works in all the scenarios we currently support.

Also, cc @Eilon - this change introduces a new third-party dependency.

Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏 thanks for the cleanup.

<AssemblyName>Microsoft.Data.Sqlite</AssemblyName>
<RootNamespace>$(AssemblyName)</RootNamespace>
<PackageId>$(MSBuildProjectName)</PackageId>
<Description>SQLite implementation of the System.Data.Common provider model.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you removed the Summary tag a cleanup commit, but consider re-adding it. NuGet will issue build warnings for long descriptions like this. In general, I'm in favor of eliminating warnings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing was handling <Summary>. NuGet doesn't support it... (I was getting the warning even with it.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, nvm. Weird...was sure NuGet supported that property.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI I've opened NuGet/Home#4587 as this long description will always produce a build warning.

<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="System.Data.Common" Version="4.4.0-*" />
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use 4.4.0-* of this too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it exist? I was having problems when I tried...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's on the https://dotnet.myget.org/feed/dotnet-core/package/nuget/System.ValueTuple. I updated our mirror settings to include this package. I manually added it to our feeds to unblock this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you. Tuple power! ✊

</ItemGroup>
<ItemGroup>
<Compile Update="SqliteCommand.cs">
<SubType>Component</SubType>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I saw VS automatically add these...but what is it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes a different icon show up in Solution Explorer 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because they inherit from Component on net451. I figured I'd stop fighting it and just check it in.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also a hint that there may be a designer associated with them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's annoying. Consider opening and issue on dotnet/roslyn-project-system.

{
stmts.Enqueue(Tuple.Create(stmt, rc != SQLITE_DONE));
stmts.Enqueue((stmt, hasRows: rc != raw.SQLITE_DONE));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i ❤️ c# 7.0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, this feature is a bit hard to grok syntactically.

{
internal static class MarshalEx
{
public static string PtrToStringUTF8(IntPtr ptr)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General question: does SQLitePCL default to UTF8 encoding of strings?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

using (var connection = new SqliteConnection("Data Source=:memory:"))
{
connection.Open();
connection.ExecuteNonQuery("PRAGMA temp_store_directory = '" + ApplicationDataHelper.TemporaryFolderPath + "';");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was required for UWP. Handled by SQLitePCL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

<PackageTags>SQLite;Data;ADO.NET</PackageTags>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)$(MSBuildProjectName).ruleset</CodeAnalysisRuleSet>
<IncludeSymbols>true</IncludeSymbols>
<Description>Metapackage that includes Microsoft.Data.Sqlite.Core and SQLitePCLRaw.bundle_green.</Description>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep the description the same? The fact that it is a metapackage is an implementation detail that 99% of people won't care about.

<ItemGroup>
<PackageReference Include="SQLite" Version="3.12.3" />
<PackageReference Include="StyleCop.Analyzers" Version="1.0.0">
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="1.1.2" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set PrivateAssets=None. SQLitePCLRaw.bundle_green has some build targets that should be included. Cref NuGet/Home#4521

foreach (var path in privateBinPath.Split(new [] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries))
{
yield return path;
yield return Path.Combine(path, GetArchitecture());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does SQLitePCL handle AnyCPU desktop apps?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has some code to try and resolve things at runtime. In sqlite3_pinvoke.cs, look for PRELOAD_FROM_ARCH_DIRECTORY. I can't claim that code is perfect, but it is generally working for people.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the same way we did: x86 and x64 directories + LoadLibraryEx.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to navigate the layers of SQLitePCL packages. I'm sure this handled, but can you point me to which package actually has the native windows x64 vs x86 binaries? What I'm trying to make sure we've addressed this this: dotnet/sdk#847. Microsoft.NET.Sdk will not require .NET Framework apps to specify a runtime identifier. But if the package is using the 'runtimes' folder of NuGet to distribute win-x86 vs win-x64 binaries, we may run into issues.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're looking for SQLitePCLRaw.lib.e_sqlite3.v110_xp

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried this package with VS 2017 and the .NET Core SDK? I suspect you are going to run into this issue: NuGet/Home#4432. Basically, because the targets file adds the library as 'Content', it will end up in nuget packages. You can probably make a simple change to fix this. Set <Pack>false</Pack> on the Content items. You may also want to set CopyToPublishDirectory in addition to output directory.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I have not yet tested with VS 2017. Until a couple of days ago when the March release date was announced, I thought I had plenty of time. :-)

Thanks for the tip. I will investigate.

@Eilon
Copy link
Contributor

Eilon commented Feb 10, 2017

@natemcmaster re: new 3rd party dependency. Yup, already noted and we filed the paperwork with the paperwork people 😄

@ericsink
Copy link

FYI about bundle_green:

I currently have three bundles:

  1. bundle_e_sqlite3 (always uses my e_sqlite3 builds)
  2. bundle_sqlcipher (uses sqlcipher builds, which I currently get from couchbaselabs/couchbase-lite-libsqlcipher )
  3. bundle_green

Basically, bundle_green means "Use the e_sqlite3 builds everywhere except iOS. On iOS, use the SQLite provided by the system."

In other words, it is identical to bundle_e_sqlite3, except on iOS.

Why is it called "green"? Because it provides the behavior that Frank Krueger aka @praeclarum wanted for sqlite-net-pcl, and it didn't seem right to call it bundle_frank, and bundle_sqlite_net is confusing, and bundle_use_e_sqlite3_everywhere_except_ios is too long, and Frank is from the pacific northwest where there are lots of trees, and trees are mostly green, and I had already spent too much time deciding on the name, so I just settled it and moved on.

Anyway, people like bundle_green, except one issue tends to come up. My e_sqlite3 builds are compiled with SQLite's default setting for thread safety, but the iOS system SQLite is compiled with a different setting. The main difference is that the iOS setting means that a sqlite3 connection handle cannot be shared across threads. Every so often, somebody has trouble because their app is giving different behavior on iOS than on other platforms.

Luckily, the thread safety setting can be changed at runtime, using sqlite3_config(). So, people can eliminate the inconsistency by changing the setting to one way or the other. However, sqlite3_config() needs to be called before any other sqlite function, and this is why those sqlite3_win32_set_directory calls in sqlite3_invoke.cs (see related comments elsewhere on this PR) are problematic. Currently, with SQLitePCL.raw on UWP, to call sqlite3_config, you have to (carefully) do a sqlite3_shutdown and then call sqlite3_config and then call sqlite3_initialize. Kinda messy, but it works, and only UWP has this problem.

Anyway, I tend to use bundle_e_sqlite3 in my own apps. Having consistent compile settings for the SQLite library seems more important to me than making the size of the iOS app smaller by using the system SQLite on that platform.

Anyway, if you stay with bundle_green, you may want to add the necessary sqlite3_config() calls to keep the thread safety behavior consistent across all platforms. OTOH, if you never share a sqlite3 connection handle across threads, those config calls probably are not necessary.

Switching to bundle_e_sqlite3 is an option as well.

Finally, it is worth noting that I would be happy to add (and maintain) another bundle which is customized for your requirements. Suppose you decide you want the same compile options on all platforms (like e_sqlite3), but you want compile options that are different from e_sqlite3. For example, I build e_sqlite3 with support for FTS, RTREE, and json. The builds would be smaller if any of those were removed.

@bricelam
Copy link
Contributor Author

bricelam commented Feb 10, 2017

@ericsink TBH, the only reason I picked SQLitePCLRaw.bundle_green is because Microsoft.Azure.Mobile.Client.SQLiteStore uses it, and I didn't want to create an ecosystem where mixing different SQLite technologies in the same project created NuGet package hell. 😈

For better or worse, it appears to have become the de facto bundle for library authors. Our saving grace is that we also let you bring your own bundle by dropping down to the Microsoft.Data.Sqlite.Core package.

Thanks for the heads up about multi-threading on iOS we saw similar issues on Mac before we started re-distributing SQLite there.

@ericsink
Copy link

@bricelam Makes sense. I believe I talked with them about the tradeoffs as well. I just want folks to be informed.

@natemcmaster
Copy link
Contributor

@ericsink what is your release timeline like for updates? I'm hesitant to sign off on this change now if we can't get a fix for ericsink/SQLitePCL.raw#140 (comment) before our next release.

The issue means anyone with VS 2017 and a class library referencing Microsoft.Data.Sqlite will end up with sqlite3.dll in their NuGet package when they call "dotnet pack".

@ericsink
Copy link

@natemcmaster I've been traveling, but this will be a priority when I get back in the office (tomorrow-ish). I would expect this to be days, or worst case, weeks.

When is your next release? I've had the impression it was still months away. Your concern makes me think I am misunderstanding something.

@natemcmaster
Copy link
Contributor

days, or worst case, weeks.

That's what I was hoping for, but wanted to double check. In that case, we will be fine. Our next release will be after that.

Copy link
Contributor

@natemcmaster natemcmaster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will probably need to bump to a new version of bundle_green with fixes to make it work better with Microsoft.NET.Sdk. Let's add an issue to track make sure we handle that before we release 2.0.

Otherwise, looks good. Let's get this in so we can get tests going.

One more bookkeeping thing: please update packages.csv in aspnet/Coherence before merging.

:shipit:

Changes:
* Switches NuGet dependency from SQLite to SQLitePCLRaw.bundle_green
* Splits into two packages:
    * Microsoft.Data.Sqlite--metapackage includes ADO.NET provider and native implementation of SQLite
    * Microsoft.Data.Sqlite.Core--just the ADO.NET provider (resolves #148, fixes #249)
* Removes SqliteEngine
* Updates SqliteConnection and SqliteDataReader Handle property return type from IntPtr to the SQLitePCL.raw primitives
* Stop normalizing relative paths (handled by SQLitePCL.raw)
* Target .NET Standard 1.2 (resolves #185)
* Bump minimum supported SQLite version to 3.7.15
* Other minor cleanups including C# 7 usage

Other notes:
* If a SQLitePCL.raw bundle is installed, Microsoft.Data.Sqlite.Core with auto-initialize it

Resolves #21, resolves #255
@bricelam bricelam merged commit 3e40a9d into aspnet:dev Feb 14, 2017
@bricelam bricelam deleted the raw branch February 14, 2017 16:16
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants