Exemple #1
0
        public async Task <Errorable <IStreamedBlob> > PersistBlob(PersistingBlob blob)
        {
            SqlCommand insert, update;

            insert = new SqlCommand(@"INSERT INTO [dbo].[Blob] ([blobid], [contents]) VALUES (@pk, @chunk)");
            insert.Parameters.Add("@pk", System.Data.SqlDbType.Binary, 21);
            insert.Parameters.Add("@chunk", System.Data.SqlDbType.Binary);

            update = new SqlCommand(@"UPDATE [dbo].[Blob] SET [contents].WRITE(@chunk, NULL, NULL) WHERE [blobid] = @pk");
            update.Parameters.Add("@pk", System.Data.SqlDbType.Binary, 21);
            update.Parameters.Add("@chunk", System.Data.SqlDbType.Binary);

            // Create a random dummy ID for uploading:
            // FIXME: we need guaranteed uniqueness!
            byte[] dummyID = new byte[21];
            using (var rng = System.Security.Cryptography.RandomNumberGenerator.Create())
                rng.GetBytes(dummyID);
            dummyID[20] = 0xFF;

            // Create a BlobWriter to INSERT and UPDATE to the database in chunks:
            var bw = new BlobWriter(db, insert, update, dummyID);

            // Create a SHA1 calculating wrapper around the input stream:
            var sha1Reader = new SHA1StreamReader(blob.Stream);

            // Asynchronously upload the blob:
            await bw.UploadAsync(sha1Reader);

            // Get the hash and use that as the BlobID:
            byte[] blobHash = sha1Reader.GetHash();

            // Now update the Blob record with the new BlobID:
            await db.ExecuteNonQueryAsync(new BlobIDUpdate(dummyID, blobHash));

            // Return the StreamedBlob instance that can read from the uploaded blob record:
            return(new StreamedBlob(this, new BlobID(blobHash), bw.Length));
        }