Skip to content

Commit

Permalink
feat: add the notion of language to the dialects (#707)
Browse files Browse the repository at this point in the history
* feat: add the notion of language to the dialects
* feat: handle language file extension in embedded resources and templates
  • Loading branch information
Seddryck authored Nov 27, 2023
1 parent ab3fe3f commit c37e200
Show file tree
Hide file tree
Showing 53 changed files with 339 additions and 207 deletions.
5 changes: 2 additions & 3 deletions DubUrl.Adomd.Testing/ConnectionUrlTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ public class ConnectionUrlTest
{
[SetUp]
public void DefaultRegistration()
{
DbProviderFactories.RegisterFactory("Microsoft.AnalysisServices.AdomdClient", Wrappers.AdomdFactory.Instance);
}
=> DbProviderFactories.RegisterFactory("Microsoft.AnalysisServices.AdomdClient"
, AdomdFactory.Instance);

[Test]
public void Connect_ValidUrl_AdomdConnection()
Expand Down
2 changes: 1 addition & 1 deletion DubUrl.Adomd/Mapping/PowerBiDesktopDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace DubUrl.Adomd.Mapping;

[Database<DaxDialect>(
[Database<StandardDaxDialect>(
"Power BI Desktop"
, new[] { "pbidesktop", "pbix", "powerbidesktop" }
, DatabaseCategory.Analytics
Expand Down
2 changes: 1 addition & 1 deletion DubUrl.Adomd/Mapping/PowerBiPremiumDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace DubUrl.Adomd.Mapping;

[Database<DaxDialect>(
[Database<StandardDaxDialect>(
"Power BI Premium"
, new[] { "powerbi", "pbi", "pbiazure", "pbipremium", "powerbipremium" }
, DatabaseCategory.Analytics
Expand Down
21 changes: 21 additions & 0 deletions DubUrl.Adomd/Querying/DaxLanguage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using DubUrl.Querying.Dialects;

namespace DubUrl.Adomd.Querying;

[Language(".dax")]
public class DaxLanguage : ILanguage
{
public virtual string Extension { get; }

public DaxLanguage()
{
Extension = GetType().GetCustomAttribute<LanguageAttribute>()?.Extension
?? throw new InvalidOperationException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ namespace DubUrl.Adomd.Querying;
[ReturnCaster<DecimalConverter>()]
[ReturnCaster<DateTimeCaster<DateOnly>>()]
[ReturnCaster<DateTimeCaster<TimeOnly>>()]
public class DaxDialect : BaseDialect
[ParentLanguage<DaxLanguage>()]
public class StandardDaxDialect : BaseDialect
{
internal DaxDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal StandardDaxDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/AnsiDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
namespace DubUrl.Querying.Dialects;

[Renderer<AnsiRenderer>()]
[ParentLanguage<SqlLanguage>]
public class AnsiDialect : BaseDialect
{
internal AnsiDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal AnsiDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
9 changes: 5 additions & 4 deletions DubUrl.Core/Querying/Dialects/BaseDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ public abstract class BaseDialect : IDialect
public IRenderer Renderer { get; }
public ICaster[] Casters { get; }
public virtual string[] Aliases { get; }

public BaseDialect(string[] aliases, IRenderer renderer)
: this(aliases, renderer, Array.Empty<ICaster>()) {}
public virtual ILanguage Language { get; }

public BaseDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
=> (Aliases, Renderer, Casters) = (aliases, renderer, casters);
=> (Language, Aliases, Renderer, Casters) = (new SqlLanguage(), aliases, renderer, casters);

public BaseDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
=> (Language, Aliases, Renderer, Casters) = (language, aliases, renderer, casters);
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/CockRoachDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace DubUrl.Querying.Dialects;
[Renderer<PgsqlRenderer>()]
[ReturnCaster<DateTimeCaster<DateOnly>>]
[ReturnCaster<TimeSpanCaster<TimeOnly>>]
[ParentLanguage<SqlLanguage>]
public class CockRoachDialect : BaseDialect
{
internal CockRoachDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal CockRoachDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/Db2Dialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
namespace DubUrl.Querying.Dialects;

[Renderer<AnsiRenderer>()]
[ParentLanguage<SqlLanguage>]
public class Db2Dialect : BaseDialect
{
internal Db2Dialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal Db2Dialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
18 changes: 15 additions & 3 deletions DubUrl.Core/Querying/Dialects/DialectBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ public void AddAlias(string alias, string original)

public void Build()
{
var languages = new Dictionary<string, ILanguage>
(
DialectAliases.Select
(
x => x.Key.GetCustomAttribute<ParentLanguageAttribute>()?.Language ?? throw new NullReferenceException()
).Distinct(new LanguageComparer())
.Select(x => new KeyValuePair<string, ILanguage>(x.Extension, x))
);

Dialects.Clear();
foreach (var dialectInfo in DialectAliases)
{
Expand All @@ -58,11 +67,14 @@ public void Build()
x => (ICaster)Activator.CreateInstance(x.CasterType)!)
?? Array.Empty<ICaster>()).ToArray();

Dialects.Add(dialectInfo.Key,
var language = dialectInfo.Key.GetCustomAttribute<ParentLanguageAttribute>()?.Language.Extension
?? throw new NullReferenceException();

Dialects.Add(dialectInfo.Key,
(IDialect)(
Activator.CreateInstance(dialectInfo.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null
, new[] { dialectInfo.Value.ToArray(), renderer, casters! }, null
)
, new[] { languages[language], dialectInfo.Value.ToArray(), renderer, casters! }, null
)
?? throw new ArgumentException()
)
);
Expand Down
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/DrillDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
namespace DubUrl.Querying.Dialects;

[Renderer<AnsiRenderer>()]
[ParentLanguage<SqlLanguage>]
public class DrillDialect : BaseDialect
{
internal DrillDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal DrillDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/DuckdbDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ namespace DubUrl.Querying.Dialects;
[ReturnCaster<Converter<TimeOnly>>]
[ReturnCaster<Converter<DateTime>>]
[ReturnCaster<Converter<TimeSpan>>]
[ParentLanguage<SqlLanguage>]
public class DuckdbDialect : BaseDialect
{
internal DuckdbDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal DuckdbDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/FirebirdSqlDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace DubUrl.Querying.Dialects;
[Renderer<FirebirdSqlRenderer>()]
[ReturnCaster<DateTimeCaster<DateOnly>>]
[ReturnCaster<TimeSpanCaster<TimeOnly>>]
[ParentLanguage<SqlLanguage>]
public class FirebirdSqlDialect : BaseDialect
{
internal FirebirdSqlDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal FirebirdSqlDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
1 change: 1 addition & 0 deletions DubUrl.Core/Querying/Dialects/IDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ public interface IDialect
public ICaster[] Casters { get; }

string[] Aliases { get; }
ILanguage Language { get; }
}
11 changes: 11 additions & 0 deletions DubUrl.Core/Querying/Dialects/ILanguage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DubUrl.Querying.Dialects;
public interface ILanguage
{
string Extension { get; }
}
16 changes: 16 additions & 0 deletions DubUrl.Core/Querying/Dialects/LanguageAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DubUrl.Querying.Dialects;

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class LanguageAttribute : Attribute
{
public LanguageAttribute(string extension)
=> Extension = extension.StartsWith(".") ? extension : $".{extension}";

public virtual string Extension { get; }
}
15 changes: 15 additions & 0 deletions DubUrl.Core/Querying/Dialects/LanguageComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DubUrl.Querying.Dialects;
internal class LanguageComparer : IEqualityComparer<ILanguage>
{
public bool Equals(ILanguage? x, ILanguage? y)
=> x?.Extension?.Equals(y?.Extension) ?? false;
public int GetHashCode([DisallowNull] ILanguage obj)
=> obj.Extension.GetHashCode();
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/MsExcelDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
namespace DubUrl.Querying.Dialects;

[Renderer<AnsiRenderer>()]
[ParentLanguage<SqlLanguage>]
public class MsExcelDialect : BaseDialect
{
internal MsExcelDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal MsExcelDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/MysqlDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ namespace DubUrl.Querying.Dialects;
[ReturnCaster<BooleanConverter>]
[ReturnCaster<DateTimeCaster<DateOnly>>]
[ReturnCaster<TimeSpanCaster<TimeOnly>>]
[ParentLanguage<SqlLanguage>]
public class MySqlDialect : BaseDialect
{
internal MySqlDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal MySqlDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/OracleDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
namespace DubUrl.Querying.Dialects;

[Renderer<AnsiRenderer>()]
[ParentLanguage<SqlLanguage>]
public class OracleDialect : BaseDialect
{
internal OracleDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal OracleDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
23 changes: 23 additions & 0 deletions DubUrl.Core/Querying/Dialects/ParentLanguageAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DubUrl.Querying.Dialects;

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class ParentLanguageAttribute : Attribute
{
public virtual ILanguage Language { get; }

public ParentLanguageAttribute(Type language)
=> Language = (ILanguage)Activator.CreateInstance(language)!;
}

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class ParentLanguageAttribute<T> : ParentLanguageAttribute where T : ILanguage
{
public ParentLanguageAttribute()
: base(typeof(T)) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/PgsqlDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace DubUrl.Querying.Dialects;
[Renderer<PgsqlRenderer>()]
[ReturnCaster<DateTimeCaster<DateOnly>>]
[ReturnCaster<TimeSpanCaster<TimeOnly>>]
[ParentLanguage<SqlLanguage>]
public class PgsqlDialect : BaseDialect
{
internal PgsqlDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal PgsqlDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/QuestDbDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ namespace DubUrl.Querying.Dialects;

[Renderer<PgsqlRenderer>()]
[ReturnCaster<DecimalConverter>]
[ParentLanguage<SqlLanguage>]
public class QuestDbDialect : BaseDialect
{
internal QuestDbDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal QuestDbDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/SnowflakeDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
namespace DubUrl.Querying.Dialects;

[Renderer<AnsiRenderer>()]
[ParentLanguage<SqlLanguage>]
public class SnowflakeDialect : BaseDialect
{
internal SnowflakeDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal SnowflakeDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
18 changes: 18 additions & 0 deletions DubUrl.Core/Querying/Dialects/SqlLanguage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DubUrl.Querying.Dialects;

[Language(".sql")]
public class SqlLanguage : ILanguage
{
public virtual string Extension { get; }

public SqlLanguage()
=> Extension = GetType().GetCustomAttribute<LanguageAttribute>()?.Extension
?? throw new InvalidOperationException();
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/SqliteDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ namespace DubUrl.Querying.Dialects;
[ReturnCaster<Parser<TimeOnly>>]
[ReturnCaster<Parser<DateTime>>]
[ReturnCaster<Parser<TimeSpan>>]
[ParentLanguage<SqlLanguage>]
public class SqliteDialect : BaseDialect
{
internal SqliteDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal SqliteDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/TSqlDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ namespace DubUrl.Querying.Dialects;
[ReturnCaster<DecimalConverter>]
[ReturnCaster<DateTimeCaster<DateOnly>>]
[ReturnCaster<TimeSpanCaster<TimeOnly>>]
[ParentLanguage<SqlLanguage>]
public class TSqlDialect : BaseDialect
{
internal TSqlDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal TSqlDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
5 changes: 3 additions & 2 deletions DubUrl.Core/Querying/Dialects/TeradataDialect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
namespace DubUrl.Querying.Dialects;

[Renderer<AnsiRenderer>()]
[ParentLanguage<SqlLanguage>]
public class TeradataDialect : BaseDialect
{
internal TeradataDialect(string[] aliases, IRenderer renderer, ICaster[] casters)
: base(aliases, renderer, casters) { }
internal TeradataDialect(ILanguage language, string[] aliases, IRenderer renderer, ICaster[] casters)
: base(language, aliases, renderer, casters) { }
}
Loading

0 comments on commit c37e200

Please sign in to comment.