Skip to content

Commit

Permalink
Publishing GlideQuery Perks Part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyday committed Aug 18, 2024
1 parent 6e4b14e commit c733d3b
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 12 deletions.
4 changes: 3 additions & 1 deletion _drafts/glidequery-perks-miscellaneous.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ layout: post
title:
author:
date: 2023-01-01
categories:
categories:
- glidequery
- glidequery perks series
---


Expand Down
4 changes: 3 additions & 1 deletion _drafts/glidequery-perks-part-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ layout: post
title: 'GlideQuery Perks, Part 2: JavaScript not Java'
author: Joey
date: 2023-01-01
categories: glidequery
categories:
- glidequery
- glidequery perks series
---

Another point I made in [Part 0](/2023/01/30/glidequery-perks-part-0.html) of this series was that GlideRecord is a Java object and its various methods return Java types and more Java objects, so it doesn't behave like native JavaScript. In contrast, though GlideQuery uses GlideRecord to perform database operations in its private implementation, its public interface is written entirely in JavaScript and was intentionally designed to behave like JavaScript.
Expand Down
4 changes: 3 additions & 1 deletion _drafts/glidequery-perks-part-3.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ layout: post
title: 'GlideQuery Perks, Part 3: Fun, Expressive Method Chaining'
author: Joey
date: 2023-01-01
categories: glidequery
categories:
- glidequery
- glidequery perks series
---

One of the problems I never knew GlideRecord has is there's pretty much only one way to get records out of it. You perform your query and then you iterate through the records with the `next()` method. GlideQuery breaks the mold by offering half a dozen new and expressive ways to loop through the resulting records.
Expand Down
4 changes: 3 additions & 1 deletion _drafts/glidequery-perks-part-4.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ layout: post
title: 'GlideQuery Perks, Part 4: Immutable Composability and Re-usability'
author: Joey
date: 2023-01-01
categories: glidequery
categories:
- glidequery
- glidequery perks series
---


Expand Down
4 changes: 3 additions & 1 deletion _drafts/glidequery-perks-part-5.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ layout: post
title: 'GlideQuery Perks, Part 5: Friendly, Helpful Error Messages'
author: Joey
date: 2023-01-01
categories: glidequery
categories:
- glidequery
- glidequery perks series
---


Expand Down
4 changes: 2 additions & 2 deletions _posts/2023-02-08-glidequery-perks-part-0.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ Bell's original CreatorCon 2020 breakout session, _[GlideQuery: A modern upgrade

From January to April 2021, Bell published a series of excellent blog posts explaining how to use GlideQuery. There's a lot of overlap here with the official documentation, but, where the docs simply list methods alphabetically, these posts order the topics more pedagogically:

