private void doWriteStandard(Handle h, String path, InputStream file) { doDelete(h, path); h.insert("INSERT INTO filestore(path, data) values (?,?)", path, file); }
@Override public InputStream read(String path) { FileStoreSupport.checkValidPath(path); try { if (databaseKind == DatabaseKind.PostgreSQL) { return doReadPostgres(path); } else if (databaseKind == DatabaseKind.Apache_Derby) { return doReadDerby(path); } else { return dbi.inTransaction((h, status) -> doReadStandard(h, path)); } } catch (CallbackFailedException ex) { throw new ExtensionDataAccessException("Unable to read data from path " + path, ex); } }
@Override public String writeTemporaryFile(InputStream file) { Objects.requireNonNull(file, "file cannot be null"); try { return dbi.inTransaction((h, status) -> { String path = newRandomTempFilePath(); doWrite(h, path, file); return path; }); } catch (CallbackFailedException ex) { throw new ExtensionDataAccessException("Unable to write on temporary path", ex); } }
private void doWrite(Handle h, String path, InputStream file) { if (databaseKind == DatabaseKind.PostgreSQL) { doWritePostgres(h, path, file); } else if (databaseKind == DatabaseKind.Apache_Derby) { doWriteDerby(h, path, file); } else { doWriteStandard(h, path, file); } }
private void doWritePostgres(Handle h, String path, InputStream file) { doDelete(h, path); try { LargeObjectManager lobj = getPostgresConnection(h.getConnection()).getLargeObjectAPI(); long oid = lobj.createLO(); LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE); try (OutputStream lob = obj.getOutputStream()) { IOUtils.copy(file, lob); } h.insert("INSERT INTO filestore(path, data) values (?,?)", path, oid); } catch (IOException | SQLException ex) { throw ExtensionDataAccessException.launderThrowable(ex); } }
@Override public void write(String path, InputStream file) { FileStoreSupport.checkValidPath(path); Objects.requireNonNull(file, "file cannot be null"); try { dbi.inTransaction((h, status) -> { doWrite(h, path, file); return true; }); } catch (CallbackFailedException ex) { throw new ExtensionDataAccessException("Unable to write on path " + path, ex); } }
/** * Postgres does not allow to read from the large object after the connection has been closed. */ private InputStream doReadPostgres(String path) { Handle h = dbi.open(); try { h.getConnection().setAutoCommit(false); List<Map<String, Object>> res = h.select("SELECT data FROM filestore WHERE path=?", path); Optional<Long> oid = res.stream() .map(row -> row.get("data")) .map(Long.class::cast) .findFirst(); if (oid.isPresent()) { LargeObjectManager lobj = getPostgresConnection(h.getConnection()).getLargeObjectAPI(); LargeObject obj = lobj.open(oid.get(), LargeObjectManager.READ); return new HandleCloserInputStream(h, obj.getInputStream()); } else { h.close(); return null; } } catch (SQLException e) { IOUtils.closeQuietly(h); throw ExtensionDataAccessException.launderThrowable(e); } }
private void doWriteDerby(Handle h, String path, InputStream file) { doDelete(h, path); try { Blob blob = h.getConnection().createBlob(); try (OutputStream out = blob.setBinaryStream(1)) { IOUtils.copy(file, out); } h.insert("INSERT INTO filestore(path, data) values (?,?)", path, blob); } catch (IOException | SQLException ex) { throw ExtensionDataAccessException.launderThrowable(ex); } }
@Override public boolean delete(String path) { FileStoreSupport.checkValidPath(path); try { return dbi.inTransaction((h, status) -> doDelete(h, path)); } catch (CallbackFailedException ex) { throw new ExtensionDataAccessException("Unable to delete path " + path, ex); } }
@Override public boolean move(String fromPath, String toPath) { FileStoreSupport.checkValidPath(fromPath); FileStoreSupport.checkValidPath(toPath); try { return dbi.inTransaction((h, status) -> { boolean existed = h.select("SELECT 1 from filestore WHERE path=?", fromPath).size() > 0; if (existed) { doDelete(h, toPath); h.update("UPDATE filestore SET path=? WHERE path=?", toPath, fromPath); } return existed; }); } catch (CallbackFailedException ex) { throw new ExtensionDataAccessException("Unable to move file from path " + fromPath + " to path " + toPath, ex); } }