Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit e5b7ebb

Browse files
committed
Merge branch 'master' of github.com:ServiceStack/ServiceStack.OrmLite
2 parents 256a5af + 779d19e commit e5b7ebb

File tree

8 files changed

+125
-29
lines changed

8 files changed

+125
-29
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "coreclr",
77
"request": "launch",
88
"preLaunchTask": "build",
9-
"program": "${workspaceRoot}/tests/ServiceStack.OrmLite.Tests/bin/Debug/netcoreapp1.0/ServiceStack.OrmLite.Tests.dll",
9+
"program": "${workspaceRoot}/tests/ServiceStack.OrmLite.Tests/bin/Debug/netcoreapp1.1/ServiceStack.OrmLite.Tests.dll",
1010
"args": ["--test=ServiceStack.OrmLite.Tests._TypeDescriptorMetadataTests.Can_add_AutoIncrement_Id_at_runtime"],
1111
"cwd": "${workspaceRoot}",
1212
"stopAtEntry": false,

src/ServiceStack.OrmLite.MySql/MySqlDialectProvider.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,32 +224,32 @@ protected MySqlDataReader Unwrap(IDataReader reader)
224224
}
225225

226226
#if ASYNC
227-
public override Task OpenAsync(IDbConnection db, CancellationToken token)
227+
public override Task OpenAsync(IDbConnection db, CancellationToken token = default(CancellationToken))
228228
{
229229
return Unwrap(db).OpenAsync(token);
230230
}
231231

232-
public override Task<IDataReader> ExecuteReaderAsync(IDbCommand cmd, CancellationToken token)
232+
public override Task<IDataReader> ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
233233
{
234234
return Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x);
235235
}
236236

237-
public override Task<int> ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token)
237+
public override Task<int> ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
238238
{
239239
return Unwrap(cmd).ExecuteNonQueryAsync(token);
240240
}
241241

242-
public override Task<object> ExecuteScalarAsync(IDbCommand cmd, CancellationToken token)
242+
public override Task<object> ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
243243
{
244244
return Unwrap(cmd).ExecuteScalarAsync(token);
245245
}
246246

247-
public override Task<bool> ReadAsync(IDataReader reader, CancellationToken token)
247+
public override Task<bool> ReadAsync(IDataReader reader, CancellationToken token = default(CancellationToken))
248248
{
249249
return Unwrap(reader).ReadAsync(token);
250250
}
251251

252-
public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn, CancellationToken token)
252+
public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn, CancellationToken token = default(CancellationToken))
253253
{
254254
try
255255
{
@@ -267,7 +267,7 @@ public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn
267267
}
268268
}
269269

270-
public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action fn, Return source, CancellationToken token)
270+
public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action fn, Return source, CancellationToken token = default(CancellationToken))
271271
{
272272
try
273273
{
@@ -283,7 +283,7 @@ public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action
283283
}
284284
}
285285

286-
public override async Task<T> ReaderRead<T>(IDataReader reader, Func<T> fn, CancellationToken token)
286+
public override async Task<T> ReaderRead<T>(IDataReader reader, Func<T> fn, CancellationToken token = default(CancellationToken))
287287
{
288288
try
289289
{

src/ServiceStack.OrmLite.PostgreSQL/PostgreSQLDialectProvider.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -334,32 +334,32 @@ protected NpgsqlDataReader Unwrap(IDataReader reader)
334334
}
335335

336336
#if ASYNC
337-
public override Task OpenAsync(IDbConnection db, CancellationToken token)
337+
public override Task OpenAsync(IDbConnection db, CancellationToken token = default(CancellationToken))
338338
{
339339
return Unwrap(db).OpenAsync(token);
340340
}
341341

342-
public override Task<IDataReader> ExecuteReaderAsync(IDbCommand cmd, CancellationToken token)
342+
public override Task<IDataReader> ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
343343
{
344344
return Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x);
345345
}
346346

347-
public override Task<int> ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token)
347+
public override Task<int> ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
348348
{
349349
return Unwrap(cmd).ExecuteNonQueryAsync(token);
350350
}
351351

352-
public override Task<object> ExecuteScalarAsync(IDbCommand cmd, CancellationToken token)
352+
public override Task<object> ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
353353
{
354354
return Unwrap(cmd).ExecuteScalarAsync(token);
355355
}
356356

357-
public override Task<bool> ReadAsync(IDataReader reader, CancellationToken token)
357+
public override Task<bool> ReadAsync(IDataReader reader, CancellationToken token = default(CancellationToken))
358358
{
359359
return Unwrap(reader).ReadAsync(token);
360360
}
361361

