Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cant get all the results of a query execute #43

Open
314gui opened this issue Feb 4, 2021 · 2 comments
Open

Cant get all the results of a query execute #43

314gui opened this issue Feb 4, 2021 · 2 comments
Labels

Comments

@314gui
Copy link

314gui commented Feb 4, 2021

Hi guys,
I'm trying to get all the results from a query but today I noticed that sometimes it wouldn't return all the rows. After reading the docs I understand that the data attribute from client.execute function can be called 2 or more times and that's why my code is wrong.

executePrestoQuery(query: string): Promise<any> {
    return new Promise<any>((resolve, reject) => {
      this.client.execute({
        query: query,
        catalog: "hive",
        schema: "default",
        source: "nodejs-client",
        data: function (error, data, columns, stats) {
          resolve(data);
        },
        success: function (error, stats, info) {
          console.log("success");
        },
        error: function (error) {
          reject(error);
        },
      });
    });
  }

So said that what's the best way to return all the data from the client.execute function? Can I return the data on the success attribute?

(Sorry If it's an easy solution I am new to Javascript)
Thank you
Guilherme

@314gui
Copy link
Author

314gui commented Feb 4, 2021

A simple solution I am using is to concatenate the data values in every iteration of the data attribute. This may not be the best solution : /

@deugene
Copy link
Contributor

deugene commented Apr 28, 2021

A simple solution I am using is to concatenate the data values in every iteration of the data attribute. This may not be the best solution : /

This simple wrapper allows both getting all the results and getting the stream of the results:

import presto = require('presto-client');
import {PassThrough} from 'stream';

export class SqlClient {
  private client: any;

  constructor(options?: Record<string, any>) {
    this.client = new presto.Client({
      host: options?.host,
      port: options?.port,
      user: options?.user
    });
  }

  async query(sql: string): Promise<any[]> {
    const result: any[] = [];
    const stream = this.queryStream(sql);

    for await (const chunk of stream) {
      result.push(chunk);
    }

    return result;
  }

  queryStream(sql: string): PassThrough {
    const stream = new PassThrough({objectMode: true});
    const onData = (
      error: any,
      data: any[][],
      columns: {name: string}[]
    ): void => {
      if (error) {
        return;
      }

      for (const row of data) {
        stream.write(
          Object.fromEntries(columns.map((c, i) => [c.name, row[i]]))
        );
      }
    };
    const onDone = (error: any): void => {
      if (error) {
        console.error(error);
        stream.destroy(error);
      }

      stream.end();
    };

    this.client.execute({
      query: sql,
      data: onData,
      callback: onDone
    });

    return stream;
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants