-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(#6741): use antlr parser for fqn and entityLink
- Loading branch information
1 parent
f8ff645
commit f67389b
Showing
4 changed files
with
242 additions
and
32 deletions.
There are no files selected for viewing
44 changes: 44 additions & 0 deletions
44
openmetadata-ui/src/main/resources/ui/src/antlr/EntityLinkSplitListener.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright 2023 Collate. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import EntityLinkListener from '../generated/antlr/EntityLinkListener'; | ||
|
||
export default class EntityLinkSplitListener extends EntityLinkListener { | ||
constructor() { | ||
super(); | ||
this.entityLinkParts = []; | ||
} | ||
|
||
// Enter a parse tree produced by EntityLinkParser#entityType. | ||
enterEntityType(ctx) { | ||
this.entityLinkParts.push(ctx.getText()); | ||
} | ||
|
||
// Enter a parse tree produced by EntityLinkParser#entityAttribute. | ||
enterEntityAttribute(ctx) { | ||
this.entityLinkParts.push(ctx.getText()); | ||
} | ||
|
||
// Enter a parse tree produced by EntityLinkParser#entityFqn. | ||
enterEntityFqn(ctx) { | ||
this.entityLinkParts.push(ctx.getText()); | ||
} | ||
|
||
// Enter a parse tree produced by EntityLinkParser#entityField. | ||
enterEntityField(ctx) { | ||
this.entityLinkParts.push(ctx.getText()); | ||
} | ||
|
||
split() { | ||
return this.entityLinkParts; | ||
} | ||
} |
111 changes: 111 additions & 0 deletions
111
openmetadata-ui/src/main/resources/ui/src/utils/EntityLink.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* Copyright 2023 Collate. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import antlr4 from 'antlr4'; | ||
import { ParseTreeWalker } from 'antlr4/src/antlr4/tree'; | ||
import EntityLinkSplitListener from '../antlr/EntityLinkSplitListener'; | ||
import EntityLinkLexer from '../generated/antlr/EntityLinkLexer'; | ||
import EntityLinkParser from '../generated/antlr/EntityLinkParser'; | ||
import { ENTITY_LINK_SEPARATOR } from './EntityUtils'; | ||
|
||
export default class EntityLink { | ||
/** | ||
* | ||
* @param string entityLink | ||
* @returns list of entity link parts | ||
*/ | ||
static split(entityLink) { | ||
const chars = new antlr4.InputStream(entityLink); | ||
const lexer = new EntityLinkLexer(chars); | ||
const tokens = new antlr4.CommonTokenStream(lexer); | ||
const parser = new EntityLinkParser(tokens); | ||
const tree = parser.entitylink(); | ||
const splitter = new EntityLinkSplitListener(); | ||
ParseTreeWalker.DEFAULT.walk(splitter, tree); | ||
|
||
return splitter.split(); | ||
} | ||
|
||
/** | ||
* | ||
* @param string entityLink | ||
* @returns entity type | ||
*/ | ||
static getEntityType(entityLink) { | ||
return EntityLink.split(entityLink)[0]; | ||
} | ||
|
||
/** | ||
* | ||
* @param string entityLink | ||
* @returns entity fqn | ||
*/ | ||
static getEntityFqn(entityLink) { | ||
return EntityLink.split(entityLink)[1]; | ||
} | ||
|
||
/** | ||
* | ||
* @param string entityLink | ||
* @returns entity field | ||
*/ | ||
static getEntityField(entityLink) { | ||
const entityType = EntityLink.getEntityType(entityLink); | ||
if (entityType === 'table') { | ||
return EntityLink.split(entityLink)[2]; | ||
} | ||
|
||
return EntityLink.split(entityLink)[-1]; | ||
} | ||
|
||
/** | ||
* | ||
* @param string entityLink | ||
* @returns column name for table entity | ||
*/ | ||
static getTableColumnName(entityLink) { | ||
return EntityLink.split(entityLink)[3]; | ||
} | ||
|
||
/** | ||
* | ||
* @param string entityLink | ||
* @returns column field for table entity | ||
*/ | ||
static getTableColumnField(entityLink) { | ||
return EntityLink.split(entityLink)[4]; | ||
} | ||
|
||
/** | ||
* | ||
* @param string tableFqn | ||
* @param string | undefined columnName | ||
* @returns entity link for table | ||
*/ | ||
static getTableEntityLink(tableFqn, columnName) { | ||
if (columnName) { | ||
return `<#E${ENTITY_LINK_SEPARATOR}table${ENTITY_LINK_SEPARATOR}${tableFqn}${ENTITY_LINK_SEPARATOR}columns${ENTITY_LINK_SEPARATOR}${columnName}>`; | ||
} else { | ||
return `<#E${ENTITY_LINK_SEPARATOR}table${ENTITY_LINK_SEPARATOR}${tableFqn}>`; | ||
} | ||
} | ||
|
||
/** | ||
* | ||
* @param string entityType | ||
* @param string entityFqn | ||
* @returns entityLink | ||
*/ | ||
static getEntityLink(entityType, entityFqn) { | ||
return `<#E${ENTITY_LINK_SEPARATOR}${entityType}${ENTITY_LINK_SEPARATOR}${entityFqn}>`; | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
openmetadata-ui/src/main/resources/ui/src/utils/EntityLink.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* Copyright 2023 Collate. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import EntityLink from './EntityLink'; | ||
|
||
const entityLink = | ||
'<#E::table::sample_data.ecommerce_db.shopify.dim_address::description>'; | ||
const entityLinkWithColumn = | ||
'<#E::table::sample_data.ecommerce_db.shopify.dim_address::columns::address_id::tags>'; | ||
|
||
describe('Test EntityLink', () => { | ||
it('Should split the entityLink into parts', () => { | ||
const entityLinkPartsWithColumn = EntityLink.split(entityLinkWithColumn); | ||
const entityLinkParts = EntityLink.split(entityLink); | ||
|
||
expect(entityLinkParts).toStrictEqual([ | ||
'table', | ||
'sample_data.ecommerce_db.shopify.dim_address', | ||
'description', | ||
]); | ||
|
||
expect(entityLinkPartsWithColumn).toStrictEqual([ | ||
'table', | ||
'sample_data.ecommerce_db.shopify.dim_address', | ||
'columns', | ||
'address_id', | ||
'tags', | ||
]); | ||
}); | ||
|
||
it('Should return the entityType from entityLink', () => { | ||
expect(EntityLink.getEntityType(entityLink)).toStrictEqual('table'); | ||
}); | ||
|
||
it('Should return the entityFqn from entityLink', () => { | ||
expect(EntityLink.getEntityFqn(entityLink)).toStrictEqual( | ||
'sample_data.ecommerce_db.shopify.dim_address' | ||
); | ||
}); | ||
|
||
it('Should return the entityField from entityLink', () => { | ||
expect(EntityLink.getEntityField(entityLink)).toStrictEqual('description'); | ||
}); | ||
|
||
it('Should return the columnName from entityLink', () => { | ||
expect(EntityLink.getTableColumnName(entityLinkWithColumn)).toStrictEqual( | ||
'address_id' | ||
); | ||
}); | ||
|
||
it('Should return the column field from entityLink', () => { | ||
expect(EntityLink.getTableColumnField(entityLinkWithColumn)).toStrictEqual( | ||
'tags' | ||
); | ||
}); | ||
|
||
it('Should return the undefined if columnName if not present in entityLink', () => { | ||
expect(EntityLink.getTableColumnName(entityLink)).toBeUndefined(); | ||
}); | ||
|
||
it('Should return the undefined if columnField if not present in entityLink', () => { | ||
expect(EntityLink.getTableColumnField(entityLink)).toBeUndefined(); | ||
}); | ||
|
||
it('Should build the entityLink', () => { | ||
expect( | ||
EntityLink.getEntityLink( | ||
'table', | ||
'sample_data.ecommerce_db.shopify.dim_address' | ||
) | ||
).toStrictEqual( | ||
'<#E::table::sample_data.ecommerce_db.shopify.dim_address>' | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters