Skip to content

Commit d3e57aa

Browse files
committed
Support detecting primary key from SQLite, support some join scenarios.
1 parent 3d6c2c3 commit d3e57aa

3 files changed

Lines changed: 120 additions & 31 deletions

File tree

DataSource.DataProviders.SQLite/SQLiteDataProvider/SQLiteDataSourceFilterExpressionVisitor.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Text;
3+
using SQLite;
34

45
#if !PORTABLE
56
using System.Runtime.CompilerServices;
@@ -136,12 +137,14 @@ public class SQLiteDataSourceFilterExpressionVisitor
136137
{
137138
private StringBuilder _sb;
138139
private ISQLiteLiteralEmitter _literalEmitter;
140+
private TableMapping _mappings;
139141

140-
/// <summary>
141-
/// Constructs an SQLiteDataSourceFilterExpressionVisitor.
142-
/// </summary>
143-
public SQLiteDataSourceFilterExpressionVisitor()
142+
/// <summary>
143+
/// Constructs an SQLiteDataSourceFilterExpressionVisitor.
144+
/// </summary>
145+
public SQLiteDataSourceFilterExpressionVisitor(TableMapping mappings)
144146
{
147+
_mappings = mappings;
145148
_literalEmitter = new DefaultSQLiteLiteralEmitter();
146149
_sb = new StringBuilder();
147150
}
@@ -150,8 +153,8 @@ public SQLiteDataSourceFilterExpressionVisitor()
150153
/// Constructs an SQLiteDataSourceFilterExpressionVisitor providing an alternative literal emitter.
151154
/// </summary>
152155
/// <param name="literalEmitter">An alternative literal emitter to use.</param>
153-
public SQLiteDataSourceFilterExpressionVisitor(ISQLiteLiteralEmitter literalEmitter)
154-
: this()
156+
public SQLiteDataSourceFilterExpressionVisitor(TableMapping mappings, ISQLiteLiteralEmitter literalEmitter)
157+
: this(mappings)
155158
{
156159
_literalEmitter = literalEmitter;
157160
}
@@ -423,7 +426,15 @@ public override void VisitPropertyReferenceExpression(PropertyReferenceFilterExp
423426

424427
private void RenderPropertyReference(string propertyReference)
425428
{
426-
_sb.Append(propertyReference);
429+
var col = _mappings.FindColumnWithPropertyName(propertyReference);
430+
if (col != null)
431+
{
432+
_sb.Append(col.Name);
433+
}
434+
else
435+
{
436+
_sb.Append(propertyReference);
437+
}
427438
}
428439
}
429440

DataSource.DataProviders.SQLite/SQLiteDataProvider/SQLiteVirtualDataSourceDataProvider.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Threading.Tasks;
99
using System.Diagnostics;
1010
using SQLite;
11+
using System.Reflection;
1112
#if !PCL
1213
using Infragistics.Controls.DataSource;
1314
#endif
@@ -324,17 +325,25 @@ public int TimeoutMilliseconds
324325
}
325326
}
326327

328+
Dictionary<string, PropertyInfo> _getters = new Dictionary<string, PropertyInfo>();
329+
327330
public object GetItemValue(object item, string valueName)
328331
{
329-
var dic = (IDictionary<string, object>)item;
330-
if (dic.ContainsKey(valueName))
332+
PropertyInfo getter;
333+
if (!_getters.TryGetValue(valueName, out getter))
331334
{
332-
return dic[valueName];
335+
getter = item.GetType().GetTypeInfo().GetDeclaredProperty(valueName);
336+
if (getter != null)
337+
{
338+
_getters.Add(valueName, getter);
339+
}
333340
}
334-
else
341+
if (getter == null)
335342
{
336-
return null;
343+
return null;
337344
}
345+
346+
return getter.GetValue(item);
338347
}
339348

340349
public event DataSourceDataProviderSchemaChangedHandler SchemaChanged;

DataSource.DataProviders.SQLite/SQLiteDataProvider/SQLiteVirtualDataSourceDataProviderWorker.cs

Lines changed: 88 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using SQLite;
1616
using System.Collections;
1717
using System.Reflection;
18+
using System.Collections.Concurrent;
1819
#endif
1920

2021
#if DATA_PRESENTER
@@ -38,7 +39,7 @@ internal class SQLiteVirtualDataSourceDataProviderWorkerSettings
3839
public string[] PropertiesRequested { get; set; }
3940
}
4041

