Hi @scott-wright_8356 ,
Thanks; it's hard to say what the issue is, and unfortunately we don't really have any good troubleshooting tools here. That error is coming from within SQL Lite, and we can't reproduce it when we do a SMB share.
I wonder if you can follow some of the same troubleshooting steps? Specifcally like using ProcMon or mounting the network drive with SysInternals?
We just don't really have any means to troubleshoot this, so we'd need to go back to the drawing board to figure out why it doesn't work for you. You're welcome to keep exploring C#, but let me share the code that's closer to ProGet.
Here is the code that ProGet is running. It's kind of similar, but a little different. Note we are using System.Data.SQLite.Core-1.0.118
and .NET6.
private static SQLiteConnection OpenOrCreateDatabase(string fileName, out Dictionary<string, string> config)
{
var str = new SQLiteConnectionStringBuilder
{
DataSource = fileName,
FailIfMissing = false
}.ToString();
if (FileEx.Exists(fileName))
{
var conn = new SQLiteConnection(str);
try
{
conn.Open();
config = ReadConfig(conn);
if (config.TryGetValue("SchemaVersion", out var versionStr))
{
int version = int.Parse(versionStr);
if (version == 1)
{
using var cmd2 = new SQLiteCommand(GetScript("UpdateSchemaToV2"), conn);
cmd2.ExecuteNonQuery();
return conn;
}
else if (version == 2)
{
return conn;
}
}
}
catch
{
}
conn?.Dispose();
FileEx.Delete(fileName);
}
else
{
DirectoryEx.Create(PathEx.GetDirectoryName(fileName));
}
var conn2 = new SQLiteConnection(str);
conn2.Open();
using var cmd = new SQLiteCommand(GetScript("CreateSchema"), conn2);
cmd.ExecuteNonQuery();
cmd.CommandText = GetScript("UpdateSchemaToV2");
cmd.ExecuteNonQuery();
config = ReadConfig(conn2);
return conn2;
}
private static Dictionary<string, string> ReadConfig(SQLiteConnection conn)
{
using var cmd = new SQLiteCommand("SELECT Key_Name, Value_Text FROM OtherData", conn);
using var reader = cmd.ExecuteReader();
var res = new Dictionary<string, string>();
while (reader.Read())
{
var key = reader.GetString(0);
var value = reader.IsDBNull(1) ? null : reader.GetString(1);
res[key] = value;
}
return res;
}
Here is the CreateSchema
script:
CREATE TABLE OtherData
(
Key_Name TEXT PRIMARY KEY NOT NULL,
Value_Text TEXT
);
INSERT INTO OtherData (Key_Name, Value_Text) VALUES ('SchemaVersion', '1');
CREATE TABLE FetchInfo
(
Subdir_Name TEXT PRIMARY KEY NOT NULL,
Modified_Date INTEGER,
Fetch_Date INTEGER NOT NULL
);
CREATE TABLE ChannelData
(
Package_Name TEXT PRIMARY KEY NOT NULL,
Flags_Value INTEGER NOT NULL,
Description_Text TEXT,
DevUrl_Text TEXT,
DocSourceUrl_Text TEXT,
DocUrl_Text TEXT,
Home_Text TEXT,
Icon_Hash TEXT,
Icon_Url TEXT,
License_Text TEXT,
RunExports_Json BLOB,
SourceGitUrl_Text TEXT,
SourceUrl_Text TEXT,
Summary_Text TEXT,
Timestamp_Value INTEGER,
Version_Text TEXT NOT NULL,
Subdirs_Csv TEXT NOT NULL
);
CREATE TABLE RepoData
(
Package_Name TEXT NOT NULL,
Subdir_Name TEXT NOT NULL,
Version_Text TEXT NOT NULL,
Build_Text TEXT NOT NULL,
ArchiveType_Code INTEGER NOT NULL,
Build_Number INTEGER NOT NULL,
License_Text TEXT,
LicenseFamily_Text TEXT,
MD5_Hash BLOB,
SHA256_Hash BLOB,
Package_Size INTEGER NOT NULL,
Timestamp_Value INTEGER,
Dependencies_Json BLOB,
AppEntry_Text TEXT,
AppType_Text TEXT,
Type_Text TEXT,
Summary_Text TEXT,
Icon_Hash BLOB,
PRIMARY KEY (Package_Name, Version_Text, Subdir_Name, Build_Text, ArchiveType_Code)
);
Here is the UpdateSchemaToV2
script:
UPDATE OtherData
SET Value_Text = '2'
WHERE Key_Name = 'SchemaVersion';
ALTER TABLE RepoData
ADD Constraints_Json BLOB;
From there, it's just a bunch of inserts into those tables. The "unable to open database file" error would probably be occurring in the middle of those, but it's hard to say.
The race condition occurs when multiple threads run OpenOrCreateDatabase
at same time. It's rare as I mentioned.
Alana