diff --git a/Foundation.Data.Doublets.Cli/Foundation.Data.Doublets.Cli.csproj b/Foundation.Data.Doublets.Cli/Foundation.Data.Doublets.Cli.csproj index 1d8f9ab..e4d6c4d 100644 --- a/Foundation.Data.Doublets.Cli/Foundation.Data.Doublets.Cli.csproj +++ b/Foundation.Data.Doublets.Cli/Foundation.Data.Doublets.Cli.csproj @@ -15,7 +15,7 @@ link-foundation A CLI tool for links manipulation. clink - 2.2.2 + 2.3.0 Unlicense https://github.com/link-foundation/link-cli diff --git a/Foundation.Data.Doublets.Cli/Program.cs b/Foundation.Data.Doublets.Cli/Program.cs index 1f9bfed..aa96362 100644 --- a/Foundation.Data.Doublets.Cli/Program.cs +++ b/Foundation.Data.Doublets.Cli/Program.cs @@ -1,4 +1,5 @@ using System.CommandLine; +using System.IO; using Platform.Data; using Platform.Data.Doublets; using Platform.Data.Doublets.Memory.United.Generic; @@ -70,6 +71,12 @@ afterOption.AddAlias("--links"); afterOption.AddAlias("-a"); +var exportOption = new Option( + name: "--export", + description: "Export the links database to a LiNo file" +); +exportOption.AddAlias("-e"); + var rootCommand = new RootCommand("LiNo CLI Tool for managing links data store") { dbOption, @@ -79,11 +86,12 @@ structureOption, beforeOption, changesOption, - afterOption + afterOption, + exportOption }; rootCommand.SetHandler( - (string db, string queryOptionValue, string queryArgumentValue, bool trace, uint? structure, bool before, bool changes, bool after) => + (string db, string queryOptionValue, string queryArgumentValue, bool trace, uint? structure, bool before, bool changes, bool after, string exportFile) => { var decoratedLinks = new NamedLinksDecorator(db, trace); @@ -145,9 +153,14 @@ { PrintAllLinks(decoratedLinks); } + + if (!string.IsNullOrWhiteSpace(exportFile)) + { + ExportToLinoFile(decoratedLinks, exportFile); + } }, // Explicitly specify the type parameters - dbOption, queryOption, queryArgument, traceOption, structureOption, beforeOption, changesOption, afterOption + dbOption, queryOption, queryArgument, traceOption, structureOption, beforeOption, changesOption, afterOption, exportOption ); await rootCommand.InvokeAsync(args); @@ -189,4 +202,45 @@ static void PrintChange(NamedLinksDecorator links, DoubletLink linkBefore, var afterText = linkAfter.IsNull() ? "" : links.Format(linkAfter); var formattedChange = $"({beforeText}) ({afterText})"; Console.WriteLine(Namify(links, formattedChange)); +} + +static void ExportToLinoFile(NamedLinksDecorator links, string fileName) +{ + var exportLinks = new List>(); + var any = links.Constants.Any; + var query = new DoubletLink(index: any, source: any, target: any); + + links.Each(query, link => + { + // Get named representation if available, otherwise use ID + var sourceName = links.GetName(link.Source) ?? link.Source.ToString(); + var targetName = links.GetName(link.Target) ?? link.Target.ToString(); + + // Create LiNo Link with ID and source/target values + var linoLink = new Platform.Protocols.Lino.Link( + link.Index.ToString(), + new List> + { + new Platform.Protocols.Lino.Link(sourceName), + new Platform.Protocols.Lino.Link(targetName) + } + ); + + exportLinks.Add(linoLink); + return links.Constants.Continue; + }); + + // Export to LiNo format with clean formatting + string linoContent = Platform.Protocols.Lino.IListExtensions.Format(exportLinks, lessParentheses: true); + + try + { + File.WriteAllText(fileName, linoContent); + Console.WriteLine($"Exported {exportLinks.Count} links to {fileName}"); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error writing to file {fileName}: {ex.Message}"); + Environment.Exit(1); + } } \ No newline at end of file