|
20 | 20 | import java.util.ArrayList;
|
21 | 21 | import java.util.Collections;
|
22 | 22 | import java.util.List;
|
| 23 | +import java.util.Iterator; |
23 | 24 | import java.util.Scanner;
|
24 | 25 | import java.util.Properties;
|
25 | 26 | import java.io.IOException;
|
@@ -47,6 +48,7 @@ protected int run(String[] args) throws IOException {
|
47 | 48 | commandHandlers.add(new YamlCommandHandler());
|
48 | 49 | commandHandlers.add(new PipelineCommandHandler());
|
49 | 50 | commandHandlers.add(new IntroCommandHandler());
|
| 51 | + commandHandlers.add(new InsertCommandHandler()); |
50 | 52 | sqlline.updateCommandHandlers(commandHandlers);
|
51 | 53 | return sqlline.begin(args, null, true).ordinal();
|
52 | 54 | }
|
@@ -264,6 +266,98 @@ public boolean echoToFile() {
|
264 | 266 | }
|
265 | 267 | }
|
266 | 268 |
|
| 269 | + private class InsertCommandHandler implements CommandHandler { |
| 270 | + |
| 271 | + @Override |
| 272 | + public String getName() { |
| 273 | + return "insert"; |
| 274 | + } |
| 275 | + |
| 276 | + @Override |
| 277 | + public List<String> getNames() { |
| 278 | + return Collections.singletonList(getName()); |
| 279 | + } |
| 280 | + |
| 281 | + @Override |
| 282 | + public String getHelpText() { |
| 283 | + return "Run an ephemeral pipeline with an existing sink."; |
| 284 | + } |
| 285 | + |
| 286 | + @Override |
| 287 | + public String matches(String line) { |
| 288 | + String sql = line; |
| 289 | + if (sql.startsWith(SqlLine.COMMAND_PREFIX)) { |
| 290 | + sql = sql.substring(1); |
| 291 | + } |
| 292 | + |
| 293 | + if (sql.startsWith("insert into")) { |
| 294 | + sql = sql.substring("insert into".length() + 1); |
| 295 | + return sql; |
| 296 | + } |
| 297 | + |
| 298 | + return null; |
| 299 | + } |
| 300 | + |
| 301 | + @Override |
| 302 | + public void execute(String line, DispatchCallback dispatchCallback) { |
| 303 | + String sql = line; |
| 304 | + if (sql.startsWith(SqlLine.COMMAND_PREFIX)) { |
| 305 | + sql = sql.substring(1); |
| 306 | + } |
| 307 | + |
| 308 | + if (sql.startsWith("insert into")) { |
| 309 | + sql = sql.substring("insert into".length() + 1); |
| 310 | + } |
| 311 | + |
| 312 | + String connectionUrl = sqlline.getConnectionMetadata().getUrl(); |
| 313 | + try { |
| 314 | + String[] parts = sql.split("(?i)SELECT"); // case insensitive |
| 315 | + if (parts.length != 2) { |
| 316 | + throw new IllegalArgumentException("Expected ... SELECT ..."); |
| 317 | + } |
| 318 | + String[] parts2 = parts[0].split("\\."); |
| 319 | + if (parts2.length != 2) { |
| 320 | + throw new IllegalArgumentException("Expected ... DATABASE.TABLE ..."); |
| 321 | + } |
| 322 | + // TODO unquote correctly |
| 323 | + String database = parts2[0].replaceAll("[\\\"']", "").trim(); |
| 324 | + String table = parts2[1].replaceAll("[\\\"']", "").trim(); |
| 325 | + String query = parts[1]; |
| 326 | + |
| 327 | + HoptimatorPlanner planner = HoptimatorPlanner.fromModelFile(connectionUrl, new Properties()); |
| 328 | + PipelineRel plan = planner.pipeline("SELECT " + query); |
| 329 | + PipelineRel.Implementor impl = new PipelineRel.Implementor(plan); |
| 330 | + HopTable sink = planner.database(database).makeTable(table, impl.rowType()); |
| 331 | + String pipelineSql = impl.insertInto(sink) + "\nSELECT 'SUCCESS';"; |
| 332 | + FlinkIterable iterable = new FlinkIterable(pipelineSql); |
| 333 | + Iterator<String> iter = iterable.<String>field(0).iterator(); |
| 334 | + if (iter.hasNext()) { |
| 335 | + dispatchCallback.setToSuccess(); |
| 336 | + } else { |
| 337 | + throw new IllegalArgumentException("No result from:\n" + pipelineSql); |
| 338 | + } |
| 339 | + while (iter.hasNext()) { |
| 340 | + sqlline.output(iter.next()); |
| 341 | + } |
| 342 | + } catch (Exception e) { |
| 343 | + sqlline.error(e.toString()); |
| 344 | + e.printStackTrace(); |
| 345 | + dispatchCallback.setToFailure(); |
| 346 | + } |
| 347 | + } |
| 348 | + |
| 349 | + @Override |
| 350 | + public List<Completer> getParameterCompleters() { |
| 351 | + return Collections.emptyList(); |
| 352 | + } |
| 353 | + |
| 354 | + @Override |
| 355 | + public boolean echoToFile() { |
| 356 | + return false; |
| 357 | + } |
| 358 | + } |
| 359 | + |
| 360 | + |
267 | 361 | private class IntroCommandHandler implements CommandHandler {
|
268 | 362 |
|
269 | 363 | @Override
|
|
0 commit comments