Skip to content

Commit 0909f18

Browse files
authored
Merge pull request #57 from paustint/bug-56
Validate query logs syntax errors to the console #56
2 parents 0d04ab1 + d603821 commit 0909f18

File tree

6 files changed

+175
-11
lines changed

6 files changed

+175
-11
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Changelog
22
All notable changes to this project will be documented in this file.
3+
## 1.0.1
4+
- Ensured that nothing is logged directly to the console unless logging is enabled
35

4-
## 1.0
6+
## 1.0.0
57
### Changed
68
**!BREAKING CHANGES!**
79
- Added literal type information to fields to provide additional information about the field type. (#51)

debug/test.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
var soqlParserJs = require('./lib');
22

3-
const query = `
4-
SELECT Id, Name, FORMAT(Amount),
5-
(SELECT Quantity, ListPrice, PricebookEntry.UnitPrice, PricebookEntry.Name FROM OpportunityLineItems)
6-
FROM Opportunity
7-
WHERE CreatedDate > LAST_N_YEARS:1
8-
AND StageName = 'Closed Won'
9-
LIMIT 150
10-
`;
3+
const query = `@`;
4+
// const query = `
5+
// SELECT Id, Name, FORMAT(Amount),
6+
// (SELECT Quantity, ListPrice, PricebookEntry.UnitPrice, PricebookEntry.Name FROM OpportunityLineItems)
7+
// FROM Opportunity
8+
// WHERE CreatedDate > LAST_N_YEARS:1
9+
// AND StageName = 'Closed Won'
10+
// LIMIT 150
11+
// `;
1112
// SELECT Id FROM Account WHERE (Id IN ('1', '2', '3') OR (NOT Id = '2') OR (Name LIKE '%FOO%' OR (Name LIKE '%ARM%' AND FOO = 'bar')))
1213
// SELECT Id FROM Account WHERE dateField != '2018-10-03' AND dateField < LAST_N_DAYS:5 AND dateField < LAST_WEEK AND isDeleted = false AND someOTherField = 'someVal'
1314
// SELECT Id, Name, Foo, Bar, Baz, Bax, aaa, bbb, ccc, ddd, Id, Name, Foo, Bar, Baz, Bax, aaa, bbb, ccc, ddd, Id, Name, Foo, Bar, Baz, Bax, aaa, bbb, ccc, ddd, Account.Name, (SELECT Id, Name, Foo, Bar, Baz, Bax, aaa, bbb, ccc, ddd, Id, Name, Foo, Bar, Baz, Bax, aaa, bbb, ccc, ddd, Contact.LastName FROM Account.Contacts), baz, (SELECT Id FROM account WHERE Boo.baz = 'bar'), bax, bar FROM Account
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import SyntaxHighlighter from 'react-syntax-highlighter/prism';
2+
import * as CopyToClipboard from 'react-copy-to-clipboard';
3+
import { xonokai } from 'react-syntax-highlighter/styles/prism';
4+
5+
import * as React from 'react';
6+
import { Button } from 'office-ui-fabric-react/lib/Button';
7+
8+
export interface CodeOutputProps {
9+
title: string | JSX.Element;
10+
lang: string;
11+
data?: string;
12+
showCopyToClipboard: boolean;
13+
copyToClipboardDisabled: boolean;
14+
showChildrenAboveClipboard?: boolean;
15+
customStyle?: any;
16+
}
17+
18+
export default class CodeOutput extends React.Component<CodeOutputProps, any> {
19+
constructor(props: CodeOutputProps) {
20+
super(props);
21+
}
22+
23+
public render() {
24+
return (
25+
<div className="ms-Grid-row">
26+
<div className="ms-Grid-col ms-sm12">
27+
<div className="ms-font-l">{this.props.title}</div>
28+
<SyntaxHighlighter language={this.props.lang} style={xonokai} customStyle={this.props.customStyle}>
29+
{this.props.data}
30+
</SyntaxHighlighter>
31+
<div>
32+
{this.props.showChildrenAboveClipboard && this.props.children}
33+
{this.props.showCopyToClipboard && this.props.data && (
34+
<CopyToClipboard text={this.props.data}>
35+
<Button
36+
primary={true}
37+
disabled={this.props.copyToClipboardDisabled}
38+
iconProps={{ iconName: 'copy' }}
39+
title="Copy"
40+
ariaLabel="Copy"
41+
text="Copy to Clipboard"
42+
/>
43+
</CopyToClipboard>
44+
)}
45+
{!this.props.showChildrenAboveClipboard && this.props.children}
46+
</div>
47+
</div>
48+
</div>
49+
);
50+
}
51+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import * as React from 'react';
2+
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
3+
import { TextField } from 'office-ui-fabric-react/lib/TextField';
4+
import { FormatOptions } from 'soql-parser-js';
5+
6+
export interface ParseSoqlFormatProps {
7+
style?: any;
8+
formatOptions: FormatOptions;
9+
enabled: boolean;
10+
toggleFormat: (enabled: boolean) => void;
11+
onChange: (formatOptions: FormatOptions) => void;
12+
}
13+
14+
export default class ParseSoqlFormat extends React.Component<ParseSoqlFormatProps, any> {
15+
public setMaxFieldLen = (ev: React.SyntheticEvent<HTMLInputElement>) => {
16+
const formatOptions = {
17+
...this.props.formatOptions,
18+
fieldMaxLineLen: Math.max(0, Number((ev.target as HTMLInputElement).value)),
19+
};
20+
this.props.onChange(formatOptions);
21+
};
22+
23+
public toggleSubqueryParens = () => {
24+
const formatOptions = {
25+
...this.props.formatOptions,
26+
fieldSubqueryParensOnOwnLine: !this.props.formatOptions.fieldSubqueryParensOnOwnLine,
27+
};
28+
this.props.onChange(formatOptions);
29+
};
30+
31+
public toggleWhereClauseIndent = () => {
32+
const formatOptions = {
33+
...this.props.formatOptions,
34+
whereClauseOperatorsIndented: !this.props.formatOptions.whereClauseOperatorsIndented,
35+
};
36+
this.props.onChange(formatOptions);
37+
};
38+
39+
public render() {
40+
return (
41+
<div style={this.props.style}>
42+
<Checkbox
43+
label="Format Output"
44+
checked={this.props.enabled}
45+
onChange={() => this.props.toggleFormat(!this.props.enabled)}
46+
/>
47+
<div style={{ margin: 5, paddingLeft: 10 }}>
48+
<div style={{ maxWidth: 400 }}>
49+
<TextField
50+
label={
51+
(
52+
<span>
53+
Number of characters before fields wrap -{' '}
54+
<small>
55+
<code>fieldMaxLineLen</code>
56+
</small>
57+
</span>
58+
) as any
59+
}
60+
type="number"
61+
value={String(this.props.formatOptions.fieldMaxLineLen)}
62+
onChange={this.setMaxFieldLen}
63+
disabled={!this.props.enabled}
64+
/>
65+
</div>
66+
<div style={{ marginTop: 5 }}>
67+
<Checkbox
68+
label={
69+
(
70+
<span>
71+
Subquery Parenthesis on own line -{' '}
72+
<small>
73+
<code>fieldSubqueryParensOnOwnLine</code>
74+
</small>
75+
</span>
76+
) as any
77+
}
78+
checked={this.props.formatOptions.fieldSubqueryParensOnOwnLine}
79+
onChange={this.toggleSubqueryParens}
80+
disabled={!this.props.enabled}
81+
/>
82+
</div>
83+
<div style={{ marginTop: 5 }}>
84+
<Checkbox
85+
label={
86+
(
87+
<span>
88+
Indent items in WHERE clause -{' '}
89+
<small>
90+
<code>whereClauseOperatorsIndented</code>
91+
</small>
92+
</span>
93+
) as any
94+
}
95+
checked={this.props.formatOptions.whereClauseOperatorsIndented}
96+
onChange={this.toggleWhereClauseIndent}
97+
disabled={!this.props.enabled}
98+
/>
99+
</div>
100+
</div>
101+
</div>
102+
);
103+
}
104+
}

lib/SoqlParser.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { ANTLRInputStream, CommonTokenStream } from 'antlr4ts';
1+
import { ANTLRInputStream, CommonTokenStream, TokenStream } from 'antlr4ts';
22
import { ParseTreeWalker } from 'antlr4ts/tree';
33
import * as utils from './utils';
44
import { SyntaxErrorListener } from './ErrorListener';
55
import { SOQLLexer } from './generated/SOQLLexer';
66
import { SOQLParser, Soql_queryContext } from './generated/SOQLParser';
77
import { Query } from './models/SoqlQuery.model';
88
import { Listener, ListenerQuick } from './SoqlListener';
9+
import { Override } from 'antlr4ts/Decorators';
910

1011
export interface ConfigBase {
1112
logging?: boolean; // default=false
@@ -32,7 +33,12 @@ function configureDefaults(config: Partial<SoqlQueryConfig> = {}) {
3233
*/
3334
function getSoqlQueryContext(soql: string, config: Partial<SoqlQueryConfig> = {}): SOQLParser {
3435
let inputStream = new ANTLRInputStream(soql);
36+
3537
let lexer = new SOQLLexer(inputStream);
38+
// bug-56 - The lever must have error listeners added to ensure no logging directly to the console
39+
lexer.removeErrorListeners();
40+
lexer.addErrorListener(new SyntaxErrorListener());
41+
3642
let tokenStream = new CommonTokenStream(lexer);
3743
const parser = new SOQLParser(tokenStream);
3844

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "soql-parser-js",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "Salesforce.com SOQL parser.",
55
"main": "dist/index.js",
66
"module": "dist/index.es.js",

0 commit comments

Comments
 (0)