Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e3de8de

Browse files
committed
Refactored Reporter, ReporterFactory and OutputBuffers to be more
clean and working with new reporter API
1 parent 2593fd7 commit e3de8de

10 files changed

Lines changed: 204 additions & 151 deletions

File tree

src/main/java/org/utplsql/api/TestRunner.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,6 @@ else if (e.getErrorCode() == UtPLSQLNotInstalledException.ERROR_CODE) {
129129
throw new UtPLSQLNotInstalledException(e);
130130
}
131131
else {
132-
// If the execution failed by unexpected reasons finishes all reporters,
133-
// this way the users don't need to care about reporters' sessions hanging.
134-
OracleConnection oraConn = conn.unwrap(OracleConnection.class);
135-
136-
try (CallableStatement closeBufferStmt = conn.prepareCall("BEGIN ut_output_buffer.close(?); END;")) {
137-
closeBufferStmt.setArray(1, oraConn.createOracleArray(CustomTypes.UT_REPORTERS, options.reporterList.toArray()));
138-
closeBufferStmt.execute();
139-
} catch (SQLException ignored) {}
140-
141132
throw e;
142133
}
143134
} finally {
@@ -156,7 +147,7 @@ else if (e.getErrorCode() == UtPLSQLNotInstalledException.ERROR_CODE) {
156147
* @throws SQLException any sql exception
157148
*/
158149
private void validateReporter(Connection conn, Reporter reporter) throws SQLException {
159-
if (reporter.getId() == null || reporter.getId().isEmpty())
150+
if (!reporter.isInit() || reporter.getId() == null || reporter.getId().isEmpty())
160151
reporter.init(conn);
161152
}
162153

src/main/java/org/utplsql/api/OutputBuffer.java renamed to src/main/java/org/utplsql/api/outputBuffer/DefaultOutputBuffer.java

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
1-
package org.utplsql.api;
1+
package org.utplsql.api.outputBuffer;
22

3+
import oracle.jdbc.OracleCallableStatement;
4+
import oracle.jdbc.OracleConnection;
5+
import oracle.jdbc.OraclePreparedStatement;
36
import org.utplsql.api.reporter.Reporter;
47
import oracle.jdbc.OracleTypes;
58

9+
import javax.xml.transform.Result;
610
import java.io.PrintStream;
711
import java.sql.*;
812
import java.util.ArrayList;
913
import java.util.List;
14+
import java.util.function.Consumer;
1015

1116
/**
1217
* Fetches the lines produced by a reporter.
18+
*
19+
* @author vinicius
20+
* @author pesse
1321
*/
14-
public class OutputBuffer {
22+
public class DefaultOutputBuffer implements OutputBuffer {
1523

1624
private Reporter reporter;
1725

1826
/**
19-
* Creates a new OutputBuffer.
27+
* Creates a new DefaultOutputBuffer.
2028
* @param reporter the reporter to be used
2129
*/
22-
public OutputBuffer(Reporter reporter) {
30+
public DefaultOutputBuffer(Reporter reporter) {
31+
32+
assert reporter.isInit() : "Reporter is not initialized! You can only create OutputBuffers for initialized Reporters";
33+
assert reporter.hasOutput() : "Reporter has no output. Please use NonOutputBuffer instead";
34+
2335
this.reporter = reporter;
2436
}
2537

@@ -59,24 +71,20 @@ public void printAvailable(Connection conn, List<PrintStream> printStreams) thro
5971
/**
6072
* Print the lines as soon as they are produced and call the callback passing the new line.
6173
* @param conn DB connection
62-
* @param cb the callback to be called
74+
* @param onLineFetched the callback to be called
6375
* @throws SQLException any sql errors
6476
*/
65-
public void fetchAvailable(Connection conn, Callback cb) throws SQLException {
66-
PreparedStatement preparedStatement = null;
67-
ResultSet resultSet = null;
68-
try {
69-
preparedStatement = conn.prepareStatement("SELECT * FROM table(ut_output_buffer.get_lines(?))");
70-
preparedStatement.setString(1, getReporter().getId());
71-
resultSet = preparedStatement.executeQuery();
72-
73-
while (resultSet.next())
74-
cb.onLineFetched(resultSet.getString(1));
75-
} finally {
76-
if (resultSet != null)
77-
resultSet.close();
78-
if (preparedStatement != null)
79-
preparedStatement.close();
77+
public void fetchAvailable(Connection conn, Consumer<String> onLineFetched) throws SQLException {
78+
79+
OracleConnection oraConn = conn.unwrap(OracleConnection.class);
80+
81+
try (OraclePreparedStatement pstmt = (OraclePreparedStatement)oraConn.prepareStatement("select * from table(?.get_lines())")) {
82+
83+
pstmt.setORAData(1, getReporter());
84+
try (ResultSet resultSet = pstmt.executeQuery() ) {
85+
while (resultSet.next())
86+
onLineFetched.accept(resultSet.getString(1));
87+
}
8088
}
8189
}
8290

@@ -87,34 +95,25 @@ public void fetchAvailable(Connection conn, Callback cb) throws SQLException {
8795
* @throws SQLException any sql errors
8896
*/
8997
public List<String> fetchAll(Connection conn) throws SQLException {
90-
CallableStatement callableStatement = null;
91-
ResultSet resultSet = null;
92-
try {
93-
callableStatement = conn.prepareCall("BEGIN ? := ut_output_buffer.get_lines_cursor(?); END;");
94-
callableStatement.registerOutParameter(1, OracleTypes.CURSOR);
95-
callableStatement.setString(2, getReporter().getId());
96-
callableStatement.execute();
97-
98-
resultSet = (ResultSet) callableStatement.getObject(1);
99-
100-
List<String> outputLines = new ArrayList<>();
101-
while (resultSet.next()) {
102-
outputLines.add(resultSet.getString("text"));
98+
99+
OracleConnection oraConn = conn.unwrap(OracleConnection.class);
100+
101+
try (OracleCallableStatement cstmt = (OracleCallableStatement)oraConn.prepareCall("{? = call ?.get_lines_cursor() }")) {
102+
103+
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
104+
cstmt.setORAData(2, getReporter());
105+
106+
cstmt.execute();
107+
108+
try ( ResultSet resultSet = (ResultSet) cstmt.getObject(1)) {
109+
110+
List<String> outputLines = new ArrayList<>();
111+
while (resultSet.next()) {
112+
outputLines.add(resultSet.getString("text"));
113+
}
114+
return outputLines;
103115
}
104-
return outputLines;
105-
} finally {
106-
if (resultSet != null)
107-
resultSet.close();
108-
if (callableStatement != null)
109-
callableStatement.close();
110116
}
111117
}
112118

113-
/**
114-
* Callback to be called when a new line is available from the output buffer.
115-
*/
116-
public interface Callback {
117-
void onLineFetched(String s);
118-
}
119-
120119
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.utplsql.api.outputBuffer;
2+
3+
import org.utplsql.api.reporter.Reporter;
4+
5+
import java.io.PrintStream;
6+
import java.sql.Connection;
7+
import java.sql.SQLException;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import java.util.function.Consumer;
11+
12+
/** An OutputBuffer replacement which just returns nothing at all. Suitable for Reporters without any output
13+
*
14+
* @author pesse
15+
*/
16+
public class NonOutputBuffer implements OutputBuffer {
17+
18+
private Reporter reporter;
19+
20+
public NonOutputBuffer( Reporter reporter) {
21+
this.reporter = reporter;
22+
}
23+
24+
@Override
25+
public Reporter getReporter() {
26+
return reporter;
27+
}
28+
29+
@Override
30+
public void printAvailable(Connection conn, PrintStream ps) throws SQLException {
31+
List<PrintStream> printStreams = new ArrayList<>(1);
32+
printStreams.add(ps);
33+
printAvailable(conn, printStreams);
34+
}
35+
36+
@Override
37+
public void printAvailable(Connection conn, List<PrintStream> printStreams) throws SQLException {
38+
fetchAvailable(conn, s -> {
39+
for (PrintStream ps : printStreams)
40+
ps.println(s);
41+
});
42+
}
43+
44+
@Override
45+
public void fetchAvailable(Connection conn, Consumer<String> onLineFetched) throws SQLException {
46+
onLineFetched.accept(null);
47+
}
48+
49+
@Override
50+
public List<String> fetchAll(Connection conn) throws SQLException {
51+
return new ArrayList<>();
52+
}
53+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.utplsql.api.outputBuffer;
2+
3+
import org.utplsql.api.reporter.Reporter;
4+
5+
import java.io.PrintStream;
6+
import java.sql.Connection;
7+
import java.sql.SQLException;
8+
import java.util.List;
9+
import java.util.function.Consumer;
10+
11+
public interface OutputBuffer {
12+
13+
Reporter getReporter();
14+
15+
/**
16+
* Print the lines as soon as they are produced and write to a PrintStream.
17+
* @param conn DB connection
18+
* @param ps the PrintStream to be used, e.g: System.out
19+
* @throws SQLException any sql errors
20+
*/
21+
void printAvailable(Connection conn, PrintStream ps) throws SQLException;
22+
23+
/**
24+
* Print the lines as soon as they are produced and write to a list of PrintStreams.
25+
* @param conn DB connection
26+
* @param printStreams the PrintStream list to be used, e.g: System.out, new PrintStream(new FileOutputStream)
27+
* @throws SQLException any sql errors
28+
*/
29+
void printAvailable(Connection conn, List<PrintStream> printStreams) throws SQLException;
30+
31+
/**
32+
* Print the lines as soon as they are produced and call the callback passing the new line.
33+
* @param conn DB connection
34+
* @param onLineFetched the callback to be called
35+
* @throws SQLException any sql errors
36+
*/
37+
void fetchAvailable(Connection conn, Consumer<String> onLineFetched) throws SQLException;
38+
39+
/**
40+
* Get all lines from output buffer and return it as a list of strings.
41+
* @param conn DB connection
42+
* @return the lines
43+
* @throws SQLException any sql errors
44+
*/
45+
List<String> fetchAll(Connection conn) throws SQLException;
46+
47+
}

src/main/java/org/utplsql/api/reporter/DefaultReporters.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.utplsql.api.reporter;
22

33
import java.util.function.BiFunction;
4-
import java.util.function.Supplier;
54

65
/** This enum defines default reporters, added and maintained by the utPLSQL team, and their (default) factory method
76
*

src/main/java/org/utplsql/api/reporter/Reporter.java

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import oracle.sql.ORAData;
88
import oracle.sql.STRUCT;
99
import oracle.sql.StructDescriptor;
10+
import org.utplsql.api.outputBuffer.DefaultOutputBuffer;
11+
import org.utplsql.api.outputBuffer.NonOutputBuffer;
12+
import org.utplsql.api.outputBuffer.OutputBuffer;
1013

1114
import java.sql.*;
1215

@@ -31,10 +34,6 @@ private void setTypeName( String typeName ) {
3134
this.selfType = typeName.replaceAll("[^0-9a-zA-Z_]", "");
3235
}
3336

34-
public void setParameters( Object[] parameters ) {
35-
// Empty method
36-
}
37-
3837
public Reporter init( Connection con ) throws SQLException {
3938

4039
OracleConnection oraConn = con.unwrap(OracleConnection.class);
@@ -48,7 +47,7 @@ public Reporter init( Connection con ) throws SQLException {
4847
}
4948

5049
/** Initializes the Reporter from database
51-
* This is necessary because we set up OutputBuffer (and maybe other stuff) we don't want to know and care about
50+
* This is necessary because we set up DefaultOutputBuffer (and maybe other stuff) we don't want to know and care about
5251
* in the java API. Let's just do the instantiation of the Reporter in the database and map it into this object.
5352
*
5453
* @param oraConn
@@ -70,18 +69,24 @@ private void initDbReporter( OracleConnection oraConn ) throws SQLException {
7069
* @throws SQLException
7170
*/
7271
private void initHasOutput( OracleConnection oraConn ) throws SQLException {
73-
OracleCallableStatement cstmt = (OracleCallableStatement)oraConn.prepareCall("{? = call ?.has_output()}");
74-
75-
cstmt.registerOutParameter(1, OracleTypes.INTEGER);
76-
cstmt.setORAData(2, this);
77-
cstmt.execute();
7872

79-
Integer i = cstmt.getInt(1);
80-
if ( i != null && i == 1 ) {
81-
hasOutput = true;
82-
}
83-
else {
84-
hasOutput = false;
73+
try ( PreparedStatement stmt = oraConn.prepareStatement("select ut_runner.is_output_reporter(?) from dual")) {
74+
stmt.setString(1, getTypeName());
75+
76+
try ( ResultSet rs = stmt.executeQuery() ) {
77+
if ( rs.next() ) {
78+
String isReporterResult = rs.getString(1);
79+
80+
if ( isReporterResult == null )
81+
throw new IllegalArgumentException("The given type " + getTypeName() + " is not a valid Reporter!");
82+
else if (isReporterResult.equalsIgnoreCase("Y") )
83+
hasOutput = true;
84+
else
85+
hasOutput = false;
86+
}
87+
else
88+
throw new SQLException("Could not check Reporter validity");
89+
}
8590
}
8691
}
8792

@@ -120,4 +125,13 @@ public Datum toDatum(Connection c) throws SQLException
120125
return new STRUCT(sd, c, getAttributes());
121126
}
122127

128+
public OutputBuffer getOutputBuffer() {
129+
130+
if ( hasOutput() ) {
131+
return new DefaultOutputBuffer(this);
132+
}
133+
else {
134+
return new NonOutputBuffer(this);
135+
}
136+
}
123137
}

src/main/java/org/utplsql/api/reporter/ReporterFactory.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
*/
2020
public final class ReporterFactory implements ORADataFactory {
2121

22-
23-
2422
public static class ReporterInfo {
2523
public ReporterInfo(BiFunction<String, Object[], ? extends Reporter> factoryMethod, String description) {
2624
this.factoryMethod = factoryMethod;
@@ -55,6 +53,14 @@ public static ReporterFactory getInstance() {
5553
return instance;
5654
}
5755

56+
public static Reporter create( DefaultReporters reporter ) {
57+
return getInstance().createReporter(reporter);
58+
}
59+
60+
public static Reporter create( String reporter ) {
61+
return getInstance().createReporter(reporter);
62+
}
63+
5864
/** Registers a creation method for a specified reporter name. Overrides eventually existing creation method
5965
*
6066
* @param reporterName the reporter's name to register
@@ -84,7 +90,7 @@ public synchronized ReporterInfo unregisterReporterFactoryMethod( String reporte
8490
*/
8591
public Reporter createReporter(String reporterName, Object[] attributes) {
8692

87-
BiFunction<String, Object[], ? extends Reporter> supplier = getDefaultReporterFactoryMethod();
93+
BiFunction<String, Object[], ? extends Reporter> supplier = Reporter::new;
8894

8995
if ( reportFactoryMethodMap.containsKey(reporterName)) {
9096

@@ -108,6 +114,15 @@ public Reporter createReporter( String reporterName ) {
108114
return createReporter(reporterName, null);
109115
}
110116

117+
/** Returns a new reporter of the given DefaultReporter type
118+
*
119+
* @param reporter
120+
* @return
121+
*/
122+
public Reporter createReporter( DefaultReporters reporter ) {
123+
return createReporter(reporter.name());
124+
}
125+
111126
/** Returns a set of all registered reporter's names
112127
*
113128
* @return Set of reporter names

0 commit comments

Comments
 (0)