/// <inheritdoc /> public async Task <Schematic <TState, TInput> > StoreSchematicAsync(Schematic <TState, TInput> schematic, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } if (schematic.SchematicName == null) { throw new ArgumentException("Schematic must have a name to be stored.", nameof(schematic)); } var schematicBytes = schematic.ToSchematicRepresentation(); var record = new Schematic { SchematicName = schematic.SchematicName, SchematicBytes = schematicBytes }; using (var context = DbContextFactory.CreateContext()) { context.Schematics.Add(record); await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); } return(schematic); }
/// <inheritdoc /> public async Task <ICollection <MachineStatus <TState, TInput> > > BulkCreateMachinesAsync( Schematic <TState, TInput> schematic, IEnumerable <IDictionary <string, string> > metadata, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } var schematicBytes = schematic.ToSchematicRepresentation(); var stateJson = schematic.InitialState.ToStateRepresentation(); var naturalStateName = schematic.InitialState is TypeState typeState?typeState.GetStateName() : null; const long commitNumber = 0L; var updatedTime = DateTimeOffset.UtcNow; var records = new List <Machine>(); var machineStatuses = new List <MachineStatus <TState, TInput> >(); foreach (var dictionary in metadata) { var machineId = Guid.NewGuid().ToString(); List <MetadataEntry> metadataEntries = null; if (dictionary != null) { metadataEntries = dictionary.Select(kvp => new MetadataEntry { Key = kvp.Key, Value = kvp.Value }).ToList(); } records.Add(new Machine { MachineId = machineId, SchematicBytes = schematicBytes, StateJson = stateJson, NaturalStateName = naturalStateName, CommitNumber = commitNumber, UpdatedTime = updatedTime, MetadataEntries = metadataEntries }); machineStatuses.Add(new MachineStatus <TState, TInput> { MachineId = machineId, Schematic = schematic.Clone(), State = schematic.InitialState, Metadata = dictionary, CommitNumber = commitNumber, UpdatedTime = updatedTime, StateBag = new Dictionary <string, string>(0) }); } using (var context = DbContextFactory.CreateContext()) { await context.AddRangeAsync(records, cancellationToken); await context.SaveChangesAsync(cancellationToken); } return(machineStatuses); }
/// <inheritdoc /> public async Task <MachineStatus <TState, TInput> > CreateMachineAsync( Schematic <TState, TInput> schematic, string machineId, IDictionary <string, string> metadata, CancellationToken cancellationToken = default) { if (schematic == null) { throw new ArgumentNullException(nameof(schematic)); } var id = machineId ?? Guid.NewGuid().ToString(); var schematicBytes = schematic.ToSchematicRepresentation(); var stateJson = schematic.InitialState.ToStateRepresentation(); var naturalStateName = schematic.InitialState is TypeState typeState?typeState.GetStateName() : null; const long commitNumber = 0L; var updatedTime = DateTimeOffset.UtcNow; var record = new Machine { MachineId = id, SchematicName = schematic.SchematicName, SchematicBytes = schematicBytes, StateJson = stateJson, NaturalStateName = naturalStateName, CommitNumber = commitNumber, UpdatedTime = updatedTime }; if (metadata != null) { record.MetadataEntries = metadata.Select(kvp => new MetadataEntry { Key = kvp.Key, Value = kvp.Value }).ToList(); } using (var context = DbContextFactory.CreateContext()) { context.Machines.Add(record); try { await context.SaveChangesAsync(cancellationToken); } catch (DbUpdateException dbEx) when(dbEx.InnerException is SqlException sqlEx && sqlEx.Number == 2627) { throw new MachineAlreadyExistException(record.MachineId); } } return(new MachineStatus <TState, TInput> { MachineId = id, Schematic = schematic.Clone(), State = schematic.InitialState, Metadata = metadata, CommitNumber = commitNumber, UpdatedTime = updatedTime, StateBag = new Dictionary <string, string>(0) }); }