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

Add return type definitions to datasources #63

Merged
merged 1 commit into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions src/lib/DataSourceDefinition/Athena.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import AthenaClient from "../AthenaClient";
import Base from "./Base";
import Base, { ConfigSchemaType } from "./Base";
import Util from "../Util";

export default class Athena extends Base {
client: AthenaClient;

static get key() {
static get key(): string {
return "athena";
}
static get label() {
static get label(): string {
return "Amazon Athena";
}
static get configSchema() {
static get configSchema(): ConfigSchemaType {
return [
{
name: "region",
Expand Down Expand Up @@ -57,21 +57,24 @@ export default class Athena extends Base {
return { fields, rows };
}

cancel() {
return this.client.cancel();
cancel(): void {
this.client.cancel();
}

async connectionTest() {
async connectionTest(): Promise<void> {
await this.client.execute("select 1");
return;
}

async fetchTables() {
async fetchTables(): Promise<{ name: string; type: string; schema?: string }[]> {
const rows = await this.client.execute("show tables");
return rows.map(row => ({ name: row[0], type: "table" }));
return rows.map(row => ({ name: row[0]!, type: "table" }));
}

async fetchTableSummary({ name }) {
async fetchTableSummary({
name
}: {
name: string;
}): Promise<{ name: string; defs: { fields: string[]; rows: (string | null)[][] }; schema?: string }> {
const rows = await this.client.execute(`describe ${name}`);
const defs = {
fields: ["name", "type"],
Expand All @@ -84,7 +87,7 @@ export default class Athena extends Base {
return { name, defs };
}

descriptionTable() {
descriptionTable(): string {
return Util.stripHeredoc(`
|region|${this.config.region}|
|database|${this.config.database}|
Expand Down
29 changes: 23 additions & 6 deletions src/lib/DataSourceDefinition/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,37 @@ export default abstract class Base {
static get label(): string {
throw new Error("Not Implemented");
}
static get configSchema(): ConfigSchemaType {
throw new Error("Not Implemented");
}

constructor(config) {
this.config = config;
}

abstract execute(query);
abstract execute(query: string): Promise<any>;

abstract cancel();
// @todo Set return type as Promise<void> ?
abstract cancel(): void | Promise<void>;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BigQuery, MySQL and PostgreSQL uses Promise, but other not use.
I suggest to every datasource returns Promise<void>.


abstract connectionTest();
// @todo Define type of the result (boolean or void ?)
abstract connectionTest(): Promise<any>;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datasources have different return value type.
(true or void)
I suggest to use Promise<void>.


abstract fetchTables();
abstract fetchTables(): Promise<{ name: string; type: string; schema?: string }[]>;

abstract descriptionTable();
abstract descriptionTable(): string;

abstract fetchTableSummary(args);
abstract fetchTableSummary(
args: any
): Promise<{ name: string; defs: { fields: string[]; rows: (string | null)[][] }; schema?: string }>;
}

export type ConfigSchemaType = {
readonly name: string;
readonly label: string;
readonly type: string;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be expressed like:

readonly type: "radio" | "checkbox" | "password" | "string" | "number";

I prefer to use union type.

readonly placeholder?: string | number;
readonly required?: boolean;
readonly values?: string[];
readonly default?: string;
}[];
31 changes: 18 additions & 13 deletions src/lib/DataSourceDefinition/BigQuery.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import bigquery from "@google-cloud/bigquery";
import Base from "./Base";
import Base, { ConfigSchemaType } from "./Base";
import { flatten } from "lodash";

export default class BigQuery extends Base {
_cancel: any;

static get key() {
static get key(): string {
return "bigquery";
}
static get label() {
static get label(): string {
return "BigQuery";
}
static get configSchema() {
static get configSchema(): ConfigSchemaType {
return [
{
name: "project",
Expand All @@ -28,7 +28,7 @@ export default class BigQuery extends Base {
];
}

execute(query) {
execute(query: string) {
this._cancel = null;
return new Promise((resolve, reject) => {
bigquery(this.config).startQuery(query, (err, job) => {
Expand All @@ -52,18 +52,17 @@ export default class BigQuery extends Base {
});
}

cancel() {
cancel(): void {
return this._cancel && this._cancel();
}

async connectionTest() {
async connectionTest(): Promise<void> {
await bigquery(this.config).query("select 1");
return true;
}

async fetchTables() {
Copy link
Collaborator Author

@mtgto mtgto Dec 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: If we update @google-cloud/bigquery to latest, we can use its type definition for typescript.
https://github.com/googleapis/nodejs-bigquery

(But I don't have the environment for testing)

const [datasets] = await bigquery(this.config).getDatasets();
const promises = datasets.map(async dataset => {
async fetchTables(): Promise<{ name: string; type: string; schema?: string }[]> {
const [datasets]: [any[]] = await bigquery(this.config).getDatasets();
const promises = datasets.map<Promise<{ name: string; type: string; schema?: string }>>(async dataset => {
const [tables] = await dataset.getTables();
return tables.map(table => ({
schema: dataset.id,
Expand All @@ -75,7 +74,13 @@ export default class BigQuery extends Base {
return flatten(results);
}

async fetchTableSummary({ schema, name }) {
async fetchTableSummary({
schema,
name
}: {
schema: string;
name: string;
}): Promise<{ name: string; defs: { fields: string[]; rows: (string | null)[][] }; schema?: string }> {
const [metadata] = await bigquery(this.config)
.dataset(schema)
.table(name)
Expand All @@ -88,7 +93,7 @@ export default class BigQuery extends Base {
return { schema, name, defs };
}

descriptionTable() {
descriptionTable(): string {
return `|project|${this.config.project}|`;
}
}
22 changes: 13 additions & 9 deletions src/lib/DataSourceDefinition/Mysql.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import mysql from "mysql2";
import Base from "./Base";
import Base, { ConfigSchemaType } from "./Base";
import Util from "../Util";
import { zipObject } from "lodash";

export default class Mysql extends Base {
currentConnection: any;

static get key() {
static get key(): string {
return "mysql";
}
static get label() {
static get label(): string {
return "MySQL";
}
static get configSchema() {
static get configSchema(): ConfigSchemaType {
return [
{ name: "host", label: "Host", type: "string", placeholder: "localhost" },
{ name: "port", label: "Port", type: "number", placeholder: 3306 },
Expand All @@ -31,7 +31,7 @@ export default class Mysql extends Base {
return this._execute(query);
}

cancel() {
cancel(): Promise<void> {
const tid = this.currentConnection && this.currentConnection.threadId;
if (!tid) return Promise.resolve();

Expand All @@ -43,7 +43,7 @@ export default class Mysql extends Base {
return true;
}

async fetchTables() {
async fetchTables(): Promise<{ name: string; type: string; schema?: string }[]> {
const query = Util.stripHeredoc(`
select table_name as name, table_type as type
from information_schema.tables
Expand All @@ -55,14 +55,18 @@ export default class Mysql extends Base {
return rows.map(row => zipObject(fields, row));
}

async fetchTableSummary({ name }) {
async fetchTableSummary({
name
}: {
name: string;
}): Promise<{ name: string; defs: { fields: string[]; rows: (string | null)[][] }; schema?: string }> {
const sql = "show columns from ??";
const defs = await this._execute(sql, name);

return { name, defs };
}

_execute(query, ...args): Promise<any> {
_execute(query: string, ...args): Promise<any> {
if (this.currentConnection) {
return Promise.reject(new Error("A query is running"));
}
Expand Down Expand Up @@ -94,7 +98,7 @@ export default class Mysql extends Base {
});
}

descriptionTable() {
descriptionTable(): string {
return Util.stripHeredoc(`
|host|${this.config.host}|
|port|${this.config.port}|
Expand Down
26 changes: 16 additions & 10 deletions src/lib/DataSourceDefinition/Postgres.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pg from "pg";
import Base from "./Base";
import Base, { ConfigSchemaType } from "./Base";
import Util from "../Util";
import { zipObject } from "lodash";

Expand Down Expand Up @@ -50,13 +50,13 @@ import { zipObject } from "lodash";
export default class Postgres extends Base {
currentClient: any;

static get key() {
static get key(): string {
return "postgres";
}
static get label() {
static get label(): string {
return "PostgreSQL";
}
static get configSchema() {
static get configSchema(): ConfigSchemaType {
return [
{ name: "host", label: "Host", type: "string", placeholder: "localhost" },
{ name: "port", label: "Port", type: "number", placeholder: 5432 },
Expand All @@ -72,27 +72,27 @@ export default class Postgres extends Base {
];
}

async execute(query, options: any = {}) {
async execute(query: string, options: any = {}): Promise<any> {
try {
return await this._execute(query);
} catch (err) {
throw this._errorWithLine(err, query, options.startLine || 1);
}
}

cancel() {
cancel(): Promise<void> {
const pid = this.currentClient && this.currentClient.processID;
if (!pid) return Promise.resolve();

return new Postgres(this.config)._execute(`select pg_cancel_backend(${pid})`);
}

async connectionTest() {
async connectionTest(): Promise<any> {
await this._execute("select 1");
return true;
}

async fetchTables() {
async fetchTables(): Promise<{ name: string; type: string; schema?: string }[]> {
const query = Util.stripHeredoc(`
select table_schema as schema, table_name as name, table_type as type
from information_schema.tables
Expand All @@ -104,7 +104,13 @@ export default class Postgres extends Base {
return rows.map(row => zipObject(fields, row));
}

async fetchTableSummary({ schema, name }) {
async fetchTableSummary({
schema,
name
}: {
schema: string;
name: string;
}): Promise<{ name: string; defs: { fields: string[]; rows: (string | null)[][] }; schema?: string }> {
const query = Util.stripHeredoc(`
select
pg_attribute.attname as name,
Expand All @@ -130,7 +136,7 @@ export default class Postgres extends Base {
return { schema, name, defs };
}

descriptionTable() {
descriptionTable(): string {
return Util.stripHeredoc(`
|host|${this.config.host}|
|port|${this.config.port}|
Expand Down
Loading