internal NpgsqlLargeObjectStream(NpgsqlLargeObjectManager manager, int fd, bool writeable)
 {
     _manager   = manager;
     _fd        = fd;
     _pos       = 0;
     _writeable = writeable;
 }
 internal NpgsqlLargeObjectStream(NpgsqlLargeObjectManager manager, uint oid, int fd, bool writeable)
 {
     _manager = manager;
     _fd = fd;
     _pos = 0;
     _writeable = writeable;
 }
Beispiel #3
0
        private async Task <StoredFile> StoreFilePostgreSQL(string fileName, string localFilePath, DatabaseOptions databaseOptions)
        {
            using (var postgreDbConnection = new NpgsqlConnection(databaseOptions.ConnectionString))
            {
                postgreDbConnection.Open();
                var manager = new NpgsqlLargeObjectManager(postgreDbConnection);
                var oid     = manager.Create();
                // Reading and writing Large Objects requires the use of a transaction
                using (var transaction = postgreDbConnection.BeginTransaction())
                {
                    // Open the file for reading and writing
                    using (var stream = manager.OpenReadWrite(oid))
                    {
                        using (var fileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read, FileShare.None))
                        {
                            await fileStream.CopyToAsync(stream);
                        }
                    }
                    // Save the changes to the object
                    transaction.Commit();
                }

                return(new StoredFile
                {
                    FileIdentifierOptions = ConvertUtil.SerializeObject(new DatabaseIdentifierOptions
                    {
                        FileId = oid
                    }),
                    UseServerHost = true
                });
            }
        }
        public async Task <uint> SetLOBBuffered(Stream value, DBTransaction transaction)
        {
            if (value.CanSeek)
            {
                value.Position = 0;
            }
            var count        = 0;
            var bufferSize   = 81920;
            var buffer       = new byte[bufferSize];
            var tempFileName = Helper.GetDocumentsFullPath(Path.GetRandomFileName(), "Temp");

            try
            {
                using (var tempStream = new FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite))
                {
                    while ((count = await value.ReadAsync(buffer, 0, bufferSize)) != 0)
                    {
                        tempStream.Write(buffer, 0, count);
                    }
                }

                var manager = new NpgsqlLargeObjectManager((NpgsqlConnection)transaction.Connection);

                var result = await(Task <object>) manager.ImportRemoteAsync(tempFileName, 0, CancellationToken.None);

                return((uint)result);
            }
            finally
            {
                File.Delete(tempFileName);
            }
        }
Beispiel #5
0
        private Stream GetContentStream(DbConnection connection, FileAccess fileAccess = FileAccess.ReadWrite, FileShare fileShare = FileShare.ReadWrite)
        {
            if (ErpSettings.EnableFileSystemStorage && ObjectId == 0)
            {
                var path = DbFileRepository.GetFileSystemPath(this);
                if (File.Exists(path))
                {
                    return(File.Open(path, FileMode.Open, fileAccess, fileShare));
                }

                throw new Exception($"File '{path}' was not found.");
            }
            else
            {
                if (ObjectId == 0)
                {
                    throw new Exception("Trying to get content of a file from database, but it was uploaded to file system. Check FileSystem support configuration.");
                }

                var manager = new NpgsqlLargeObjectManager(connection.connection);
                switch (fileAccess)
                {
                case FileAccess.Read:
                    return(manager.OpenRead(ObjectId));

                case FileAccess.Write:
                    return(manager.OpenRead(ObjectId));

                case FileAccess.ReadWrite:
                    return(manager.OpenReadWrite(ObjectId));
                }
                return(manager.OpenReadWrite(ObjectId));
            }
        }
Beispiel #6
0
        public async Task <byte[]> GetFileAsync(StoredFile storedFile, DatabaseOptions databaseOptions)
        {
            var fileId = ConvertUtil.DeserializeObject <DatabaseIdentifierOptions>(storedFile.FileIdentifierOptions).FileId;

            byte[] bytes;
            using (var postgreDbConnection = new NpgsqlConnection(databaseOptions.ConnectionString))
            {
                postgreDbConnection.Open();
                var manager = new NpgsqlLargeObjectManager(postgreDbConnection);
                // Reading and writing Large Objects requires the use of a transaction
                using (var transaction = postgreDbConnection.BeginTransaction())
                {
                    // Open the file for reading and writing
                    using (var stream = manager.OpenRead(fileId))
                    {
                        using (var memoryStream = new MemoryStream())
                        {
                            await stream.CopyToAsync(memoryStream);

                            bytes = memoryStream.GetBuffer();
                            memoryStream.Close();
                        }
                    }
                }
            }

            return(bytes);
        }
Beispiel #7
0
        static void HandleDownload(NetworkStream stream, FileRequestInfo requestInfo)
        {
            var context = new SmartShareContext();
            var file    = context.UploadedFiles.First(x => x.Name == requestInfo.FileName);

            if (file == null)
            {
                stream.Write(new byte[] { FAIL_BYTE });
                return;
            }

            if (!(file.Password == requestInfo.Password))
            {
                stream.Write(new byte[] { FAIL_BYTE });
                return;
            }

            if (file.DownloadsExceeded() || file.IsExpired())
            {
                stream.Write(new byte[] { FAIL_BYTE });
                stream.Close();
                file.Delete(context);
                return;
            }

            stream.Write(new byte[] { ACK_BYTE });
            file.DownloadCount++;
            context.UploadedFiles.Update(file);
            context.SaveChanges();

            var connection = context.Database.GetDbConnection();

            if (connection is NpgsqlConnection)
            {
                var conn = (NpgsqlConnection)connection;
                conn.Open();
                var blobManager = new NpgsqlLargeObjectManager(conn);
                using (var transaction = connection.BeginTransaction())
                {
                    var blobStream = blobManager.OpenRead(file.BlobOid);
                    blobStream.CopyTo(stream);
                    transaction.Commit();
                }
                conn.Close();
                Console.WriteLine("Download successful.");
            }
            else
            {
                throw new NotSupportedException("Unsupported database adapter.");
            }
        }
Beispiel #8
0
        public DbUploadStream(DbContext context, string filename, Dictionary <string, string> fileInfo)
        {
            _context  = context;
            _filename = filename;
            _fileInfo = fileInfo;

            _transaction = _context.Database.BeginTransaction();

            _connection = _context.Database.GetDbConnection() as NpgsqlConnection;
            var objectManager = new NpgsqlLargeObjectManager(_connection);

            _oid    = objectManager.Create();
            _stream = objectManager.OpenReadWrite(_oid);
        }
Beispiel #9
0
        private Stream GetContentStream(DbConnection connection)
        {
            if (Settings.EnableFileSystemStorage && ObjectId == 0)
            {
                var path = DbFileRepository.GetFileSystemPath(this);
                if (File.Exists(path))
                {
                    return(File.Open(path, FileMode.Open, FileAccess.ReadWrite));
                }

                throw new Exception($"File '{path}' was not found.");
            }
            else
            {
                var manager = new NpgsqlLargeObjectManager(connection.connection);
                return(manager.OpenReadWrite(ObjectId));
            }
        }
Beispiel #10
0
        public async Task <Stream> GetLOBBuffered(uint oid, DBTransaction transaction)
        {
            var outStream  = new MemoryStream();
            var manager    = new NpgsqlLargeObjectManager((NpgsqlConnection)transaction.Connection);
            var bufferSize = 81920;
            var buffer     = new byte[bufferSize];

            using (var lobStream = await manager.OpenReadAsync(oid, CancellationToken.None))
            {
                int count;
                while ((count = await lobStream.ReadAsync(buffer, 0, bufferSize)) != 0)
                {
                    outStream.Write(buffer, 0, count);
                }
            }
            outStream.Position = 0;
            return(outStream);
        }
        public void Test()
        {
            using (var conn = OpenConnection())
            using (var transaction = conn.BeginTransaction())
            {
                var manager = new NpgsqlLargeObjectManager(conn);
                uint oid = manager.Create();
                using (var stream = manager.OpenReadWrite(oid))
                {
                    var buf = Encoding.UTF8.GetBytes("Hello");
                    stream.Write(buf, 0, buf.Length);
                    stream.Seek(0, System.IO.SeekOrigin.Begin);
                    var buf2 = new byte[buf.Length];
                    stream.Read(buf2, 0, buf2.Length);
                    Assert.That(buf.SequenceEqual(buf2));

                    Assert.AreEqual(5, stream.Position);

                    Assert.AreEqual(5, stream.Length);

                    stream.Seek(-1, System.IO.SeekOrigin.Current);
                    Assert.AreEqual((int)'o', stream.ReadByte());

                    manager.MaxTransferBlockSize = 3;

                    stream.Write(buf, 0, buf.Length);
                    stream.Seek(-5, System.IO.SeekOrigin.End);
                    var buf3 = new byte[100];
                    Assert.AreEqual(5, stream.Read(buf3, 0, 100));
                    Assert.That(buf.SequenceEqual(buf3.Take(5)));

                    stream.SetLength(43);
                    Assert.AreEqual(43, stream.Length);
                }

                manager.Unlink(oid);

                transaction.Rollback();
            }
        }
