internal async Task DeleteRefByNameTest()
        {
            TreeNode tr = new TreeNode.Builder(new List <TreeTreeReference>(0), new List <TreeBlobReference>(0));
            await trrepo.PersistTree(tr.ID, new IVO.Definition.Containers.ImmutableContainer <TreeID, TreeNode>(trx => trx.ID, tr));

            Commit cm = new Commit.Builder(new List <CommitID>(0), tr.ID, "James S. Dunne", DateTimeOffset.Now, "Initial commit.");
            await cmrepo.PersistCommit(cm);

            Ref rf = new Ref.Builder((RefName)"v1.0", cm.ID);
            await rfrepo.PersistRef(rf);

            var edrf = await rfrepo.DeleteRefByName((RefName)"v1.0");

            Assert.IsFalse(edrf.HasErrors);
            Ref drf = edrf.Value;

            Assert.IsNotNull(drf);
            Assert.AreEqual(rf.Name.ToString(), drf.Name.ToString());
            Assert.AreEqual(rf.CommitID, drf.CommitID);

            var errf = await rfrepo.GetRefByName((RefName)"v1.0");

            Assert.IsTrue(errf.HasErrors);
            Assert.AreEqual(1, errf.Errors.Count);
        }
Пример #2
0
        internal async Task DeleteTagByNameTest()
        {
            TreeNode tr = new TreeNode.Builder(new List <TreeTreeReference>(0), new List <TreeBlobReference>(0));
            await trrepo.PersistTree(tr.ID, new IVO.Definition.Containers.ImmutableContainer <TreeID, TreeNode>(trx => trx.ID, tr));

            Commit cm = new Commit.Builder(new List <CommitID>(0), tr.ID, "James S. Dunne", DateTimeOffset.Now, "Initial commit.");
            await cmrepo.PersistCommit(cm);

            Tag tg = new Tag.Builder((TagName)"v1.0", cm.ID, "James S. Dunne", DateTimeOffset.Now, "Testing tags");
            await tgrepo.PersistTag(tg);

            var retgPre = await tgrepo.GetTag(tg.ID);

            Assert.IsFalse(retgPre.HasErrors);

            Tag rtgPre = retgPre.Value;

            Assert.IsNotNull(rtgPre);
            Assert.AreEqual(tg.ID, rtgPre.ID);
            Assert.AreEqual(tg.Name.ToString(), rtgPre.Name.ToString());
            Assert.AreEqual(tg.CommitID, rtgPre.CommitID);
            Assert.AreEqual(tg.Tagger, rtgPre.Tagger);
            Assert.AreEqual(tg.DateTagged.ToString(), rtgPre.DateTagged.ToString());

            await tgrepo.DeleteTagByName((TagName)"v1.0");

            var retgPost = await tgrepo.GetTag(tg.ID);

            Assert.IsTrue(retgPost.HasErrors);
            Assert.AreEqual(1, retgPost.Errors.Count);
        }
Пример #3
0
        void TestIDGeneration()
        {
            // Create a Blob:
            Blob bl = new Blob.Builder(
                pContents: Encoding.UTF8.GetBytes("Sample README content.")
                );

            Console.WriteLine(bl.ID.ToString());

            // Create a Tree:
            Tree tr = new Tree.Builder(
                new List <TreeTreeReference>(0),
                new List <TreeBlobReference> {
                new TreeBlobReference.Builder("README", bl.ID)
            }
                );

            Console.WriteLine(tr.ID.ToString());

            // Create a Commit:
            Commit cm = new Commit.Builder(
                pParents: new List <CommitID>(0),
                pTreeID: tr.ID,
                pCommitter: "James Dunne <*****@*****.**>",
                pDateCommitted: DateTimeOffset.Now,
                pMessage: "A commit message here."
                );

            Console.WriteLine(cm.ID.ToString());
        }