<div class="column-left" markdown="1">
<div class="column-left" markdown="1" style="width: 44%">
- ["GlideQuery Part 1"](https://developer.servicenow.com/blog.do?p=/post/glidequery-p1/)
- ["GlideQuery Part 2"](https://developer.servicenow.com/blog.do?p=/post/glidequery-p2/)
- ["GlideQuery Part 3"](https://developer.servicenow.com/blog.do?p=/post/glidequery-p3/)
- ["GlideQuery Part 4: Aggregates"](https://developer.servicenow.com/blog.do?p=/post/glidequery-p4/)
</div>
<div class="column-right" markdown="1">
<div class="column-right" markdown="1" style="width: 56%">
- ["GlideQuery Part 5: Dotwalking and Flags"](https://developer.servicenow.com/blog.do?p=/post/glidequery-p5/)
- ["GlideQuery: Stream Processing Part 1"](https://developer.servicenow.com/blog.do?p=/post/glidequery-p6/)
- ["GlideQuery: Stream Processing Part 2"](https://developer.servicenow.com/blog.do?p=/post/glidequery-p7/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@
layout: post
title: 'GlideQuery Perks, Part 1: Unambiguous Boolean Logic'
author: Joey
date: 2023-01-01
categories: glidequery
date: 2024-08-18
categories:
- glidequery
- glidequery perks series
excerpt_separator: <!--more-->
---

One of the problems I mentioned in [Part 0](/2023/01/30/glidequery-perks-part-0.html) of this series is that GlideRecord is squirrelly when it comes to precedence of logical <abbr>AND</abbr> and <abbr>OR</abbr>. GlideQuery avoids this issue by disallowing ambiguous boolean logic.
<span class="lead">I published [Part 0](/2023/01/30/glidequery-perks-part-0.html) and [Part 0.5](/2023/02/08/glidequery-perks-part-0.5.html) of this series so long ago</span> you probably thought I forgot about it, but this is a favorite topic of mine so I couldn't leave it unfinished. 😅 If you haven't read the first part, I highly recommend catching up before reading this.

One of the problems I mentioned in Part 0 is that GlideRecord is squirrelly when it comes to precedence of logical <abbr>AND</abbr> and <abbr>OR</abbr>. GlideQuery avoids this issue by disallowing ambiguous boolean logic.

<!--more-->

## Mind your <abbr>AND</abbr>s and <abbr>OR</abbr>s

To avoid uncertainty in queries, GlideQuery's interface requires you to nest <abbr>AND</abbr>'s and <abbr>OR</abbr>'s that could have more than one possible order of operation.

For example, "A <abbr>AND</abbr> B <abbr>AND</abbr> C" raises no cause for alarm, as does "A <abbr>OR</abbr> B <abbr>OR</abbr> C", but "A <abbr>OR</abbr> B <abbr>AND</abbr> C" is problematic. How so? You could simply evaluate the logic in order, taking the <abbr>OR</abbr> first and then the <abbr>AND</abbr>. However, in most programming languages and query languages, including JavaScript, <abbr>AND</abbr> takes precedence over <abbr>OR</abbr> (without any need for parentheses; cf. how multiplication takes natural precedence over addition in arithmetic), but, curiously, in ServiceNow queries, both encoded queries and GlideRecord queries, <abbr>OR</abbr> has always taken precedence over <abbr>AND</abbr>.
For example, "A <abbr>AND</abbr> B <abbr>AND</abbr> C" raises no cause for alarm, as does "A <abbr>OR</abbr> B <abbr>OR</abbr> C", but "A <abbr>OR</abbr> B <abbr>AND</abbr> C" is problematic. How so? You could simply evaluate the logic in order, taking the <abbr>OR</abbr> first and then the <abbr>AND</abbr>. However, in most programming languages and query languages, including JavaScript, <abbr>AND</abbr> takes precedence over <abbr>OR</abbr> (without any need for parentheses; cf. how multiplication takes natural precedence over addition in arithmetic), but, curiously, in ServiceNow queriesboth encoded queries and GlideRecord queries<abbr>OR</abbr> has always taken precedence over <abbr>AND</abbr>. In fact, with normal calls to `addQuery` and `addOrCondition`, it's not even possible to force <abbr>AND</abbr> to take precedence over <abbr>OR</abbr> (you have to switch to using an encoded query with the `^NQ` operator).

Given the inconsistency, you can see there's a lot of potential for confusion here. Rather than simply evaluating a query from left to right, and rather than letting either logical operator take precedence over the other, GlideQuery takes the approach of simply always requiring parentheses (in a manner of speaking) so that there is never any ambiguity about order of operations in a query.

Expand Down Expand Up @@ -51,8 +58,30 @@ In the case of our third example above, the error is "Ambiguous query: cannot co

## How to write "parentheses" in GlideQuery

The way GlideQuery disambiguates whether <abbr>AND</abbr> should come before <abbr>OR</abbr> and vice versa is by having you pass a new table-agnostic GlideQuery object as the only parameter to a `where` or `orWhere` clause, like these examples:

~~~ javascript
// (active OR blue smoke) AND itil user
new GlideQuery('incident')
.where(new GlideQuery()
.where('active', true)
.orWhere('short_description', 'CONTAINS', 'blue smoke'))
.where('assigned_to.name', 'ITIL User');

// active OR (blue smoke AND itil user)
new GlideQuery('incident')
.where('active', true)
.orWhere(new GlideQuery()
.where('short_description', 'CONTAINS', 'blue smoke')
.where('assigned_to.name', 'ITIL User'));
~~~

Doing it this way feels somewhat cumbersome (count your parentheses carefully!), but if a little awkwardness is the price to pay for clearer code, I'm here for it. Usually, writing them the way I have above is readable enough, but you could make this look less busy and complicated by assigning the sub-queries to variables beforehand.


## Conclusion

ServiceNow's inexplicable "<abbr>OR</abbr>" bias has always bothered me, but the way these GlideQuery clauses can be nested addresses my gripe and makes the boolean logic more transparent and precise. And recall that with GlideRecord you _can't_ make <abbr>AND</abbr> take precedence over <abbr>OR</abbr> without resorting to encoded queries, so being able to do so with normal calls to `where` and `orWhere` with GlideQuery is a massive improvement.

{% include endmark.html %}
That's it for this installment. I hope this starts to persuade you GlideQuery is superior to GlideRecord and should be the way forward for all pro-code solutions on the ServiceNow platform, and I hope you're looking forward to future articles in the series. Cheers!{% include endmark.html %}

0 comments on commit c733d3b

Please sign in to comment.