Skip to content

Commit 0e954bd

Browse files
author
Jareth Hein
committed
Remove a lot of 'homegrown' xml formation/creation and use System.Xml to avoid problems with invalid entities, etc. Should refactor soon to remove a lot of the ToString calls.
Also shut off genCSV uploads for tables with file columns.
1 parent 246c59e commit 0e954bd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+232
-154
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
Intuit.QuickBase.Client/obj/
33
Intuit.QuickBase.Core/obj/
44
QBFunctionTest/obj/
5-
QBFunctionTest/app.config
5+
QBFunctionTest/*.config
66
TestResults/
7+
*.CodeAnalysisLog.xml
8+
*.ruleset
9+
*.lastcodeanalysissucceeded

Intuit.QuickBase.Client/Intuit.QuickBase.Client.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<DefineConstants>DEBUG;TRACE</DefineConstants>
3333
<ErrorReport>prompt</ErrorReport>
3434
<WarningLevel>4</WarningLevel>
35+
<RunCodeAnalysis>true</RunCodeAnalysis>
3536
</PropertyGroup>
3637
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
3738
<DebugType>pdbonly</DebugType>

Intuit.QuickBase.Client/QRecord.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public string GetAsCSV(string clist)
201201
}
202202
else
203203
{
204-
if (field.Type == FieldType.file) throw new InvalidChoiceException();
204+
if (field.Type == FieldType.file) throw new InvalidChoiceException(); //Can't upload a file via CSV upload
205205
csvList.Add(CSVQuoter(field.QBValue));
206206
}
207207
}

Intuit.QuickBase.Client/QTable.cs

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Linq;
1212
using System.Xml.XPath;
1313
using Intuit.QuickBase.Core;
14+
using Intuit.QuickBase.Core.Exceptions;
1415

1516
namespace Intuit.QuickBase.Client
1617
{
@@ -166,15 +167,30 @@ public int GetServerRecordCount()
166167
return int.Parse(xml.SelectSingleNode("/qdbapi/num_records").Value);
167168
}
168169

170+
private void _doQuery(DoQuery qry)
171+
{
172+
XPathNavigator xml;
173+
Records.Clear();
174+
try
175+
{
176+
xml = qry.Post().CreateNavigator();
177+
}
178+
catch (ViewTooLargeException ex)
179+
{
180+
//split into smaller queries automagically eventually
181+
throw;
182+
}
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);
185+
}
186+
169187
public void Query()
170188
{
171189
var doQuery = new DoQuery.Builder(Application.Client.Ticket, Application.Token, Application.Client.AccountDomain, TableId)
172190
.SetCList("a")
173191
.SetFmt(true)
174192
.Build();
175-
var xml = doQuery.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 difering subset of columns
177-
LoadRecords(xml);
193+
_doQuery(doQuery);
178194
}
179195

180196
public void Query(string options)
@@ -184,9 +200,7 @@ public void Query(string options)
184200
.SetFmt(true)
185201
.SetOptions(options)
186202
.Build();
187-
var xml = doQuery.Post().CreateNavigator();
188-
LoadColumns(xml);
189-
LoadRecords(xml);
203+
_doQuery(doQuery);
190204
}
191205

192206
public void Query(int[] clist)
@@ -197,9 +211,7 @@ public void Query(int[] clist)
197211
.SetCList(colList)
198212
.SetFmt(true)
199213
.Build();
200-
var xml = doQuery.Post().CreateNavigator();
201-
LoadColumns(xml);
202-
LoadRecords(xml);
214+
_doQuery(doQuery);
203215
}
204216

205217
public void Query(int[] clist, string options)
@@ -211,9 +223,7 @@ public void Query(int[] clist, string options)
211223
.SetOptions(options)
212224
.SetFmt(true)
213225
.Build();
214-
var xml = doQuery.Post().CreateNavigator();
215-
LoadColumns(xml);
216-
LoadRecords(xml);
226+
_doQuery(doQuery);
217227
}
218228

219229
public void Query(Query query)
@@ -223,9 +233,7 @@ public void Query(Query query)
223233
.SetCList("a")
224234
.SetFmt(true)
225235
.Build();
226-
var xml = doQuery.Post().CreateNavigator();
227-
LoadColumns(xml);
228-
LoadRecords(xml);
236+
_doQuery(doQuery);
229237
}
230238

231239
public void Query(Query query, string options)
@@ -236,9 +244,7 @@ public void Query(Query query, string options)
236244
.SetOptions(options)
237245
.SetFmt(true)
238246
.Build();
239-
var xml = doQuery.Post().CreateNavigator();
240-
LoadColumns(xml);
241-
LoadRecords(xml);
247+
_doQuery(doQuery);
242248
}
243249

244250
public void Query(Query query, int[] clist)
@@ -250,9 +256,7 @@ public void Query(Query query, int[] clist)
250256
.SetCList(colList)
251257
.SetFmt(true)
252258
.Build();
253-
var xml = doQuery.Post().CreateNavigator();
254-
LoadColumns(xml);
255-
LoadRecords(xml);
259+
_doQuery(doQuery);
256260
}
257261

258262
public void Query(Query query, int[] clist, int[] slist)
@@ -266,9 +270,7 @@ public void Query(Query query, int[] clist, int[] slist)
266270
.SetSList(solList)
267271
.SetFmt(true)
268272
.Build();
269-
var xml = doQuery.Post().CreateNavigator();
270-
LoadColumns(xml);
271-
LoadRecords(xml);
273+
_doQuery(doQuery);
272274
}
273275

274276
public void Query(Query query, int[] clist, int[] slist, string options)
@@ -283,9 +285,7 @@ public void Query(Query query, int[] clist, int[] slist, string options)
283285
.SetOptions(options)
284286
.SetFmt(true)
285287
.Build();
286-
var xml = doQuery.Post().CreateNavigator();
287-
LoadColumns(xml);
288-
LoadRecords(xml);
288+
_doQuery(doQuery);
289289
}
290290

291291
public void Query(int queryId)
@@ -294,9 +294,7 @@ public void Query(int queryId)
294294
.SetQid(queryId)
295295
.SetFmt(true)
296296
.Build();
297-
var xml = doQuery.Post().CreateNavigator();
298-
LoadColumns(xml);
299-
LoadRecords(xml);
297+
_doQuery(doQuery);
300298
}
301299

302300
public void Query(int queryId, string options)
@@ -306,9 +304,7 @@ public void Query(int queryId, string options)
306304
.SetFmt(true)
307305
.SetOptions(options)
308306
.Build();
309-
var xml = doQuery.Post().CreateNavigator();
310-
LoadColumns(xml);
311-
LoadRecords(xml);
307+
_doQuery(doQuery);
312308
}
313309

314310
public int QueryCount(Query query)
@@ -362,7 +358,10 @@ public void AcceptChanges()
362358
List<IQRecord> modList = Records.Where(record => record.RecordState == RecordState.Modified).ToList();
363359
int acnt = addList.Count;
364360
int mcnt = modList.Count;
365-
if (acnt + mcnt > 0)
361+
bool hasFileColumn = false;
362+
foreach (var col in Columns)
363+
if (col.ColumnType == FieldType.file) hasFileColumn = true;
364+
if (acnt + mcnt > 5 && !hasFileColumn) // if greater than 5 and no file-type columns involved, use csv upload method for reducing API calls
366365
{
367366
List<String> csvLines = new List<string>(acnt + mcnt);
368367
String clist = String.Join(".", KeyFID == -1 ? Columns.Where(col => (col.ColumnVirtual == false && col.ColumnLookup == false) || col.ColumnName == "Record ID#").Select(col => col.ColumnId.ToString())
@@ -387,13 +386,20 @@ public void AcceptChanges()
387386
foreach (IQRecord rec in addList)
388387
{
389388
xNodes.MoveNext();
390-
((IQRecord_int)rec).ForceUpdateState(Int32.Parse(xNodes.Current.Value));
389+
((IQRecord_int)rec).ForceUpdateState(Int32.Parse(xNodes.Current.Value)); //set in-memory recordid to new server value
391390
}
392391
foreach (IQRecord rec in modList)
393392
{
394393
((IQRecord_int)rec).ForceUpdateState();
395394
}
396395
}
396+
else
397+
{
398+
foreach (IQRecord rec in addList)
399+
rec.AcceptChanges();
400+
foreach (IQRecord rec in modList)
401+
rec.AcceptChanges();
402+
}
397403
}
398404

399405
public IQRecord NewRecord()
@@ -414,7 +420,6 @@ internal void Load()
414420

415421
private void LoadRecords(XPathNavigator xml)
416422
{
417-
Records.Clear();
418423
var recordNodes = xml.Select("/qdbapi/table/records/record");
419424
foreach (XPathNavigator recordNode in recordNodes)
420425
{

Intuit.QuickBase.Core/DoQuery.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ private DoQuery(Builder builder)
131131
_uri = new QUriDbid(builder.AccountDomain, builder.Dbid);
132132
}
133133

134+
internal string Options
135+
{
136+
get { return (DoQueryPayload)_doQueryPayload.Options; }
137+
}
138+
134139
public string XmlPayload
135140
{
136141
get

Intuit.QuickBase.Core/Field.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public string Value
5050
{
5151
get
5252
{
53-
return EncodeSpecialCharacters(_value);
53+
return _value;
5454
}
5555
private set
5656
{
@@ -73,15 +73,5 @@ public string File
7373
_file = value;
7474
}
7575
}
76-
77-
private static string EncodeSpecialCharacters(string strLine)
78-
{
79-
strLine = Regex.Replace(strLine, "&(?!amp;)", "&amp;");
80-
strLine = Regex.Replace(strLine, "<", "&lt;");
81-
strLine = Regex.Replace(strLine, ">", "&gt;");
82-
strLine = Regex.Replace(strLine, "\"", "&quot;");
83-
strLine = Regex.Replace(strLine, "'", "&apos;");
84-
return strLine;
85-
}
8676
}
8777
}

Intuit.QuickBase.Core/Http.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ internal void GetFile(DownloadFile downloadFile)
4747
BinaryReader br = null;
4848
BinaryWriter bw = null;
4949
WebResponse response = null;
50-
Stream responseStream = null;
51-
50+
5251
try
5352
{
5453
// Request
@@ -63,7 +62,7 @@ internal void GetFile(DownloadFile downloadFile)
6362

6463
// Response
6564
response = request.GetResponse();
66-
responseStream = response.GetResponseStream();
65+
var responseStream = response.GetResponseStream();
6766

6867
// Write file
6968
if (!Directory.Exists(downloadFile.Path))
@@ -79,7 +78,6 @@ internal void GetFile(DownloadFile downloadFile)
7978
{
8079
if (bw != null) bw.Close();
8180
if (br != null) br.Close();
82-
if (responseStream != null) responseStream.Close();
8381
if (response != null) response.Close();
8482
}
8583
}

Intuit.QuickBase.Core/Intuit.QuickBase.Core.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
<DefineConstants>DEBUG;TRACE</DefineConstants>
3333
<ErrorReport>prompt</ErrorReport>
3434
<WarningLevel>4</WarningLevel>
35+
<RunCodeAnalysis>true</RunCodeAnalysis>
36+
<CodeAnalysisRuleSet>Intuit.QuickBase.Core.ruleset</CodeAnalysisRuleSet>
3537
</PropertyGroup>
3638
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
3739
<DebugType>pdbonly</DebugType>
@@ -40,6 +42,7 @@
4042
<DefineConstants>TRACE</DefineConstants>
4143
<ErrorReport>prompt</ErrorReport>
4244
<WarningLevel>4</WarningLevel>
45+
<CodeAnalysisRuleSet>Intuit.QuickBase.Core.ruleset</CodeAnalysisRuleSet>
4346
</PropertyGroup>
4447
<ItemGroup>
4548
<Reference Include="System" />
@@ -211,6 +214,9 @@
211214
<Compile Include="Uri\QUriMain.cs" />
212215
<Compile Include="UserRoles.cs" />
213216
</ItemGroup>
217+
<ItemGroup>
218+
<None Include="Intuit.QuickBase.Core.ruleset" />
219+
</ItemGroup>
214220
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
215221
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
216222
Other similar extension points exist, see Microsoft.Common.targets.

Intuit.QuickBase.Core/Payload/AddFieldPayload.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88
using System;
99
using System.Text;
10+
using System.Xml.Linq;
1011

1112
namespace Intuit.QuickBase.Core.Payload
1213
{
@@ -44,8 +45,9 @@ private string Label
4445
internal override string GetXmlPayload()
4546
{
4647
var sb = new StringBuilder();
47-
sb.Append(String.Format("<label>{0}</label><type>{1}</type>", Label, Type));
48-
sb.Append(Mode != Mode.none ? String.Format("<mode>{0}</mode>", Mode) : String.Empty);
48+
sb.Append(new XElement("label", Label));
49+
sb.Append(new XElement("type", Type));
50+
if (Mode != Mode.none) sb.Append(new XElement("mode", Mode));
4951
return sb.ToString();
5052
}
5153
}

Intuit.QuickBase.Core/Payload/AddRecordPayload.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Collections.Generic;
1010
using System.IO;
1111
using System.Text;
12+
using System.Xml.Linq;
1213

1314
namespace Intuit.QuickBase.Core.Payload
1415
{
@@ -61,19 +62,20 @@ internal override string GetXmlPayload()
6162
{
6263
if (field.Type == FieldType.file)
6364
{
64-
sb.Append(String.Format(
65-
"<field fid=\"{0}\" filename=\"{1}\">{2}</field>",
66-
field.Fid, field.Value, EncodeFile(field.File)));
65+
XElement xelm = new XElement("field", EncodeFile(field.File));
66+
xelm.SetAttributeValue("fid", field.Fid);
67+
xelm.SetAttributeValue("filename", field.Value);
68+
sb.Append(xelm);
6769
}
6870
else
6971
{
70-
sb.Append(String.Format(
71-
"<field fid=\"{0}\">{1}</field>",
72-
field.Fid, field.Value));
72+
XElement xelm = new XElement("field", field.Value);
73+
xelm.SetAttributeValue("fid", field.Fid);
74+
sb.Append(xelm);
7375
}
7476
}
75-
sb.Append(_disprec ? "<disprec/>" : String.Empty);
76-
sb.Append(_fform ? "<fform/>" : String.Empty);
77+
if (_disprec) sb.Append(new XElement("disprec"));
78+
if (_fform) sb.Append(new XElement("fform"));
7779
return sb.ToString();
7880
}
7981

0 commit comments

Comments
 (0)