Пример #4
0
        async Task <CommitID> TestCreateCommit(TreeID treeid, int num)
        {
            var db = getDataContext();

            ICommitRepository cmrepo = new CommitRepository(db);
            IRefRepository    rfrepo = new RefRepository(db);

            Tuple <Ref, Commit> parent = await cmrepo.GetCommitByRef("HEAD");

            Commit cm = new Commit.Builder(
                pParents:       parent == null ? new List <CommitID>(0) : new List <CommitID>(1)
            {
                parent.Item2.ID
            },
                pTreeID:        treeid,
                pCommitter:     "James Dunne <*****@*****.**>",
                pDateCommitted: DateTimeOffset.Parse("2011-08-29 00:00:00 -0500"),
                pMessage:       "Commit #" + num.ToString() + "."
                );

            Console.WriteLine("CommitID {0}", cm.ID);

            // Persist the commit:
            await cmrepo.PersistCommit(cm);

            // Once the commit is persisted, update HEAD ref:
            await rfrepo.PersistRef(new Ref.Builder("HEAD", cm.ID));

            return(cm.ID);
        }
        internal static Errorable <Tuple <Tag, Commit> > retrieve(ConsistencyError errorIfNotExist, SqlCommand cmd, SqlDataReader dr)
        {
            // If no result, return null:
            if (!dr.Read())
            {
                return(errorIfNotExist);
            }

            TagID tgid = (TagID)dr.GetSqlBinary(0).Value;

            Tag.Builder tgb = new Tag.Builder(
                pName:          (TagName)dr.GetSqlString(1).Value,
                pCommitID:      (CommitID)dr.GetSqlBinary(2).Value,
                pTagger:        dr.GetSqlString(3).Value,
                pDateTagged:    dr.GetDateTimeOffset(4),
                pMessage:       dr.GetSqlString(5).Value
                );

            Tag tg = tgb;

            if (tg.ID != tgid)
            {
                return(new ComputedTagIDMismatchError(tg.ID, tgid));
            }

            const int offs = 6;
            CommitID  id   = (CommitID)dr.GetSqlBinary(0 + offs).Value;

            Commit.Builder cmb = new Commit.Builder(
                pParents: new System.Collections.Generic.List <CommitID>(2),
                pTreeID: (TreeID)dr.GetSqlBinary(1 + offs).Value,
                pCommitter: dr.GetSqlString(2 + offs).Value,
                pDateCommitted: dr.GetDateTimeOffset(3 + offs),
                pMessage: dr.GetSqlString(4 + offs).Value
                );

            // Read the parent commit ids from the second result:
            if (dr.NextResult())
            {
                while (dr.Read())
                {
                    cmb.Parents.Add((CommitID)dr.GetSqlBinary(0).Value);
                }
                cmb.Parents.Sort(new CommitID.Comparer());
            }

            Commit cm = cmb;

            if (cm.ID != id)
            {
                return(new ComputedCommitIDMismatchError(cm.ID, id));
            }

            return(new Tuple <Tag, Commit>(tg, cm));
        }
        internal async Task PersistRefTest()
        {
            TreeNode tr = new TreeNode.Builder(new List <TreeTreeReference>(0), new List <TreeBlobReference>(0));
            await trrepo.PersistTree(tr.ID, new IVO.Definition.Containers.ImmutableContainer <TreeID, TreeNode>(trx => trx.ID, tr));

            Commit cm = new Commit.Builder(new List <CommitID>(0), tr.ID, "James S. Dunne", DateTimeOffset.Now, "Initial commit.");
            await cmrepo.PersistCommit(cm);

            Ref rf = new Ref.Builder((RefName)"v1.0", cm.ID);
            await rfrepo.PersistRef(rf);
        }
Пример #7
0
        internal async Task PersistTagTest()
        {
            TreeNode tr = new TreeNode.Builder(new List <TreeTreeReference>(0), new List <TreeBlobReference>(0));
            await trrepo.PersistTree(tr.ID, new IVO.Definition.Containers.ImmutableContainer <TreeID, TreeNode>(trx => trx.ID, tr));

            Commit cm = new Commit.Builder(new List <CommitID>(0), tr.ID, "James S. Dunne", DateTimeOffset.Now, "Initial commit.");
            await cmrepo.PersistCommit(cm);

            Tag tg = new Tag.Builder((TagName)"v1.0", cm.ID, "James S. Dunne", DateTimeOffset.Now, "Testing tags");
            await tgrepo.PersistTag(tg);
        }
