/// If no version specified and atom does not exist, creates atom with default version "1.0.0" /// If no version specified and atom does exist, or there is an atom with specified version, /// creates new version with the same major and middle versions and incremented minor version public async Task <AtomId> AddAsync(AtomId atomId, IEnumerable <AtomId> dependencies, byte[] content) { if (await ExistsExactAsync(atomId)) { throw new ArgumentException(string.Format(AtomAlreadyExists, atomId.Kind, atomId.Name, atomId.Version)); } var version = atomId.Version ?? await LastVersionAsync(atomId.Kind, atomId.Name); if (atomId.Version == null && version != null) { VersionUtils.TryParse(version, out int major, out int?middle, out int?minor, out string name); version = VersionUtils.Serialize(major, middle.GetValueOrDefault(), minor.GetValueOrDefault() + 1, null); } else if (atomId.Version == null) { version = AtomId.DefaultVersion; } var dbAtom = new Atom { Kind = atomId.Kind, Name = atomId.Name, Version = version, }; await _context.Atoms.AddAsync(dbAtom); dependencies = await FetchVersionsAsync(dependencies); var depRefs = dependencies.Select(depId => _context.Atoms.Single(a => a.Kind == depId.Kind && a.Name == depId.Name && a.Version == depId.Version)); var dbDeps = from dep in depRefs select new AtomDependency { Dependent = dbAtom, Dependency = dep }; await _context.AtomDependencies.AddRangeAsync(dbDeps); var dbContent = new AtomContent { Atom = dbAtom, Content = content }; await _context.AtomContents.AddAsync(dbContent); await _context.SaveChangesAsync(); return(new AtomId(atomId.Kind, atomId.Name, version)); }