/******************************************************************************
* Copyright © 2013-2016 The Nxt Core Developers. *
* *
* See the AUTHORS.txt, DEVELOPER-AGREEMENT.txt and LICENSE.txt files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* Nxt software, including this file, may be copied, modified, propagated, *
* or distributed except according to the terms contained in the LICENSE.txt *
* file. *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
package nxt.db;
import nxt.Nxt;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public abstract class VersionedValuesDbTable<T, V> extends ValuesDbTable<T, V> {
protected VersionedValuesDbTable(String table, DbKey.Factory<T> dbKeyFactory) {
super(table, dbKeyFactory, true);
}
public final boolean delete(T t) {
if (t == null) {
return false;
}
if (!db.isInTransaction()) {
throw new IllegalStateException("Not in transaction");
}
DbKey dbKey = dbKeyFactory.newKey(t);
int height = Nxt.getBlockchain().getHeight();
try (Connection con = db.getConnection();
PreparedStatement pstmtCount = con.prepareStatement("SELECT COUNT(*) AS count FROM " + table + dbKeyFactory.getPKClause()
+ " AND height < ?")) {
int i = dbKey.setPK(pstmtCount);
pstmtCount.setInt(i, height);
try (ResultSet rs = pstmtCount.executeQuery()) {
rs.next();
if (rs.getInt("count") > 0) {
try (PreparedStatement pstmt = con.prepareStatement("UPDATE " + table
+ " SET latest = FALSE " + dbKeyFactory.getPKClause() + " AND height = ? AND latest = TRUE")) {
int j = dbKey.setPK(pstmt);
pstmt.setInt(j, height);
if (pstmt.executeUpdate() > 0) {
return true;
}
}
List<V> values = get(dbKey);
if (values.isEmpty()) {
return false;
}
for (V v : values) {
save(con, t, v);
}
try (PreparedStatement pstmt = con.prepareStatement("UPDATE " + table
+ " SET latest = FALSE " + dbKeyFactory.getPKClause() + " AND latest = TRUE")) {
dbKey.setPK(pstmt);
if (pstmt.executeUpdate() == 0) {
throw new RuntimeException(); // should not happen
}
}
return true;
} else {
try (PreparedStatement pstmtDelete = con.prepareStatement("DELETE FROM " + table + dbKeyFactory.getPKClause())) {
dbKey.setPK(pstmtDelete);
return pstmtDelete.executeUpdate() > 0;
}
}
}
} catch (SQLException e) {
throw new RuntimeException(e.toString(), e);
} finally {
db.getCache(table).remove(dbKey);
}
}
}