diff --git a/Deploy/buildlpx.cmd b/Deploy/buildlpx.cmd index a499cdd..40fbe7b 100644 --- a/Deploy/buildlpx.cmd +++ b/Deploy/buildlpx.cmd @@ -1,4 +1,4 @@ -@set version=6.5.0 +@set version=6.5.1 @set zip="%ProgramFiles%\7-Zip\7z.exe" @set output="CsvLINQPadDriver.%version%.lpx6" diff --git a/Src/CsvLINQPadDriver/CodeGen/CsvCSharpCodeGenerator.cs b/Src/CsvLINQPadDriver/CodeGen/CsvCSharpCodeGenerator.cs index df80827..1d74050 100644 --- a/Src/CsvLINQPadDriver/CodeGen/CsvCSharpCodeGenerator.cs +++ b/Src/CsvLINQPadDriver/CodeGen/CsvCSharpCodeGenerator.cs @@ -1,6 +1,7 @@ using System; using System.CodeDom; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using System.Security; @@ -41,7 +42,7 @@ public static (string Code, IReadOnlyCollection GenerateTableRowDataTypeClass(table, _properties.HideRelationsFromDump)) .GroupBy(typeCode => typeCode.Type) - .ToList(); + .ToImmutableList(); return ($@" using System; diff --git a/Src/CsvLINQPadDriver/CsvDataContextDriver.cs b/Src/CsvLINQPadDriver/CsvDataContextDriver.cs index ffcade8..301639e 100644 --- a/Src/CsvLINQPadDriver/CsvDataContextDriver.cs +++ b/Src/CsvLINQPadDriver/CsvDataContextDriver.cs @@ -1,14 +1,17 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Reflection; -using CsvLINQPadDriver.DataDisplay; -using CsvLINQPadDriver.Helpers; +using Humanizer; using LINQPad; using LINQPad.Extensibility.DataContext; +using CsvLINQPadDriver.DataDisplay; +using CsvLINQPadDriver.Helpers; + namespace CsvLINQPadDriver { // ReSharper disable once ClassNeverInstantiated.Global @@ -24,8 +27,12 @@ public class CsvDataContextDriver : DynamicDataContextDriver public override string Author => "Martin Dobroucký (dobrou@gmail.com), Ivan Ivon (ivan.ivon@gmail.com)"; - public override string GetConnectionDescription(IConnectionInfo cxInfo) => - FileUtils.GetLongestCommonPrefixPath(new CsvDataContextDriverProperties(cxInfo).ParsedFiles); + public override string GetConnectionDescription(IConnectionInfo cxInfo) + { + var parsedFiles = new CsvDataContextDriverProperties(cxInfo).ParsedFiles.ToImmutableList(); + var parsedFilesCount = parsedFiles.Count; + return $"{FileUtils.GetLongestCommonPrefixPath(parsedFiles)}{(parsedFilesCount > 1 ? $" ({"file".ToQuantity(parsedFilesCount)})" : string.Empty)}"; + } public override bool ShowConnectionDialog(IConnectionInfo cxInfo, ConnectionDialogOptions connectionDialogOptions) { @@ -56,7 +63,7 @@ public override ICustomMemberProvider GetCustomDisplayMemberProvider(object obje public override IEnumerable GetNamespacesToAdd(IConnectionInfo cxInfo) { - yield return typeof(StringExtensions).Namespace!; + yield return typeof(Helpers.StringExtensions).Namespace!; } public override List GetSchemaAndBuildAssembly(IConnectionInfo cxInfo, AssemblyName assemblyToBuild, ref string nameSpace, ref string typeName) => diff --git a/Src/CsvLINQPadDriver/CsvDataContextDriverProperties.cs b/Src/CsvLINQPadDriver/CsvDataContextDriverProperties.cs index d51001d..7fb3ec5 100644 --- a/Src/CsvLINQPadDriver/CsvDataContextDriverProperties.cs +++ b/Src/CsvLINQPadDriver/CsvDataContextDriverProperties.cs @@ -37,7 +37,7 @@ public string Files public IEnumerable ParsedFiles => Regex.Split(Files, @"[\r\n]+") .Select(fileName => fileName.Trim()) - .Where(fileName => !string.IsNullOrEmpty(fileName)) + .GetFilesOnly() .Distinct(StringComparer.InvariantCultureIgnoreCase); public string CsvSeparator diff --git a/Src/CsvLINQPadDriver/CsvLINQPadDriver.csproj b/Src/CsvLINQPadDriver/CsvLINQPadDriver.csproj index 830415a..5862b27 100644 --- a/Src/CsvLINQPadDriver/CsvLINQPadDriver.csproj +++ b/Src/CsvLINQPadDriver/CsvLINQPadDriver.csproj @@ -24,11 +24,11 @@ MIT https://github.com/i2van/CsvLINQPadDriver NuGetIcon.png - Added single class generation for the similar CSV files. + Display number of files loaded. Copyright © Martin Dobroucký 2013-2014, Ivan Ivon 2021 - 6.5.0.0 - 6.5.0.0 - 6.5.0 + 6.5.1.0 + 6.5.1.0 + 6.5.1 true Connection.ico diff --git a/Src/CsvLINQPadDriver/DataDisplay/CsvRowMemberProvider.cs b/Src/CsvLINQPadDriver/DataDisplay/CsvRowMemberProvider.cs index 4975994..be6f480 100644 --- a/Src/CsvLINQPadDriver/DataDisplay/CsvRowMemberProvider.cs +++ b/Src/CsvLINQPadDriver/DataDisplay/CsvRowMemberProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Reflection; @@ -42,8 +43,8 @@ protected record ProviderData(IList Properties, IList F protected static ProviderData GetProviderData(Type objectType) { var param = Parameter(typeof(object)); - var properties = objectType.GetProperties().Where(IsMemberVisible).ToList(); - var fields = objectType.GetFields().Where(IsMemberVisible).ToList(); + var properties = objectType.GetProperties().Where(IsMemberVisible).ToImmutableList(); + var fields = objectType.GetFields().Where(IsMemberVisible).ToImmutableList(); return new ProviderData( properties, @@ -61,7 +62,7 @@ static bool IsMemberVisible(MemberInfo member) => (member.MemberType & (MemberTypes.Field | MemberTypes.Property)) != 0 && member.GetCustomAttributes(typeof(HideFromDumpAttribute), true).Length == 0; } - + public static ICustomMemberProvider? GetCsvRowMemberProvider(object objectToDisplay) { var objectType = objectToDisplay.GetType(); diff --git a/Src/CsvLINQPadDriver/DataModel/CsvDataModelGenerator.cs b/Src/CsvLINQPadDriver/DataModel/CsvDataModelGenerator.cs index 98e1301..8b28b1a 100644 --- a/Src/CsvLINQPadDriver/DataModel/CsvDataModelGenerator.cs +++ b/Src/CsvLINQPadDriver/DataModel/CsvDataModelGenerator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; @@ -27,12 +28,11 @@ private CsvDatabase CreateModel() { var files = FileUtils .EnumFiles(_csvDataContextDriverProperties.ParsedFiles) - .Select(f => f.Trim()) - .ToArray(); + .ToImmutableList(); var baseDir = FileUtils.GetLongestCommonPrefixPath(files); - var csvDatabase = new CsvDatabase(baseDir, CreateTables().ToList()); + var csvDatabase = new CsvDatabase(baseDir, CreateTables().ToImmutableList()); MakeCodeNamesUnique(csvDatabase.Tables); @@ -81,7 +81,7 @@ IEnumerable CreateTables() CodeName = CodeGenHelper.GetSafeCodeName(col.value), DisplayName = string.Empty }) - .ToList(); + .ToImmutableList(); yield return new CsvTable(file, csvSeparator, columns, new List()) { diff --git a/Src/CsvLINQPadDriver/Helpers/FileUtils.cs b/Src/CsvLINQPadDriver/Helpers/FileUtils.cs index 89a8042..6cf8b06 100644 --- a/Src/CsvLINQPadDriver/Helpers/FileUtils.cs +++ b/Src/CsvLINQPadDriver/Helpers/FileUtils.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Linq; @@ -179,18 +180,18 @@ public static char CsvDetectSeparator(string fileName, string[]? csvData = null) public static string GetLongestCommonPrefixPath(IEnumerable paths) { - var pathsValid = GetFiles(paths).ToArray(); + var pathsValid = paths.GetFilesOnly().ToImmutableList(); // Get longest common path prefix. var filePaths = pathsValid.FirstOrDefault()?.Split(Path.DirectorySeparatorChar) ?? new string[0]; return Enumerable.Range(1, filePaths.Length) - .Select(i => string.Join(Path.DirectorySeparatorChar, filePaths.Take(i).ToArray())) + .Select(i => string.Join(Path.DirectorySeparatorChar, filePaths.Take(i).ToImmutableList())) .LastOrDefault(prefix => pathsValid.All(path => path.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))) ?? string.Empty; } public static IEnumerable EnumFiles(IEnumerable paths) => - GetFiles(paths) + GetFilesOnly(paths) .SelectMany(EnumFiles) .Distinct(StringComparer.Ordinal); @@ -221,12 +222,13 @@ private static CsvParser CreateCsvParser(string fileName, char csvSeparator) return new CsvParser(new StreamReader(fileName, Encoding.Default, true, csvConfiguration.BufferSize / sizeof(char)), csvConfiguration); } - private static IEnumerable GetFiles(IEnumerable paths) => + public static IEnumerable GetFilesOnly(this IEnumerable paths) => paths + .Select(p => p.Trim()) .Where(p => !p.StartsWith("#")) .Where(p => !string.IsNullOrWhiteSpace(p)); - private static string[] EnumFiles(string path) + private static IEnumerable EnumFiles(string path) { try { @@ -253,18 +255,18 @@ private static string[] EnumFiles(string path) if (!Directory.Exists(baseDir)) { - return new string[0]; + return Enumerable.Empty(); } return Directory .EnumerateFiles(baseDir, file, file.Contains("**") ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly) - .ToArray(); + .ToImmutableList(); } catch(Exception exception) { CsvDataContextDriver.WriteToLog($"File enumeration failed for {path}", exception); - return new string[0]; + return Enumerable.Empty(); } } } diff --git a/Src/CsvLINQPadDriver/SchemaBuilder.cs b/Src/CsvLINQPadDriver/SchemaBuilder.cs index 751c915..7564fd7 100644 --- a/Src/CsvLINQPadDriver/SchemaBuilder.cs +++ b/Src/CsvLINQPadDriver/SchemaBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Reflection; @@ -49,9 +50,9 @@ internal static List GetSchemaAndBuildAssembly(ICsvDataContextDriv { foreach (var tableCodeGroup in tableCodeGroups.Where(codeGroup => codeGroup.Count() > 1)) { - var codeNames = tableCodeGroup.Select(g => g.CodeName).ToList(); + var codeNames = tableCodeGroup.Select(g => g.CodeName).ToImmutableList(); - var total = $"({codeNames.Count} total)"; + var total = $"({codeNames.Count} of {csvDataContextDriverProperties.ParsedFiles.Count()})"; schema.Insert(index++, new ExplorerItem($"{codeNames.First()} similar files {total} joined data", ExplorerItemKind.Schema, ExplorerIcon.View) { diff --git a/Tests/CsvLINQPadDriverTest/SchemaBuilderTest.cs b/Tests/CsvLINQPadDriverTest/SchemaBuilderTest.cs index e84b6a9..b8f96be 100644 --- a/Tests/CsvLINQPadDriverTest/SchemaBuilderTest.cs +++ b/Tests/CsvLINQPadDriverTest/SchemaBuilderTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using System.Reflection; @@ -52,7 +53,7 @@ public void GetSchemaAndBuildAssembly_CreatedAssembly_AsExpected((ICsvDataContex contextAssemblyName, ref nameSpace, ref contextTypeName - ).ToList(); + ).ToImmutableList(); // Debug info to console. explorerItems.ForEach(item => Console.WriteLine(item.DragText)); @@ -60,7 +61,7 @@ ref contextTypeName // Check returned explorer tree. explorerItems.Should().HaveCount(3); - explorerItems = explorerItems.Where(i => i.Kind == ExplorerItemKind.QueryableObject).ToList(); + explorerItems = explorerItems.Where(i => i.Kind == ExplorerItemKind.QueryableObject).ToImmutableList(); explorerItems.Select(i => i.DragText) .Should()