Microsoft.Data.Sqlite

This commit is contained in:
Natsumi
2025-09-01 17:40:22 +12:00
parent 61d34db219
commit 6bbc46c9c4
5 changed files with 57 additions and 44 deletions
+2 -2
View File
@@ -7,12 +7,12 @@
using NLog; using NLog;
using NLog.Targets; using NLog.Targets;
using System; using System;
using System.Data.SQLite;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using Microsoft.Data.Sqlite;
namespace VRCX namespace VRCX
{ {
@@ -172,7 +172,7 @@ namespace VRCX
#region Handle Database Error #region Handle Database Error
catch (SQLiteException e) catch (SqliteException e)
{ {
logger.Fatal(e, "Unhandled SQLite Exception, closing."); logger.Fatal(e, "Unhandled SQLite Exception, closing.");
var messageBoxResult = MessageBox.Show( var messageBoxResult = MessageBox.Show(
+29 -24
View File
@@ -1,18 +1,17 @@
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.SQLite;
using System.IO;
using System.Text.Json.Nodes;
using System.Threading; using System.Threading;
using System.Text.Json; using System.Text.Json;
using Microsoft.Data.Sqlite;
namespace VRCX namespace VRCX
{ {
public class SQLite public class SQLite
{ {
public static SQLite Instance; public static SQLite Instance;
private readonly ReaderWriterLockSlim m_ConnectionLock; private readonly ReaderWriterLockSlim _connectionLock;
private SQLiteConnection m_Connection; private SqliteConnection _connection;
static SQLite() static SQLite()
{ {
@@ -21,7 +20,7 @@ namespace VRCX
public SQLite() public SQLite()
{ {
m_ConnectionLock = new ReaderWriterLockSlim(); _connectionLock = new ReaderWriterLockSlim();
} }
public void Init() public void Init()
@@ -34,18 +33,24 @@ namespace VRCX
if (!string.IsNullOrEmpty(jsonDataSource)) if (!string.IsNullOrEmpty(jsonDataSource))
dataSource = jsonDataSource; dataSource = jsonDataSource;
m_Connection = new SQLiteConnection($"Data Source=\"{dataSource}\";Version=3;PRAGMA locking_mode=NORMAL;PRAGMA busy_timeout=5000;PRAGMA journal_mode=WAL;PRAGMA optimize=0x10002;", true); _connection = new SqliteConnection($"Data Source=\"{dataSource}\";Mode=ReadWriteCreate;Cache=Shared;");
_connection.Open();
m_Connection.Open(); using var command = _connection.CreateCommand();
command.CommandText = @"PRAGMA locking_mode=NORMAL;
PRAGMA busy_timeout=5000;
PRAGMA journal_mode=WAL;
PRAGMA optimize=0x10002;";
command.ExecuteNonQuery();
} }
public void Exit() public void Exit()
{ {
m_Connection.Close(); _connection.Close();
m_Connection.Dispose(); _connection.Dispose();
} }
public string ExecuteJson(string sql, IDictionary<string, object> args = null) // for Electron
public string ExecuteJson(string sql, IDictionary<string, object>? args = null)
{ {
var result = Execute(sql, args); var result = Execute(sql, args);
if (result.Item1 != null) if (result.Item1 != null)
@@ -63,17 +68,17 @@ namespace VRCX
}); });
} }
public Tuple<string, object[]> Execute(string sql, IDictionary<string, object> args = null) public Tuple<string?, object[][]?> Execute(string sql, IDictionary<string, object>? args = null)
{ {
m_ConnectionLock.EnterReadLock(); _connectionLock.EnterReadLock();
try try
{ {
using var command = new SQLiteCommand(sql, m_Connection); using var command = new SqliteCommand(sql, _connection);
if (args != null) if (args != null)
{ {
foreach (var arg in args) foreach (var arg in args)
{ {
command.Parameters.Add(new SQLiteParameter(arg.Key, arg.Value)); command.Parameters.Add(new SqliteParameter(arg.Key, arg.Value));
} }
} }
@@ -88,37 +93,37 @@ namespace VRCX
} }
result.Add(values); result.Add(values);
} }
return new Tuple<string, object[]>(null, result.ToArray()); return new Tuple<string?, object[][]?>(null, result.ToArray());
} }
catch (Exception ex) catch (Exception ex)
{ {
return new Tuple<string, object[]>(ex.Message, null); return new Tuple<string?, object[][]?>(ex.Message, null);
} }
finally finally
{ {
m_ConnectionLock.ExitReadLock(); _connectionLock.ExitReadLock();
} }
} }
public int ExecuteNonQuery(string sql, IDictionary<string, object> args = null) public int ExecuteNonQuery(string sql, IDictionary<string, object>? args = null)
{ {
int result = -1; int result = -1;
m_ConnectionLock.EnterWriteLock(); _connectionLock.EnterWriteLock();
try try
{ {
using var command = new SQLiteCommand(sql, m_Connection); using var command = new SqliteCommand(sql, _connection);
if (args != null) if (args != null)
{ {
foreach (var arg in args) foreach (var arg in args)
{ {
command.Parameters.Add(new SQLiteParameter(arg.Key, arg.Value)); command.Parameters.Add(new SqliteParameter(arg.Key, arg.Value));
} }
} }
result = command.ExecuteNonQuery(); result = command.ExecuteNonQuery();
} }
finally finally
{ {
m_ConnectionLock.ExitWriteLock(); _connectionLock.ExitWriteLock();
} }
return result; return result;
@@ -1,6 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.SQLite; using Microsoft.Data.Sqlite;
namespace VRCX namespace VRCX
{ {
@@ -16,20 +16,27 @@ namespace VRCX
// Couldn't be me... oh wait // Couldn't be me... oh wait
internal class ScreenshotMetadataDatabase internal class ScreenshotMetadataDatabase
{ {
private readonly SQLiteConnection _sqlite; private readonly SqliteConnection _sqlite;
public ScreenshotMetadataDatabase(string databaseLocation) public ScreenshotMetadataDatabase(string databaseLocation)
{ {
_sqlite = new SQLiteConnection($"Data Source=\"{databaseLocation}\";Version=3;PRAGMA locking_mode=NORMAL;PRAGMA busy_timeout=5000;PRAGMA journal_mode=WAL;PRAGMA optimize=0x10002;", true); _sqlite = new SqliteConnection($"Data Source=\"{databaseLocation}\";Mode=ReadWriteCreate;Cache=Shared;");
_sqlite.Open(); _sqlite.Open();
using var cmd = new SQLiteCommand(_sqlite); using var command = _sqlite.CreateCommand();
cmd.CommandText = @"CREATE TABLE IF NOT EXISTS cache ( command.CommandText = @"PRAGMA locking_mode=NORMAL;
PRAGMA busy_timeout=5000;
PRAGMA journal_mode=WAL;
PRAGMA optimize=0x10002;";
command.ExecuteNonQuery();
var createCommand = _sqlite.CreateCommand();
createCommand.CommandText = @"CREATE TABLE IF NOT EXISTS cache (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
file_path TEXT NOT NULL UNIQUE, file_path TEXT NOT NULL UNIQUE,
metadata TEXT, metadata TEXT,
cached_at INTEGER NOT NULL cached_at INTEGER NOT NULL
);"; );";
cmd.ExecuteNonQuery(); createCommand.ExecuteNonQuery();
} }
public void AddMetadataCache(string filePath, string metadata) public void AddMetadataCache(string filePath, string metadata)
@@ -46,7 +53,7 @@ namespace VRCX
CachedAt = DateTimeOffset.Now CachedAt = DateTimeOffset.Now
}; };
const string sql = "INSERT OR REPLACE INTO cache (file_path, metadata, cached_at) VALUES (@FilePath, @Metadata, @CachedAt);"; const string sql = "INSERT OR REPLACE INTO cache (file_path, metadata, cached_at) VALUES (@FilePath, @Metadata, @CachedAt);";
using var command = new SQLiteCommand(sql, _sqlite); using var command = new SqliteCommand(sql, _sqlite);
command.Parameters.AddWithValue("@FilePath", cache.FilePath); command.Parameters.AddWithValue("@FilePath", cache.FilePath);
command.Parameters.AddWithValue("@Metadata", cache.Metadata); command.Parameters.AddWithValue("@Metadata", cache.Metadata);
command.Parameters.AddWithValue("@CachedAt", cache.CachedAt.Ticks); command.Parameters.AddWithValue("@CachedAt", cache.CachedAt.Ticks);
@@ -56,12 +63,12 @@ namespace VRCX
public void BulkAddMetadataCache(IEnumerable<MetadataCache> cache) public void BulkAddMetadataCache(IEnumerable<MetadataCache> cache)
{ {
using var transaction = _sqlite.BeginTransaction(); using var transaction = _sqlite.BeginTransaction();
using var command = new SQLiteCommand(_sqlite); using var command = _sqlite.CreateCommand();
const string sql = "INSERT OR REPLACE INTO cache (file_path, metadata, cached_at) VALUES (@FilePath, @Metadata, @CachedAt);"; const string sql = "INSERT OR REPLACE INTO cache (file_path, metadata, cached_at) VALUES (@FilePath, @Metadata, @CachedAt);";
command.CommandText = sql; command.CommandText = sql;
var filePathParam = command.Parameters.Add("@FilePath", System.Data.DbType.String); var filePathParam = command.Parameters.Add("@FilePath", SqliteType.Text);
var metadataParam = command.Parameters.Add("@Metadata", System.Data.DbType.String); var metadataParam = command.Parameters.Add("@Metadata", SqliteType.Text);
var cachedAtParam = command.Parameters.Add("@CachedAt", System.Data.DbType.Int64); var cachedAtParam = command.Parameters.Add("@CachedAt", SqliteType.Integer);
foreach (var item in cache) foreach (var item in cache)
{ {
var isFileCached = IsFileCached(item.FilePath); var isFileCached = IsFileCached(item.FilePath);
@@ -79,7 +86,8 @@ namespace VRCX
public int IsFileCached(string filePath) public int IsFileCached(string filePath)
{ {
const string sql = "SELECT id FROM cache WHERE file_path = @FilePath;"; const string sql = "SELECT id FROM cache WHERE file_path = @FilePath;";
using var command = new SQLiteCommand(sql, _sqlite); using var command = _sqlite.CreateCommand();
command.CommandText = sql;
command.Parameters.AddWithValue("@FilePath", filePath); command.Parameters.AddWithValue("@FilePath", filePath);
using var reader = command.ExecuteReader(); using var reader = command.ExecuteReader();
var result = new List<int>(); var result = new List<int>();
@@ -97,7 +105,8 @@ namespace VRCX
public string? GetMetadata(string filePath) public string? GetMetadata(string filePath)
{ {
const string sql = "SELECT id, file_path, metadata, cached_at FROM cache WHERE file_path = @FilePath;"; const string sql = "SELECT id, file_path, metadata, cached_at FROM cache WHERE file_path = @FilePath;";
using var command = new SQLiteCommand(sql, _sqlite); using var command = _sqlite.CreateCommand();
command.CommandText = sql;
command.Parameters.AddWithValue("@FilePath", filePath); command.Parameters.AddWithValue("@FilePath", filePath);
using var reader = command.ExecuteReader(); using var reader = command.ExecuteReader();
var result = new List<MetadataCache>(); var result = new List<MetadataCache>();
@@ -121,7 +130,8 @@ namespace VRCX
public string? GetMetadataById(int id) public string? GetMetadataById(int id)
{ {
const string sql = "SELECT id, file_path, metadata, cached_at FROM cache WHERE id = @Id;"; const string sql = "SELECT id, file_path, metadata, cached_at FROM cache WHERE id = @Id;";
using var command = new SQLiteCommand(sql, _sqlite); using var command = _sqlite.CreateCommand();
command.CommandText = sql;
command.Parameters.AddWithValue("@Id", id); command.Parameters.AddWithValue("@Id", id);
using var reader = command.ExecuteReader(); using var reader = command.ExecuteReader();
var result = new List<MetadataCache>(); var result = new List<MetadataCache>();
+1 -2
View File
@@ -91,6 +91,7 @@
<PackageReference Include="CefSharp.OffScreen.NETCore" Version="138.0.340" /> <PackageReference Include="CefSharp.OffScreen.NETCore" Version="138.0.340" />
<PackageReference Include="CefSharp.WinForms.NETCore" Version="138.0.340" /> <PackageReference Include="CefSharp.WinForms.NETCore" Version="138.0.340" />
<PackageReference Include="DiscordRichPresence" Version="1.6.1.70" /> <PackageReference Include="DiscordRichPresence" Version="1.6.1.70" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.8" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" /> <PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="6.0.3" /> <PackageReference Include="NLog" Version="6.0.3" />
@@ -98,8 +99,6 @@
<PackageReference Include="SharpDX.Mathematics" Version="4.2.0" /> <PackageReference Include="SharpDX.Mathematics" Version="4.2.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" /> <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
<PackageReference Include="System.Data.SQLite" Version="2.0.1" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" />
<PackageReference Include="System.Drawing.Common" Version="9.0.8" /> <PackageReference Include="System.Drawing.Common" Version="9.0.8" />
<PackageReference Include="System.Management" Version="9.0.8" /> <PackageReference Include="System.Management" Version="9.0.8" />
<PackageReference Include="System.Text.Json" Version="9.0.8" /> <PackageReference Include="System.Text.Json" Version="9.0.8" />
+1 -2
View File
@@ -87,6 +87,7 @@
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.8" />
<PackageReference Include="Microsoft.JavaScript.NodeApi" Version="0.9.15" /> <PackageReference Include="Microsoft.JavaScript.NodeApi" Version="0.9.15" />
<PackageReference Include="Microsoft.JavaScript.NodeApi.Generator" Version="0.9.15" /> <PackageReference Include="Microsoft.JavaScript.NodeApi.Generator" Version="0.9.15" />
<PackageReference Include="DiscordRichPresence" Version="1.6.1.70" /> <PackageReference Include="DiscordRichPresence" Version="1.6.1.70" />
@@ -94,8 +95,6 @@
<PackageReference Include="NLog" Version="6.0.3" /> <PackageReference Include="NLog" Version="6.0.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" /> <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
<PackageReference Include="System.Data.SQLite" Version="2.0.1" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" />
<PackageReference Include="System.Drawing.Common" Version="9.0.8" /> <PackageReference Include="System.Drawing.Common" Version="9.0.8" />
<PackageReference Include="System.Management" Version="9.0.8" /> <PackageReference Include="System.Management" Version="9.0.8" />
<PackageReference Include="System.Text.Json" Version="9.0.8" /> <PackageReference Include="System.Text.Json" Version="9.0.8" />