Skip to content

Commit 720faf0

Browse files
author
Jareth Hein
committed
Alter QTable _doQuery to automatically handle ViewTooLarge exceptions by spliting the query in half and trying agian, etc.
1 parent 503cda0 commit 720faf0

File tree

2 files changed

+76
-11
lines changed

2 files changed

+76
-11
lines changed

Intuit.QuickBase.Client/QTable.cs

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,19 +169,75 @@ public int GetServerRecordCount()
169169

170170
private void _doQuery(DoQuery qry)
171171
{
172-
XPathNavigator xml;
173172
Records.Clear();
174173
try
175174
{
176-
xml = qry.Post().CreateNavigator();
175+
XPathNavigator xml = qry.Post().CreateNavigator();
176+
LoadColumns(xml); //Must be done each time, incase the schema changes due to another user, or from a previous query that has a differing subset of columns
177+
LoadRecords(xml);
177178
}
178-
catch (ViewTooLargeException ex)
179+
catch (ViewTooLargeException)
179180
{
180-
//split into smaller queries automagically eventually
181-
throw;
181+
//split into smaller queries automagically
182+
List<string> optionsList = new List<string>();
183+
string query = qry.Query;
184+
int maxCount = 0;
185+
int baseSkip = 0;
186+
if (!string.IsNullOrEmpty(qry.Options))
187+
{
188+
string[] optArry = qry.Options.Split('.');
189+
foreach (string opt in optArry)
190+
{
191+
if (opt.StartsWith("num-"))
192+
{
193+
maxCount = int.Parse(opt.Substring(4));
194+
}
195+
else if (opt.StartsWith("skp-"))
196+
{
197+
baseSkip = int.Parse(opt.Substring(4));
198+
}
199+
else
200+
{
201+
optionsList.Add(opt);
202+
}
203+
}
204+
}
205+
if (maxCount == 0)
206+
{
207+
var doQuery = new DoQueryCount.Builder(Application.Client.Ticket, Application.Token, Application.Client.AccountDomain, TableId)
208+
.SetQuery(query)
209+
.Build();
210+
var cntXml = doQuery.Post().CreateNavigator();
211+
maxCount = int.Parse(cntXml.SelectSingleNode("/qdbapi/numMatches").Value);
212+
}
213+
int stride = maxCount/2;
214+
int fetched = 0;
215+
while (fetched < maxCount)
216+
{
217+
List<string> optLst = new List<string>();
218+
optLst.AddRange(optionsList);
219+
optLst.Add($"skp-{fetched + baseSkip}");
220+
optLst.Add($"num-{stride}");
221+
string options = string.Join(".",optLst);
222+
var doQuery = new DoQuery.Builder(Application.Client.Ticket, Application.Token, Application.Client.AccountDomain, TableId)
223+
.SetQuery(query)
224+
.SetCList("a")
225+
.SetOptions(options)
226+
.SetFmt(true)
227+
.Build();
228+
try
229+
{
230+
XPathNavigator xml = doQuery.Post().CreateNavigator();
231+
if (fetched == 0) LoadColumns(xml);
232+
LoadRecords(xml);
233+
fetched += stride;
234+
}
235+
catch (ViewTooLargeException)
236+
{
237+
stride = stride/2;
238+
}
239+
}
182240
}
183-
LoadColumns(xml); //Must be done each time, incase the schema changes due to another user, or from a previous query that has a differing subset of columns
184-
LoadRecords(xml);
185241
}
186242

187243
public void Query()

Intuit.QuickBase.Core/DoQuery.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public class DoQuery : IQObject
2525
private const string QUICKBASE_ACTION = "API_DoQuery";
2626
private readonly Payload.Payload _doQueryPayload;
2727
private readonly IQUri _uri;
28+
private readonly string _options;
29+
private readonly string _query;
2830

2931
public class Builder
3032
{
@@ -125,16 +127,23 @@ private DoQuery(Builder builder)
125127
.SetFmt(builder.Fmt)
126128
.SetOptions(builder.Options)
127129
.Build();
130+
_options = builder.Options;
131+
_query = builder.Query;
128132
_doQueryPayload = new ApplicationTicket(_doQueryPayload, builder.Ticket);
129133
_doQueryPayload = new ApplicationToken(_doQueryPayload, builder.AppToken);
130134
_doQueryPayload = new WrapPayload(_doQueryPayload);
131135
_uri = new QUriDbid(builder.AccountDomain, builder.Dbid);
132136
}
133137

134-
//internal string Options
135-
//{
136-
// get { return (DoQueryPayload)_doQueryPayload.Options; }
137-
//}
138+
public string Options
139+
{
140+
get { return _options; }
141+
}
142+
143+
public string Query
144+
{
145+
get { return _query; }
146+
}
138147

139148
public string XmlPayload
140149
{

0 commit comments

Comments
 (0)