/****************************************************************************** * 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 java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public interface DbKey { abstract class Factory<T> { private final String pkClause; private final String pkColumns; private final String selfJoinClause; protected Factory(String pkClause, String pkColumns, String selfJoinClause) { this.pkClause = pkClause; this.pkColumns = pkColumns; this.selfJoinClause = selfJoinClause; } public abstract DbKey newKey(T t); public abstract DbKey newKey(ResultSet rs) throws SQLException; public T newEntity(DbKey dbKey) { throw new UnsupportedOperationException("Not implemented"); } public final String getPKClause() { return pkClause; } public final String getPKColumns() { return pkColumns; } // expects tables to be named a and b public final String getSelfJoinClause() { return selfJoinClause; } } int setPK(PreparedStatement pstmt) throws SQLException; int setPK(PreparedStatement pstmt, int index) throws SQLException; abstract class LongKeyFactory<T> extends Factory<T> { private final String idColumn; public LongKeyFactory(String idColumn) { super(" WHERE " + idColumn + " = ? ", idColumn, " a." + idColumn + " = b." + idColumn + " "); this.idColumn = idColumn; } @Override public DbKey newKey(ResultSet rs) throws SQLException { return new LongKey(rs.getLong(idColumn)); } public DbKey newKey(long id) { return new LongKey(id); } } abstract class StringKeyFactory<T> extends Factory<T> { private final String idColumn; public StringKeyFactory(String idColumn) { super(" WHERE " + idColumn + " = ? ", idColumn, " a." + idColumn + " = b." + idColumn + " "); this.idColumn = idColumn; } @Override public DbKey newKey(ResultSet rs) throws SQLException { return new StringKey(rs.getString(idColumn)); } public DbKey newKey(String id) { return new StringKey(id); } } abstract class LinkKeyFactory<T> extends Factory<T> { private final String idColumnA; private final String idColumnB; public LinkKeyFactory(String idColumnA, String idColumnB) { super(" WHERE " + idColumnA + " = ? AND " + idColumnB + " = ? ", idColumnA + ", " + idColumnB, " a." + idColumnA + " = b." + idColumnA + " AND a." + idColumnB + " = b." + idColumnB + " "); this.idColumnA = idColumnA; this.idColumnB = idColumnB; } @Override public DbKey newKey(ResultSet rs) throws SQLException { return new LinkKey(rs.getLong(idColumnA), rs.getLong(idColumnB)); } public DbKey newKey(long idA, long idB) { return new LinkKey(idA, idB); } } final class LongKey implements DbKey { private final long id; private LongKey(long id) { this.id = id; } public long getId() { return id; } @Override public int setPK(PreparedStatement pstmt) throws SQLException { return setPK(pstmt, 1); } @Override public int setPK(PreparedStatement pstmt, int index) throws SQLException { pstmt.setLong(index, id); return index + 1; } @Override public boolean equals(Object o) { return o instanceof LongKey && ((LongKey)o).id == id; } @Override public int hashCode() { return (int)(id ^ (id >>> 32)); } } final class StringKey implements DbKey { private final String id; private StringKey(String id) { this.id = id; } public String getId() { return id; } @Override public int setPK(PreparedStatement pstmt) throws SQLException { return setPK(pstmt, 1); } @Override public int setPK(PreparedStatement pstmt, int index) throws SQLException { pstmt.setString(index, id); return index + 1; } @Override public boolean equals(Object o) { return o instanceof StringKey && (id != null ? id.equals(((StringKey)o).id) : ((StringKey)o).id == null); } @Override public int hashCode() { return id != null ? id.hashCode() : 0; } } final class LinkKey implements DbKey { private final long idA; private final long idB; private LinkKey(long idA, long idB) { this.idA = idA; this.idB = idB; } public long[] getId() { return new long[]{idA, idB}; } @Override public int setPK(PreparedStatement pstmt) throws SQLException { return setPK(pstmt, 1); } @Override public int setPK(PreparedStatement pstmt, int index) throws SQLException { pstmt.setLong(index, idA); pstmt.setLong(index + 1, idB); return index + 2; } @Override public boolean equals(Object o) { return o instanceof LinkKey && ((LinkKey) o).idA == idA && ((LinkKey) o).idB == idB; } @Override public int hashCode() { return (int)(idA ^ (idA >>> 32)) ^ (int)(idB ^ (idB >>> 32)); } } }