提交 a317bc36 authored 作者: Thomas Mueller's avatar Thomas Mueller

The H2 Console now stream results one statement / result set at a time.

上级 c4a5040b
...@@ -27,6 +27,7 @@ import java.util.Arrays; ...@@ -27,6 +27,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
...@@ -47,7 +48,6 @@ import org.h2.tools.Restore; ...@@ -47,7 +48,6 @@ import org.h2.tools.Restore;
import org.h2.tools.RunScript; import org.h2.tools.RunScript;
import org.h2.tools.Script; import org.h2.tools.Script;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.Utils;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.Profiler; import org.h2.util.Profiler;
...@@ -56,6 +56,7 @@ import org.h2.util.SortedProperties; ...@@ -56,6 +56,7 @@ import org.h2.util.SortedProperties;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Tool; import org.h2.util.Tool;
import org.h2.util.Utils;
/** /**
* For each connection to a session, an object of this class is created. * For each connection to a session, an object of this class is created.
...@@ -934,10 +935,8 @@ public class WebApp { ...@@ -934,10 +935,8 @@ public class WebApp {
private String query() { private String query() {
String sql = attributes.getProperty("sql").trim(); String sql = attributes.getProperty("sql").trim();
try { try {
Connection conn = session.getConnection();
String result;
ScriptReader r = new ScriptReader(new StringReader(sql)); ScriptReader r = new ScriptReader(new StringReader(sql));
ArrayList<String> list = New.arrayList(); final ArrayList<String> list = New.arrayList();
while (true) { while (true) {
String s = r.readStatement(); String s = r.readStatement();
if (s == null) { if (s == null) {
...@@ -945,13 +944,38 @@ public class WebApp { ...@@ -945,13 +944,38 @@ public class WebApp {
} }
list.add(s); list.add(s);
} }
final Connection conn = session.getConnection();
if (SysProperties.CONSOLE_STREAM) {
String page = StringUtils.utf8Decode(server.getFile("result.jsp"));
int idx = page.indexOf("${result}");
// the first element of the list is the header, the last the footer
list.add(0, page.substring(0, idx));
list.add(page.substring(idx + "${result}".length()));
session.put("chunks", new Iterator<String>() {
private int i;
public boolean hasNext() {
return i < list.size();
}
public String next() {
String s = list.get(i++);
if (i == 1 || i == list.size()) {
return s;
}
StringBuilder b = new StringBuilder();
query(conn, s, i - 1, list.size(), b);
return b.toString();
}
public void remove() {
throw new UnsupportedOperationException();
}
});
return "result.jsp";
}
String result;
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
String s = list.get(i); String s = list.get(i);
if (!(s.startsWith("@") && s.endsWith("."))) { query(conn, s, i, list.size(), buff);
buff.append(PageParser.escapeHtml(s + ";")).append("<br />");
}
buff.append(getResult(conn, i + 1, s, list.size() == 1, false)).append("<br />");
} }
result = buff.toString(); result = buff.toString();
session.put("result", result); session.put("result", result);
...@@ -961,6 +985,22 @@ public class WebApp { ...@@ -961,6 +985,22 @@ public class WebApp {
return "result.jsp"; return "result.jsp";
} }
/**
* Execute a query and append the result to the buffer.
*
* @param conn the connection
* @param s the statement
* @param i the index
* @param size the number of statements
* @param buff the target buffer
*/
protected void query(Connection conn, String s, int i, int size, StringBuilder buff) {
if (!(s.startsWith("@") && s.endsWith("."))) {
buff.append(PageParser.escapeHtml(s + ";")).append("<br />");
}
buff.append(getResult(conn, i + 1, s, size == 1, false)).append("<br />");
}
private String editResult() { private String editResult() {
ResultSet rs = session.result; ResultSet rs = session.result;
int row = Integer.parseInt(attributes.getProperty("row")); int row = Integer.parseInt(attributes.getProperty("row"));
......
...@@ -13,9 +13,11 @@ import java.io.InputStream; ...@@ -13,9 +13,11 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.h2.constant.SysProperties;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
...@@ -101,6 +103,7 @@ class WebThread extends WebApp implements Runnable { ...@@ -101,6 +103,7 @@ class WebThread extends WebApp implements Runnable {
} }
} }
@SuppressWarnings("unchecked")
private boolean process() throws IOException { private boolean process() throws IOException {
boolean keepAlive = false; boolean keepAlive = false;
String head = readHeaderLine(); String head = readHeaderLine();
...@@ -135,30 +138,58 @@ class WebThread extends WebApp implements Runnable { ...@@ -135,30 +138,58 @@ class WebThread extends WebApp implements Runnable {
byte[] bytes; byte[] bytes;
if (cache && ifModifiedSince != null && ifModifiedSince.equals(server.getStartDateTime())) { if (cache && ifModifiedSince != null && ifModifiedSince.equals(server.getStartDateTime())) {
bytes = null; bytes = null;
message = "HTTP/1.1 304 Not Modified\n"; message = "HTTP/1.1 304 Not Modified\r\n";
} else { } else {
bytes = server.getFile(file); bytes = server.getFile(file);
if (bytes == null) { if (bytes == null) {
message = "HTTP/1.0 404 Not Found\n"; message = "HTTP/1.0 404 Not Found\r\n";
bytes = StringUtils.utf8Encode("File not found: " + file); bytes = StringUtils.utf8Encode("File not found: " + file);
} else { } else {
if (session != null && file.endsWith(".jsp")) { if (session != null && file.endsWith(".jsp")) {
String page = StringUtils.utf8Decode(bytes); String page = StringUtils.utf8Decode(bytes);
if (SysProperties.CONSOLE_STREAM) {
Iterator<String> it = (Iterator<String>) session.map.remove("chunks");
if (it != null) {
message = "HTTP/1.1 200 OK\r\n";
message += "Content-Type: " + mimeType + "\r\n";
message += "Cache-Control: no-cache\r\n";
message += "Transfer-Encoding: chunked\r\n";
message += "\r\n";
trace(message);
output.write(message.getBytes());
while (it.hasNext()) {
String s = it.next();
s = PageParser.parse(s, session.map);
if (bytes.length == 0) {
continue;
}
bytes = StringUtils.utf8Encode(s);
output.write(Integer.toHexString(bytes.length).getBytes());
output.write("\r\n".getBytes());
output.write(bytes);
output.write("\r\n".getBytes());
output.flush();
}
output.write("0\r\n\r\n".getBytes());
output.flush();
return keepAlive;
}
}
page = PageParser.parse(page, session.map); page = PageParser.parse(page, session.map);
bytes = StringUtils.utf8Encode(page); bytes = StringUtils.utf8Encode(page);
} }
message = "HTTP/1.1 200 OK\n"; message = "HTTP/1.1 200 OK\r\n";
message += "Content-Type: " + mimeType + "\n"; message += "Content-Type: " + mimeType + "\r\n";
if (!cache) { if (!cache) {
message += "Cache-Control: no-cache\n"; message += "Cache-Control: no-cache\r\n";
} else { } else {
message += "Cache-Control: max-age=10\n"; message += "Cache-Control: max-age=10\r\n";
message += "Last-Modified: " + server.getStartDateTime() + "\n"; message += "Last-Modified: " + server.getStartDateTime() + "\r\n";
} }
message += "Content-Length: " + bytes.length + "\n"; message += "Content-Length: " + bytes.length + "\r\n";
} }
} }
message += "\n"; message += "\r\n";
trace(message); trace(message);
output.write(message.getBytes()); output.write(message.getBytes());
if (bytes != null) { if (bytes != null) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论