feat(git-provider): Initial git registration storage in database
- update PostBuild.ps1 to not delete data directory created during debug - move sqlite-net-pcl to ModuleCore
This commit is contained in:
parent
caa65ca7c3
commit
633b35f7e9
5 changed files with 95 additions and 14 deletions
|
|
@ -1,4 +1,6 @@
|
||||||
namespace ModuleCore.Database;
|
using SQLite;
|
||||||
|
|
||||||
|
namespace ModuleCore.Database;
|
||||||
|
|
||||||
public class DatabaseManager
|
public class DatabaseManager
|
||||||
{
|
{
|
||||||
|
|
@ -16,8 +18,37 @@ public class DatabaseManager
|
||||||
_databaseLocation = new FileInfo(Path.Combine(".", "data", $"{SanitiseFilename(databaseName)}.db"));
|
_databaseLocation = new FileInfo(Path.Combine(".", "data", $"{SanitiseFilename(databaseName)}.db"));
|
||||||
|
|
||||||
Directory.CreateDirectory(_databaseLocation.DirectoryName!);
|
Directory.CreateDirectory(_databaseLocation.DirectoryName!);
|
||||||
var file = File.Create(_databaseLocation.FullName);
|
|
||||||
file.Close();
|
if (!File.Exists(_databaseLocation.FullName))
|
||||||
|
{
|
||||||
|
var file = File.Create(_databaseLocation.FullName);
|
||||||
|
file.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InConnection(Action<SQLiteConnection> dbAction)
|
||||||
|
{
|
||||||
|
using var conn = new SQLiteConnection(_databaseLocation.FullName);
|
||||||
|
dbAction(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T InConnection<T>(Func<SQLiteConnection, T> dbAction)
|
||||||
|
{
|
||||||
|
using var conn = new SQLiteConnection(_databaseLocation.FullName);
|
||||||
|
return dbAction(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a bool for the given query. Convenience method for <see cref="SQLiteConnection.ExecuteScalar"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">A query starting with SELECT 1, optionally paramaterised with ?</param>
|
||||||
|
/// <param name="args">Parameter values</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool Exists(string query, params object[] args)
|
||||||
|
{
|
||||||
|
using var conn = new SQLiteConnection(_databaseLocation.FullName);
|
||||||
|
var exists = conn.ExecuteScalar<bool?>(query, args);
|
||||||
|
return exists ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using ModuleCore.Database;
|
using ModuleCore.Database;
|
||||||
using ModuleCore.Git.Models;
|
using ModuleCore.Git.Models;
|
||||||
|
using SQLite;
|
||||||
|
|
||||||
namespace ModuleCore.Git;
|
namespace ModuleCore.Git;
|
||||||
|
|
||||||
|
|
@ -18,6 +19,11 @@ public class GitManager
|
||||||
|
|
||||||
_registrations = new ConcurrentDictionary<string, InternalGitRegistration>();
|
_registrations = new ConcurrentDictionary<string, InternalGitRegistration>();
|
||||||
_db = new DatabaseManager("git.db");
|
_db = new DatabaseManager("git.db");
|
||||||
|
|
||||||
|
_db.InConnection(conn =>
|
||||||
|
{
|
||||||
|
conn.CreateTable<InternalGitRegistration>();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GitManager Instance => GitManagerInstance.Value;
|
public static GitManager Instance => GitManagerInstance.Value;
|
||||||
|
|
@ -40,16 +46,46 @@ public class GitManager
|
||||||
? new DirectoryInfo(absoluteRepositoryLocation).Name
|
? new DirectoryInfo(absoluteRepositoryLocation).Name
|
||||||
: registrationName;
|
: registrationName;
|
||||||
|
|
||||||
if (_registrations.TryAdd(registrationName, new InternalGitRegistration
|
var gitRegistration = new InternalGitRegistration
|
||||||
{
|
|
||||||
Name = registrationName,
|
|
||||||
Location = absoluteRepositoryLocation,
|
|
||||||
}))
|
|
||||||
{
|
{
|
||||||
return registrationName;
|
Name = registrationName,
|
||||||
}
|
Location = absoluteRepositoryLocation,
|
||||||
|
Id = Guid.CreateVersion7(),
|
||||||
|
};
|
||||||
|
|
||||||
throw new Exception($"Git repo already registered with the name {registrationName}");
|
return _db.InConnection<string>(conn =>
|
||||||
|
{
|
||||||
|
// Query if we already have a registration either by name or location.
|
||||||
|
// tbh this is a bit of a janky way to do exists when I have to pass the query in anyway, but I just didn't
|
||||||
|
// want to do null checks and a truthy check so I wrap it in a barely-valuable method.
|
||||||
|
var registrationExists = _db.Exists(
|
||||||
|
$"""
|
||||||
|
SELECT 1
|
||||||
|
FROM {InternalGitRegistration.TableName}
|
||||||
|
WHERE Name = ? OR
|
||||||
|
Location = ?
|
||||||
|
""",
|
||||||
|
gitRegistration.Name,
|
||||||
|
gitRegistration.Location
|
||||||
|
);
|
||||||
|
|
||||||
|
if (registrationExists)
|
||||||
|
{
|
||||||
|
throw new Exception($"A Git repo is already registered with the name {registrationName} or location {absoluteRepositoryLocation}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the new record
|
||||||
|
conn.Insert(gitRegistration);
|
||||||
|
|
||||||
|
if (_registrations.TryAdd(registrationName, gitRegistration))
|
||||||
|
{
|
||||||
|
return registrationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This error case should be unlikely, but if a registration was removed but the registrations wasn't updated
|
||||||
|
// correctly then we'd unable to re-add a repo with the same name
|
||||||
|
throw new Exception("An error occured during registration.");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GitRegistration> ListRepos()
|
public List<GitRegistration> ListRepos()
|
||||||
|
|
@ -83,12 +119,22 @@ public class GitManager
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used for internal git registration and handles getting the current branch
|
/// Used for internal git registration and handles getting the current branch
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Table(TableName)]
|
||||||
private class InternalGitRegistration
|
private class InternalGitRegistration
|
||||||
{
|
{
|
||||||
private string _currentBranch = string.Empty;
|
private string _currentBranch = string.Empty;
|
||||||
private long _nextCheckTime;
|
private long _nextCheckTime;
|
||||||
public required string Name { get; set; }
|
internal const string TableName = "GitRegistration";
|
||||||
public required string Location { get; set; }
|
|
||||||
|
[PrimaryKey]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
[Indexed(Unique = true)]
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
[Indexed(Unique = true)]
|
||||||
|
public string Location { get; set; } = null!;
|
||||||
|
|
||||||
public string CurrentBranch => GetCurrentBranch();
|
public string CurrentBranch => GetCurrentBranch();
|
||||||
|
|
||||||
// TODO: not fully decided on if I want this feature or not, but keeping it in for now
|
// TODO: not fully decided on if I want this feature or not, but keeping it in for now
|
||||||
|
|
|
||||||
|
|
@ -13,4 +13,8 @@
|
||||||
</AssemblyAttribute>
|
</AssemblyAttribute>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="sqlite-net-pcl" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ $allowList = @(
|
||||||
"ModuleCore*"
|
"ModuleCore*"
|
||||||
"PowershellModule*"
|
"PowershellModule*"
|
||||||
"*SQLite*"
|
"*SQLite*"
|
||||||
|
"data"
|
||||||
)
|
)
|
||||||
Write-Host "Removing all non-module required files from '$targetDir'"
|
Write-Host "Removing all non-module required files from '$targetDir'"
|
||||||
Get-ChildItem -Path $targetDir -exclude $allowList | Remove-Item -Recurse
|
Get-ChildItem -Path $targetDir -exclude $allowList | Remove-Item -Recurse
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
<PackageReference Include="PowerShellStandard.Library" >
|
<PackageReference Include="PowerShellStandard.Library" >
|
||||||
<PrivateAssets>All</PrivateAssets>
|
<PrivateAssets>All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="sqlite-net-pcl" />
|
|
||||||
<PackageReference Include="System.Management.Automation" />
|
<PackageReference Include="System.Management.Automation" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue