-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGetDataViewStoredData.pqm
167 lines (167 loc) · 7.7 KB
/
GetDataViewStoredData.pqm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
let
GetDataViewStoredData = (
token as text,
resource as text,
apiVersion as text,
tenantId as text,
namespaceId as text,
dataViewId as text,
startIndex as datetime,
endIndex as datetime
) as table =>
let
GetContinuation = (response) as nullable text =>
let
headers = Value.Metadata(response)[Headers],
nextPageLink = Record.FieldOrDefault(headers, "Next-Page"),
continuationToken =
if nextPageLink = null then
null
else
List.Last(Text.Split(nextPageLink, "continuationtoken="))
in
continuationToken,
GetPage = (continuation as nullable text) as table =>
let
dataQuery = "/api/"
& apiVersion
& "/Tenants/"
& tenantId
& "/Namespaces/"
& namespaceId
& "/Dataviews/"
& dataViewId
& "/Data/Stored?startIndex="
& DateTime.ToText(startIndex, "o")
& "&endIndex="
& DateTime.ToText(endIndex, "o"),
queryWithContinuation =
if continuation = null then
dataQuery
else
dataQuery & "&continuationToken=" & continuation,
response = Web.Contents(
resource, [
RelativePath = queryWithContinuation,
Headers = [Authorization = token]
]
),
newContinuation = GetContinuation(response),
getJsonQuery = Json.Document(response),
tableOfData = Table.FromList(
getJsonQuery, Splitter.SplitByNothing(), null, null, ExtraValues.Error
)
in
tableOfData meta [Continuation = newContinuation],
// The getNextPage function takes a single argument and is expected to return a nullable table
Table.GenerateByPage = (getNextPage as function) as table =>
let
listOfPages = List.Generate(
() => getNextPage(null),
// get the first page of data
(lastPage) => lastPage <> null,
// stop when the function returns null
(lastPage) => getNextPage(lastPage)
// pass the previous page to the next function call
),
// concatenate the pages together
tableOfPages = Table.FromList(listOfPages, Splitter.SplitByNothing(), {"Column1"}),
firstRow = tableOfPages{0} ?
in
// if we didn't get back any pages of data, return an empty table
// otherwise set the table type based on the columns of the first page
if (firstRow = null) then
Table.FromRows({})
// check for empty first table
else if (Table.IsEmpty(firstRow[Column1])) then
firstRow[Column1]
else
Value.ReplaceType(
Table.ExpandTableColumn(tableOfPages, "Column1", Table.ColumnNames(firstRow[Column1])),
Value.Type(firstRow[Column1])
),
// Read all pages of data.
// After every page, we check the "NextLink" record on the metadata of the previous request.
// Table.GenerateByPage will keep asking for more pages until we return null.
GetAllPagesByNextLink = Table.GenerateByPage(
(previous) =>
let
// if previous is null, then this is our first page of data
continuation = if (previous = null) then "" else Value.Metadata(previous)[Continuation]?,
// if continuation was set to null by the previous call, we know we have no more data
page = if (continuation <> null) then GetPage(continuation) else null
in
page
)
in
GetAllPagesByNextLink,
GetDataViewStoredDataType = type function (
token as (
type text meta [
Documentation.FieldCaption = "Token",
Documentation.FieldDescription = "OAuth bearer token. Generate using GetToken.",
Documentation.SampleValues = {"Generate using GetToken()"}
]
),
resource as (
type text meta [
Documentation.FieldCaption = "Resource",
Documentation.FieldDescription = "Region Endpoint.",
Documentation.SampleValues = {"https://uswe.datahub.connect.aveva.com"}
]
),
apiVersion as (
type text meta [
Documentation.FieldCaption = "API Version",
Documentation.FieldDescription = "API Version.",
Documentation.SampleValues = {"v1"}
]
),
tenantId as (
type text meta [
Documentation.FieldCaption = "Tenant Id",
Documentation.FieldDescription = "Tenant Identifier.",
Documentation.SampleValues = {"Enter Tenant Id"}
]
),
namespaceId as (
type text meta [
Documentation.FieldCaption = "Namespace Id",
Documentation.FieldDescription = "Namespace Identifier.",
Documentation.SampleValues = {"Enter Namespace Id"}
]
),
assetId as (
type text meta [
Documentation.FieldCaption = "Data View Id",
Documentation.FieldDescription = "Data View Identifier.",
Documentation.SampleValues = {"Enter Data View Id"}
]
),
startIndex as (
type datetime meta [
Documentation.FieldCaption = "Start Index",
Documentation.FieldDescription = "Index identifying the beginning of the series of events to return."
]
),
endIndex as (
type datetime meta [
Documentation.FieldCaption = "End Index",
Documentation.FieldDescription = "Index identifying the end of the series of events to return."
]
)
) as binary meta [
Documentation.Name = "Get Data View Stored Data",
Documentation.LongDescription = "Returns stored data for the provided Data View and index parameters.
<br>
<br>     <b>Token</b>: OAuth bearer token. Generate using GetToken().
<br>     <b>Resource</b>: Region Endpoint.
<br>     <b>API Version</b>: API Version.
<br>     <b>Tenant Id</b>: Tenant Identifier.
<br>     <b>Namespace Id</b>: Namespace Identifier.
<br>     <b>Data View Id</b>: Data View Identifier.
<br>     <b>Start Index</b>: Index identifying the beginning of the series of events to return.
<br>     <b>End Index</b>: Index identifying the end of the series of events to return."
]
in
Value.ReplaceType(GetDataViewStoredData, GetDataViewStoredDataType)