private void doWriteStandard(Handle h, String id, InputStream file) { doDelete(h, id); h.insert("INSERT INTO icon_filestore(id, data) values (?,?)", id, file); }
@Override public InputStream read(String id) { try { if (databaseKind == DatabaseKind.PostgreSQL) { return doReadPostgres(id); } else if (databaseKind == DatabaseKind.Apache_Derby) { return doReadDerby(id); } else { return dbi.inTransaction((h, status) -> doReadStandard(h, id)); } } catch (CallbackFailedException ex) { throw new IconDataAccessException("Unable to read data from id " + id, ex); } }
private void doWrite(Handle h, String id, InputStream file) { if (databaseKind == DatabaseKind.PostgreSQL) { doWritePostgres(h, id, file); } else if (databaseKind == DatabaseKind.Apache_Derby) { doWriteDerby(h, id, file); } else { doWriteStandard(h, id, file); } }
private void doWritePostgres(Handle h, String id, InputStream file) { doDelete(h, id); 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 icon_filestore(id, data) values (?,?)", id, oid); } catch (IOException | SQLException ex) { throw IconDataAccessException.launderThrowable(ex); } }
@Override public void write(String id, InputStream file) { Objects.requireNonNull(file, "file cannot be null"); try { dbi.inTransaction((h, status) -> { doWrite(h, id, file); return true; }); } catch (CallbackFailedException ex) { throw new IconDataAccessException("Unable to write on id " + id, ex); } }
/** * Postgres does not allow to read from the large object after the connection has been closed. */ private InputStream doReadPostgres(String id) { Handle h = dbi.open(); try { h.getConnection().setAutoCommit(false); List<Map<String, Object>> res = h.select("SELECT data FROM icon_filestore WHERE id=?", id); 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 IconDataAccessException.launderThrowable(e); } }
@Override public void init() { boolean needsInitialization = !dbi.inTransaction((h, s) -> tableExists(h, "icon_filestore")); if (needsInitialization) { try { dbi.useHandle(h -> { if (databaseKind == DatabaseKind.PostgreSQL) { h.execute("CREATE TABLE icon_filestore (id VARCHAR COLLATE \"C\" PRIMARY KEY, data OID)"); } else if (databaseKind == DatabaseKind.H2) { h.execute("CREATE TABLE icon_filestore (id VARCHAR PRIMARY KEY, data BLOB)"); } else if (databaseKind == DatabaseKind.Apache_Derby) { h.execute("CREATE TABLE icon_filestore (id VARCHAR(1000), data BLOB, PRIMARY KEY (path))"); } else { throw new IconDataAccessException("Unsupported database kind: " + databaseKind); } }); } catch (CallbackFailedException ex) { throw new IconDataAccessException("Unable to initialize the icon_filestore", ex); } } }
@Override public boolean delete(String id) { try { return dbi.inTransaction((h, status) -> doDelete(h, id)); } catch (CallbackFailedException ex) { throw new IconDataAccessException("Unable to delete id " + id, ex); } }
private void doWriteDerby(Handle h, String id, InputStream file) { doDelete(h, id); try { Blob blob = h.getConnection().createBlob(); try (OutputStream out = blob.setBinaryStream(1)) { IOUtils.copy(file, out); } h.insert("INSERT INTO icon_filestore(id, data) values (?,?)", id, blob); } catch (IOException | SQLException ex) { throw IconDataAccessException.launderThrowable(ex); } }