From 73dc0e568750922233d05b60a62b3c75fd0d6590 Mon Sep 17 00:00:00 2001 From: vlast Date: Sun, 21 Aug 2022 16:10:31 +0300 Subject: [PATCH] hw-25 --- .../src/main/java/com/bobocode/DemoApp.java | 23 +- .../com/bobocode/pool/ConnectionProxy.java | 334 +++++++++++++++++- .../com/bobocode/pool/PooledDataSource.java | 32 +- 3 files changed, 364 insertions(+), 25 deletions(-) diff --git a/lesson-demo/src/main/java/com/bobocode/DemoApp.java b/lesson-demo/src/main/java/com/bobocode/DemoApp.java index e937300d..cafa53f7 100644 --- a/lesson-demo/src/main/java/com/bobocode/DemoApp.java +++ b/lesson-demo/src/main/java/com/bobocode/DemoApp.java @@ -1,9 +1,10 @@ package com.bobocode; +import com.bobocode.pool.PooledDataSource; import lombok.SneakyThrows; -import org.postgresql.ds.PGSimpleDataSource; import javax.sql.DataSource; +import java.sql.SQLException; public class DemoApp { @SneakyThrows @@ -24,23 +25,11 @@ public static void main(String[] args) { } System.out.println((System.nanoTime() - start) / 1000_000 + " ms"); System.out.println(total); - - - } - - private static DataSource initializeDataSource() { - PGSimpleDataSource dataSource = new PGSimpleDataSource(); - dataSource.setURL("jdbc:postgresql://localhost:5432/postgres"); - dataSource.setUser("ju22user"); - dataSource.setPassword("ju22pass"); - return dataSource; } - private static DataSource initializePooledDataSource() { - PGSimpleDataSource dataSource = new PGSimpleDataSource(); - dataSource.setURL("jdbc:postgresql://localhost:5432/postgres"); - dataSource.setUser("ju22user"); - dataSource.setPassword("ju22pass"); - return dataSource; + private static DataSource initializePooledDataSource() throws SQLException, InterruptedException { + return new PooledDataSource("jdbc:postgresql://localhost:5432/postgres", + "postgres", + "root"); } } diff --git a/lesson-demo/src/main/java/com/bobocode/pool/ConnectionProxy.java b/lesson-demo/src/main/java/com/bobocode/pool/ConnectionProxy.java index 06461956..3add39e7 100644 --- a/lesson-demo/src/main/java/com/bobocode/pool/ConnectionProxy.java +++ b/lesson-demo/src/main/java/com/bobocode/pool/ConnectionProxy.java @@ -1,8 +1,332 @@ package com.bobocode.pool; -public class ConnectionProxy { - // todo: 1. store a physical connection and a pool reference - // todo: 2. override method close - // todo: 3. delegate all method invocations to a physical connection - +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.NClob; +import java.sql.PreparedStatement; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.ShardingKey; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; +import java.util.Queue; +import java.util.concurrent.Executor; + +public class ConnectionProxy implements Connection { + private final Connection connection; + private final Queue pool; + + public ConnectionProxy(Connection connection, Queue pool) { + this.connection = connection; + this.pool = pool; + } + + @Override + public Statement createStatement() throws SQLException { + return connection.createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + return connection.prepareStatement(sql); + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + return connection.prepareCall(sql); + } + + @Override + public String nativeSQL(String sql) throws SQLException { + return connection.nativeSQL(sql); + } + + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException { + connection.setAutoCommit(autoCommit); + } + + @Override + public boolean getAutoCommit() throws SQLException { + return connection.getAutoCommit(); + } + + @Override + public void commit() throws SQLException { + connection.commit(); + } + + @Override + public void rollback() throws SQLException { + connection.rollback(); + } + + @Override + public void close() throws SQLException { + pool.add(this); + } + + @Override + public boolean isClosed() throws SQLException { + return connection.isClosed(); + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + return connection.getMetaData(); + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + connection.setReadOnly(readOnly); + } + + @Override + public boolean isReadOnly() throws SQLException { + return connection.isReadOnly(); + } + + @Override + public void setCatalog(String catalog) throws SQLException { + connection.setCatalog(catalog); + } + + @Override + public String getCatalog() throws SQLException { + return connection.getCatalog(); + } + + @Override + public void setTransactionIsolation(int level) throws SQLException { + connection.setTransactionIsolation(level); + } + + @Override + public int getTransactionIsolation() throws SQLException { + return connection.getTransactionIsolation(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return connection.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + connection.clearWarnings(); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { + return connection.createStatement(resultSetType, resultSetConcurrency); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return connection.prepareStatement(sql, resultSetType, resultSetConcurrency); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return connection.prepareCall(sql, resultSetType, resultSetConcurrency); + } + + @Override + public Map> getTypeMap() throws SQLException { + return connection.getTypeMap(); + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + connection.setTypeMap(map); + } + + @Override + public void setHoldability(int holdability) throws SQLException { + connection.setHoldability(holdability); + } + + @Override + public int getHoldability() throws SQLException { + return connection.getHoldability(); + } + + @Override + public Savepoint setSavepoint() throws SQLException { + return connection.setSavepoint(); + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + return connection.setSavepoint(name); + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + connection.rollback(savepoint); + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + connection.releaseSavepoint(savepoint); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { + return connection.prepareStatement(sql, autoGeneratedKeys); + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { + return connection.prepareStatement(sql, columnIndexes); + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { + return connection.prepareStatement(sql, columnNames); + } + + @Override + public Clob createClob() throws SQLException { + return connection.createClob(); + } + + @Override + public Blob createBlob() throws SQLException { + return connection.createBlob(); + } + + @Override + public NClob createNClob() throws SQLException { + return connection.createNClob(); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + return connection.createSQLXML(); + } + + @Override + public boolean isValid(int timeout) throws SQLException { + return connection.isValid(timeout); + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + connection.setClientInfo(name, value); + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + connection.setClientInfo(properties); + } + + @Override + public String getClientInfo(String name) throws SQLException { + return connection.getClientInfo(name); + } + + @Override + public Properties getClientInfo() throws SQLException { + return connection.getClientInfo(); + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + return connection.createArrayOf(typeName, elements); + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + return connection.createStruct(typeName, attributes); + } + + @Override + public void setSchema(String schema) throws SQLException { + connection.setSchema(schema); + } + + @Override + public String getSchema() throws SQLException { + return connection.getSchema(); + } + + @Override + public void abort(Executor executor) throws SQLException { + connection.abort(executor); + } + + @Override + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { + connection.setNetworkTimeout(executor, milliseconds); + } + + @Override + public int getNetworkTimeout() throws SQLException { + return connection.getNetworkTimeout(); + } + + @Override + public void beginRequest() throws SQLException { + connection.beginRequest(); + } + + @Override + public void endRequest() throws SQLException { + connection.endRequest(); + } + + @Override + public boolean setShardingKeyIfValid(ShardingKey shardingKey, ShardingKey superShardingKey, int timeout) throws SQLException { + return connection.setShardingKeyIfValid(shardingKey, superShardingKey, timeout); + } + + @Override + public boolean setShardingKeyIfValid(ShardingKey shardingKey, int timeout) throws SQLException { + return connection.setShardingKeyIfValid(shardingKey, timeout); + } + + @Override + public void setShardingKey(ShardingKey shardingKey, ShardingKey superShardingKey) throws SQLException { + connection.setShardingKey(shardingKey, superShardingKey); + } + + @Override + public void setShardingKey(ShardingKey shardingKey) throws SQLException { + connection.setShardingKey(shardingKey); + } + + @Override + public T unwrap(Class iface) throws SQLException { + return connection.unwrap(iface); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return connection.isWrapperFor(iface); + } } diff --git a/lesson-demo/src/main/java/com/bobocode/pool/PooledDataSource.java b/lesson-demo/src/main/java/com/bobocode/pool/PooledDataSource.java index 92f72068..1b563030 100644 --- a/lesson-demo/src/main/java/com/bobocode/pool/PooledDataSource.java +++ b/lesson-demo/src/main/java/com/bobocode/pool/PooledDataSource.java @@ -1,9 +1,35 @@ package com.bobocode.pool; +import lombok.SneakyThrows; import org.postgresql.ds.PGSimpleDataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + public class PooledDataSource extends PGSimpleDataSource { - // todo: 1. store a queue of connections (this is a pool) - // todo: 2. initialize a datasource with 10 physical connection - // todo: 3. override method getConnection so it uses a pool + private Queue pool; + private final int poolSize = 10; + + public PooledDataSource(String url, String userName, String pass) { + this.pool = new ConcurrentLinkedQueue<>(); + this.setUrl(url); + this.setUser(userName); + this.setPassword(pass); + initPool(); + } + + @SneakyThrows + private void initPool() { + for (int i = 0; i < poolSize; i++) { + Connection connection = super.getConnection(); + pool.add(new ConnectionProxy(connection, pool)); + } + } + + @Override + public Connection getConnection() throws SQLException { + return pool.poll(); + } }