362-
public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn, CancellationToken token)
362+
public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn, CancellationToken token = default(CancellationToken))
363363
{
364364
try
365365
{
@@ -377,7 +377,7 @@ public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn
377377
}
378378
}
379379

380-
public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action fn, Return source, CancellationToken token)
380+
public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action fn, Return source, CancellationToken token = default(CancellationToken))
381381
{
382382
try
383383
{
@@ -393,7 +393,7 @@ public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action
393393
}
394394
}
395395

396-
public override async Task<T> ReaderRead<T>(IDataReader reader, Func<T> fn, CancellationToken token)
396+
public override async Task<T> ReaderRead<T>(IDataReader reader, Func<T> fn, CancellationToken token = default(CancellationToken))
397397
{
398398
try
399399
{

src/ServiceStack.OrmLite.SqlServer/SqlServerOrmLiteDialectProvider.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,17 +362,22 @@ public override string GetLoadChildrenSubSelect<From>(SqlExpression<From> expr)
362362
protected SqlDataReader Unwrap(IDataReader reader) => (SqlDataReader)reader;
363363

364364
#if ASYNC
365-
public override Task OpenAsync(IDbConnection db, CancellationToken token) => Unwrap(db).OpenAsync(token);
365+
public override Task OpenAsync(IDbConnection db, CancellationToken token = default(CancellationToken))
366+
=> Unwrap(db).OpenAsync(token);
366367

367-
public override Task<IDataReader> ExecuteReaderAsync(IDbCommand cmd, CancellationToken token) => Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x);
368+
public override Task<IDataReader> ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
369+
=> Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x);
368370

369-
public override Task<int> ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token) => Unwrap(cmd).ExecuteNonQueryAsync(token);
371+
public override Task<int> ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
372+
=> Unwrap(cmd).ExecuteNonQueryAsync(token);
370373

371-
public override Task<object> ExecuteScalarAsync(IDbCommand cmd, CancellationToken token) => Unwrap(cmd).ExecuteScalarAsync(token);
374+
public override Task<object> ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default(CancellationToken))
375+
=> Unwrap(cmd).ExecuteScalarAsync(token);
372376

373-
public override Task<bool> ReadAsync(IDataReader reader, CancellationToken token) => Unwrap(reader).ReadAsync(token);
377+
public override Task<bool> ReadAsync(IDataReader reader, CancellationToken token = default(CancellationToken))
378+
=> Unwrap(reader).ReadAsync(token);
374379

375-
public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn, CancellationToken token)
380+
public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn, CancellationToken token = default(CancellationToken))
376381
{
377382
try
378383
{
@@ -390,7 +395,7 @@ public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn
390395
}
391396
}
392397

393-
public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action fn, Return source, CancellationToken token)
398+
public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action fn, Return source, CancellationToken token = default(CancellationToken))
394399
{
395400
try
396401
{
@@ -406,7 +411,7 @@ public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action
406411
}
407412
}
408413