Beispiel #12
0
        public void Test()
        {
            using (var conn = OpenConnection())
                using (var transaction = conn.BeginTransaction())
                {
                    var  manager = new NpgsqlLargeObjectManager(conn);
                    uint oid     = manager.Create();
                    using (var stream = manager.OpenReadWrite(oid))
                    {
                        var buf = Encoding.UTF8.GetBytes("Hello");
                        stream.Write(buf, 0, buf.Length);
                        stream.Seek(0, System.IO.SeekOrigin.Begin);
                        var buf2 = new byte[buf.Length];
                        stream.Read(buf2, 0, buf2.Length);
                        Assert.That(buf.SequenceEqual(buf2));

                        Assert.AreEqual(5, stream.Position);

                        Assert.AreEqual(5, stream.Length);

                        stream.Seek(-1, System.IO.SeekOrigin.Current);
                        Assert.AreEqual((int)'o', stream.ReadByte());

                        manager.MaxTransferBlockSize = 3;

                        stream.Write(buf, 0, buf.Length);
                        stream.Seek(-5, System.IO.SeekOrigin.End);
                        var buf3 = new byte[100];
                        Assert.AreEqual(5, stream.Read(buf3, 0, 100));
                        Assert.That(buf.SequenceEqual(buf3.Take(5)));

                        stream.SetLength(43);
                        Assert.AreEqual(43, stream.Length);
                    }

                    manager.Unlink(oid);

                    transaction.Rollback();
                }
        }
Beispiel #13
0
        public async Task <IActionResult> GetDownloadAction(string fileId)
        {
            var file = await _context.StoredFiles.FirstOrDefaultAsync(f => f.Id == Guid.Parse(fileId));

            if (file == null)
            {
                return(new NotFoundResult());
            }

            var dbConnection = _context.Database.GetDbConnection() as NpgsqlConnection;
            var manager      = new NpgsqlLargeObjectManager(dbConnection);

            dbConnection.Open();
            var transaction = dbConnection.BeginTransaction();

            var readStream = manager.OpenRead(file.ObjectId);

            return(new DbDownloadStreamResult(readStream, "application/zip", transaction)
            {
                FileDownloadName = file.FileName
            });
        }
Beispiel #14
0
        public static async Task <uint> SetLOBDirect(Stream value, DBTransaction transaction)
        {
            if (value.CanSeek)
            {
                value.Position = 0;
            }
            var manager    = new NpgsqlLargeObjectManager((NpgsqlConnection)transaction.Connection);
            var bufferSize = 81920;
            var buffer     = new byte[bufferSize];

            var oid = await manager.CreateAsync(0, CancellationToken.None);

            using (var lobStream = await manager.OpenReadWriteAsync(oid, CancellationToken.None))
            {
                //await value.CopyToAsync(lobStream);
                int count;
                while ((count = await value.ReadAsync(buffer, 0, bufferSize)) != 0)
                {
                    lobStream.Write(buffer, 0, count);
                }
            }
            return(oid);
        }
