You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2018/11/16 23:51:51 UTC

[GitHub] williaster closed pull request #6377: [SIP-5] QueryBuilder in the client for granularity and groupby in word cloud

williaster closed pull request #6377: [SIP-5] QueryBuilder in the client for granularity and groupby in word cloud
URL: https://github.com/apache/incubator-superset/pull/6377
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/superset/assets/jest.config.js b/superset/assets/jest.config.js
index 64dcb6f3b3..858f6f9295 100644
--- a/superset/assets/jest.config.js
+++ b/superset/assets/jest.config.js
@@ -1,5 +1,5 @@
 module.exports = {
-  testRegex: '\\/spec\\/.*_spec\\.(j|t)sx?$',
+  testRegex: '\\/spec\\/.*(_spec|\\.test)\\.(j|t)sx?$',
   moduleNameMapper: {
     '\\.(css|less)$': '<rootDir>/spec/__mocks__/styleMock.js',
     '\\.(gif|ttf|eot|svg)$': '<rootDir>/spec/__mocks__/fileMock.js',
diff --git a/superset/assets/spec/javascripts/superset-ui/WordCloudBuildQuery.test.ts b/superset/assets/spec/javascripts/superset-ui/WordCloudBuildQuery.test.ts
new file mode 100644
index 0000000000..a6edfbc31d
--- /dev/null
+++ b/superset/assets/spec/javascripts/superset-ui/WordCloudBuildQuery.test.ts
@@ -0,0 +1,15 @@
+import buildQuery from 'src/visualizations/wordcloud/buildQuery';
+
+describe('WordCloud buildQuery', () => {
+  const formData = {
+    datasource: '5__table',
+    granularity_sqla: 'ds',
+    series: 'foo',
+  };
+
+  it('should build groupby with series in form data', () => {
+    const queryContext = buildQuery(formData);
+    const [ query ] = queryContext.queries;
+    expect(query.groupby).toEqual(['foo']);
+  });
+});
diff --git a/superset/assets/spec/javascripts/superset-ui/buildQueryContext.test.ts b/superset/assets/spec/javascripts/superset-ui/buildQueryContext.test.ts
new file mode 100644
index 0000000000..b6fd995f4d
--- /dev/null
+++ b/superset/assets/spec/javascripts/superset-ui/buildQueryContext.test.ts
@@ -0,0 +1,22 @@
+import build from 'src/query/buildQueryContext';
+import * as queryObjectBuilder from 'src/query/buildQueryObject';
+
+describe('queryContextBuilder', () => {
+  it('should build datasource for table sources', () => {
+    const queryContext = build({ datasource: '5__table', granularity_sqla: 'ds'});
+    expect(queryContext.datasource.id).toBe(5);
+    expect(queryContext.datasource.type).toBe('table');
+  });
+
+  it('should build datasource for druid sources', () => {
+    const queryContext = build({ datasource: '5__druid', granularity: 'ds'});
+    expect(queryContext.datasource.id).toBe(5);
+    expect(queryContext.datasource.type).toBe('druid');
+  });
+
+  it('should call queryObjectBuilder to build queries', () => {
+    const buildQueryObjectSpy = jest.spyOn(queryObjectBuilder, 'default');
+    build({ datasource: '5__table', granularity_sqla: 'ds'});
+    expect(buildQueryObjectSpy).toHaveBeenCalledTimes(1);
+  });
+});
diff --git a/superset/assets/spec/javascripts/superset-ui/buildQueryObject.test.ts b/superset/assets/spec/javascripts/superset-ui/buildQueryObject.test.ts
new file mode 100644
index 0000000000..ec111dfdad
--- /dev/null
+++ b/superset/assets/spec/javascripts/superset-ui/buildQueryObject.test.ts
@@ -0,0 +1,13 @@
+import build from 'src/query/buildQueryObject';
+
+describe('queryObjectBuilder', () => {
+  it('should build granularity for sql alchemy datasources', () => {
+    const query = build({datasource: '5__table', granularity_sqla: 'ds'});
+    expect(query.granularity).toEqual('ds');
+  });
+
+  it('should build granularity for sql alchemy datasources', () => {
+    const query = build({datasource: '5__druid', granularity: 'ds'});
+    expect(query.granularity).toEqual('ds');
+  });
+});
diff --git a/superset/assets/src/query/DatasourceKey.ts b/superset/assets/src/query/DatasourceKey.ts
new file mode 100644
index 0000000000..a13c121663
--- /dev/null
+++ b/superset/assets/src/query/DatasourceKey.ts
@@ -0,0 +1,29 @@
+enum DatasourceType {
+  Table = 'table',
+  Druid = 'druid',
+}
+
+export default interface DatasourceKey {
+  id: number;
+  type: DatasourceType;
+}
+
+// Declaration merging with the interface above. No need to redeclare id and type.
+export default class DatasourceKey {
+  constructor(key: string) {
+    const [ idStr, typeStr ] = key.split('__');
+    this.id = parseInt(idStr, 10);
+    this.type = typeStr === 'table' ? DatasourceType.Table : DatasourceType.Druid;
+  }
+
+  public toString() {
+    return `${this.id}__${this.type}`;
+  }
+
+  public toObject() {
+    return {
+      id: this.id,
+      type: this.type,
+    };
+  }
+}
diff --git a/superset/assets/src/query/FormData.ts b/superset/assets/src/query/FormData.ts
new file mode 100644
index 0000000000..daa7abf161
--- /dev/null
+++ b/superset/assets/src/query/FormData.ts
@@ -0,0 +1,21 @@
+// Type signature and utility functions for formData shared by all viz types
+// It will be gradually filled out as we build out the query object
+interface BaseFormData {
+  datasource: string;
+}
+
+// FormData is either sqla-based or druid-based
+interface SqlaFormData extends BaseFormData {
+  granularity_sqla: string;
+}
+
+interface DruidFormData extends BaseFormData {
+  granularity: string;
+}
+
+type FormData = SqlaFormData | DruidFormData;
+export default FormData;
+
+export function getGranularity(formData: FormData): string {
+  return 'granularity_sqla' in formData ? formData.granularity_sqla : formData.granularity;
+}
diff --git a/superset/assets/src/query/buildQueryContext.ts b/superset/assets/src/query/buildQueryContext.ts
new file mode 100644
index 0000000000..8ce0464c63
--- /dev/null
+++ b/superset/assets/src/query/buildQueryContext.ts
@@ -0,0 +1,15 @@
+import buildQueryObject, { QueryObject } from './buildQueryObject';
+import DatasourceKey from './DatasourceKey';
+import FormData from './FormData';
+
+const WRAP_IN_ARRAY = (baseQueryObject: QueryObject) => [baseQueryObject];
+
+// Note: let TypeScript infer the return type
+export default function buildQueryContext(
+  formData: FormData,
+  buildQuery: (baseQueryObject: QueryObject) => QueryObject[] = WRAP_IN_ARRAY) {
+  return {
+    datasource: new DatasourceKey(formData.datasource).toObject(),
+    queries: buildQuery(buildQueryObject(formData)),
+  };
+}
diff --git a/superset/assets/src/query/buildQueryObject.ts b/superset/assets/src/query/buildQueryObject.ts
new file mode 100644
index 0000000000..578d9ae531
--- /dev/null
+++ b/superset/assets/src/query/buildQueryObject.ts
@@ -0,0 +1,18 @@
+import FormData, { getGranularity } from './FormData';
+
+// TODO: fill out the rest of the query object
+export interface QueryObject {
+  granularity: string;
+  groupby?: string[];
+}
+
+// Build the common segments of all query objects (e.g. the granularity field derived from
+// either sql alchemy or druid). The segments specific to each viz type is constructed in the
+// buildQuery method for each viz type (see `wordcloud/buildQuery.ts` for an example).
+// Note the type of the formData argument passed in here is the type of the formData for a
+// specific viz, which is a subtype of the generic formData shared among all viz types.
+export default function buildQueryObject<T extends FormData>(formData: T): QueryObject {
+  return {
+    granularity: getGranularity(formData),
+  };
+}
diff --git a/superset/assets/src/query/index.ts b/superset/assets/src/query/index.ts
new file mode 100644
index 0000000000..cda71267a5
--- /dev/null
+++ b/superset/assets/src/query/index.ts
@@ -0,0 +1,3 @@
+// Public API of the query module
+export { default } from './buildQueryContext';
+export { default as FormData } from './FormData';
diff --git a/superset/assets/src/visualizations/wordcloud/FormData.ts b/superset/assets/src/visualizations/wordcloud/FormData.ts
new file mode 100644
index 0000000000..55f81313af
--- /dev/null
+++ b/superset/assets/src/visualizations/wordcloud/FormData.ts
@@ -0,0 +1,11 @@
+import { FormData as GenericFormData } from 'src/query';
+
+// FormData specific to the wordcloud viz
+interface WordCloudFormData {
+  series: string;
+}
+
+// FormData for wordcloud contains both common properties of all form data
+// and properties specific to wordcloud vizzes
+type FormData = GenericFormData & WordCloudFormData;
+export default FormData;
diff --git a/superset/assets/src/visualizations/wordcloud/WordCloudChartPlugin.js b/superset/assets/src/visualizations/wordcloud/WordCloudChartPlugin.js
index b82882080f..19b43c5966 100644
--- a/superset/assets/src/visualizations/wordcloud/WordCloudChartPlugin.js
+++ b/superset/assets/src/visualizations/wordcloud/WordCloudChartPlugin.js
@@ -1,5 +1,6 @@
 import { t } from '@superset-ui/translation';
 import { ChartMetadata, ChartPlugin } from '@superset-ui/chart';
+import buildQuery from './buildQuery';
 import transformProps from './transformProps';
 import thumbnail from './images/thumbnail.png';
 
@@ -14,6 +15,7 @@ export default class WordCloudChartPlugin extends ChartPlugin {
   constructor() {
     super({
       metadata,
+      buildQuery,
       transformProps,
       loadChart: () => import('./ReactWordCloud.js'),
     });
diff --git a/superset/assets/src/visualizations/wordcloud/buildQuery.ts b/superset/assets/src/visualizations/wordcloud/buildQuery.ts
new file mode 100644
index 0000000000..2aa0f2cd75
--- /dev/null
+++ b/superset/assets/src/visualizations/wordcloud/buildQuery.ts
@@ -0,0 +1,10 @@
+import buildQueryContext from 'src/query';
+import FormData from './FormData';
+
+export default function buildQuery(formData: FormData) {
+  // Set the single QueryObject's groupby field with series in formData
+  return buildQueryContext(formData, (baseQueryObject) => [{
+    ...baseQueryObject,
+    groupby: [formData.series],
+  }]);
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org