Skip to content

Commit

Permalink
Merge pull request #344 from jibedoubleve/issue/334
Browse files Browse the repository at this point in the history
(#334) (#343) Fix icons & Fix DB connection issues
  • Loading branch information
jibedoubleve authored Oct 26, 2023
2 parents 0892843 + 5f24dad commit defe230
Show file tree
Hide file tree
Showing 51 changed files with 681 additions and 408 deletions.
2 changes: 1 addition & 1 deletion src/Lanceur.Core/Models/AliasQueryResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public string Synonyms

public static AliasQueryResult FromName(string aliasName) => new() { Name = aliasName, Synonyms = aliasName };

public override int GetHashCode() => base.GetHashCode() + Parameters?.GetHashCode() ?? 0;
public override int GetHashCode() => (base.GetHashCode(), (Parameters?.GetHashCode() ?? 0)).GetHashCode();

#endregion Methods
}
16 changes: 16 additions & 0 deletions src/Lanceur.Core/Models/AliasQueryResultMixin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Lanceur.Core.Models;

public static class AliasQueryResultMixin
{
#region Methods

public static void UpdateIcon(this AliasQueryResult alias)
{
if (Uri.TryCreate(alias.FileName, UriKind.Absolute, out _))
{
alias.Icon = "Web";
}
}

#endregion Methods
}
2 changes: 1 addition & 1 deletion src/Lanceur.Core/Models/PluginExecutableQueryResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Lanceur.Core.Models
{
public class PluginExecutableQueryResult : SelfExecutableQueryResult
public sealed class PluginExecutableQueryResult : SelfExecutableQueryResult
{
#region Fields

Expand Down
14 changes: 10 additions & 4 deletions src/Lanceur.Core/Models/SelfExecutableQueryResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@ public abstract class SelfExecutableQueryResult : ExecutableQueryResult, ISelfEx
{
#region Constructors

public SelfExecutableQueryResult()
protected SelfExecutableQueryResult(string name, string description)
{
Name = name;
Description = description;
}

public SelfExecutableQueryResult(string name, string description)
protected SelfExecutableQueryResult()
{
Name = name;
Description = description;
}

#endregion Constructors

#region Properties

public override string Icon => "Console";

#endregion Properties

#region Methods

public abstract Task<IEnumerable<QueryResult>> ExecuteAsync(Cmdline cmdline = null);
Expand Down
10 changes: 10 additions & 0 deletions src/Lanceur.Core/Repositories/IDataDoctorRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Lanceur.Core.Repositories;

public interface IDataDoctorRepository
{
#region Methods

Task FixIconsAsync();

#endregion Methods
}
28 changes: 14 additions & 14 deletions src/Lanceur.Core/Repositories/IDbRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ public interface IDbRepository
/// <returns></returns>
public ExistingNameResponse CheckNamesExist(string[] names, long? idSession = null);

/// <summary>
/// Update the id and the counter of <paramref name="queryResult"/>
/// with the data of the database. It is used mainly to update
/// plugins therfore it'll make an exact search on the name
/// of the <see cref="QueryResult"/> and take the first item
/// of the list (that should only have one item)
/// </summary>
/// <param name="queryResult">The query result to hydrate</param>
void Hydrate(QueryResult queryResult);

/// <summary>
/// Get all the aliases
/// </summary>
Expand Down Expand Up @@ -91,18 +81,28 @@ public interface IDbRepository
IEnumerable<DataPoint<DateTime, double>> GetUsage(Per per, long? idSession = null);

/// <summary>
/// Hydrate the macro with its <c>id</c> and <c>count</c>. This method will try to find the
/// macro by using its name that should be something like '@it_s_name@'
/// Update the id and the counter of <paramref name="queryResult"/>
/// with the data of the database. It is used mainly to update
/// plugins therfore it'll make an exact search on the name
/// of the <see cref="QueryResult"/> and take the first item
/// of the list (that should only have one item)
/// </summary>
/// <param name="alias">Macro to hydrate</param>
void HydrateMacro(QueryResult alias);
/// <param name="queryResult">The query result to hydrate</param>
void Hydrate(QueryResult queryResult);

/// <summary>
/// Hydrate the alias with the additional parameters.
/// </summary>
/// <param name="alias">The alias to hydrate</param>
void HydrateAlias(AliasQueryResult alias);

/// <summary>
/// Hydrate the macro with its <c>id</c> and <c>count</c>. This method will try to find the
/// macro by using its name that should be something like '@it_s_name@'
/// </summary>
/// <param name="alias">Macro to hydrate</param>
void HydrateMacro(QueryResult alias);

/// <summary>
/// Update the usage of the specified <see cref="QueryResult"/>
/// </summary>
Expand Down
130 changes: 74 additions & 56 deletions src/Lanceur.Infra.SQLite/DbActions/AliasDbAction.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Dapper;
using System.Data.SQLite;
using System.Diagnostics.CodeAnalysis;
using System.Transactions;
using Dapper;
using Lanceur.Core.Models;
using Lanceur.Core.Services;
using Lanceur.Infra.SQLite.Entities;
Expand All @@ -7,18 +10,18 @@

namespace Lanceur.Infra.SQLite.DbActions
{
public class AliasDbAction : IDisposable
public class AliasDbAction
{
#region Fields

private readonly SQLiteConnectionScope _db;
private readonly ISQLiteConnectionScope _db;
private readonly IAppLogger _log;

#endregion Fields

#region Constructors

public AliasDbAction(SQLiteConnectionScope db, IAppLoggerFactory logFactory)
public AliasDbAction(ISQLiteConnectionScope db, IAppLoggerFactory logFactory)
{
_db = db;
_log = logFactory.GetLogger<AliasDbAction>();
Expand Down Expand Up @@ -72,33 +75,35 @@ delete from alias_usage
_log.Debug($"Removed '{cnt}' row(s) from 'alias_usage'. Id: {idd}");
}

private void CreateAdditionalParameters(AliasQueryResult alias) =>
CreateAdditionalParameters(alias.Id, alias.AdditionalParameters);
private void CreateAdditionalParameters(AliasQueryResult alias, SQLiteTransaction tx)
=> CreateAdditionalParameters(alias.Id, alias.AdditionalParameters, tx);

private void CreateAdditionalParameters(long idAlias, IEnumerable<QueryResultAdditionalParameters> parameters)
private void CreateAdditionalParameters(long idAlias, IEnumerable<QueryResultAdditionalParameters> parameters,
SQLiteTransaction tx)
{
// Remove existing additional alias parameters
var sql1 = "delete from alias_argument where id_alias = @idAlias";
_db.Connection.Execute(sql1, new { idAlias });

const string sql1 = "delete from alias_argument where id_alias = @idAlias";
tx.Connection.Execute(sql1, new { idAlias });
// Create alias additional parameters
var sql2 = @"
const string sql2 = @"
insert into alias_argument (id_alias, argument, name)
values(@idAlias, @parameter, @name);";
_db.Connection.Execute(sql2, parameters.ToEntity(idAlias));
tx.Connection.Execute(sql2, parameters.ToEntity(idAlias));
}

private void UpdateName(AliasQueryResult alias)
private void UpdateName(AliasQueryResult alias, SQLiteTransaction tx)
{
//Remove all names
var sql = @"delete from alias_name where id_alias = @id";
_db.Connection.Execute(sql, new { id = alias.Id });

const string sql = @"delete from alias_name where id_alias = @id";
tx.Connection.Execute(sql, new { id = alias.Id });
//Recreate new names
sql = @"insert into alias_name (id_alias, name) values (@id, @name)";
const string sql2 = @"insert into alias_name (id_alias, name) values (@id, @name)";
foreach (var name in alias.Synonyms.SplitCsv())
{
_db.Connection.Execute(sql, new { id = alias.Id, name });
tx.Connection.Execute(sql2, new { id = alias.Id, name });

}
}

Expand All @@ -113,9 +118,10 @@ internal IEnumerable<QueryResult> RefreshUsage(IEnumerable<QueryResult> results)
where id_alias in @ids;";

var dbResultAr = results as QueryResult[] ?? results.ToArray();
var dbResults = _db.Connection
.Query<KeywordUsage>(sql, new { ids = dbResultAr.Select(x => x.Id).ToArray() })
.ToArray();
var dbResults = _db.WithinTransaction(
tx => tx.Connection.Query<KeywordUsage>(sql, new { ids = dbResultAr.Select(x => x.Id).ToArray() })
.ToArray()
);

foreach (var result in dbResultAr)
{
Expand All @@ -128,7 +134,7 @@ internal IEnumerable<QueryResult> RefreshUsage(IEnumerable<QueryResult> results)

public bool CheckNameExists(AliasQueryResult alias, long idSession)
{
var sql = @"
const string sql = @"
select count(*)
from
alias_name an
Expand All @@ -137,11 +143,11 @@ alias_name an
lower(name) = @name
and a.id_session = @idSession";

var count = _db.Connection.ExecuteScalar<int>(sql, new
var count = _db.WithinTransaction(tx => tx.Connection.ExecuteScalar<int>(sql, new
{
name = alias.Name,
idSession
});
}));
return count > 0;
}

Expand All @@ -156,15 +162,17 @@ alias_name an
an.name in @names
and a.id_session = @idSession";

var result = _db.Connection
.Query<string>(sql, new { names, idSession })
.ToArray();
var result = _db.WithinTransaction(
tx => tx.Connection.Query<string>(sql, new { names, idSession })
.ToArray()
);

return new(result);
}

public long Create(ref AliasQueryResult alias, long idSession)
{
alias.UpdateIcon();
const string sqlAlias = @"
insert into alias (
arguments,
Expand All @@ -188,7 +196,7 @@ insert into alias (
@isHidden
);
select last_insert_rowid() from alias limit 1;";
var id = _db.Connection.ExecuteScalar<long>(sqlAlias, new
var param = new
{
Arguments = alias.Parameters,
alias.FileName,
Expand All @@ -199,23 +207,32 @@ insert into alias (
idSession,
alias.Icon,
alias.IsHidden
});
};

// Create synonyms
const string sqlSynonyms = @"insert into alias_name (id_alias, name) values (@id, @name)";
foreach (var name in alias.Synonyms.SplitCsv())
var csv = alias.Synonyms.SplitCsv();
var additionalParameters = alias.AdditionalParameters;
var id = _db.WithinTransaction(tx =>
{
_db.Connection.ExecuteScalar<long>(sqlSynonyms, new
var id = tx.Connection.ExecuteScalar<long>(sqlAlias, param);

// Create synonyms
const string sqlSynonyms = @"insert into alias_name (id_alias, name) values (@id, @name)";
foreach (var name in csv)
{
id,
name
});
}
tx.Connection.ExecuteScalar<long>(sqlSynonyms, new
{
id,
name
});
}

//Create additional arguments
CreateAdditionalParameters(id, additionalParameters, tx);
return id;
});

alias.Id = id;

//Create additional arguments
CreateAdditionalParameters(id, alias.AdditionalParameters);

// Return either the id of the created Alias or
// return the id of the just updated alias (which
Expand All @@ -237,12 +254,10 @@ public void CreateInvisible(ref QueryResult alias)
alias.Id = Create(ref queryResult, idSession);
}

public void Dispose() => _db.Dispose();

public long GetDefaultSessionId()
{
var sql = "select s_value from settings where lower(s_key) = 'idsession'";
var result = _db.Connection.Query<long>(sql).FirstOrDefault();
var result = _db.WithinTransaction(tx => tx.Connection.Query<long>(sql).FirstOrDefault());
return result;
}

Expand Down Expand Up @@ -288,7 +303,7 @@ order by
var hidden = includeHidden ? new[] { 0, 1 } : 0.ToEnumerable();
var arguments = new { idSession, name, hidden };

return _db.Connection.Query<AliasQueryResult>(sql, arguments).FirstOrDefault();
return _db.WithinTransaction(tx => tx.Connection.Query<AliasQueryResult>(sql, arguments).FirstOrDefault());
}

public KeywordUsage GetHiddenKeyword(string name)
Expand All @@ -308,7 +323,7 @@ alias a
where
hidden = 1
and n.name = @name;";
var result = _db.Connection.Query<KeywordUsage>(sql, new { name }).FirstOrDefault();
var result = _db.WithinTransaction(tx => tx.Connection.Query<KeywordUsage>(sql, new { name }).FirstOrDefault());

return result;
}
Expand Down Expand Up @@ -336,7 +351,7 @@ public void Remove(IEnumerable<SelectableAliasQueryResult> alias)

public long Update(AliasQueryResult alias)
{
var sql = @"
const string sql = @"
update alias
set
arguments = @parameters,
Expand All @@ -348,20 +363,23 @@ update alias
icon = @Icon
where id = @id;";

_db.Connection.Execute(sql, new
_db.WithinTransaction(tx =>
{
alias.Parameters,
alias.FileName,
alias.Notes,
alias.RunAs,
alias.StartMode,
alias.WorkingDirectory,
alias.Icon,
id = alias.Id
tx.Connection.Execute(sql, new
{
alias.Parameters,
alias.FileName,
alias.Notes,
alias.RunAs,
alias.StartMode,
alias.WorkingDirectory,
alias.Icon,
id = alias.Id
});
CreateAdditionalParameters(alias, tx);
UpdateName(alias, tx);
});

UpdateName(alias);
CreateAdditionalParameters(alias);
alias.SynonymsPreviousState = alias.Synonyms;
return alias.Id;
}
Expand Down
Loading

0 comments on commit defe230

Please sign in to comment.