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; }
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); } }
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)); } }
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); }
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."); } }
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); }
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)); } }
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(); } }
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 }); }
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); }
/// <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."); } }
public override async Task DeleteLOB(uint oid, DBTransaction transaction) { var manager = new NpgsqlLargeObjectManager((NpgsqlConnection)transaction.Connection); await manager.UnlinkAsync(oid, CancellationToken.None); }
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)); }
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)); }
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); }
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)); }
private Stream GetContentStream(DbConnection connection) { var manager = new NpgsqlLargeObjectManager(connection.connection); return(manager.OpenReadWrite(ObjectId)); }
public ImageRepository(IDbConnection connection, NpgsqlLargeObjectManager largeObjectManager) { _connection = connection; _largeObjectManager = largeObjectManager; }
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 })); }
private Stream GetContentStream(DbConnection connection) { var manager = new NpgsqlLargeObjectManager(connection.connection); return manager.OpenReadWrite(ObjectId); }