more work on DAO - for illustrative purposes only!!

This commit is contained in:
catbref
2018-06-08 13:30:12 +01:00
parent a0345412e8
commit 3b02432b73
11 changed files with 395 additions and 121 deletions

View File

@@ -8,12 +8,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.util.Arrays;
import org.hsqldb.jdbc.JDBCPool;
import com.google.common.primitives.Bytes;
/**
* Helper methods for common database actions.
*
@@ -148,20 +145,20 @@ public abstract class DB {
}
/**
* Convert InputStream, from ResultSet.getBinaryStream(), into byte[] of set length.
* Convert InputStream, from ResultSet.getBinaryStream(), into byte[].
*
* @param inputStream
* @param length
* @return byte[length]
* @return byte[]
*/
public static byte[] getResultSetBytes(InputStream inputStream, int length) {
public static byte[] getResultSetBytes(InputStream inputStream) {
// inputStream could be null if database's column's value is null
if (inputStream == null)
return null;
byte[] result = new byte[length];
try {
int length = inputStream.available();
byte[] result = new byte[length];
if (inputStream.read(result) == length)
return result;
} catch (IOException e) {
@@ -171,38 +168,6 @@ public abstract class DB {
return null;
}
/**
* Convert InputStream, from ResultSet.getBinaryStream(), into byte[] of unknown length.
*
* @param inputStream
* @return byte[]
*/
public static byte[] getResultSetBytes(InputStream inputStream) {
final int BYTE_BUFFER_LENGTH = 1024;
// inputStream could be null if database's column's value is null
if (inputStream == null)
return null;
byte[] result = new byte[0];
while (true) {
try {
byte[] buffer = new byte[BYTE_BUFFER_LENGTH];
int length = inputStream.read(buffer);
if (length == -1)
break;
result = Bytes.concat(result, Arrays.copyOf(buffer, length));
} catch (IOException e) {
// No more bytes
break;
}
}
return result;
}
/**
* Execute SQL and return ResultSet with but added checking.
* <p>

View File

@@ -21,6 +21,8 @@ import qora.account.PublicKeyAccount;
import qora.block.Block;
import qora.block.BlockChain;
import qora.block.BlockTransaction;
import repository.Repository;
import repository.RepositoryManager;
import settings.Settings;
import utils.Base58;
@@ -289,7 +291,8 @@ public abstract class Transaction {
if (this.reference == null)
return null;
return TransactionFactory.fromSignature(this.reference);
// return TransactionFactory.fromSignature(this.reference);
// return RepositoryManager.getTransactionRepository().fromSignature(this.reference);
}
/**

View File

@@ -1,57 +0,0 @@
package qora.transaction;
import java.sql.ResultSet;
import java.sql.SQLException;
import database.DB;
import qora.transaction.Transaction.TransactionType;
public class TransactionFactory {
/**
* Load Transaction from DB using signature.
*
* @param signature
* @return ? extends Transaction, or null if not found
* @throws SQLException
*/
public static Transaction fromSignature(byte[] signature) throws SQLException {
ResultSet resultSet = DB.checkedExecute("SELECT type, signature FROM Transactions WHERE signature = ?", signature);
return fromResultSet(resultSet);
}
/**
* Load Transaction from DB using reference.
*
* @param reference
* @return ? extends Transaction, or null if not found
* @throws SQLException
*/
public static Transaction fromReference(byte[] reference) throws SQLException {
ResultSet resultSet = DB.checkedExecute("SELECT type, signature FROM Transactions WHERE reference = ?", reference);
return fromResultSet(resultSet);
}
private static Transaction fromResultSet(ResultSet resultSet) throws SQLException {
if (resultSet == null)
return null;
TransactionType type = TransactionType.valueOf(resultSet.getInt(1));
if (type == null)
return null;
byte[] signature = DB.getResultSetBytes(resultSet.getBinaryStream(2), Transaction.SIGNATURE_LENGTH);
switch (type) {
case GENESIS:
return GenesisTransaction.fromSignature(signature);
case PAYMENT:
return PaymentTransaction.fromSignature(signature);
default:
return null;
}
}
}

View File

@@ -1,9 +1,11 @@
package repository;
public interface Repository {
public abstract class Repository {
// public void save();
protected TransactionRepository transactionRepository;
// public void delete();
public TransactionRepository getTransactionRepository() {
return this.transactionRepository;
}
}

View File

@@ -0,0 +1,15 @@
package repository;
public abstract class RepositoryManager {
private static Repository repository;
public static void setRepository(Repository newRepository) {
repository = newRepository;
}
public static TransactionRepository getTransactionRepository() {
return repository.transactionRepository;
}
}

View File

@@ -2,8 +2,10 @@ package repository;
import data.transaction.Transaction;
public interface TransactionRepository extends Repository {
public interface TransactionRepository {
public Transaction fromSignature(byte[] signature);
public Transaction fromReference(byte[] reference);
}

View File

@@ -12,7 +12,7 @@ import database.DB;
public class HSQLDBGenesisTransaction extends HSQLDBTransaction {
protected Transaction fromSignature(byte[] signature, byte[] reference, PublicKeyAccount creator, long timestamp, BigDecimal fee) {
protected Transaction fromBase(byte[] signature, byte[] reference, PublicKeyAccount creator, long timestamp, BigDecimal fee) {
try {
ResultSet rs = DB.checkedExecute("SELECT recipient, amount FROM GenesisTransactions WHERE signature = ?", signature);
if (rs == null)

View File

@@ -0,0 +1,11 @@
package repository.hsqldb;
import repository.Repository;
public class HSQLDBRepository extends Repository {
public HSQLDBRepository() {
this.transactionRepository = new HSQLDBTransaction();
}
}

View File

@@ -11,32 +11,57 @@ import data.transaction.Transaction.TransactionType;
import repository.TransactionRepository;
public class HSQLDBTransaction implements TransactionRepository {
private static final int REFERENCE_LENGTH = 64;
private HSQLDBGenesisTransaction genesisTransactionRepository;
public HSQLDBTransaction() {
genesisTransactionRepository = new HSQLDBGenesisTransaction();
}
public Transaction fromSignature(byte[] signature) {
try {
ResultSet rs = DB.checkedExecute("SELECT type, reference, creator, creation, fee FROM Transactions WHERE signature = ?", signature);
if (rs == null)
return null;
TransactionType type = TransactionType.valueOf(rs.getInt(1));
byte[] reference = DB.getResultSetBytes(rs.getBinaryStream(1), REFERENCE_LENGTH);
// Note: can't use CREATOR_LENGTH in case we encounter Genesis Account's short, 8-byte public key
PublicKeyAccount creator = new PublicKeyAccount(DB.getResultSetBytes(rs.getBinaryStream(2)));
long timestamp = rs.getTimestamp(3).getTime();
BigDecimal fee = rs.getBigDecimal(4).setScale(8);
switch (type) {
case GENESIS:
return new HSQLDBGenesisTransaction().fromSignature(signature, reference, creator, timestamp, fee);
default:
return null;
}
byte[] reference = DB.getResultSetBytes(rs.getBinaryStream(2));
PublicKeyAccount creator = new PublicKeyAccount(DB.getResultSetBytes(rs.getBinaryStream(3)));
long timestamp = rs.getTimestamp(4).getTime();
BigDecimal fee = rs.getBigDecimal(5).setScale(8);
return this.fromBase(type, signature, reference, creator, timestamp, fee);
} catch (SQLException e) {
return null;
}
}
public Transaction fromReference(byte[] reference) {
try {
ResultSet rs = DB.checkedExecute("SELECT type, signature, creator, creation, fee FROM Transactions WHERE reference = ?", reference);
if (rs == null)
return null;
TransactionType type = TransactionType.valueOf(rs.getInt(1));
byte[] signature = DB.getResultSetBytes(rs.getBinaryStream(2));
PublicKeyAccount creator = new PublicKeyAccount(DB.getResultSetBytes(rs.getBinaryStream(3)));
long timestamp = rs.getTimestamp(4).getTime();
BigDecimal fee = rs.getBigDecimal(5).setScale(8);
return this.fromBase(type, signature, reference, creator, timestamp, fee);
} catch (SQLException e) {
return null;
}
}
private Transaction fromBase(TransactionType type, byte[] signature, byte[] reference, PublicKeyAccount creator, long timestamp, BigDecimal fee) {
switch (type) {
case GENESIS:
return this.genesisTransactionRepository.fromBase(signature, reference, creator, timestamp, fee);
default:
return null;
}
}
}