1 package org.openslx.imagemaster.db.mappers;
3 import java.nio.ByteBuffer;
4 import java.sql.ResultSet;
5 import java.sql.SQLException;
6 import java.util.ArrayList;
8 import java.util.concurrent.ArrayBlockingQueue;
10 import org.apache.logging.log4j.LogManager;
11 import org.apache.logging.log4j.Logger;
13 import org.
openslx.filetransfer.util.ChunkStatus;
14 import org.
openslx.filetransfer.util.FileChunk;
28 if ( asyncBlockUpdate == null ) {
30 asyncBlockUpdate.start();
34 public static void asyncUpdate( String imageVersionId, FileChunk chunk )
throws InterruptedException
37 asyncBlockUpdate.
put(
new ChunkUpdate( imageVersionId, chunk.range, chunk.getStatus() != ChunkStatus.COMPLETE ) );
42 private final ArrayBlockingQueue<ChunkUpdate>
queue =
new ArrayBlockingQueue<>( 100 );
53 while ( !interrupted() ) {
57 MysqlStatement stmt = connection.prepareStatement(
"UPDATE imageblock SET ismissing = :ismissing"
58 +
" WHERE imageversionid = :imageversionid AND startbyte = :startbyte AND blocksize = :blocksize" );
63 stmt.
setInt(
"blocksize", chunk.
range.getLength() );
66 }
while ( chunk != null );
68 }
catch ( SQLException e ) {
69 LOGGER.error(
"Query failed in DbImageBlock.AsyncThread.run()", e );
74 }
catch ( InterruptedException e ) {
75 LOGGER.debug(
"async thread interrupted" );
87 public ChunkUpdate( String imageVersionId, FileRange range,
boolean isMissing )
95 public static void insertChunkList( String imageVersionId, List<FileChunk> all,
boolean missing )
throws SQLException
98 MysqlStatement stmt = connection.prepareStatement(
"INSERT IGNORE INTO imageblock"
99 +
" (imageversionid, startbyte, blocksize, blocksha1, ismissing) VALUES"
100 +
" (:imageversionid, :startbyte, :blocksize, :blocksha1, :ismissing)" );
101 stmt.
setString(
"imageversionid", imageVersionId );
103 for ( FileChunk chunk : all ) {
104 stmt.
setLong(
"startbyte", chunk.range.startOffset );
105 stmt.
setInt(
"blocksize", chunk.range.getLength() );
106 stmt.
setBinary(
"blocksha1", chunk.getSha1Sum() );
110 }
catch ( SQLException e ) {
111 LOGGER.error(
"Query failed in DbImageBlock.insertChunkList()", e );
119 MysqlStatement stmt = connection.prepareStatement(
"SELECT startbyte, ismissing FROM imageblock"
120 +
" WHERE imageversionid = :imageversionid ORDER BY startbyte ASC" );
121 stmt.
setString(
"imageversionid", imageVersionId );
123 List<Boolean> list =
new ArrayList<>();
124 long expectedOffset = 0;
125 while ( rs.next() ) {
126 long currentOffset = rs.getLong(
"startbyte" );
127 if ( currentOffset < expectedOffset )
129 while ( currentOffset > expectedOffset ) {
130 list.add( Boolean.TRUE );
131 expectedOffset += FileChunk.CHUNK_SIZE;
133 if ( currentOffset == expectedOffset ) {
134 list.add( rs.getBoolean(
"ismissing" ) );
135 expectedOffset += FileChunk.CHUNK_SIZE;
139 }
catch ( SQLException e ) {
140 LOGGER.error(
"Query failed in DbImageBlock.getBlockStatuses()", e );
145 public static List<ByteBuffer>
getBlockHashes( String imageVersionId )
throws SQLException
149 }
catch ( SQLException e ) {
150 LOGGER.error(
"Query failed in DbImageBlock.getBlockHashes()", e );
158 MysqlStatement stmt = connection.prepareStatement(
"SELECT startbyte, blocksha1 FROM imageblock"
159 +
" WHERE imageversionid = :imageversionid ORDER BY startbyte ASC" );
160 stmt.
setString(
"imageversionid", imageVersionId );
162 List<ByteBuffer> list =
new ArrayList<>();
163 long expectedOffset = 0;
164 while ( rs.next() ) {
165 long currentOffset = rs.getLong(
"startbyte" );
166 if ( currentOffset < expectedOffset )
168 while ( currentOffset > expectedOffset ) {
170 expectedOffset += FileChunk.CHUNK_SIZE;
172 if ( currentOffset == expectedOffset ) {
173 list.add( ByteBuffer.wrap( rs.getBytes(
"blocksha1" ) ) );
174 expectedOffset += FileChunk.CHUNK_SIZE;
static List< Boolean > getMissingStatusList(String imageVersionId)
static void insertChunkList(String imageVersionId, List< FileChunk > all, boolean missing)
static MysqlConnection getConnection()
Get a connection to the database.
ResultSet executeQuery()
Executes the statement, which must be a query.
static final Logger LOGGER
int executeUpdate()
Executes the statement, which must be an SQL INSERT, UPDATE or DELETE statement; or an SQL statement ...
void setInt(String name, int value)
Sets a parameter.
final String imageVersionId
void setBoolean(String name, boolean value)
Sets a parameter.
ChunkUpdate(String imageVersionId, FileRange range, boolean isMissing)
void setString(String name, String value)
Sets a parameter.
final ArrayBlockingQueue< ChunkUpdate > queue
Class for creating PreparedStatements with named parameters.
static synchronized void initAsyncThread()
static AsyncThread asyncBlockUpdate
void put(ChunkUpdate chunk)
void setBinary(String name, byte[] value)
Sets a parameter.
static List< ByteBuffer > getBlockHashes(MysqlConnection connection, String imageVersionId)
static void asyncUpdate(String imageVersionId, FileChunk chunk)
static List< ByteBuffer > getBlockHashes(String imageVersionId)
void setLong(String name, long value)
Sets a parameter.