Пример #8
0
        public Errorable <Tuple <Ref, Commit> > retrieve(SqlCommand cmd, SqlDataReader dr)
        {
            // If no result, return null:
            if (!dr.Read())
            {
                return(new RefNameDoesNotExistError(this._refName));
            }

            Ref.Builder rfb = new Ref.Builder(
                pName:      (RefName)dr.GetSqlString(0).Value,
                pCommitID:  (CommitID)dr.GetSqlBinary(1).Value
                );

            Ref rf = rfb;

            const int offs = 2;

            CommitID id = (CommitID)dr.GetSqlBinary(0 + offs).Value;

            Commit.Builder cmb = new Commit.Builder(
                pParents:       new System.Collections.Generic.List <CommitID>(2),
                pTreeID:        (TreeID)dr.GetSqlBinary(1 + offs).Value,
                pCommitter:     dr.GetSqlString(2 + offs).Value,
                pDateCommitted: dr.GetDateTimeOffset(3 + offs),
                pMessage:       dr.GetSqlString(4 + offs).Value
                );

            // Read the parent commit ids from the second result:
            if (dr.NextResult())
            {
                while (dr.Read())
                {
                    cmb.Parents.Add((CommitID)dr.GetSqlBinary(0).Value);
                }
                cmb.Parents.Sort(new CommitID.Comparer());
            }

            Commit cm = cmb;

            if (cm.ID != id)
            {
                return(new ComputedCommitIDMismatchError(cm.ID, id));
            }

            return(new Tuple <Ref, Commit>(rf, cm));
        }
Пример #9
0
        private Errorable <Commit> retrieve(SqlCommand cmd, SqlDataReader dr)
        {
            // If no result, return null:
            if (!dr.Read())
            {
                return(new CommitIDRecordDoesNotExistError(this._id));
            }

            CommitID id = (CommitID)dr.GetSqlBinary(0).Value;

            Commit.Builder b = new Commit.Builder(
                pParents:       new System.Collections.Generic.List <CommitID>(10),
                pTreeID:        (TreeID)dr.GetSqlBinary(1).Value,
                pCommitter:     dr.GetSqlString(2).Value,
                pDateCommitted: dr.GetDateTimeOffset(3),
                pMessage:       dr.GetSqlString(4).Value
                );

            // Read the parent commit ids from the second result:
            if (dr.NextResult())
            {
                while (dr.Read())
                {
                    b.Parents.Add((CommitID)dr.GetSqlBinary(0).Value);
                }
                b.Parents.Sort(new CommitID.Comparer());
            }

            Commit cm = b;

            if (cm.ID != id)
            {
                throw new ComputedCommitIDMismatchError(cm.ID, id);
            }

            return(cm);
        }
