Skip to content

Commit

Permalink
fix query
Browse files Browse the repository at this point in the history
  • Loading branch information
lexoyo committed Oct 25, 2023
1 parent 189e3f0 commit 8083dcc
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 43 deletions.
24 changes: 18 additions & 6 deletions src/datasources/GraphQL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,23 @@ export default class GraphQL extends Backbone.Model<GraphQLOptions> implements I
getQuery(expressions: Expression[]): string {
if(expressions.length === 0) return ''
const tree: Tree = expressions
// From Expression to Tree
.map(expression => this.getTree(expression
// Ignore filters
.filter(token => token.type !== 'filter'))
)
// Add the main query object which is the root of the tree
.map(tree => ({
token: {
dataSourceId: tree.token.dataSourceId,
fieldId: 'query',
kind: 'object',
},
children: [tree],
} as Tree))
// Merge all trees from the root
.reduce((finalTree, tree) => this.mergeTrees(finalTree, tree))
// To GraphQL query
return this.buildQuery(tree)
}

Expand Down Expand Up @@ -381,18 +393,18 @@ export default class GraphQL extends Backbone.Model<GraphQLOptions> implements I
/**
* Build a GraphQL query from a tree
*/
protected buildQuery(tree: Tree): string {
protected buildQuery(tree: Tree, indent = ''): string {
switch(tree.token.kind) {
case 'scalar':
return tree.token.fieldId
return indent + tree.token.fieldId
case 'object':
case 'list': {
const children = tree.children
.map(child => this.buildQuery(child))
.map(child => this.buildQuery(child, indent + ' '))
.join('\n')
return dedent`${tree.token.fieldId} {
${children}
}`
return dedent`${indent}${tree.token.fieldId} {
${children}
${indent}}`
}
default:
console.error('Unable to build GraphQL query', tree)
Expand Down
183 changes: 146 additions & 37 deletions src/datasources/graphql.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,9 @@ test('build query from tree', () => {
children: [],
}],
}
expect(gql.buildQuery(tree))
.toEqual(`testFieldId {\n testFieldPropertyId\n}`)
const query = gql.buildQuery(tree)
expect(query)
.toEqual(`testFieldId {\ntestFieldPropertyId\n}`)
})

test('merge trees', () => {
Expand Down Expand Up @@ -420,43 +421,43 @@ test('merge trees', () => {
children: [],
}],
})
})
})

test('get tree', () => {
const gql = new GQLTest({
url: 'http://localhost',
method: 'POST',
headers: {},
queryable: [],
id: 'testDataSourceId',
label: 'test',
type: 'graphql',
})
const expression: Expression = [{
type: 'property',
propType: 'field',
fieldId: 'testFieldId',
label: 'test field name',
typeIds: ['testTypeId'],
kind: 'object',
dataSourceId: 'DataSourceId',
}]
expect(gql.getTree(expression))
.toEqual({
token: {
type: 'property',
propType: 'field',
fieldId: 'testFieldId',
label: 'test field name',
typeIds: ['testTypeId'],
kind: 'object',
dataSourceId: 'DataSourceId',
},
children: [],
})
test('get tree', () => {
const gql = new GQLTest({
url: 'http://localhost',
method: 'POST',
headers: {},
queryable: [],
id: 'testDataSourceId',
label: 'test',
type: 'graphql',
})
const expression: Expression = [{
type: 'property',
propType: 'field',
fieldId: 'testFieldId',
label: 'test field name',
typeIds: ['testTypeId'],
kind: 'object',
dataSourceId: 'DataSourceId',
}]
expect(gql.getTree(expression))
.toEqual({
token: {
type: 'property',
propType: 'field',
fieldId: 'testFieldId',
label: 'test field name',
typeIds: ['testTypeId'],
kind: 'object',
dataSourceId: 'DataSourceId',
},
children: [],
})
})

test('Get query from expressions', async () => {
test('Get query from 1 expression', async () => {
const DataSource = (await importDataSource([simpleSchema]))
const dataSource = new DataSource(options)
await dataSource.connect()
Expand All @@ -478,7 +479,115 @@ test('Get query from expressions', async () => {
dataSourceId: 'TestDataSourceId',
}]])
expect(query).not.toBeUndefined()
expect(query).toEqual(`testFieldId {\n testFieldPropertyId\n}`)
expect(query).toEqual(`query {
testFieldId {
testFieldPropertyId
}
}`)
})

test('Get query from multiple expressions', async () => {
const DataSource = (await importDataSource([simpleSchema]))
const dataSource = new DataSource(options)
await dataSource.connect()
const query = await dataSource.getQuery([[{
type: 'property',
propType: 'field',
fieldId: 'testFieldId',
label: 'test field name',
typeIds: ['testTypeId'],
kind: 'object',
dataSourceId: 'TestDataSourceId',
}, {
type: 'property',
propType: 'field',
fieldId: 'testFieldPropertyId',
label: 'test field property name',
typeIds: ['testFieldPropertyTypeId'],
kind: 'scalar',
dataSourceId: 'TestDataSourceId',
}], [{
type: 'property',
propType: 'field',
fieldId: 'testFieldId',
label: 'test field name',
typeIds: ['testTypeId'],
kind: 'object',
dataSourceId: 'TestDataSourceId',
}, {
type: 'property',
propType: 'field',
fieldId: 'testFieldPropertyId2',
label: 'test field property name',
typeIds: ['testFieldPropertyTypeId'],
kind: 'list',
dataSourceId: 'TestDataSourceId',
}, {
type: 'property',
propType: 'field',
fieldId: 'testFieldPropertyId3',
label: 'test field property name',
typeIds: ['testFieldPropertyTypeId'],
kind: 'scalar',
dataSourceId: 'TestDataSourceId',
}]])
expect(query).not.toBeUndefined()
expect(query).toEqual(`query {
testFieldId {
testFieldPropertyId
testFieldPropertyId2 {
testFieldPropertyId3
}
}
}`)
})

test('Get query from multiple expressions', async () => {
const DataSource = (await importDataSource([simpleSchema]))
const dataSource = new DataSource(options)
await dataSource.connect()
const query = await dataSource.getQuery([[{
type: 'property',
propType: 'field',
fieldId: 'testFieldId1',
label: 'test field name',
typeIds: ['testTypeId'],
kind: 'object',
dataSourceId: 'TestDataSourceId',
}, {
type: 'property',
propType: 'field',
fieldId: 'testFieldPropertyId',
label: 'test field property name',
typeIds: ['testFieldPropertyTypeId'],
kind: 'scalar',
dataSourceId: 'TestDataSourceId',
}], [{
type: 'property',
propType: 'field',
fieldId: 'testFieldId2',
label: 'test field name',
typeIds: ['testTypeId'],
kind: 'object',
dataSourceId: 'TestDataSourceId',
}, {
type: 'property',
propType: 'field',
fieldId: 'testFieldPropertyId2',
label: 'test field property name',
typeIds: ['testFieldPropertyTypeId'],
kind: 'scalar',
dataSourceId: 'TestDataSourceId',
}]])
expect(query).not.toBeUndefined()
expect(query).toEqual(`query {
testFieldId1 {
testFieldPropertyId
}
testFieldId2 {
testFieldPropertyId2
}
}`)
})

// test('Get data', async () => {
Expand Down

0 comments on commit 8083dcc

Please sign in to comment.