Skip to content

Commit cf4af64

Browse files
committed
CRD commands for import map
1 parent d5b41e5 commit cf4af64

21 files changed

+254
-80
lines changed

Figment.Common/Schema.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ public async Task<bool> SaveAsync(CancellationToken cancellationToken)
8585
if (provider == null)
8686
return false;
8787

88-
var success = await provider.SaveAsync(this, cancellationToken);
88+
var saved = await provider.SaveAsync(this, cancellationToken);
8989
MarkModified();
90-
return success;
90+
return saved;
9191
}
9292

9393
public SchemaTextField AddTextField(string name, ushort? minLength = null, ushort? maxLength = null, string? pattern = null)

Figment.Common/Thing.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -578,9 +578,9 @@ public async Task<bool> SaveAsync(CancellationToken cancellationToken)
578578
if (provider == null)
579579
return false;
580580

581-
var success = await provider.SaveAsync(this, cancellationToken);
581+
var saved = await provider.SaveAsync(this, cancellationToken);
582582
MarkModified();
583-
return success;
583+
return saved;
584584
}
585585

586586
public async Task<(bool, Thing?)> AssociateWithSchemaAsync(string schemaGuid, CancellationToken cancellationToken)

Figment.Data.Local/JsonSchemaDefinition.cs

+2
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ public Schema ToSchema(FileInfo schemaFileInfo)
117117
schema.Properties.Add(prop.Key, prop.Value);
118118
}
119119

120+
schema.ImportMaps.AddRange(ImportMaps);
121+
120122
return schema;
121123
}
122124
}

Figment.Test/Data/Memory/Thing.cs

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Figment.Common;
12
using Figment.Common.Data;
23
using Figment.Data.Memory;
34

@@ -31,10 +32,19 @@ public async Task ThingCrud()
3132

3233
var tsp = AmbientStorageContext.StorageProvider.GetThingStorageProvider();
3334
Assert.IsNotNull(tsp);
35+
36+
var allThings = tsp.GetAll(CancellationToken.None).ToBlockingEnumerable();
37+
Assert.IsNotNull(allThings);
38+
Assert.AreEqual(0, allThings.Count());
39+
3440
var thing = await tsp.CreateAsync(csr.NewGuid, nameof(ThingCrud), CancellationToken.None);
3541
Assert.IsNotNull(thing);
3642
Assert.IsTrue(await tsp.GuidExists(thing.Guid, CancellationToken.None));
3743

44+
allThings = tsp.GetAll(CancellationToken.None).ToBlockingEnumerable();
45+
Assert.IsNotNull(allThings);
46+
Assert.AreEqual(1, allThings.Count());
47+
3848
// Set
3949
var tsr = await thing.Set("random", "value", CancellationToken.None);
4050
Assert.IsTrue(tsr.Success);
@@ -45,13 +55,38 @@ public async Task ThingCrud()
4555
// Clear
4656
await thing.Set("random", null, CancellationToken.None);
4757
Assert.AreEqual(0, thing.GetPropertyByName("random", CancellationToken.None).ToBlockingEnumerable().Count());
48-
props = thing.GetProperties(CancellationToken.None).ToBlockingEnumerable().ToArray();
58+
props = [.. thing.GetProperties(CancellationToken.None).ToBlockingEnumerable()];
4959
Assert.IsFalse(props.Any(p => string.CompareOrdinal("random", p.SimpleDisplayName) == 0));
5060

5161
// Still clear after reload
5262
thing = await tsp.LoadAsync(thing.Guid, CancellationToken.None);
5363
Assert.IsNotNull(thing);
5464
Assert.IsFalse(props.Any(p => string.CompareOrdinal("random", p.SimpleDisplayName) == 0));
5565

