SOQL Parser JS
Description
SOQL Parser JS will parse a SOQL query string into an object that is easy to work with and has the query broken down into usable parts.
TODO
Future Idea List
Examples
For an example of the parser, check out the example application.
Typescript / ES6
import { parseQuery } from './SoqlParser';
const soql = 'SELECT UserId, COUNT(Id) from LoginHistory WHERE LoginTime > 2010-09-20T22:16:30.000Z AND LoginTime < 2010-09-21T22:16:30.000Z GROUP BY UserId';
const soqlQuery = parseQuery(soql);
console.log(JSON.stringify(soqlQuery, null, 2));
Node
var soqlParserJs = require("soql-parser-js");
const soql = 'SELECT UserId, COUNT(Id) from LoginHistory WHERE LoginTime > 2010-09-20T22:16:30.000Z AND LoginTime < 2010-09-21T22:16:30.000Z GROUP BY UserId';
const soqlQuery = soqlParserJs.parseQuery(soql);
console.log(JSON.stringify(soqlQuery, null, 2));
This yields an object with the following structure:
{
"fields": [
{
"text": "UserId"
},
{
"fn": {
"text": "COUNT(Id)",
"name": "COUNT",
"parameter": "Id"
}
}
],
"subqueries": [],
"sObject": "LoginHistory",
"whereClause": {
"left": {
"field": "LoginTime",
"operator": ">",
"value": "2010-09-20T22:16:30.000Z"
},
"operator": "AND",
"right": {
"left": {
"field": "LoginTime",
"operator": "<",
"value": "2010-09-21T22:16:30.000Z"
}
}
},
"groupBy": {
"field": "UserId"
}
}
Data Model of Parsed Data
export type LogicalOperator = 'AND' | 'OR';
export type Operator = '=' | '<=' | '>=' | '>' | '<' | 'LIKE' | 'IN' | 'NOT IN' | 'INCLUDES' | 'EXCLUDES';
export interface Query {
fields: Field[];
subqueries: Query[];
sObject: string;
sObjectAlias?: string;
whereClause?: WhereClause;
limit?: number;
offset?: number;
groupBy?: GroupByClause;
having?: HavingClause;
orderBy?: OrderByClause | OrderByClause[];
}
export interface SelectStatement {
fields: Field[];
}
export interface Field {
text?: string;
alias?: string;
relationshipFields?: string[];
fn?: FunctionExp;
subqueryObjName?: string;
}
export interface WhereClause {
left: Condition | WhereClause;
right?: Condition | WhereClause;
operator?: LogicalOperator;
}
export interface Condition {
openParen?: boolean;
closeParen?: boolean;
logicalPrefix?: 'NOT';
field: string;
operator: Operator;
value: string | string[];
}
export interface OrderByClause {
field?: string;
fn?: FunctionExp;
order?: 'ASC' | 'DESC';
nulls?: 'FIRST' | 'LAST';
}
export interface GroupByClause {
field: string | string[];
type?: 'CUBE' | 'ROLLUP';
}
export interface HavingClause {
left: HavingCondition | HavingClause;
right?: HavingCondition | HavingClause;
operator?: LogicalOperator;
}
export interface HavingCondition {
field?: string;
fn?: FunctionExp;
operator: string;
value: string | number;
}
export interface FunctionExp {
text?: string;
name?: string;
alias?: string;
parameter?: string | string[];
}
Contributing
All contributions are welcome on the project. Please read the contribution guidelines.
Special Thanks