Beispiel #15
0
        /// <summary>
        /// Deletes blob from DB and removes record from files table
        /// </summary>
        /// <param name="context"></param>
        public void Delete(DbContext context)
        {
            var connection = context.Database.GetDbConnection();

            if (connection is NpgsqlConnection)
            {
                var conn = (NpgsqlConnection)connection;
                conn.Open();
                using (var transaction = conn.BeginTransaction())
                {
                    var blobManager = new NpgsqlLargeObjectManager(conn);
                    blobManager.Unlink(BlobOid);
                    transaction.Commit();
                }
                conn.Close();
                context.Remove(this);
                context.SaveChanges();
            }
            else
            {
                throw new NotSupportedException("Unsupported database adapter.");
            }
        }
Beispiel #16
0
 public override async Task DeleteLOB(uint oid, DBTransaction transaction)
 {
     var manager = new NpgsqlLargeObjectManager((NpgsqlConnection)transaction.Connection);
     await manager.UnlinkAsync(oid, CancellationToken.None);
 }
Beispiel #17
0
        public override async Task <Stream> GetLOB(uint oid, DBTransaction transaction, int bufferSize = 81920)
        {
            var manager = new NpgsqlLargeObjectManager((NpgsqlConnection)transaction.Connection);

            return(await manager.OpenReadAsync(oid, CancellationToken.None));
        }
Beispiel #18
0
        static void HandleUpload(NetworkStream stream, FileRequestInfo requestInfo)
        {
            var context    = new SmartShareContext();
            var connection = context.Database.GetDbConnection();

            // check if file already exists, and if that file is expired we can delete it and continue the upload.
            try
            {
                var possibleFile = context.UploadedFiles.First(x => x.Name == requestInfo.FileName);
                if (possibleFile != null)
                {
                    if (possibleFile.DownloadsExceeded() || possibleFile.IsExpired())
                    {
                        possibleFile.Delete(context);
                    }
                    else
                    {
                        return;
                    }
                }
            }
            catch (InvalidOperationException e)
            {
                Console.WriteLine("File table is empty");
            }

            stream.Write(new byte[1] {
                ACK_BYTE
            });                                     // let client know we're ready to receive

            if (connection is NpgsqlConnection)
            {
                var  blobManager = new NpgsqlLargeObjectManager((NpgsqlConnection)connection);
                uint oid;
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    oid = blobManager.Create();
                    using (var blobStream = blobManager.OpenReadWrite(oid))
                    {
                        stream.CopyTo(blobStream);
                    }

                    transaction.Commit();
                }

                stream.Close();
                connection.Close();

                Console.WriteLine("Upload successful.");

                var uploadedFile = new UploadedFile(requestInfo, oid);

                context.Add(uploadedFile);
                context.SaveChanges();
            }
            else
            {
                throw new NotSupportedException("Unsupported database adapter");
            }
        }
        public DbFile Create(string filepath, byte[] buffer, DateTime?createdOn, Guid?createdBy)
        {
            if (string.IsNullOrWhiteSpace(filepath))
            {
                throw new ArgumentException("filepath cannot be null or empty");
            }

            //all filepaths are lowercase and all starts with folder separator
            filepath = filepath.ToLowerInvariant();
            if (!filepath.StartsWith(FOLDER_SEPARATOR))
            {
                filepath = FOLDER_SEPARATOR + filepath;
            }

            if (Find(filepath) != null)
            {
                throw new ArgumentException(filepath + ": file already exists");
            }

            using (var connection = DbContext.Current.CreateConnection())
            {
                try
                {
                    connection.BeginTransaction();

                    var  manager  = new NpgsqlLargeObjectManager(connection.connection);
                    uint objectId = manager.Create();

                    using (var stream = manager.OpenReadWrite(objectId))
                    {
                        stream.Write(buffer, 0, buffer.Length);
                        stream.Close();
                    }


                    var command = connection.CreateCommand(@"INSERT INTO files(id,object_id,filepath,created_on,modified_on,created_by,modified_by) 
															 VALUES (@id,@object_id,@filepath,@created_on,@modified_on,@created_by,@modified_by)"                                                            );

                    command.Parameters.Add(new NpgsqlParameter("@id", Guid.NewGuid()));
                    command.Parameters.Add(new NpgsqlParameter("@object_id", (decimal)objectId));
                    command.Parameters.Add(new NpgsqlParameter("@filepath", filepath));
                    var date = createdOn ?? DateTime.UtcNow;
                    command.Parameters.Add(new NpgsqlParameter("@created_on", date));
                    command.Parameters.Add(new NpgsqlParameter("@modified_on", date));
                    command.Parameters.Add(new NpgsqlParameter("@created_by", (object)createdBy ?? DBNull.Value));
                    command.Parameters.Add(new NpgsqlParameter("@modified_by", (object)createdBy ?? DBNull.Value));

                    command.ExecuteNonQuery();

                    var result = Find(filepath);

                    connection.CommitTransaction();
                }
                catch (Exception)
                {
                    connection.RollbackTransaction();
                }
            }

            return(Find(filepath));
        }
Beispiel #20
0
        public DbFile Create(string filepath, byte[] buffer, DateTime? createdOn, Guid? createdBy)
        {
            if (string.IsNullOrWhiteSpace(filepath))
                throw new ArgumentException("filepath cannot be null or empty");

            //all filepaths are lowercase and all starts with folder separator
            filepath = filepath.ToLowerInvariant();
            if (!filepath.StartsWith(FOLDER_SEPARATOR))
                filepath = FOLDER_SEPARATOR + filepath;

            if (Find(filepath) != null)
                throw new ArgumentException(filepath + ": file already exists");

            using (var connection = DbContext.Current.CreateConnection())
            {
                try
                {
                    connection.BeginTransaction();

                    var manager = new NpgsqlLargeObjectManager(connection.connection);
                    uint objectId = manager.Create();

                    using (var stream = manager.OpenReadWrite(objectId))
                    {
                        stream.Write(buffer, 0, buffer.Length);
                        stream.Close();
                    }

                    var command = connection.CreateCommand(@"INSERT INTO files(id,object_id,filepath,created_on,modified_on,created_by,modified_by)
                                                             VALUES (@id,@object_id,@filepath,@created_on,@modified_on,@created_by,@modified_by)");

                    command.Parameters.Add(new NpgsqlParameter("@id", Guid.NewGuid()));
                    command.Parameters.Add(new NpgsqlParameter("@object_id", (decimal)objectId));
                    command.Parameters.Add(new NpgsqlParameter("@filepath", filepath ));
                    var date = createdOn ?? DateTime.UtcNow;
                    command.Parameters.Add(new NpgsqlParameter("@created_on", date));
                    command.Parameters.Add(new NpgsqlParameter("@modified_on", date));
                    command.Parameters.Add(new NpgsqlParameter("@created_by", (object)createdBy ?? DBNull.Value ));
                    command.Parameters.Add(new NpgsqlParameter("@modified_by", (object)createdBy ?? DBNull.Value ));

                    command.ExecuteNonQuery();

                    var result = Find(filepath);

                    connection.CommitTransaction();
                }
                catch( Exception )
                {
                    connection.RollbackTransaction();
                }
            }

            return Find(filepath);
        }
Beispiel #21
0
        public async Task <Result <Unit, Unit> > Add(
            string?userName,
            Guid id,
            string correlationId,
            string projectName,
            Stream?content,
            string?mediaType,
            string?text)
        {
            if (text == null && mediaType == null && content == null)
            {
                return(Result <Unit, Unit> .Failure(
                           HttpStatusCode.BadRequest,
                           "either text or content (with its media type) must be specified"));
            }

            var context = await this.dbContext.Contexts.FindAsync(id);

            if (context != null)
            {
                return(Result <Unit, Unit> .Failure(
                           HttpStatusCode.BadRequest,
                           "request with such a guid exists"));
            }

            var user = await this.userManager.FindByNameAsync(userName);

            var project = await this.dbContext.Projects
                          .FirstOrDefaultAsync(project =>
                                               (project.Owner.UserName == userName ||
                                                project.Contributors.Any(contributor => contributor.User.UserName == userName)) &&
                                               project.Name == projectName);

            if (project == null)
            {
                return(Result <Unit, Unit> .Failure(
                           HttpStatusCode.BadRequest,
                           "project not found"));
            }

            if (content != null && mediaType == null)
            {
                return(Result <Unit, Unit> .Failure(
                           HttpStatusCode.BadRequest,
                           "if a request provides content, its media type must be specified"));
            }

            if (content == null && mediaType != null)
            {
                return(Result <Unit, Unit> .Failure(
                           HttpStatusCode.BadRequest,
                           "no content provided"));
            }

            AllowedMediaType?mediaTypeModel = null;

            if (mediaType != null)
            {
                mediaTypeModel = await this.dbContext.MediaTypes.FirstOrDefaultAsync(m => m.MediaType == mediaType);

                if (mediaTypeModel == null)
                {
                    return(Result <Unit, Unit> .Failure(
                               HttpStatusCode.BadRequest,
                               "media type not acceptable"));
                }
            }

            uint?contentObjectId = null;

            await this.dbContext.Database.OpenConnectionAsync();

            var connection = (NpgsqlConnection)this.dbContext.Database.GetDbConnection();

            using (var transaction = await connection.BeginTransactionAsync())
            {
                if (content != null)
                {
                    var lobManager = new NpgsqlLargeObjectManager(connection);
                    var contentOid = await lobManager.CreateAsync(0);

                    using (var stream = await lobManager.OpenReadWriteAsync(contentOid))
                    {
                        await content.CopyToAsync(stream);
                    }

                    contentObjectId = contentOid;
                }

                await this.dbContext.Database.ExecuteSqlInterpolatedAsync(
                    $@"INSERT INTO ""Contexts"" (
                        ""Id"",
                        ""ProjectId"",
                        ""CorrelationId"",
                        ""Text"",
                        ""ContentObjectId"",
                        ""MediaTypeId"",
                        ""CreatedById"",
                        ""CreationTime"")
                    VALUES (
                        {id},
                        {project.Id},
                        {correlationId},
                        {text},
                        {contentObjectId},
                        {mediaTypeModel?.Id},
                        {user.Id},
                        {currentTimeProvider.GetCurrentTime()});");

                await transaction.CommitAsync();
            }
            return(Result <Unit, Unit> .Ok(Unit.Value));
        }
Beispiel #22
0
        private Stream GetContentStream(DbConnection connection)
        {
            var manager = new NpgsqlLargeObjectManager(connection.connection);

            return(manager.OpenReadWrite(ObjectId));
        }
Beispiel #23
0
 public ImageRepository(IDbConnection connection, NpgsqlLargeObjectManager largeObjectManager)
 {
     _connection         = connection;
     _largeObjectManager = largeObjectManager;
 }
Beispiel #24
0
        public DbFile Create(string filepath, byte[] buffer, DateTime?createdOn, Guid?createdBy)
        {
            if (string.IsNullOrWhiteSpace(filepath))
            {
                throw new ArgumentException("filepath cannot be null or empty");
            }

            //all filepaths are lowercase and all starts with folder separator
            filepath = filepath.ToLowerInvariant();
            if (!filepath.StartsWith(FOLDER_SEPARATOR))
            {
                filepath = FOLDER_SEPARATOR + filepath;
            }

            if (Find(filepath) != null)
            {
                throw new ArgumentException(filepath + ": file already exists");
            }

            using (var connection = CurrentContext.CreateConnection())
            {
                try
                {
                    uint objectId = 0;
                    connection.BeginTransaction();

                    if (!ErpSettings.EnableFileSystemStorage)
                    {
                        var manager = new NpgsqlLargeObjectManager(connection.connection);
                        objectId = manager.Create();

                        using (var stream = manager.OpenReadWrite(objectId))
                        {
                            stream.Write(buffer, 0, buffer.Length);
                            stream.Close();
                        }
                    }


                    var command = connection.CreateCommand(@"INSERT INTO files(id,object_id,filepath,created_on,modified_on,created_by,modified_by) 
															 VALUES (@id,@object_id,@filepath,@created_on,@modified_on,@created_by,@modified_by)"                                                            );

                    command.Parameters.Add(new NpgsqlParameter("@id", Guid.NewGuid()));
                    command.Parameters.Add(new NpgsqlParameter("@object_id", (decimal)objectId));
                    command.Parameters.Add(new NpgsqlParameter("@filepath", filepath));
                    var date = createdOn ?? DateTime.UtcNow;
                    command.Parameters.Add(new NpgsqlParameter("@created_on", date));
                    command.Parameters.Add(new NpgsqlParameter("@modified_on", date));
                    command.Parameters.Add(new NpgsqlParameter("@created_by", (object)createdBy ?? DBNull.Value));
                    command.Parameters.Add(new NpgsqlParameter("@modified_by", (object)createdBy ?? DBNull.Value));

                    command.ExecuteNonQuery();

                    var result = Find(filepath);

                    if (ErpSettings.EnableCloudBlobStorage)
                    {
                        var path = GetBlobPath(result);
                        using (IBlobStorage storage = GetBlobStorage())
                        {
                            storage.WriteAsync(path,
                                               buffer).Wait();
                        }
                    }
                    else if (ErpSettings.EnableFileSystemStorage)
                    {
                        var path       = GetFileSystemPath(result);
                        var folderPath = Path.GetDirectoryName(path);
                        if (!Directory.Exists(folderPath))
                        {
                            Directory.CreateDirectory(folderPath);
                        }
                        using (Stream stream = File.Open(path, FileMode.CreateNew, FileAccess.ReadWrite))
                        {
                            stream.Write(buffer, 0, buffer.Length);
                            stream.Close();
                        }
                    }

                    connection.CommitTransaction();
                }
                catch (Exception ex)
                {
                    connection.RollbackTransaction();
                    throw ex;
                }
            }

            return(Find(filepath));
        }
        public async Task <Result <FileResult, Unit> > Get(
            string?userName,
            DateTimeOffset?ifModifiedSince,
            Guid id)
        {
            var contextData = await this.dbContext.Contexts
                              .Where(context =>
                                     context.Project.PublicallyReadable ||
                                     (context.Project.Owner.UserName == userName ||
                                      context.Project.Contributors.Any(contributor => contributor.User.UserName == userName)))
                              .Select(context => new
            {
                Id = context.Id,
                ContentObjectId = context.ContentObjectId,
                MediaType       = context.MediaType != null ? context.MediaType.MediaType : null,
                Extension       = context.MediaType != null ? context.MediaType.Extension : null,
                LastModified    = context.CreationTime
            })
                              .FirstOrDefaultAsync(contextData => contextData.Id == id);

            if (contextData == null)
            {
                return(Result <FileResult, Unit> .Failure(
                           HttpStatusCode.NotFound,
                           "context not found"));
            }

            if (contextData.ContentObjectId == null || contextData.MediaType == null)
            {
                return(Result <FileResult, Unit> .Failure(
                           HttpStatusCode.NotFound,
                           "context has no associated binary data"));
            }

            if (ifModifiedSince != null && contextData.LastModified < ifModifiedSince)
            {
                return(Result <FileResult, Unit> .Failure(
                           HttpStatusCode.NotModified,
                           "not modified"));
            }

            await this.dbContext.Database.OpenConnectionAsync();

            var connection = (NpgsqlConnection)this.dbContext.Database.GetDbConnection();
            // we have to begin a transaction, in order for LOB access to work
            // (otherwise we get a "invalid large-object descriptor: 0" error)
            // but we can't dispose it in this method, so we wrap the created stream
            // in a wrapper that disposes another object after disposing the stream
            var transaction = await this.dbContext.Database.BeginTransactionAsync();

            var lobManager = new NpgsqlLargeObjectManager(connection);

            return(Result <FileResult, Unit> .Ok(new FileResult()
            {
                Content = new DisposingStream(
                    await lobManager.OpenReadAsync(contextData.ContentObjectId.Value),
                    transaction),
                FileName = $"{contextData.Id}.{contextData.Extension}",
                MediaType = contextData.MediaType,
                LastModified = contextData.LastModified
            }));
        }
Beispiel #26
0
 private Stream GetContentStream(DbConnection connection)
 {
     var manager = new NpgsqlLargeObjectManager(connection.connection);
     return manager.OpenReadWrite(ObjectId);
 }