41-
42+
4243

4344

4445
internal class SQLiteVirtualDataSourceProviderTaskDataHolder
@@ -47,7 +48,7 @@ internal class SQLiteVirtualDataSourceProviderTaskDataHolder
4748
public int FullCount { get; set; }
4849
}
4950

50-
51+
5152
internal class SQLiteVirtualDataSourceDataProviderWorker
5253
: AsyncVirtualDataSourceProviderWorker
5354
{
@@ -114,8 +115,10 @@ protected override void GetTasksData(AsyncVirtualDataSourceProviderTaskDataHolde
114115
base.GetTasksData(holder);
115116
}
116117

118+
private TableMapping _propertyMappings = null;
119+
117120
public SQLiteVirtualDataSourceDataProviderWorker(SQLiteVirtualDataSourceDataProviderWorkerSettings settings)
118-
:base(settings)
121+
: base(settings)
119122
{
120123
_tableExpression = settings.TableExpression;
121124
_projectionType = settings.ProjectionType;
@@ -124,9 +127,17 @@ public SQLiteVirtualDataSourceDataProviderWorker(SQLiteVirtualDataSourceDataProv
124127
_sortDescriptions = settings.SortDescriptions;
125128
_filterExpressions = settings.FilterExpressions;
126129
_desiredPropeties = settings.PropertiesRequested;
130+
_propertyMappings = ResolvePropertyMappings();
131+
ActualSchema = ResolveSchema();
132+
127133
Task.Factory.StartNew(() => DoWork(), TaskCreationOptions.LongRunning);
128-
}
129-
134+
}
135+
136+
private TableMapping ResolvePropertyMappings()
137+
{
138+
return _connection.GetConnection().GetMapping(_projectionType);
139+
}
140+
130141
protected override void ProcessCompletedTask(AsyncDataSourcePageTaskHolder completedTask, int currentDelay, int pageIndex, AsyncVirtualDataSourceProviderTaskDataHolder taskDataHolder)
131142
{
132143
SQLiteVirtualDataSourceProviderTaskDataHolder h = (SQLiteVirtualDataSourceProviderTaskDataHolder)taskDataHolder;
@@ -147,7 +158,7 @@ protected override void ProcessCompletedTask(AsyncDataSourcePageTaskHolder compl
147158
Task<SQLiteDataSourceQueryResult> task = (Task<SQLiteDataSourceQueryResult>)completedTask.Task;
148159

149160
result = task.Result;
150-
}
161+
}
151162
}
152163
catch (AggregateException e)
153164
{
@@ -199,7 +210,7 @@ protected override void ProcessCompletedTask(AsyncDataSourcePageTaskHolder compl
199210
}
200211

201212
lock (SyncLock)
202-
{
213+
{
203214
ActualSchema = schema;
204215
executionContext = ExecutionContext;
205216
pageLoaded = PageLoaded;
@@ -237,7 +248,7 @@ protected override void ProcessCompletedTask(AsyncDataSourcePageTaskHolder compl
237248
executionContext.Execute(() =>
238249
{
239250
pageLoaded(page, ActualCount, ActualPageSize);
240-
});
251+
});
241252
}
242253
else
243254
{
@@ -267,7 +278,12 @@ private IDataSourceSchema ResolveSchema()
267278

268279

269280
var actualPrimaryKey = schema.PrimaryKey;
270-
//TODO: get primary key;
281+
282+
var pkCol = _propertyMappings.PK;
283+
if (pkCol != null)
284+
{
285+
actualPrimaryKey = new string[1] { pkCol.Name };
286+
}
271287

272288
var actualSchema = new DefaultDataSourceSchema(
273289
schema.PropertyNames, schema.PropertyTypes, actualPrimaryKey, schema.PropertyDataIntents);
@@ -296,7 +312,7 @@ protected override void MakeTaskForRequest(AsyncDataSourcePageRequest request, i
296312

297313
lock (SyncLock)
298314
{
299-
315+
300316
if (_selectedString == null)
301317
{
302318
StringBuilder selectBuilder = new StringBuilder();
@@ -307,15 +323,61 @@ protected override void MakeTaskForRequest(AsyncDataSourcePageRequest request, i
307323
}
308324
else
309325
{
310-
if (DesiredProperties != null && DesiredProperties.Length > 0)
326+
var actualProperties = new List<string>();
327+
var propertySet = new HashSet<string>();
328+
if (DesiredProperties != null)
311329
{
312330
for (var i = 0; i < DesiredProperties.Length; i++)
331+
{
332+
actualProperties.Add(DesiredProperties[i]);
333+
if (!propertySet.Contains(DesiredProperties[i]))
334+
{
335+
propertySet.Add(DesiredProperties[i]);
336+
}
337+
}
338+
string[] pk = null;
339+
if (ActualSchema != null && ActualSchema.PrimaryKey != null &&
340+
ActualSchema.PrimaryKey.Length > 0)
341+
{
342+
pk = ActualSchema.PrimaryKey;
343+
}
344+
if (pk != null)
345+
{
346+
for (var i = 0; i < pk.Length; i++)
347+
{
348+
if (!propertySet.Contains(pk[i]))
349+
{
350+
propertySet.Add(pk[i]);
351+
actualProperties.Add(pk[i]);
352+
}
353+
}
354+
}
355+
}
356+
357+
if (actualProperties.Count > 0)
358+
{
359+
for (var i = 0; i < actualProperties.Count; i++)
313360
{
314361
if (i > 0)
315362
{
316363
selectBuilder.Append(", ");
317364
}
318-
selectBuilder.Append(DesiredProperties[i]);
365+
var col = _propertyMappings.FindColumnWithPropertyName(actualProperties[i]);
366+
if (col != null)
367+
{
368+
if (col.Name.Contains("__"))
369+
{
370+
selectBuilder.Append(col.Name.Replace("__", ".") + " AS " + col.Name);
371+
}
372+
else
373+
{
374+
selectBuilder.Append(col.Name);
375+
}
376+
}
377+
else
378+
{
379+
selectBuilder.Append(actualProperties[i]);
380+
}
319381
}
320382
}
321383
else
@@ -350,7 +412,7 @@ protected override void MakeTaskForRequest(AsyncDataSourcePageRequest request, i
350412
filterBuilder.Append(" AND ");
351413
}
352414

353-
SQLiteDataSourceFilterExpressionVisitor visitor = new SQLiteDataSourceFilterExpressionVisitor();
415+
SQLiteDataSourceFilterExpressionVisitor visitor = new SQLiteDataSourceFilterExpressionVisitor(_propertyMappings);
354416

355417
visitor.Visit(expr);
356418

@@ -385,19 +447,26 @@ protected override void MakeTaskForRequest(AsyncDataSourcePageRequest request, i
385447
sb.Append(", ");
386448
}
387449

450+
var propertyName = sort.PropertyName;
451+
var col = _propertyMappings.FindColumnWithPropertyName(propertyName);
452+
if (col != null)
453+
{
454+
propertyName = col.Name;
455+
}
456+
388457
if (sort.Direction ==
389458
#if PCL
390-
ListSortDirection.Descending
459+
ListSortDirection.Descending
391460
#else
392461
System.ComponentModel.ListSortDirection.Descending
393462
#endif
394-
)
463+
)
395464
{
396-
sb.Append(sort.PropertyName + " DESC");
465+
sb.Append(propertyName + " DESC");
397466
}
398467
else
399468
{
400-
sb.Append(sort.PropertyName + " ASC");
469+
sb.Append(propertyName + " ASC");
401470
}
402471
}
403472
}
@@ -419,7 +488,7 @@ protected override void MakeTaskForRequest(AsyncDataSourcePageRequest request, i
419488
if (_specific == null)
420489
{
421490
var queryAsync = _connection.GetType().GetTypeInfo().GetDeclaredMethod("QueryAsync");
422-
491+
423492
var specific = queryAsync.MakeGenericMethod(_projectionType);
424493
_specific = specific;
425494
}
@@ -442,7 +511,7 @@ private async Task<SQLiteDataSourceQueryResult> GetResult(string query, MethodIn
442511
return await Task.Run(async () =>
443512
{
444513
SQLiteDataSourceQueryResult res = new SQLiteDataSourceQueryResult();
445-
514+
446515
var count = await _connection.ExecuteScalarAsync<int>("SELECT count(*) FROM " + _tableExpression);
447516
res.FullCount = count;
448517

0 commit comments

Comments
 (0)