Skip to content

Commit

Permalink
SqlLine integration
Browse files Browse the repository at this point in the history
  • Loading branch information
snuyanzin authored and vlsi committed Oct 12, 2020
1 parent a57a5ba commit b052c4e
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 2 deletions.
5 changes: 5 additions & 0 deletions MatCalciteDependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>sqlline</groupId>
<artifactId>sqlline</artifactId>
<version>1.9.0</version>
</dependency>
</dependencies>

<build>
Expand Down
22 changes: 20 additions & 2 deletions MatCalcitePlugin/src/com/github/vlsi/mat/calcite/Executor.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.vlsi.mat.calcite;

import sqlline.MCPSqlLine;
import com.google.common.base.Joiner;
import com.google.common.escape.Escaper;
import com.google.common.escape.Escapers;
Expand All @@ -15,22 +16,40 @@
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

import static org.jline.terminal.TerminalBuilder.PROP_JANSI;

public class Executor implements IApplication {

@Override
public Object start(IApplicationContext context) {
String[] args = (String[]) context.getArguments().get("application.args");
char delimiter = ',';

if (args.length < 3) {
if (args.length == 0 || (args.length < 3 && !"sqlline".equalsIgnoreCase(args[0]))) {
System.out.println("java com.github.vlsi.mat.calcite.Executor <heap-dump> <query> <result>");
System.out.println("java com.github.vlsi.mat.calcite.Executor sqlline");
return IApplication.EXIT_OK;
}

if ("sqlline".equalsIgnoreCase(args[0])) {
try {
System.setProperty(PROP_JANSI, Boolean.TRUE.toString());
MCPSqlLine sqlLine = new MCPSqlLine();
String[] sqllineArgs = new String[args.length - 1];
System.arraycopy(args, 1, sqllineArgs, 0, args.length - 1);
sqlLine.begin(sqllineArgs, null, false);
} catch (IOException e) {
e.printStackTrace();
return IApplication.EXIT_OK;
}
return IApplication.EXIT_OK;
}

Expand All @@ -57,7 +76,6 @@ public Object start(IApplicationContext context) {
return IApplication.EXIT_OK;
}


try (Connection con = CalciteDataSource.getConnection(openSnapshot(heapFile));
BufferedWriter w = new BufferedWriter(new FileWriter(resultsFile))) {
PreparedStatement ps = con.prepareStatement(sbQuery.toString());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.github.vlsi.mat.calcite.cli;

import org.jline.builtins.Completers;

import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;

public class DumpFileNameCompleter extends Completers.FileNameCompleter {
private static final PathMatcher DUMP_FILE_MATCHER =
FileSystems.getDefault().getPathMatcher("glob:**.{bin,hprof}");

@Override
protected boolean accept(Path path) {
return super.accept(path)
&& (Files.isDirectory(path) || DUMP_FILE_MATCHER.matches(path));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.vlsi.mat.calcite.cli;

import sqlline.Application;
import sqlline.CommandHandler;
import sqlline.MCPSqlLine;
import sqlline.SqlLine;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class MCPApplication extends Application {
private static final Set<String> ALLOWED_SQLLINE_COMMANDS = new HashSet<String>() {{
add("quit");
add("history");
add("verbose");
add("run");
add("list");
add("all");
add("go");
add("script");
add("record");
add("brief");
add("close");
add("closeall");
add("outputformat");
add("set");
add("help");
add("reset");
add("save");
add("rerun");
add("prompthandler");
}};

@Override
public Collection<CommandHandler> getCommandHandlers(SqlLine sqlLine) {
Collection<CommandHandler> handlers = new ArrayList<>();
for (CommandHandler commandHandler : super.getCommandHandlers(sqlLine)) {
if (ALLOWED_SQLLINE_COMMANDS.contains(commandHandler.getName())) {
handlers.add(commandHandler);
}
}
handlers.add(new OpenDumpCommandHandler((MCPSqlLine) sqlLine, new DumpFileNameCompleter(), "Open heap dump",
"open_dump"));
return handlers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.github.vlsi.mat.calcite.cli;

import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.snapshot.ISnapshot;
import org.eclipse.mat.snapshot.SnapshotFactory;
import org.eclipse.mat.util.VoidProgressListener;
import org.jline.reader.Completer;
import sqlline.AbstractCommandHandler;
import sqlline.Commands;
import sqlline.DispatchCallback;
import sqlline.MCPDatabaseConnection;
import sqlline.MCPSqlLine;

import java.io.File;
import java.util.Collections;
import java.util.List;

public class OpenDumpCommandHandler extends AbstractCommandHandler {
public OpenDumpCommandHandler(MCPSqlLine sqlLine, List<Completer> completers,
String helpText, String... cmds) {
super(sqlLine, cmds, helpText, completers);
}

public OpenDumpCommandHandler(MCPSqlLine sqlLine, Completer completer,
String helpText, String... cmds) {
this(sqlLine, Collections.singletonList(completer), helpText, cmds);
}

public void execute(String line, DispatchCallback callback) {
final String[] parts = sqlLine.split(line, " ", 0);
if (parts.length != 2) {
sqlLine.error("Usage: open_dump <path to file>");
callback.setToFailure();
return;
}
// replace ~/ with user directory
final String filename = Commands.expand(parts[1]);
if (!new File(filename).isFile()) {
sqlLine.error("Dump file " + filename + " does not exists!");
callback.setToFailure();
return;
}

final MCPSqlLine mcpSqlLine = (MCPSqlLine) sqlLine;
final MCPDatabaseConnection mcpDatabaseConnection;
try {
mcpDatabaseConnection = new MCPDatabaseConnection(mcpSqlLine, filename, openSnapshot(new File(filename)));
} catch (SnapshotException e) {
callback.setToFailure();
mcpSqlLine.error(e);
return;
}
try {
mcpSqlLine.setUpConnection(mcpDatabaseConnection);
callback.setToSuccess();
} catch (Exception e) {
mcpDatabaseConnection.close();
mcpSqlLine.removeConnection(mcpDatabaseConnection);
callback.setToFailure();
mcpSqlLine.error(e);
}
}

private static ISnapshot openSnapshot(File heapDump) throws SnapshotException {
System.out.println("exists = " + heapDump.exists() + ", file = " + heapDump.getAbsolutePath());
return SnapshotFactory.openSnapshot(heapDump, new VoidProgressListener());
}
}
22 changes: 22 additions & 0 deletions MatCalcitePlugin/src/sqlline/MCPDatabaseConnection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package sqlline;

import com.github.vlsi.mat.calcite.CalciteDataSource;

import org.eclipse.mat.snapshot.ISnapshot;

import java.sql.SQLException;

public class MCPDatabaseConnection extends DatabaseConnection {
private final ISnapshot snapshot;

public MCPDatabaseConnection(MCPSqlLine sqlLine, String filename, ISnapshot snapshot) {
super(sqlLine, null, filename, "username", "password", null);
this.snapshot = snapshot;
}

@Override
boolean connect() throws SQLException {
connection = CalciteDataSource.getConnection(snapshot);
return true;
}
}
27 changes: 27 additions & 0 deletions MatCalcitePlugin/src/sqlline/MCPSqlLine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package sqlline;

import com.github.vlsi.mat.calcite.cli.MCPApplication;

import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;

public class MCPSqlLine extends SqlLine {
void setAppConfig(Application application) {
super.setAppConfig(new MCPApplication());
}

public void setUpConnection(final MCPDatabaseConnection mcpDatabaseConnection) throws SQLException {
getDatabaseConnections().setConnection(mcpDatabaseConnection);
Connection connection = getDatabaseConnection().getConnection();
mcpDatabaseConnection.meta = (DatabaseMetaData) Proxy.newProxyInstance(
DatabaseMetaData.class.getClassLoader(),
new Class[]{DatabaseMetaData.class},
new DatabaseMetaDataHandler(connection.getMetaData()));
}

public void removeConnection(final MCPDatabaseConnection mcpDatabaseConnection) {
getDatabaseConnections().removeConnection(mcpDatabaseConnection);
}
}

0 comments on commit b052c4e

Please sign in to comment.