/****************************************************************************** * 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; import nxt.db.DbClause; import nxt.db.DbIterator; import nxt.db.DbKey; import nxt.db.VersionedEntityDbTable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; /** * Each CurrencyFounder instance represents a single founder contribution for a non issued currency * Once the currency is issued all founder contributions are removed * In case the currency is not issued because of insufficient funding, all funds are returned to the founders */ public class CurrencyFounder { private static final DbKey.LinkKeyFactory<CurrencyFounder> currencyFounderDbKeyFactory = new DbKey.LinkKeyFactory<CurrencyFounder>("currency_id", "account_id") { @Override public DbKey newKey(CurrencyFounder currencyFounder) { return currencyFounder.dbKey; } }; private static final VersionedEntityDbTable<CurrencyFounder> currencyFounderTable = new VersionedEntityDbTable<CurrencyFounder>("currency_founder", currencyFounderDbKeyFactory) { @Override protected CurrencyFounder load(Connection con, ResultSet rs) throws SQLException { return new CurrencyFounder(rs); } @Override protected void save(Connection con, CurrencyFounder currencyFounder) throws SQLException { currencyFounder.save(con); } @Override public String defaultSort() { return " ORDER BY height DESC "; } }; static void init() {} private final DbKey dbKey; private final long currencyId; private final long accountId; private long amountPerUnitNQT; private CurrencyFounder(long currencyId, long accountId, long amountPerUnitNQT) { this.currencyId = currencyId; this.dbKey = currencyFounderDbKeyFactory.newKey(currencyId, accountId); this.accountId = accountId; this.amountPerUnitNQT = amountPerUnitNQT; } private CurrencyFounder(ResultSet rs) throws SQLException { this.currencyId = rs.getLong("currency_id"); this.accountId = rs.getLong("account_id"); this.dbKey = currencyFounderDbKeyFactory.newKey(currencyId, accountId); this.amountPerUnitNQT = rs.getLong("amount"); } private void save(Connection con) throws SQLException { try (PreparedStatement pstmt = con.prepareStatement("MERGE INTO currency_founder (currency_id, account_id, amount, height, latest) " + "KEY (currency_id, account_id, height) VALUES (?, ?, ?, ?, TRUE)")) { int i = 0; pstmt.setLong(++i, this.getCurrencyId()); pstmt.setLong(++i, this.getAccountId()); pstmt.setLong(++i, this.getAmountPerUnitNQT()); pstmt.setInt(++i, Nxt.getBlockchain().getHeight()); pstmt.executeUpdate(); } } public long getCurrencyId() { return currencyId; } public long getAccountId() { return accountId; } public long getAmountPerUnitNQT() { return amountPerUnitNQT; } static void addOrUpdateFounder(long currencyId, long accountId, long amount) { CurrencyFounder founder = getFounder(currencyId, accountId); if (founder == null) { founder = new CurrencyFounder(currencyId, accountId, amount); } else { founder.amountPerUnitNQT += amount; } currencyFounderTable.insert(founder); } public static CurrencyFounder getFounder(long currencyId, long accountId) { return currencyFounderTable.get(currencyFounderDbKeyFactory.newKey(currencyId, accountId)); } public static DbIterator<CurrencyFounder> getCurrencyFounders(long currencyId, int from, int to) { return currencyFounderTable.getManyBy(new DbClause.LongClause("currency_id", currencyId), from, to); } public static DbIterator<CurrencyFounder> getFounderCurrencies(long accountId, int from, int to) { return currencyFounderTable.getManyBy(new DbClause.LongClause("account_id", accountId), from, to); } static void remove(long currencyId) { List<CurrencyFounder> founders = new ArrayList<>(); try (DbIterator<CurrencyFounder> currencyFounders = CurrencyFounder.getCurrencyFounders(currencyId, 0, Integer.MAX_VALUE)) { for (CurrencyFounder founder : currencyFounders) { founders.add(founder); } } founders.forEach(currencyFounderTable::delete); } }