/****************************************************************************** * 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.DbUtils; import nxt.db.VersionedEntityDbTable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public final class Alias { public static class Offer { private long priceNQT; private long buyerId; private final long aliasId; private final DbKey dbKey; private Offer(long aliasId, long priceNQT, long buyerId) { this.priceNQT = priceNQT; this.buyerId = buyerId; this.aliasId = aliasId; this.dbKey = offerDbKeyFactory.newKey(this.aliasId); } private Offer(ResultSet rs) throws SQLException { this.aliasId = rs.getLong("id"); this.dbKey = offerDbKeyFactory.newKey(this.aliasId); this.priceNQT = rs.getLong("price"); this.buyerId = rs.getLong("buyer_id"); } private void save(Connection con) throws SQLException { try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO alias_offer (id, price, buyer_id, " + "height) VALUES (?, ?, ?, ?)")) { int i = 0; pstmt.setLong(++i, this.aliasId); pstmt.setLong(++i, this.priceNQT); DbUtils.setLongZeroToNull(pstmt, ++i, this.buyerId); pstmt.setInt(++i, Nxt.getBlockchain().getHeight()); pstmt.executeUpdate(); } } public long getId() { return aliasId; } public long getPriceNQT() { return priceNQT; } public long getBuyerId() { return buyerId; } } private static final DbKey.LongKeyFactory<Alias> aliasDbKeyFactory = new DbKey.LongKeyFactory<Alias>("id") { @Override public DbKey newKey(Alias alias) { return alias.dbKey; } }; private static final VersionedEntityDbTable<Alias> aliasTable = new VersionedEntityDbTable<Alias>("alias", aliasDbKeyFactory) { @Override protected Alias load(Connection con, ResultSet rs) throws SQLException { return new Alias(rs); } @Override protected void save(Connection con, Alias alias) throws SQLException { alias.save(con); } @Override protected String defaultSort() { return " ORDER BY alias_name_lower "; } }; private static final DbKey.LongKeyFactory<Offer> offerDbKeyFactory = new DbKey.LongKeyFactory<Offer>("id") { @Override public DbKey newKey(Offer offer) { return offer.dbKey; } }; private static final VersionedEntityDbTable<Offer> offerTable = new VersionedEntityDbTable<Offer>("alias_offer", offerDbKeyFactory) { @Override protected Offer load(Connection con, ResultSet rs) throws SQLException { return new Offer(rs); } @Override protected void save(Connection con, Offer offer) throws SQLException { offer.save(con); } }; public static int getCount() { return aliasTable.getCount(); } public static int getAccountAliasCount(long accountId) { return aliasTable.getCount(new DbClause.LongClause("account_id", accountId)); } public static DbIterator<Alias> getAliasesByOwner(long accountId, int from, int to) { return aliasTable.getManyBy(new DbClause.LongClause("account_id", accountId), from, to); } public static Alias getAlias(String aliasName) { return aliasTable.getBy(new DbClause.StringClause("alias_name_lower", aliasName.toLowerCase())); } public static DbIterator<Alias> getAliasesLike(String aliasName, int from, int to) { return aliasTable.getManyBy(new DbClause.LikeClause("alias_name_lower", aliasName.toLowerCase()), from, to); } public static Alias getAlias(long id) { return aliasTable.get(aliasDbKeyFactory.newKey(id)); } public static Offer getOffer(Alias alias) { return offerTable.get(offerDbKeyFactory.newKey(alias.getId())); } static void deleteAlias(final String aliasName) { final Alias alias = getAlias(aliasName); final Offer offer = Alias.getOffer(alias); if (offer != null) { offerTable.delete(offer); } aliasTable.delete(alias); } static void addOrUpdateAlias(Transaction transaction, Attachment.MessagingAliasAssignment attachment) { Alias alias = getAlias(attachment.getAliasName()); if (alias == null) { alias = new Alias(transaction, attachment); } else { alias.accountId = transaction.getSenderId(); alias.aliasURI = attachment.getAliasURI(); alias.timestamp = Nxt.getBlockchain().getLastBlockTimestamp(); } aliasTable.insert(alias); } static void sellAlias(Transaction transaction, Attachment.MessagingAliasSell attachment) { final String aliasName = attachment.getAliasName(); final long priceNQT = attachment.getPriceNQT(); final long buyerId = transaction.getRecipientId(); if (priceNQT > 0) { Alias alias = getAlias(aliasName); Offer offer = getOffer(alias); if (offer == null) { offerTable.insert(new Offer(alias.id, priceNQT, buyerId)); } else { offer.priceNQT = priceNQT; offer.buyerId = buyerId; offerTable.insert(offer); } } else { changeOwner(buyerId, aliasName); } } static void changeOwner(long newOwnerId, String aliasName) { Alias alias = getAlias(aliasName); alias.accountId = newOwnerId; alias.timestamp = Nxt.getBlockchain().getLastBlockTimestamp(); aliasTable.insert(alias); Offer offer = getOffer(alias); offerTable.delete(offer); } static void init() {} private long accountId; private final long id; private final DbKey dbKey; private final String aliasName; private String aliasURI; private int timestamp; private Alias(Transaction transaction, Attachment.MessagingAliasAssignment attachment) { this.id = transaction.getId(); this.dbKey = aliasDbKeyFactory.newKey(this.id); this.accountId = transaction.getSenderId(); this.aliasName = attachment.getAliasName(); this.aliasURI = attachment.getAliasURI(); this.timestamp = Nxt.getBlockchain().getLastBlockTimestamp(); } private Alias(ResultSet rs) throws SQLException { this.id = rs.getLong("id"); this.dbKey = aliasDbKeyFactory.newKey(this.id); this.accountId = rs.getLong("account_id"); this.aliasName = rs.getString("alias_name"); this.aliasURI = rs.getString("alias_uri"); this.timestamp = rs.getInt("timestamp"); } private void save(Connection con) throws SQLException { try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO alias (id, account_id, alias_name, " + "alias_uri, timestamp, height) " + "VALUES (?, ?, ?, ?, ?, ?)")) { int i = 0; pstmt.setLong(++i, this.id); pstmt.setLong(++i, this.accountId); pstmt.setString(++i, this.aliasName); pstmt.setString(++i, this.aliasURI); pstmt.setInt(++i, this.timestamp); pstmt.setInt(++i, Nxt.getBlockchain().getHeight()); pstmt.executeUpdate(); } } public long getId() { return id; } public String getAliasName() { return aliasName; } public String getAliasURI() { return aliasURI; } public int getTimestamp() { return timestamp; } public long getAccountId() { return accountId; } }