Пример #10
0
        public Errorable <CommitTree> retrieve(SqlCommand cmd, SqlDataReader dr, int expectedCount)
        {
            Dictionary <CommitID, Commit.Builder> commits = new Dictionary <CommitID, Commit.Builder>(expectedCount);

            CommitPartial.Builder cmPartial = null;

            // Iterate through rows of the recursive query, assuming ordering of rows guarantees tree depth locality.
            while (dr.Read())
            {
                SqlBinary b0 = dr.GetSqlBinary(0);
                SqlBinary b1 = dr.GetSqlBinary(1);

                CommitID?cmid        = b0.IsNull ? (CommitID?)null : (CommitID?)b0.Value;
                CommitID?parent_cmid = b1.IsNull ? (CommitID?)null : (CommitID?)b1.Value;

                int depth = dr.GetSqlInt32(6).Value;
                if (depth == this._depth)
                {
                    // This should be the last record and it is partial because its parent CommitIDs are unknown:
                    cmPartial = new CommitPartial.Builder(
                        pID:            parent_cmid.Value,
                        pTreeID:        (TreeID)dr.GetSqlBinary(2).Value,
                        pCommitter:     dr.GetSqlString(3).Value,
                        pDateCommitted: dr.GetDateTimeOffset(4),
                        pMessage:       dr.GetSqlString(5).Value
                        );

                    if (cmid.HasValue)
                    {
                        commits[cmid.Value].Parents.Add(parent_cmid.Value);
                    }

                    Debug.Assert(!dr.Read());
                    break;
                }

                // Create a commit builder:
                Commit.Builder cmb = new Commit.Builder(
                    pParents:       new List <CommitID>(2),
                    pTreeID:        (TreeID)dr.GetSqlBinary(2).Value,
                    pCommitter:     dr.GetSqlString(3).Value,
                    pDateCommitted: dr.GetDateTimeOffset(4),
                    pMessage:       dr.GetSqlString(5).Value
                    );
                commits.Add(parent_cmid.Value, cmb);

                if (cmid.HasValue)
                {
                    commits[cmid.Value].Parents.Add(parent_cmid.Value);
                }
            }

            // Finalize each commit builder:
            List <ICommit> finals = new List <ICommit>(commits.Count);

            foreach (KeyValuePair <CommitID, Commit.Builder> pair in commits)
            {
                Commit cm = pair.Value;
                // TODO: Would it be useful to know which CommitIDs?
                if (cm.ID != pair.Key)
                {
                    return(new ComputedCommitIDMismatchError(cm.ID, pair.Key));
                }
                finals.Add(cm);
            }
            if (cmPartial != null)
            {
                finals.Add((CommitPartial)cmPartial);
            }

            // Return the final result with immutable objects:
            return(new CommitTree(this._id, new ImmutableContainer <CommitID, ICommit>(cm => cm.ID, finals)));
        }
        private async Task <Errorable <Commit> > getCommit(CommitID id)
        {
            FileInfo fi = system.getPathByID(id);

            if (!fi.Exists)
            {
                return(null);
            }

            byte[] buf;
            int    nr = 0;

            using (var fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 16384, true))
            {
                // TODO: implement an async buffered Stream:
                buf = new byte[16384];
                nr  = await fs.ReadAsync(buf, 0, 16384).ConfigureAwait(continueOnCapturedContext: false);

                if (nr >= 16384)
                {
                    // My, what a large commit you have!
                    throw new NotSupportedException();
                }
            }

            Commit.Builder cb = new Commit.Builder()
            {
                Parents = new List <CommitID>()
            };

            // Parse the Commit:
            using (var ms = new MemoryStream(buf, 0, nr, false))
                using (var sr = new StreamReader(ms, Encoding.UTF8))
                {
                    string line;

                    // Read the list of parent CommitIDs:
                    while ((line = sr.ReadLine()) != null)
                    {
                        if (!line.StartsWith("parent "))
                        {
                            break;
                        }

                        string parent_commitid = line.Substring("parent ".Length);
                        var    ecid            = CommitID.TryParse(parent_commitid);
                        if (ecid.HasErrors)
                        {
                            return(ecid.Errors);
                        }
                        cb.Parents.Add(ecid.Value);
                    }

                    // Set TreeID:
                    if (line == null || !line.StartsWith("tree "))
                    {
                        return(new CommitParseExpectedTreeError());
                    }
                    var etrid = TreeID.TryParse(line.Substring("tree ".Length));
                    if (etrid.HasErrors)
                    {
                        return(etrid.Errors);
                    }
                    cb.TreeID = etrid.Value;

                    // Set Committer:
                    line = sr.ReadLine();
                    if (line == null || !line.StartsWith("committer "))
                    {
                        return(new CommitParseExpectedCommitterError());
                    }
                    cb.Committer = line.Substring("committer ".Length);

                    // Set DateCommitted:
                    line = sr.ReadLine();
                    if (line == null || !line.StartsWith("date "))
                    {
                        return(new CommitParseExpectedDateError());
                    }

                    // NOTE: date parsing will result in an inexact DateTimeOffset from what was created with, but it
                    // is close enough because the SHA-1 hash is calculated using the DateTimeOffset.ToString(), so
                    // only the ToString() representations of the DateTimeOffsets need to match.
                    DateTimeOffset tmpDate;
                    if (!DateTimeOffset.TryParse(line.Substring("date ".Length), out tmpDate))
                    {
                        return(new CommitParseBadDateFormatError());
                    }
                    cb.DateCommitted = tmpDate;

                    // Skip empty line:
                    line = sr.ReadLine();
                    if (line == null || line.Length != 0)
                    {
                        return(new CommitParseExpectedBlankLineError());
                    }

                    // Set Message:
                    cb.Message = sr.ReadToEnd();
                }

            // Create the immutable Commit from the Builder:
            Commit cm = cb;

            // Validate the computed CommitID:
            if (cm.ID != id)
            {
                return(new ComputedCommitIDMismatchError(cm.ID, id));
            }

            return(cm);
        }