66+
var thing2 = await tsp.FindByNameAsync(nameof(ThingCrud), CancellationToken.None);
67+
Assert.AreNotEqual(Reference.EMPTY, thing2);
68+
Assert.AreEqual(thing.Guid, thing2.Guid);
69+
Assert.AreEqual(Reference.ReferenceType.Thing, thing2.Type);
70+
71+
var partialThings = tsp.FindByPartialNameAsync(csr.NewGuid, nameof(ThingCrud), CancellationToken.None).ToBlockingEnumerable();
72+
Assert.IsNotNull(partialThings);
73+
Assert.AreEqual(1, partialThings.Count());
74+
Assert.AreEqual(thing.Name, partialThings.First().name);
75+
Assert.AreEqual(thing.Guid, partialThings.First().reference.Guid);
76+
Assert.AreEqual(Reference.ReferenceType.Thing, partialThings.First().reference.Type);
77+
78+
var deleted = await thing.DeleteAsync(CancellationToken.None);
79+
Assert.IsTrue(deleted);
80+
81+
allThings = tsp.GetAll(CancellationToken.None).ToBlockingEnumerable();
82+
Assert.IsNotNull(allThings);
83+
Assert.AreEqual(0, allThings.Count());
84+
85+
thing2 = await tsp.FindByNameAsync(nameof(ThingCrud), CancellationToken.None);
86+
Assert.AreEqual(Reference.EMPTY, thing2);
87+
88+
partialThings = tsp.FindByPartialNameAsync(csr.NewGuid, nameof(ThingCrud), CancellationToken.None).ToBlockingEnumerable();
89+
Assert.IsNotNull(partialThings);
90+
Assert.AreEqual(0, partialThings.Count());
5691
}
5792
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using Figment.Common;
2+
using Figment.Common.Errors;
3+
using Spectre.Console.Cli;
4+
5+
namespace jot.Commands.Schemas.ImportMaps;
6+
7+
public class DeleteImportMapCommand : SchemaCancellableAsyncCommand<DeleteImportMapCommandSettings>
8+
{
9+
private enum ERROR_CODES : int
10+
{
11+
}
12+
13+
public override async Task<int> ExecuteAsync(CommandContext context, DeleteImportMapCommandSettings settings, CancellationToken cancellationToken)
14+
{
15+
if (string.IsNullOrWhiteSpace(settings.ImportMapName))
16+
{
17+
AmbientErrorContext.Provider.LogError("Import map name must be specified.");
18+
return (int)Globals.GLOBAL_ERROR_CODES.ARGUMENT_ERROR;
19+
}
20+
21+
var (tgs, schema, _) = await TryGetSchema(settings, cancellationToken);
22+
if (tgs != Globals.GLOBAL_ERROR_CODES.SUCCESS)
23+
return (int)tgs;
24+
25+
var importMap = schema!.ImportMaps.FirstOrDefault(i => string.Compare(i.Name, settings.ImportMapName, StringComparison.InvariantCultureIgnoreCase) == 0);
26+
27+
if (importMap == null)
28+
{
29+
AmbientErrorContext.Provider.LogError($"Schema '{schema.Name}' does not have an import map named '{settings.ImportMapName}'.");
30+
return (int)Globals.GLOBAL_ERROR_CODES.NOT_FOUND;
31+
}
32+
33+
schema.ImportMaps.Remove(importMap);
34+
var saved = await schema.SaveAsync(cancellationToken);
35+
if (!saved)
36+
{
37+
if (settings.Verbose ?? false)
38+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}' ({schema.Guid}).");
39+
else
40+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}'.");
41+
return (int)Globals.GLOBAL_ERROR_CODES.SCHEMA_SAVE_ERROR;
42+
}
43+
44+
AmbientErrorContext.Provider.LogDone($"Deleted import map '{importMap.Name}' from '{schema.Name}'.");
45+
return (int)Globals.GLOBAL_ERROR_CODES.SUCCESS;
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
using System.ComponentModel;
3+
using Spectre.Console;
4+
using Spectre.Console.Cli;
5+
6+
namespace jot.Commands.Schemas.ImportMaps;
7+
8+
public class DeleteImportMapCommandSettings : SchemaCommandSettings
9+
{
10+
public const int ARG_POSITION_MAP_NAME = 0;
11+
12+
[Description("Name of the import map")]
13+
[CommandArgument(ARG_POSITION_MAP_NAME, "<MAP_NAME>")]
14+
public string? ImportMapName { get; init; }
15+
16+
public override ValidationResult Validate()
17+
{
18+
if (string.IsNullOrWhiteSpace(ImportMapName))
19+
return ValidationResult.Error("Import map name must be specified");
20+
21+
return ValidationResult.Success();
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Spectre.Console;
2+
using Spectre.Console.Cli;
3+
4+
namespace jot.Commands.Schemas.ImportMaps;
5+
6+
public class ListImportMapsCommand : SchemaCancellableAsyncCommand<ListImportMapsCommandSettings>
7+
{
8+
public override async Task<int> ExecuteAsync(CommandContext context, ListImportMapsCommandSettings settings, CancellationToken cancellationToken)
9+
{
10+
var (tgs, schema, _) = await TryGetSchema(settings, cancellationToken);
11+
if (tgs != Globals.GLOBAL_ERROR_CODES.SUCCESS)
12+
return (int)tgs;
13+
14+
if (settings.AsTable ?? false)
15+
{
16+
Table table = new();
17+
table.AddColumn("Name");
18+
table.AddColumn("Type");
19+
table.AddColumn("Field Count");
20+
21+
foreach (var map in schema!.ImportMaps)
22+
{
23+
table.AddRow(map.Name, map.Format, map.FieldConfiguration.Count.ToString());
24+
}
25+
AnsiConsole.Write(table);
26+
}
27+
else
28+
{
29+
foreach (var map in schema!.ImportMaps)
30+
Console.WriteLine(map.Name);
31+
}
32+
33+
return (int)Globals.GLOBAL_ERROR_CODES.SUCCESS;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.ComponentModel;
2+
using Spectre.Console.Cli;
3+
4+
namespace jot.Commands.Schemas.ImportMaps;
5+
6+
public class ListImportMapsCommandSettings : SchemaCommandSettings
7+
{
8+
[Description("Outputs the list in a human-readable tabular format")]
9+
[CommandOption("--as-table")]
10+
public bool? AsTable { get; init; } = false;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using Figment.Common;
2+
using Figment.Common.Errors;
3+
using Spectre.Console.Cli;
4+
5+
namespace jot.Commands.Schemas.ImportMaps;
6+
7+
public class NewImportMapCommand : SchemaCancellableAsyncCommand<NewImportMapCommandSettings>
8+
{
9+
public override async Task<int> ExecuteAsync(CommandContext context, NewImportMapCommandSettings settings, CancellationToken cancellationToken)
10+
{
11+
if (string.IsNullOrWhiteSpace(settings.ImportMapName))
12+
{
13+
AmbientErrorContext.Provider.LogError("Import map name must be specified.");
14+
return (int)Globals.GLOBAL_ERROR_CODES.ARGUMENT_ERROR;
15+
}
16+
17+
if (string.IsNullOrWhiteSpace(settings.FileType))
18+
{
19+
AmbientErrorContext.Provider.LogError("Import map name must be specified.");
20+
return (int)Globals.GLOBAL_ERROR_CODES.ARGUMENT_ERROR;
21+
}
22+
23+
var (tgs, schema, _) = await TryGetSchema(settings, cancellationToken);
24+
if (tgs != Globals.GLOBAL_ERROR_CODES.SUCCESS)
25+
return (int)tgs;
26+
27+
if (schema!.ImportMaps.Any(i => string.Compare(i.Name, settings.ImportMapName, StringComparison.InvariantCultureIgnoreCase) == 0)) {
28+
AmbientErrorContext.Provider.LogError($"Schema '{schema.Name}' already has an import map named '{settings.ImportMapName}'.");
29+
return (int)Globals.GLOBAL_ERROR_CODES.ARGUMENT_ERROR;
30+
}
31+
32+
var importMap = new SchemaImportMap(settings.ImportMapName, settings.FileType);
33+
34+
schema!.ImportMaps.Add(importMap);
35+
var saved = await schema.SaveAsync(cancellationToken);
36+
if (!saved)
37+
{
38+
if (settings.Verbose ?? false)
39+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}' ({schema.Guid}).");
40+
else
41+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}'.");
42+
return (int)Globals.GLOBAL_ERROR_CODES.SCHEMA_SAVE_ERROR;
43+
}
44+
45+
AmbientErrorContext.Provider.LogDone($"Added new import map for '{importMap.Name}' to '{schema.Name}'.");
46+
return (int)Globals.GLOBAL_ERROR_CODES.SUCCESS;
47+
}
48+
}

jot/Commands/Schemas/NewImportMapCommandSettings.cs renamed to jot/Commands/Schemas/ImportMaps/NewImportMapCommandSettings.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using Spectre.Console;
44
using Spectre.Console.Cli;
55

6-
namespace jot.Commands.Schemas;
6+
namespace jot.Commands.Schemas.ImportMaps;
77

88
public class NewImportMapCommandSettings : SchemaCommandSettings
99
{

jot/Commands/Schemas/NewImportMapCommand.cs

-50
This file was deleted.

jot/Commands/Schemas/SchemaRenameCommand.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ public override async Task<int> ExecuteAsync(CommandContext context, SchemaRenam
2222
var saved = await schema.SaveAsync(cancellationToken);
2323
if (!saved)
2424
{
25-
AmbientErrorContext.Provider.LogError($"Unable to save schema with Guid '{schema.Guid}'.");
25+
if (settings.Verbose ?? false)
26+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}' ({schema.Guid}).");
27+
else
28+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}'.");
2629
return (int)Globals.GLOBAL_ERROR_CODES.SCHEMA_SAVE_ERROR;
2730
}
2831

jot/Commands/Schemas/SetSchemaDescriptionCommand.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ public override async Task<int> ExecuteAsync(CommandContext context, SetSchemaDe
1515
var saved = await schema.SaveAsync(cancellationToken);
1616
if (!saved)
1717
{
18-
AmbientErrorContext.Provider.LogError($"Unable to save schema with Guid '{schema.Guid}'.");
18+
if (settings.Verbose ?? false)
19+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}' ({schema.Guid}).");
20+
else
21+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}'.");
1922
return (int)Globals.GLOBAL_ERROR_CODES.SCHEMA_SAVE_ERROR;
2023
}
2124

jot/Commands/Schemas/SetSchemaPluralCommand.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ public override async Task<int> ExecuteAsync(CommandContext context, SetSchemaPl
2828
var saved = await schema.SaveAsync(cancellationToken);
2929
if (!saved)
3030
{
31-
AmbientErrorContext.Provider.LogError($"Unable to save schema with Guid '{schema.Guid}'.");
31+
if (settings.Verbose ?? false)
32+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}' ({schema.Guid}).");
33+
else
34+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}'.");
3235
return (int)ERROR_CODES.SCHEMA_SAVE_ERROR;
3336
}
3437

jot/Commands/Schemas/SetSchemaPropertyDisplayCommand.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ public override async Task<int> ExecuteAsync(CommandContext context, SetSchemaPr
5151
var saved = await schema.SaveAsync(cancellationToken);
5252
if (!saved)
5353
{
54-
AmbientErrorContext.Provider.LogError($"Unable to save schema with Guid '{schema.Guid}'.");
54+
if (settings.Verbose ?? false)
55+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}' ({schema.Guid}).");
56+
else
57+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}'.");
5558
return (int)Globals.GLOBAL_ERROR_CODES.SCHEMA_SAVE_ERROR;
5659
}
5760

jot/Commands/Schemas/SetSchemaPropertyFormulaCommand.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ public override async Task<int> ExecuteAsync(CommandContext context, SetSchemaPr
5050
var saved = await schema.SaveAsync(cancellationToken);
5151
if (!saved)
5252
{
53-
AmbientErrorContext.Provider.LogError($"Unable to save schema with Guid '{schema.Guid}'.");
53+
if (settings.Verbose ?? false)
54+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}' ({schema.Guid}).");
55+
else
56+
AmbientErrorContext.Provider.LogError($"Unable to save schema '{schema.Name}'.");
5457
return (int)Globals.GLOBAL_ERROR_CODES.SCHEMA_SAVE_ERROR;
5558
}
5659

0 commit comments

Comments
 (0)