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

Transaction fails due to invalid temporary directory on UWP #116

Closed
AlekseyMartynov opened this issue Aug 19, 2015 · 9 comments
Closed

Transaction fails due to invalid temporary directory on UWP #116

AlekseyMartynov opened this issue Aug 19, 2015 · 9 comments
Assignees
Milestone

Comments

@AlekseyMartynov
Copy link

(Not sure whether this library is meant to be usable in UAP, but based on aspnet/dnx#2302 I suppose that yes. Currently it works fine when referenced directly).

In UAP you need to adjust SQLite temp path (see similar issue oysteinkrog/SQLite.Net-PCL#157). Without it, certain scenarios involving DDL inside a transaction fail with "SQL logic error".

Related test case:

public MainPage() {
    this.InitializeComponent();

    var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, Guid.NewGuid().ToString());

    // >>>>> this line is a fix
    //SetDirectory(2, Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);

    using(var conn = new SqliteConnection("data source=" + dbPath)) {
        conn.Open();
        using(var cmd = conn.CreateCommand()) {
            cmd.CommandText = @"
                create table foo(id integer primary key, value integer);
                insert into foo(value) values ('a');

                begin; -- >>>>> this causes 'sql logic error'

                create table foo_copy(id integer primary key, value text);
                insert into foo_copy select * from foo;
            ";
            cmd.ExecuteNonQuery();
        }
    }
}

[DllImport("sqlite3", EntryPoint = "sqlite3_win32_set_directory", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
static extern int SetDirectory(uint directoryType, string directoryPath);
@bricelam
Copy link
Contributor

Hmm, I thought the native library had code that did this automatically...

@bricelam
Copy link
Contributor

You could always just do this too:

var command = connection.CreateCommand();
command.CommandText =
    $"PRAGMA data_store_directory = '{ApplicationData.Current.TemporaryFolder.Path}';";

connection.Open();
connection.ExecuteNonQuery();

@bricelam
Copy link
Contributor

I think the "pit of failure" here relates to #55. It sucks that you have to do two extra things on UWP just to get it working.

@natemcmaster
Copy link
Contributor

Interesting...why is this bug occurring? (and not just in our library). Isn't SQLite supposed to put temp files in the same directory as the database file?

@AlekseyMartynov
Copy link
Author

Both data_store_directory and temp_store_directory are deprecated. https://www.sqlite.org/pragma.html#pragma_data_store_directory

PRAGMA temp_store=MEMORY helps.

@divega
Copy link

divega commented Oct 22, 2015

According to the documentation PRAGMA data_store_directory is still supported for "WinRT" (read UWP) apps.

I am not sure we need to do anything with temp_store. In case it helps, I found a thread that claims SQLite will use whatever the TEMP environment variable says.

@natemcmaster
Copy link
Contributor

We could add automatically run this when a new connection opens. (e.g. https://github.com/natemcmaster/Microsoft.Data.Sqlite/commit/91e2be3ba5acd020aecf08bbfc2123f3992ee3fa). @bricelam how would we setup x-compile? This sample doesn't compile because there is no DNX-friendly way to add a reference Windows SDK APIs.

@bricelam
Copy link
Contributor

Blocked on aspnet/dnx#2302?

@natemcmaster
Copy link
Contributor

For true cross-compile, yes. We can probably get around this using DLR.

@natemcmaster natemcmaster changed the title Add API to set temp directory (needed for UAP) Transaction fails due to invalid temporary directory on UWP Oct 30, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants