/** * This file is part of alf.io. * * alf.io is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * alf.io is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with alf.io. If not, see <http://www.gnu.org/licenses/>. */ package alfio.repository; import alfio.model.FileBlobMetadata; import alfio.model.modification.UploadBase64FileModification; import alfio.util.Json; import ch.digitalfondue.npjt.Bind; import ch.digitalfondue.npjt.Query; import ch.digitalfondue.npjt.QueryRepository; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.support.AbstractLobCreatingPreparedStatementCallback; import org.springframework.jdbc.support.lob.DefaultLobHandler; import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobHandler; import java.io.*; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Date; import java.util.Map; import java.util.Optional; @QueryRepository public interface FileUploadRepository { @Query("select count(id) from file_blob where id = :id") Integer isPresent(@Bind("id") String id); @Query("select id, name, content_size, content_type, attributes from file_blob where id = :id") Optional<FileBlobMetadata> findById(@Bind("id") String id); @Query("delete from file_blob where creation_time <= :date and id not in (select file_blob_id from event where file_blob_id is not null)") int cleanupUnreferencedBlobFiles(@Bind("date") Date date); default void upload(UploadBase64FileModification file, String digest, Map<String, String> attributes) { LobHandler lobHandler = new DefaultLobHandler(); NamedParameterJdbcTemplate jdbc = getNamedParameterJdbcTemplate(); jdbc.getJdbcOperations().execute("insert into file_blob (id, name, content_size, content, content_type, attributes) values(?, ?, ?, ?, ?, ?)", new AbstractLobCreatingPreparedStatementCallback(lobHandler) { @Override protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException { ps.setString(1, digest); ps.setString(2, file.getName()); ps.setLong(3, file.getFile().length); lobCreator.setBlobAsBytes(ps, 4, file.getFile()); ps.setString(5, file.getType()); ps.setString(6, Json.GSON.toJson(attributes)); } }); } NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(); default File file(String id) { try { File cachedFile = File.createTempFile("fileupload-cache", ".tmp"); cachedFile.deleteOnExit(); SqlParameterSource param = new MapSqlParameterSource("id", id); getNamedParameterJdbcTemplate().query("select content from file_blob where id = :id", param, rs -> { try (InputStream is = rs.getBinaryStream("content"); OutputStream os = new FileOutputStream(cachedFile)) { is.transferTo(os); } catch (IOException e) { throw new IllegalStateException("Error while copying data", e); } }); return cachedFile; } catch (IOException e) { throw new IllegalStateException(e); } } }