409-
public override async Task<T> ReaderRead<T>(IDataReader reader, Func<T> fn, CancellationToken token)
414+
public override async Task<T> ReaderRead<T>(IDataReader reader, Func<T> fn, CancellationToken token = default(CancellationToken))
410415
{
411416
try
412417
{
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Data;
5+
6+
namespace ServiceStack.OrmLite
7+
{
8+
public class IndexFieldsCacheKey
9+
{
10+
int hashCode;
11+
12+
public ModelDefinition ModelDefinition { get; private set; }
13+
14+
public IOrmLiteDialectProvider Dialect { get; private set; }
15+
16+
public List<string> Fields { get; private set; }
17+
18+
public IndexFieldsCacheKey(IDataReader reader, ModelDefinition modelDefinition, IOrmLiteDialectProvider dialect)
19+
{
20+
ModelDefinition = modelDefinition;
21+
Dialect = dialect;
22+
23+
int startPos = 0;
24+
int endPos = reader.FieldCount;
25+
26+
Fields = new List<string>(endPos - startPos);
27+
28+
for (int i = startPos; i < endPos; i++)
29+
Fields.Add(reader.GetName(i));
30+
31+
unchecked
32+
{
33+
hashCode = 17;
34+
hashCode = hashCode * 23 + ModelDefinition.GetHashCode();
35+
hashCode = hashCode * 23 + Dialect.GetHashCode();
36+
hashCode = hashCode * 23 + Fields.Count;
37+
for (int i = 0; i < Fields.Count; i++)
38+
hashCode = hashCode * 23 + Fields[i].Length;
39+
}
40+
}
41+
42+
public override bool Equals (object obj)
43+
{
44+
var that = obj as IndexFieldsCacheKey;
45+
46+
if (obj == null) return false;
47+
48+
return this.ModelDefinition == that.ModelDefinition
49+
&& this.Dialect == that.Dialect
50+
&& this.Fields.Count == that.Fields.Count
51+
&& this.Fields.SequenceEqual(that.Fields);
52+
}
53+
54+
public override int GetHashCode()
55+
{
56+
return hashCode;
57+
}
58+
}
59+
}

src/ServiceStack.OrmLite/OrmLiteUtils.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ public static class OrmLiteUtils
3131
{
3232
internal const string AsyncRequiresNet45Error = "Async support is only available in .NET 4.5 builds";
3333

34+
const int maxCachedIndexFields = 10000;
35+
private static Dictionary<IndexFieldsCacheKey, Tuple<FieldDefinition, int, IOrmLiteConverter>[]> indexFieldsCache
36+
= new Dictionary<IndexFieldsCacheKey, Tuple<FieldDefinition, int, IOrmLiteConverter>[]>(maxCachedIndexFields);
37+
3438
public static void DebugCommand(this ILog log, IDbCommand cmd)
3539
{
3640
var sb = StringBuilderCache.Allocate();
@@ -160,7 +164,7 @@ public static List<T> ConvertToList<T>(this IDataReader reader, IOrmLiteDialectP
160164
}
161165
return (List<T>)(object)to.ToList();
162166
}
163-
if (typeof(T).Name.StartsWith("Tuple`"))
167+
if (typeof(T).Name.StartsWith("Tuple`", StringComparison.Ordinal))
164168
{
165169
var to = new List<T>();
166170
using (reader)
@@ -491,12 +495,25 @@ public static Tuple<FieldDefinition, int, IOrmLiteConverter>[] GetIndexFieldsCac
491495
int startPos=0,
492496
int? endPos = null)
493497
{
498+
var end = endPos.GetValueOrDefault(reader.FieldCount);
499+
var cacheKey = (startPos == 0 && end == reader.FieldCount && onlyFields == null)
500+
? new IndexFieldsCacheKey(reader, modelDefinition, dialect)
501+
: null;
502+
503+
if (cacheKey != null)
504+
{
505+
lock (indexFieldsCache)
506+
{
507+
if (indexFieldsCache.ContainsKey(cacheKey))
508+
return indexFieldsCache[cacheKey];
509+
}
510+
}
511+
494512
var cache = new List<Tuple<FieldDefinition, int, IOrmLiteConverter>>();
495513
var ignoredFields = modelDefinition.IgnoredFieldDefinitions;
496514
var remainingFieldDefs = modelDefinition.FieldDefinitionsArray
497515
.Where(x => !ignoredFields.Contains(x) && x.SetValueFn != null).ToList();
498516

499-
var end = endPos.GetValueOrDefault(reader.FieldCount);
500517
var mappedReaderColumns = new bool[end];
501518

502519
for (var i = startPos; i < end; i++)
@@ -549,7 +566,20 @@ public static Tuple<FieldDefinition, int, IOrmLiteConverter>[] GetIndexFieldsCac
549566
}
550567
}
551568

552-
return cache.ToArray();
569+
var result = cache.ToArray();
570+
571+
if (cacheKey != null)
572+
{
573+
lock(indexFieldsCache)
574+
{
575+
if (indexFieldsCache.ContainsKey(cacheKey))
576+
return indexFieldsCache[cacheKey];
577+
else if (indexFieldsCache.Count < maxCachedIndexFields)
578+
indexFieldsCache.Add(cacheKey, result);
579+
}
580+
}
581+
582+
return result;
553583
}
554584

555585
private const int NotFound = -1;

src/ServiceStack.OrmLite/ServiceStack.OrmLite.Signed.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@
249249
<Compile Include="Support\LoadList.cs" />
250250
<Compile Include="Support\LoadReferences.cs" />
251251
<Compile Include="UntypedApi.cs" />
252+
<Compile Include="IndexFieldsCacheKey.cs" />
252253
</ItemGroup>
253254
<ItemGroup>
254255
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">

src/ServiceStack.OrmLite/ServiceStack.OrmLite.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@
243243
<Compile Include="Support\LoadList.cs" />
244244
<Compile Include="Support\LoadReferences.cs" />
245245
<Compile Include="UntypedApi.cs" />
246-
</ItemGroup>
246+
<Compile Include="IndexFieldsCacheKey.cs" />
247+
</ItemGroup>
247248
<ItemGroup>
248249
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
249250
<Visible>False</Visible>

0 commit comments

Comments
 (0)