Skip to content

Commit b7c26b7

Browse files
committed
Support deferral and fetch of schema during
1 parent d8020da commit b7c26b7

5 files changed

Lines changed: 177 additions & 34 deletions

File tree

DataSource.DataProviders.OData/ODataSampleApp/MainWindow.xaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
>
1818

1919
<grid:XGrid.Columns>
20-
<grid:TextColumn Key="CustomerID" HeaderText="Customer ID" />
21-
<grid:TextColumn Key="ShipName" HeaderText="Ship Name" />
22-
<grid:NumericColumn Key="OrderID" HeaderText="Order ID" />
23-
<grid:TextColumn Key="ShipCountry" HeaderText="Ship Country" />
20+
<grid:TextColumn Key="CustomerID" Title="Customer ID" />
21+
<grid:TextColumn Key="ShipName" Title="Ship Name" />
22+
<grid:NumericColumn Key="OrderID" Title="Order ID" />
23+
<grid:TextColumn Key="ShipCountry" Title="Ship Country" />
2424
</grid:XGrid.Columns>
2525
</grid:XGrid>
2626
</Grid>

DataSource.DataProviders.OData/ODataSampleApp/MainWindow.xaml.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public MainWindow()
3333
EntitySet = "Orders",
3434
DesiredPageSize = 200
3535
};
36+
source.ShouldDeferAutoRefresh = true;
37+
source.SchemaChanged += Source_SchemaChanged;
3638

3739
source.SortDescriptions.Add(new SortDescription("ShipName", ListSortDirection.Descending));
3840

@@ -44,6 +46,19 @@ public MainWindow()
4446
}));
4547

4648
grid1.ItemsSource = source;
49+
50+
Task.Delay(10000).ContinueWith((t) =>
51+
{
52+
Dispatcher.BeginInvoke(new Action(() =>
53+
{
54+
source.ShouldDeferAutoRefresh = false;
55+
}));
56+
});
57+
}
58+
59+
private void Source_SchemaChanged(object sender, DataSourceSchemaChangedEventArgs args)
60+
{
61+
System.Diagnostics.Debug.WriteLine("schema fetched: " + args.Count);
4762
}
4863
}
4964
}

ODataDataProvider/ODataDataSourcePage.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@ public class ODataDataSourcePage
2727

2828
public ODataDataSourcePage(IEnumerable<IDictionary<string, object>> sourceData, IDataSourceSchema schema, int pageIndex)
2929
{
30-
_actualData = sourceData.ToArray();
30+
if (sourceData == null)
31+
{
32+
_actualData = null;
33+
}
34+
else
35+
{
36+
_actualData = sourceData.ToArray();
37+
}
3138
_schema = schema;
3239
_pageIndex = pageIndex;
3340
}

ODataDataProvider/ODataVirtualDataSourceDataProvider.cs

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ private void SortDescriptions_CollectionChanged(object sender, System.Collection
4444

4545
public void AddPageRequest(int pageIndex, DataSourcePageRequestPriority priority)
4646
{
47+
if (ShouldDeferAutoRefresh)
48+
{
49+
return;
50+
}
51+
4752
if (_worker != null && _worker.IsShutdown)
4853
{
4954
_worker = null;
@@ -84,7 +89,6 @@ private void CreateWorker()
8489

8590
_worker = new ODataVirtualDataSourceDataProviderWorker(
8691
settings);
87-
_worker.AddPageRequest(0, DataSourcePageRequestPriority.Normal);
8892
}
8993

9094
private bool Valid()
@@ -172,7 +176,11 @@ private void RaisePageLoaded(IDataSourcePage page, int fullCount, int actualPage
172176
SchemaChanged(this, new DataSourceDataProviderSchemaChangedEventArgs(_currentSchema, _currentFullCount));
173177
}
174178
}
175-
_pageLoaded(page, fullCount, actualPageSize);
179+
180+
if (page.PageIndex() != ODataVirtualDataSourceDataProviderWorker.SchemaRequestIndex)
181+
{
182+
_pageLoaded(page, fullCount, actualPageSize);
183+
}
176184
}
177185
}
178186