Пример #12
0
        async Task DemonstrateHashing()
        {
            var db = getDataContext();

            IBlobRepository   blrepo = new BlobRepository(db);
            ITreeRepository   trrepo = new TreeRepository(db);
            ICommitRepository cmrepo = new CommitRepository(db);
            IRefRepository    rfrepo = new RefRepository(db);

            // Create a sample set of blobs:
            Blob readmeBlob;
            ImmutableContainer <BlobID, Blob> blobs = new ImmutableContainer <BlobID, Blob>(
                bl => bl.ID,
                readmeBlob = new Blob.Builder(pContents: Encoding.UTF8.GetBytes(@"Hello world"))
                );

            Console.Out.WriteAsync(String.Format("Blob {0} = \"{1}\"" + Environment.NewLine, readmeBlob.ID.ToString(firstLength: 7), Encoding.UTF8.GetString(readmeBlob.Contents)));
            // Persist them:
            var persistingBlobs = blrepo.PersistBlobs(blobs);

            // Create an initial tree:
            Tree trRoot;
            ImmutableContainer <TreeID, Tree> trees = new ImmutableContainer <TreeID, Tree>(
                tr => tr.ID,
                new Tree[] {
                trRoot = new Tree.Builder(
                    pTrees: new List <TreeTreeReference>(0),
                    pBlobs: new List <TreeBlobReference> {
                    new TreeBlobReference.Builder(pName: "README", pBlobID: readmeBlob.ID)
                }
                    )
            }
                );

            // Dump the tree:
            RecursivePrint(trRoot.ID, trees);

            // Now wait for the blob persistence to complete:
            await persistingBlobs;
            // Persist our tree now:
            var   persistTrees = trrepo.PersistTree(trRoot.ID, trees);
            await persistTrees;

            // Let's make a commit out of all that:
            Commit cm1 = new Commit.Builder(
                pParents:       new List <CommitID>(0),
                pTreeID:        trRoot.ID,
                pCommitter:     @"James Dunne <*****@*****.**>",
                pDateCommitted: DateTimeOffset.Now,
                pMessage:       "Initial commit."
                );

            // Persist that commit:
            Console.Out.WriteAsync(String.Format("Persisting commit {0}..." + Environment.NewLine, cm1.ID.ToString(firstLength: 7)));
            await cmrepo.PersistCommit(cm1);

            // Let's create a ref to point to it:
            await rfrepo.DestroyRefByName("demo/HEAD");

            await rfrepo.PersistRef(new Ref.Builder(pName: "demo/HEAD", pCommitID: cm1.ID));

            await Console.Out.WriteAsync(String.Format("Pointed demo/HEAD to commit {0}" + Environment.NewLine, cm1.ID.ToString(firstLength: 7)));

            // Now let's create a new blob with some revised contents: (adding a period at the end)
            Blob readmeBlob2;

            blobs = new ImmutableContainer <BlobID, Blob>(
                bl => bl.ID,
                readmeBlob2 = new Blob.Builder(Encoding.UTF8.GetBytes(@"Hello world."))
                );
            var persistBlobs2 = blrepo.PersistBlobs(blobs);

            // Make a new tree out of the old tree:
            Tree.Builder trRoot2b = new Tree.Builder(trRoot);
            // Point README to the new BlobID:
            trRoot2b.Blobs[0] = new TreeBlobReference.Builder(trRoot2b.Blobs[0])
            {
                BlobID = readmeBlob2.ID
            };

            // Freeze our Tree.Builder to a Tree:
            Tree trRoot2;

            trees = new ImmutableContainer <TreeID, Tree>(tr => tr.ID, trRoot2 = trRoot2b);

            // Wait for the blobs to persist:
            await persistBlobs2;
            // Now persist the new tree:
            await trrepo.PersistTree(trRoot2.ID, trees);

            // Load a streamed blob:
            IStreamedBlob strbl = await blrepo.GetStreamedBlob(readmeBlob.ID);

            await strbl.ReadStream(blsr =>
            {
                Console.WriteLine("blob is {0} length", blsr.Length);

                byte[] dum = new byte[8040];
                int count  = 8040;

                try
                {
                    while ((count = blsr.Read(dum, 0, 8040)) > 0)
                    {
                        for (int i = 0; i < (count / 40) + ((count % 40) > 0 ? 1 : 0); ++i)
                        {
                            Console.WriteLine(dum.ToHexString(i * 40, Math.Min(count - (i * 40), 40)));
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex.ToString());
                }
            });
        }