Skip to content

Commit 0c9d6c8

Browse files
authored
Add datetime support for querying (#154)
* support datetime for querying * release prep * help updates
1 parent ef50d3b commit 0c9d6c8

File tree

5 files changed

+72
-32
lines changed

5 files changed

+72
-32
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 3.1.0
2+
- Add DateTime support to querying, [#68](https://github.com/Snow-Shell/servicenow-powershell/issues/68)
3+
- Add `-between` operator
4+
- Enhanced value validation for all operators in `New-ServiceNowQuery` which is used by `Get-ServiceNowRecord`
5+
16
## 3.0.2
27
- Fix [#152](https://github.com/Snow-Shell/servicenow-powershell/issues/152), object conversion to json failing.
38

ServiceNow/Public/Get-ServiceNowRecord.ps1

+4-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
Each array should be of the format @(field, comparison operator, value) separated by a join, either 'and', 'or', or 'group'.
3333
For a complete list of comparison operators, see $script:ServiceNowOperator and use Name in your filter.
3434
See the examples.
35-
Also, see https://docs.servicenow.com/bundle/quebec-platform-user-interface/page/use/common-ui-elements/reference/r_OpAvailableFiltersQueries.html
36-
for how to represent date values with javascript.
3735
3836
.PARAMETER Sort
3937
Array or multidimensional array of fields to sort on.
@@ -87,6 +85,10 @@
8785
Get incident records where state is New and short description contains the word powershell or state is In Progress.
8886
The first 2 filters are combined and then or'd against the last.
8987
88+
.EXAMPLE
89+
Get-ServiceNowRecord -Table 'Incident' -Filter @('opened_at', '-between', (Get-Date).AddMonths(-24), (get-date).AddMonths(-12)) -IncludeTotalCount
90+
Get all incident records that were opened between 1 and 2 years ago
91+
9092
.EXAMPLE
9193
Get-ServiceNowRecord -Table incident -Filter @('state', '-eq', '1') -Sort @('opened_at', 'desc'), @('state')
9294
Get incident records where state equals New and first sort by the field opened_at descending and then sort by the field state ascending

ServiceNow/Public/New-ServiceNowQuery.ps1

+38-11
Original file line numberDiff line numberDiff line change
@@ -145,31 +145,58 @@ function New-ServiceNowQuery {
145145
if ( $i -eq $filterList.Count - 1) {
146146
throw '$Filter cannot end with a join'
147147
}
148+
149+
break
148150
}
149151

150-
2 {
151-
# should be a non-value operator, eg. ='' / ISEMPTY
152+
{ $_ -ne 1 } {
153+
# perform data validation on all filters other than a join operator
152154
$thisOperator = $script:ServiceNowOperator | Where-Object { $_.Name -eq $thisFilter[1] }
153155
if ( -not $thisOperator ) {
154156
throw ('Operator ''{0}'' is not valid' -f $thisFilter[1])
155157
}
156-
if ( $thisOperator.RequiresValue ) {
157-
throw ('Value not provided, {0} {1} ?' -f $thisFilter[0], $thisOperator.QueryOperator)
158+
if ( $thisOperator.NumValues -ne $thisFilter.Count - 2 ) {
159+
throw ('Operator ''{0}'' requires 1 field name and {1} value(s)' -f $thisFilter[1], $thisOperator.NumValues)
158160
}
161+
}
162+
163+
2 {
164+
# should be a non-value operator, eg. ='' / ISEMPTY
159165
'{0}{1}' -f $thisFilter[0], $thisOperator.QueryOperator
166+
break
160167
}
161168

162169
3 {
163-
# should be field operator value
164-
$thisOperator = $script:ServiceNowOperator | Where-Object { $_.Name -eq $thisFilter[1] }
165-
if ( -not $thisOperator ) {
166-
throw ('Operator ''{0}'' is not valid', $thisFilter[1])
170+
# should be format - field operator value
171+
172+
if ( $thisFilter[2] -is [DateTime] ) {
173+
$dateGen = "'{0}','{1}'" -f $thisFilter[2].ToString('yyyy-MM-dd'), $thisFilter[2].ToString('HH:mm:ss')
174+
'{0}{1}javascript:gs.dateGenerate({2})' -f $thisFilter[0], $thisOperator.QueryOperator, $dateGen
175+
}
176+
else {
177+
'{0}{1}{2}' -f $thisFilter[0], $thisOperator.QueryOperator, $thisFilter[2]
167178
}
168-
'{0}{1}{2}' -f $thisFilter[0], $thisOperator.QueryOperator, $thisFilter[2]
179+
180+
break
181+
}
182+
183+
4 {
184+
# should be format - field operator value1 value2, where applicable, eg. between
185+
186+
if ( $thisFilter[2] -is [DateTime] ) {
187+
$dateGen1 = "'{0}','{1}'" -f $thisFilter[2].ToString('yyyy-MM-dd'), $thisFilter[2].ToString('HH:mm:ss')
188+
$dateGen2 = "'{0}','{1}'" -f $thisFilter[3].ToString('yyyy-MM-dd'), $thisFilter[3].ToString('HH:mm:ss')
189+
'{0}{1}javascript:gs.dateGenerate({2})@javascript:gs.dateGenerate({3})' -f $thisFilter[0], $thisOperator.QueryOperator, $dateGen1, $dateGen2
190+
}
191+
else {
192+
'{0}{1}{2}@{3}' -f $thisFilter[0], $thisOperator.QueryOperator, $thisFilter[2], $thisFilter[3]
193+
}
194+
195+
break
169196
}
170197

171198
Default {
172-
throw ('Too many items for {0}, see the help' -f $thisFilter[0])
199+
throw ('Too many filter items for {0}, see the help' -f $thisFilter[0])
173200
}
174201
}
175202
}
@@ -234,7 +261,7 @@ function New-ServiceNowQuery {
234261
}
235262
}
236263

237-
$query -join ''
264+
($query -join '').Trim('^')
238265

239266
}
240267
else {

ServiceNow/ServiceNow.psd1

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
RootModule = 'ServiceNow.psm1'
66

77
# Version number of this module.
8-
ModuleVersion = '3.0.2'
8+
ModuleVersion = '3.1.0'
99

1010
# ID used to uniquely identify this module
1111
GUID = 'b90d67da-f8d0-4406-ad74-89d169cd0633'

ServiceNow/config/main.json

+24-18
Original file line numberDiff line numberDiff line change
@@ -68,109 +68,115 @@
6868
"Name": "-eq",
6969
"QueryOperator": "=",
7070
"Description": "is equal to",
71-
"RequiresValue": true
71+
"NumValues": 1
7272
},
7373
{
7474
"Name": "-ne",
7575
"QueryOperator": "!=",
7676
"Description": "is not equal to",
77-
"RequiresValue": true
77+
"NumValues": 1
7878
},
7979
{
8080
"Name": "=''",
8181
"QueryOperator": "ISEMPTY",
8282
"Description": "field has no value",
83-
"RequiresValue": false
83+
"NumValues": 0
8484
},
8585
{
8686
"Name": "=\"\"",
8787
"QueryOperator": "ISEMPTY",
8888
"Description": "field has no value",
89-
"RequiresValue": false
89+
"NumValues": 0
9090
},
9191
{
9292
"Name": "!=''",
9393
"QueryOperator": "ISNOTEMPTY",
9494
"Description": "field has any value",
95-
"RequiresValue": false
95+
"NumValues": 0
9696
},
9797
{
9898
"Name": "!=\"\"",
9999
"QueryOperator": "ISNOTEMPTY",
100100
"Description": "field has any value",
101-
"RequiresValue": false
101+
"NumValues": 0
102102
},
103103
{
104104
"Name": "-like",
105105
"QueryOperator": "LIKE",
106106
"Description": "value is found anywhere in field",
107-
"RequiresValue": true
107+
"NumValues": 1
108108
},
109109
{
110110
"Name": "-notlike",
111111
"QueryOperator": "NOT LIKE",
112112
"Description": "value is not found anywhere in field",
113-
"RequiresValue": true
113+
"NumValues": 1
114114
},
115115
{
116116
"Name": "-in",
117117
"QueryOperator": "IN",
118118
"Description": "field is populated by one of the values",
119-
"RequiresValue": true
119+
"NumValues": 1
120120
},
121121
{
122122
"Name": "-notin",
123123
"QueryOperator": "NOT IN",
124124
"Description": "field is populated by any value except for these",
125-
"RequiresValue": true
125+
"NumValues": 1
126126
},
127127
{
128128
"Name": "-lt",
129129
"QueryOperator": "<",
130130
"Description": "field is less than the value. can be used with dates to represent prior to the value.",
131-
"RequiresValue": true
131+
"NumValues": 1
132132
},
133133
{
134134
"Name": "-le",
135135
"QueryOperator": "<=",
136136
"Description": "field is less than or equal to the value. can be used with dates to represent prior to or the day of the value.",
137-
"RequiresValue": true
137+
"NumValues": 1
138138
},
139139
{
140140
"Name": "-gt",
141141
"QueryOperator": ">",
142142
"Description": "field is greater than the value. can be used with dates to represent after the value.",
143-
"RequiresValue": true
143+
"NumValues": 1
144144
},
145145
{
146146
"Name": "-ge",
147147
"QueryOperator": ">=",
148148
"Description": "field is greater than or equal to the value. can be used with dates to represent after or the day of the value.",
149-
"RequiresValue": true
149+
"NumValues": 1
150150
},
151151
{
152152
"Name": ".startswith",
153153
"QueryOperator": "STARTSWITH",
154154
"Description": "field starts with the value",
155-
"RequiresValue": true
155+
"NumValues": 1
156156
},
157157
{
158158
"Name": "-startswith",
159159
"QueryOperator": "STARTSWITH",
160160
"Description": "field starts with the value",
161-
"RequiresValue": true
161+
"NumValues": 1
162162
},
163163
{
164164
"Name": ".endswith",
165165
"QueryOperator": "%",
166166
"Description": "field ends with the value",
167-
"RequiresValue": true
167+
"NumValues": 1
168168
},
169169
{
170170
"Name": "-endswith",
171171
"QueryOperator": "%",
172172
"Description": "field ends with the value",
173-
"RequiresValue": true
173+
"NumValues": 1
174+
},
175+
{
176+
"Name": "-between",
177+
"QueryOperator": "BETWEEN",
178+
"Description": "value is between 2 dates or integers",
179+
"NumValues": 2
174180
}
175181
]
176182
}

0 commit comments

Comments
 (0)