@@ -209,8 +217,16 @@ public string BaseUri
209217
}
210218
set
211219
{
220+
var oldValue = _baseUri;
212221
_baseUri = value;
213-
QueueAutoRefresh();
222+
if (oldValue != _baseUri)
223+
{
224+
QueueAutoRefresh();
225+
if (Valid() && ShouldDeferAutoRefresh)
226+
{
227+
QueueSchemaFetch();
228+
}
229+
}
214230
}
215231
}
216232

@@ -223,8 +239,16 @@ public string EntitySet
223239
}
224240
set
225241
{
242+
var oldValue = _entitySet;
226243
_entitySet = value;
227-
QueueAutoRefresh();
244+
if (oldValue != _entitySet)
245+
{
246+
QueueAutoRefresh();
247+
if (Valid() && ShouldDeferAutoRefresh)
248+
{
249+
QueueSchemaFetch();
250+
}
251+
}
228252
}
229253
}
230254

@@ -311,6 +335,10 @@ public bool ShouldDeferAutoRefresh
311335
{
312336
QueueAutoRefresh();
313337
}
338+
if (_shouldDeferAutoRefresh && Valid() && _currentSchema == null)
339+
{
340+
QueueSchemaFetch();
341+
}
314342
}
315343
}
316344

@@ -418,6 +446,57 @@ public void NotifyRemoveItem(int index, object oldItem)
418446
}
419447
}
420448

449+
internal bool _schemaFetchQueued = false;
450+
public void QueueSchemaFetch()
451+
{
452+
if (_schemaFetchQueued)
453+
{
454+
return;
455+
}
456+
457+
if (ExecutionContext != null)
458+
{
459+
_schemaFetchQueued = true;
460+
ExecutionContext.EnqueueAction(DoSchemaFetchInternal);
461+
}
462+
}
463+
464+
internal void DoSchemaFetchInternal()
465+
{
466+
if (!_schemaFetchQueued)
467+
{
468+
return;
469+
}
470+
_schemaFetchQueued = false;
471+
SchemaFetchInternal();
472+
}
473+
474+
internal void SchemaFetchInternal()
475+
{
476+
SchemaFetchInternalOverride();
477+
}
478+
479+
protected virtual void SchemaFetchInternalOverride()
480+
{
481+
if (!ShouldDeferAutoRefresh)
482+
{
483+
return;
484+
}
485+
RemoveAllPageRequests();
486+
KillWorker();
487+
CreateWorker();
488+
489+
AddSchemaRequest();
490+
}
491+
492+
private void AddSchemaRequest()
493+
{
494+
_worker.AddPageRequest(
495+
ODataVirtualDataSourceDataProviderWorker.SchemaRequestIndex,
496+
DataSourcePageRequestPriority.High
497+
);
498+
}
499+
421500
internal bool _autoRefreshQueued = false;
422501
public void QueueAutoRefresh()
423502
{
@@ -441,6 +520,7 @@ internal void DoRefreshInternal()
441520
{
442521
if (ShouldDeferAutoRefresh)
443522
{
523+
_autoRefreshQueued = false;
444524
return;
445525
}
446526
if (!_autoRefreshQueued)
@@ -461,6 +541,8 @@ protected virtual void RefreshInternalOverride()
461541
RemoveAllPageRequests();
462542
KillWorker();
463543
CreateWorker();
544+
//TODO: should we have this here? prob need to readd request for current page instead.
545+
_worker.AddPageRequest(0, DataSourcePageRequestPriority.Normal);
464546
}
465547

466548
public void FlushAutoRefresh()

ODataDataProvider/ODataVirtualDataSourceDataProviderWorker.cs

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,23 @@ protected override void ProcessCompletedTask(AsyncDataSourcePageTaskHolder compl
131131
{
132132
ODataVirtualDataSourceProviderTaskDataHolder h = (ODataVirtualDataSourceProviderTaskDataHolder)taskDataHolder;
133133
IDataSourceSchema schema = null;
134-
IEnumerable<IDictionary<string, object>> result;
135-
Task<IEnumerable<IDictionary<string, object>>> task = (Task<IEnumerable<IDictionary<string, object>>>)completedTask.Task;
134+
IEnumerable<IDictionary<string, object>> result = null;
135+
int schemaFetchCount = -1;
136+
136137
try
137138
{
138-
result = task.Result;
139+
if (pageIndex == SchemaRequestIndex)
140+
{
141+
Task<int> task = (Task<int>)completedTask.Task;
142+
143+
schemaFetchCount = task.Result;
144+
}
145+
else
146+
{
147+
Task<IEnumerable<IDictionary<string, object>>> task = (Task<IEnumerable<IDictionary<string, object>>>)completedTask.Task;
148+
149+
result = task.Result;
150+
}
139151
}
140152
catch (AggregateException e)
141153
{
@@ -169,31 +181,52 @@ protected override void ProcessCompletedTask(AsyncDataSourcePageTaskHolder compl
169181
DataSourcePageLoadedCallback pageLoaded;
170182
lock (SyncLock)
171183
{
172-
var completedAnnotation = h.CompletedAnnotation;
173-
if (completedAnnotation.Count.HasValue)
184+
if (schemaFetchCount >= 0)
174185
{
175-
ActualCount = (int)completedAnnotation.Count.Value;
186+
ActualCount = schemaFetchCount;
176187
}
177-
178-
schema = ActualSchema;
179-
if (schema == null)
188+
else
180189
{
181-
schema = ResolveSchema(result.FirstOrDefault());
190+
var completedAnnotation = h.CompletedAnnotation;
191+
if (completedAnnotation.Count.HasValue)
192+
{
193+
ActualCount = (int)completedAnnotation.Count.Value;
194+
}
182195
}
196+
197+
schema = ActualSchema;
198+
}
199+
200+
if (schema == null)
201+
{
202+
schema = ResolveSchema();
203+
}
204+
205+
lock (SyncLock)
206+
{
183207
ActualSchema = schema;
184208
executionContext = ExecutionContext;
185209
pageLoaded = PageLoaded;
186210
}
187211

188-
ODataDataSourcePage page = new ODataDataSourcePage(result, schema, pageIndex);
189-
lock (SyncLock)
212+
ODataDataSourcePage page = null;
213+
214+
if (result != null)
190215
{
191-
if (!IsLastPage(pageIndex) && page.Count() > 0 && !PopulatedActualPageSize)
216+
page = new ODataDataSourcePage(result, schema, pageIndex);
217+
lock (SyncLock)
192218
{
193-
PopulatedActualPageSize = true;
194-
ActualPageSize = page.Count();
219+
if (!IsLastPage(pageIndex) && page.Count() > 0 && !PopulatedActualPageSize)
220+
{
221+
PopulatedActualPageSize = true;
222+
ActualPageSize = page.Count();
223+
}
195224
}
196225
}
226+
else
227+
{
228+
page = new ODataDataSourcePage(null, schema, pageIndex);
229+
}
197230

198231
if (PageLoaded != null)
199232
{
@@ -225,13 +258,8 @@ protected override void ProcessCompletedTask(AsyncDataSourcePageTaskHolder compl
225258

226259

227260

228-
private IDataSourceSchema ResolveSchema(IDictionary<string, object> item)
261+
private IDataSourceSchema ResolveSchema()
229262
{
230-
if (item == null)
231-
{
232-
return null;
233-
}
234-
235263
var t = this._client.GetMetadataDocumentAsync();
236264
t.Wait();
237265
var metadataDocument = t.Result;
@@ -241,6 +269,7 @@ private IDataSourceSchema ResolveSchema(IDictionary<string, object> item)
241269

242270
private string _filterString = null;
243271
private string _selectedString = null;
272+
public const int SchemaRequestIndex = -1;
244273

245274
protected override void MakeTaskForRequest(AsyncDataSourcePageRequest request, int retryDelay)
246275
{
@@ -315,10 +344,20 @@ protected override void MakeTaskForRequest(AsyncDataSourcePageRequest request, i
315344
}
316345
}
317346

318-
Task<IEnumerable<IDictionary<string, object>>> task = client
319-
.Skip(request.Index * actualPageSize)
320-
.Top(actualPageSize)
321-
.FindEntriesAsync(annotations);
347+
Task task;
348+
if (request.Index == SchemaRequestIndex)
349+
{
350+
task = client
351+
.Count()
352+
.FindScalarAsync<int>();
353+
}
354+
else
355+
{
356+
task = client
357+
.Skip(request.Index * actualPageSize)
358+
.Top(actualPageSize)
359+
.FindEntriesAsync(annotations);
360+
}
322361

323362
request.TaskHolder = new AsyncDataSourcePageTaskHolder();
324363
request.TaskHolder.Task = task;

0 commit comments

Comments
 (0)