From b25b614c59b782d454013af258c1aa68cd572c89 Mon Sep 17 00:00:00 2001 From: Sambo Chea Date: Wed, 6 Jul 2022 11:21:25 +0700 Subject: [PATCH] Task: Add execute result with count queries and add connection factory with custom builder and create datasource and add queryOf methods and updated the jdbc data query and jdbc count query enhancement for cubetiq sql core --- .../com/cubetiqs/sql/ConnectionFactory.java | 133 ++++++++++++++++++ .../com/cubetiqs/sql/DataSourceProps.java | 15 ++ .../java/com/cubetiqs/sql/IExecuteResult.java | 4 + .../cubetiqs/sql/IExecuteResultWithCount.java | 47 +++++++ .../java/com/cubetiqs/sql/JdbcCountQuery.java | 16 +++ .../com/cubetiqs/sql/JdbcDataFactory.java | 36 +++++ .../java/com/cubetiqs/sql/JdbcDataQuery.java | 76 +++++++++- .../com/cubetiqs/sql/JdbcDataQueryImpl.java | 29 ++++ 8 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/cubetiqs/sql/ConnectionFactory.java create mode 100644 src/main/java/com/cubetiqs/sql/DataSourceProps.java create mode 100644 src/main/java/com/cubetiqs/sql/IExecuteResultWithCount.java create mode 100644 src/main/java/com/cubetiqs/sql/JdbcCountQuery.java diff --git a/src/main/java/com/cubetiqs/sql/ConnectionFactory.java b/src/main/java/com/cubetiqs/sql/ConnectionFactory.java new file mode 100644 index 0000000..5c0c288 --- /dev/null +++ b/src/main/java/com/cubetiqs/sql/ConnectionFactory.java @@ -0,0 +1,133 @@ +package com.cubetiqs.sql; + +import javax.sql.DataSource; +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.logging.Logger; + +public final class ConnectionFactory { + public static class ConnectionBuilder { + private String driver; + private String url; + private String user; + private String password; + + public ConnectionBuilder driver(String driver) { + this.driver = driver; + return this; + } + + public ConnectionBuilder url(String url) { + this.url = url; + return this; + } + + public ConnectionBuilder user(String user) { + this.user = user; + return this; + } + + public ConnectionBuilder password(String password) { + this.password = password; + return this; + } + + public ConnectionBuilder properties(DataSourceProps properties) { + this.driver = properties.getDriver(); + this.url = properties.getUrl(); + this.user = properties.getUser(); + this.password = properties.getPassword(); + return this; + } + + public Connection build() throws SQLException { + if (driver == null) { + return null; + } + + try { + Class.forName(driver); + } catch (ClassNotFoundException e) { + throw new SQLException(e); + } + + if (user == null && password == null) { + return DriverManager.getConnection(url); + } + + return DriverManager.getConnection(url, user, password); + } + } + + public static ConnectionBuilder builder() { + return new ConnectionBuilder(); + } + + public static class SimpleDataSource implements DataSource { + private final ConnectionBuilder connectionBuilder; + private PrintWriter printWriter; + private int loginTimeout = 0; + + public SimpleDataSource(ConnectionBuilder connectionBuilder) { + this.connectionBuilder = connectionBuilder; + this.printWriter = new PrintWriter(System.out); + } + + public SimpleDataSource(ConnectionBuilder connectionBuilder, PrintWriter printWriter) { + this.connectionBuilder = connectionBuilder; + this.printWriter = printWriter; + } + + @Override + public Connection getConnection() throws SQLException { + return connectionBuilder.build(); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + return connectionBuilder.user(username).password(password).build(); + } + + @Override + public PrintWriter getLogWriter() throws SQLException { + return printWriter; + } + + @Override + public void setLogWriter(PrintWriter out) throws SQLException { + this.printWriter = out; + } + + @Override + public void setLoginTimeout(int seconds) throws SQLException { + this.loginTimeout = seconds; + } + + @Override + public int getLoginTimeout() throws SQLException { + return loginTimeout; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return Logger.getGlobal(); + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } + } + + public static DataSource createDataSource(ConnectionBuilder builder) { + return new SimpleDataSource(builder); + } +} diff --git a/src/main/java/com/cubetiqs/sql/DataSourceProps.java b/src/main/java/com/cubetiqs/sql/DataSourceProps.java new file mode 100644 index 0000000..584d84d --- /dev/null +++ b/src/main/java/com/cubetiqs/sql/DataSourceProps.java @@ -0,0 +1,15 @@ +package com.cubetiqs.sql; + +import java.util.Map; + +public interface DataSourceProps extends java.io.Serializable { + String getDriver(); + + String getUrl(); + + String getUser(); + + String getPassword(); + + Map getProperties(); +} diff --git a/src/main/java/com/cubetiqs/sql/IExecuteResult.java b/src/main/java/com/cubetiqs/sql/IExecuteResult.java index f631a77..7062048 100644 --- a/src/main/java/com/cubetiqs/sql/IExecuteResult.java +++ b/src/main/java/com/cubetiqs/sql/IExecuteResult.java @@ -10,4 +10,8 @@ public interface IExecuteResult { default long getDuration() { return 0L; } + + static IExecuteResult newEmpty() { + return () -> null; + } } diff --git a/src/main/java/com/cubetiqs/sql/IExecuteResultWithCount.java b/src/main/java/com/cubetiqs/sql/IExecuteResultWithCount.java new file mode 100644 index 0000000..a59b13e --- /dev/null +++ b/src/main/java/com/cubetiqs/sql/IExecuteResultWithCount.java @@ -0,0 +1,47 @@ +package com.cubetiqs.sql; + +import java.util.Objects; + +public interface IExecuteResultWithCount extends IExecuteResult { + long getCount(); + + static IExecuteResultWithCount newEmpty() { + return new IExecuteResultWithCount() { + @Override + public long getCount() { + return 0; + } + + @Override + public R getData() { + return null; + } + }; + } + + static IExecuteResultWithCount with(long count, IExecuteResult result) { + Objects.requireNonNull(result, "IExecuteResult must be not null!"); + + return new IExecuteResultWithCount() { + @Override + public long getCount() { + return count; + } + + @Override + public R getData() { + return result.getData(); + } + + @Override + public long getDuration() { + return result.getDuration(); + } + + @Override + public Throwable getError() { + return result.getError(); + } + }; + } +} diff --git a/src/main/java/com/cubetiqs/sql/JdbcCountQuery.java b/src/main/java/com/cubetiqs/sql/JdbcCountQuery.java new file mode 100644 index 0000000..a3fc9ef --- /dev/null +++ b/src/main/java/com/cubetiqs/sql/JdbcCountQuery.java @@ -0,0 +1,16 @@ +package com.cubetiqs.sql; + +public interface JdbcCountQuery { + long count(String sql); + + long count(String sql, Object... args); + + default long count(ISqlMapParameter parameter) { + if (parameter.getParams().size() == 0) { + return count(parameter.getSql()); + } + + Object[] args = parameter.getSqlArgs(); + return count(parameter.getFormatSql(), args); + } +} diff --git a/src/main/java/com/cubetiqs/sql/JdbcDataFactory.java b/src/main/java/com/cubetiqs/sql/JdbcDataFactory.java index ae2a734..de851ae 100644 --- a/src/main/java/com/cubetiqs/sql/JdbcDataFactory.java +++ b/src/main/java/com/cubetiqs/sql/JdbcDataFactory.java @@ -76,4 +76,40 @@ public final class JdbcDataFactory { public IExecuteResult query(ISqlMapParameter parameter, RowMapperProvider mapper) { return queryManager.query(parameter, mapper); } + + public IExecuteResultWithCount queryOf(String sql) { + return queryManager.queryOf(sql); + } + + public IExecuteResultWithCount queryOf(String sql, Object... args) { + return queryManager.queryOf(sql, args); + } + + public IExecuteResultWithCount queryOf(String sql, RowMapperProvider mapper) { + return queryManager.queryOf(sql, mapper); + } + + public IExecuteResultWithCount queryOf(String sql, RowMapperProvider mapper, Object... args) { + return queryManager.queryOf(sql, mapper, args); + } + + public IExecuteResultWithCount queryOf(ISqlMapParameter parameter) { + return queryManager.queryOf(parameter); + } + + public IExecuteResultWithCount queryOf(ISqlMapParameter parameter, RowMapperProvider mapper) { + return queryManager.queryOf(parameter, mapper); + } + + public long count(String sql) { + return queryManager.count(sql); + } + + public long count(String sql, Object... args) { + return queryManager.count(sql, args); + } + + public long count(ISqlMapParameter parameter) { + return queryManager.count(parameter); + } } diff --git a/src/main/java/com/cubetiqs/sql/JdbcDataQuery.java b/src/main/java/com/cubetiqs/sql/JdbcDataQuery.java index 827c07a..645e85e 100644 --- a/src/main/java/com/cubetiqs/sql/JdbcDataQuery.java +++ b/src/main/java/com/cubetiqs/sql/JdbcDataQuery.java @@ -6,7 +6,7 @@ import com.cubetiqs.mapper.RowMapperProvider; import java.util.List; import java.util.Map; -public interface JdbcDataQuery extends JdbcAccessor { +public interface JdbcDataQuery extends JdbcAccessor, JdbcCountQuery { IExecuteResult> queryForList(String sql); IExecuteResult> queryForList(String sql, Object... args); @@ -35,6 +35,80 @@ public interface JdbcDataQuery extends JdbcAccessor { IExecuteResult query(String sql, RowMapperProvider mapper, Object... args); + default IExecuteResultWithCount> queryOf(String sql) { + IExecuteResult> result = queryForList(sql); + long count = 0; + if (result.getData() != null) { + count = result.getData().size(); + } + + if (count == 0) { + return IExecuteResultWithCount.newEmpty(); + } + + return IExecuteResultWithCount.with(count, result); + } + + default IExecuteResultWithCount> queryOf(String sql, Object... args) { + IExecuteResult> result = queryForList(sql, args); + long count = 0; + if (result.getData() != null) { + count = result.getData().size(); + } + + if (count == 0) { + return IExecuteResultWithCount.newEmpty(); + } + + return IExecuteResultWithCount.with(count, result); + } + + default IExecuteResultWithCount> queryOf(ISqlMapParameter parameter) { + if (parameter.getParams().size() == 0) { + return queryOf(parameter.getSql()); + } + + Object[] args = parameter.getSqlArgs(); + return queryOf(parameter.getFormatSql(), args); + } + + default IExecuteResultWithCount> queryOf(String sql, RowMapperProvider mapper) { + IExecuteResult> result = queryForList(sql, mapper); + long count = 0; + if (result.getData() != null) { + count = result.getData().size(); + } + + if (count == 0) { + return IExecuteResultWithCount.newEmpty(); + } + + return IExecuteResultWithCount.with(count, result); + } + + default IExecuteResultWithCount> queryOf(String sql, RowMapperProvider mapper, Object... args) { + IExecuteResult> result = queryForList(sql, mapper, args); + long count = 0; + if (result.getData() != null) { + count = result.getData().size(); + } + + if (count == 0) { + return IExecuteResultWithCount.newEmpty(); + } + + return IExecuteResultWithCount.with(count, result); + } + + default IExecuteResultWithCount> queryOf(ISqlMapParameter parameter, RowMapperProvider mapper) { + if (parameter.getParams().size() == 0) { + return queryOf(parameter.getSql(), mapper); + } + + Object[] args = parameter.getSqlArgs(); + return queryOf(parameter.getFormatSql(), mapper, args); + } + default IExecuteResult> queryForList(ISqlMapParameter parameter) { if (parameter.getParams().size() == 0) { return queryForList(parameter.getSql()); diff --git a/src/main/java/com/cubetiqs/sql/JdbcDataQueryImpl.java b/src/main/java/com/cubetiqs/sql/JdbcDataQueryImpl.java index 9e605b7..82325d2 100644 --- a/src/main/java/com/cubetiqs/sql/JdbcDataQueryImpl.java +++ b/src/main/java/com/cubetiqs/sql/JdbcDataQueryImpl.java @@ -171,4 +171,33 @@ public class JdbcDataQueryImpl implements JdbcDataQuery { return builder.build(); } + + @Override + public long count(String sql) { + try (Statement statement = manager.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + ResultSet rs = statement.executeQuery(sql); + if (rs.next()) { + return rs.getLong(1); + } else { + return 0; + } + } catch (SQLException ex) { + return 0; + } + } + + @Override + public long count(String sql, Object... args) { + try (PreparedStatement statement = manager.getConnection().prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + ResultSetUtil.applyParameterized(statement, sql, args); + ResultSet rs = statement.executeQuery(); + if (rs.next()) { + return rs.getLong(1); + } else { + return 0; + } + } catch (SQLException ex) { + return 0; + } + } }