Skip to content

Commit 8c49fc5

Browse files
committed
Fixing issues with reading result sets larger than 100 rows, and no transaction support in InMemoryAdapter
1 parent 033240b commit 8c49fc5

9 files changed

Lines changed: 188 additions & 5 deletions

File tree

Simple.Data.Ado/BulkUpdater.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ public int Update(AdoAdapter adapter, string tableName, IList<IDictionary<string
3737
using (connection.MaybeDisposable())
3838
using (var command = commandBuilder.GetRepeatableCommand(connection))
3939
{
40+
connection.OpenIfClosed();
4041
var propertyToParameterMap = CreatePropertyToParameterMap(data, table, command);
4142

4243
foreach (var row in data)
4344
{
4445
foreach (var kvp in row)
4546
{
46-
propertyToParameterMap[kvp.Key].Value = kvp.Value ?? DBNull.Value;
47+
if (propertyToParameterMap.ContainsKey(kvp.Key))
48+
{
49+
propertyToParameterMap[kvp.Key].Value = kvp.Value ?? DBNull.Value;
50+
}
4751
}
4852
count += command.ExecuteNonQuery();
4953
}
@@ -65,11 +69,18 @@ private static Dictionary<string, IDbDataParameter> CreatePropertyToParameterMap
6569

6670
private static IDbDataParameter GetDbDataParameter(Table table, IDbCommand command, KeyValuePair<string, object> kvp)
6771
{
68-
return command.Parameters.Cast<IDbDataParameter>().
72+
try
73+
{
74+
return command.Parameters.Cast<IDbDataParameter>().
6975
FirstOrDefault
7076
(p =>
7177
p.SourceColumn ==
7278
table.FindColumn(kvp.Key).ActualName);
79+
}
80+
catch (UnresolvableObjectException)
81+
{
82+
return null;
83+
}
7384
}
7485

7586
private static bool AllRowsHaveSameKeys(IList<IDictionary<string, object>> data)

Simple.Data.Ado/DataReaderEnumerable.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private bool SetCurrent()
110110
_current = _reader.ToDictionary(_index);
111111

112112
// We don't want to cache more than 100 rows, too much memory would be used.
113-
if (_cache.Count < 100)
113+
if (_cache != null && _cache.Count < 100)
114114
{
115115
_cache.Add(_current);
116116
}
@@ -161,7 +161,8 @@ private void CreateIndexIfNecessary()
161161
public void Reset()
162162
{
163163
if (_reader != null) _reader.Dispose();
164-
_cache.Clear();
164+
if (_cache != null)
165+
_cache.Clear();
165166
ExecuteReader();
166167
}
167168

Simple.Data.InMemoryTest/InMemoryTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,5 +525,22 @@ public void TestJoinWithAlias()
525525
Assert.AreEqual(2, orders.Count());
526526
Assert.AreEqual(2, orders.Count(x => x.CustomerName == "ACME"));
527527
}
528+
529+
[Test]
530+
public void InsertAndGetWithTransactionShouldWork()
531+
{
532+
var adapter = new InMemoryAdapter();
533+
adapter.SetKeyColumn("Test", "Id");
534+
Database.UseMockAdapter(adapter);
535+
var db = Database.Open();
536+
using (var tx = db.BeginTransaction())
537+
{
538+
tx.Test.Insert(Id: 1, Name: "Alice");
539+
var record = tx.Test.Get(1);
540+
Assert.IsNotNull(record);
541+
Assert.AreEqual(1, record.Id);
542+
Assert.AreEqual("Alice", record.Name);
543+
}
544+
}
528545
}
529546
}

Simple.Data.SqlTest/QueryTest.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,5 +362,33 @@ public void WithClauseShouldCastToStaticTypeWithCollection()
362362
Assert.AreEqual(1, actual.Orders.Single().OrderId);
363363
Assert.AreEqual(new DateTime(2010,10,10), actual.Orders.Single().OrderDate);
364364
}
365+
366+
[Test]
367+
public void SelfJoinShouldNotThrowException()
368+
{
369+
var db = DatabaseHelper.Open();
370+
371+
var q = db.Employees.Query().LeftJoin(db.Employees.As("Manager"), Id: db.Employees.ManagerId);
372+
q = q.Select(db.Employees.Name, q.Manager.Name.As("Manager"));
373+
List<dynamic> employees = q.ToList();
374+
375+
Assert.AreEqual(3, employees.Count); // The top man is missing
376+
377+
var kingsSubordinates = employees.Where(e => e.Manager == "Alice").ToList();
378+
379+
Assert.AreEqual(1, kingsSubordinates.Count);
380+
}
381+
382+
[Test]
383+
public void CanFetchMoreThanOneHundredRows()
384+
{
385+
var db = DatabaseHelper.Open();
386+
387+
db.Customers.Insert(Enumerable.Range(0, 200).Select(n => new Customer {Name = "Customer " + n}));
388+
389+
List<dynamic> customers = db.Customers.All().ToList();
390+
391+
Assert.GreaterOrEqual(customers.Count, 200);
392+
}
365393
}
366394
}

Simple.Data.SqlTest/Resources/DatabaseReset.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ AS
3434
BEGIN
3535
SET NOCOUNT ON;
3636

37+
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Employee]') AND type in (N'U'))
38+
DROP TABLE [dbo].[Employee];
3739
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Users]') AND type in (N'U'))
3840
DROP TABLE [dbo].[Users];
3941
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[OrderItems]') AND type in (N'U'))
@@ -67,6 +69,13 @@ BEGIN
6769
ALTER TABLE [dbo].[Users]
6870
ADD CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([Id] ASC) WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF);
6971

72+
CREATE TABLE [dbo].[Employee](
73+
[Id] [int] IDENTITY(1,1) NOT NULL,
74+
[Name] [nvarchar](50) NOT NULL,
75+
[ManagerId] [int] NULL)
76+
77+
ALTER TABLE [dbo].[Employee]
78+
ADD CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED ([Id] ASC)
7079

7180
CREATE TABLE [dbo].[Orders] (
7281
[OrderId] INT IDENTITY (1, 1) NOT NULL,
@@ -161,6 +170,11 @@ BEGIN
161170
INSERT INTO [dbo].[Users] ([Id], [Name], [Password], [Age]) VALUES (2,'Charlie','Charlie',49)
162171
INSERT INTO [dbo].[Users] ([Id], [Name], [Password], [Age]) VALUES (3,'Dave','Dave',12)
163172
SET IDENTITY_INSERT [dbo].[Users] OFF
173+
SET IDENTITY_INSERT [dbo].[Employee] ON
174+
INSERT INTO [dbo].[Employee] ([Id], [Name], [ManagerId]) VALUES (1, 'Alice', NULL)
175+
INSERT INTO [dbo].[Employee] ([Id], [Name], [ManagerId]) VALUES (2, 'Bob', 1)
176+
INSERT INTO [dbo].[Employee] ([Id], [Name], [ManagerId]) VALUES (3, 'Charlie', 2)
177+
SET IDENTITY_INSERT [dbo].[Employee] OFF
164178

165179
DECLARE @PagingId AS INT
166180
SET @PagingId = 1

Simple.Data.SqlTest/UpdateTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
namespace Simple.Data.SqlTest
77
{
8+
using System.Collections.Generic;
9+
810
[TestFixture]
911
public class UpdateTests
1012
{
@@ -84,5 +86,18 @@ public void TestUpdateWithVarBinaryMaxColumn()
8486

8587
Assert.IsTrue(newData.SequenceEqual(blob.Data));
8688
}
89+
90+
[Test]
91+
public void ToListShouldExecuteQuery()
92+
{
93+
var db = DatabaseHelper.Open();
94+
List<Customer> customers = db.Customers.All().ToList<Customer>();
95+
foreach (var customer in customers)
96+
{
97+
customer.Address = "Updated";
98+
}
99+
100+
db.Customers.Update(customers);
101+
}
87102
}
88103
}

Simple.Data/InMemoryAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using System.Linq;
77
using QueryPolyfills;
88

9-
public class InMemoryAdapter : Adapter
9+
public partial class InMemoryAdapter : Adapter
1010
{
1111
private readonly Dictionary<string, string> _autoIncrementColumns = new Dictionary<string, string>();
1212
private readonly Dictionary<string, string[]> _keyColumns = new Dictionary<string, string[]>();
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Simple.Data
7+
{
8+
public partial class InMemoryAdapter : IAdapterWithTransactions
9+
{
10+
class InMemoryAdapterTransaction : IAdapterTransaction
11+
{
12+
private readonly string _name;
13+
14+
public InMemoryAdapterTransaction() : this(string.Empty)
15+
{
16+
}
17+
18+
public InMemoryAdapterTransaction(string name)
19+
{
20+
_name = name;
21+
}
22+
23+
public void Dispose()
24+
{
25+
}
26+
27+
public void Commit()
28+
{
29+
}
30+
31+
public void Rollback()
32+
{
33+
}
34+
35+
public string Name
36+
{
37+
get { return _name; }
38+
}
39+
}
40+
41+
public IAdapterTransaction BeginTransaction()
42+
{
43+
return new InMemoryAdapterTransaction();
44+
}
45+
46+
public IAdapterTransaction BeginTransaction(string name)
47+
{
48+
return new InMemoryAdapterTransaction(name);
49+
}
50+
51+
public IEnumerable<IDictionary<string, object>> Find(string tableName, SimpleExpression criteria, IAdapterTransaction transaction)
52+
{
53+
return Find(tableName, criteria);
54+
}
55+
56+
public IDictionary<string, object> Insert(string tableName, IDictionary<string, object> data, IAdapterTransaction transaction, bool resultRequired)
57+
{
58+
return Insert(tableName, data, resultRequired);
59+
}
60+
61+
public IEnumerable<IDictionary<string, object>> InsertMany(string tableName, IEnumerable<IDictionary<string, object>> data, IAdapterTransaction transaction, Func<IDictionary<string, object>, Exception, bool> onError, bool resultRequired)
62+
{
63+
return InsertMany(tableName, data, onError, resultRequired);
64+
}
65+
66+
public int Update(string tableName, IDictionary<string, object> data, SimpleExpression criteria, IAdapterTransaction transaction)
67+
{
68+
return Update(tableName, data, criteria);
69+
}
70+
71+
public int Delete(string tableName, SimpleExpression criteria, IAdapterTransaction transaction)
72+
{
73+
return Delete(tableName, criteria);
74+
}
75+
76+
public int UpdateMany(string tableName, IEnumerable<IDictionary<string, object>> dataList, IAdapterTransaction adapterTransaction)
77+
{
78+
return UpdateMany(tableName, dataList);
79+
}
80+
81+
public int UpdateMany(string tableName, IEnumerable<IDictionary<string, object>> dataList, IAdapterTransaction adapterTransaction, IList<string> keyFields)
82+
{
83+
return UpdateMany(tableName, dataList, keyFields);
84+
}
85+
86+
public int Update(string tableName, IDictionary<string, object> data, IAdapterTransaction adapterTransaction)
87+
{
88+
return Update(tableName, data);
89+
}
90+
91+
public int UpdateMany(string tableName, IList<IDictionary<string, object>> dataList, IEnumerable<string> criteriaFieldNames, IAdapterTransaction adapterTransaction)
92+
{
93+
return UpdateMany(tableName, dataList, criteriaFieldNames);
94+
}
95+
}
96+
}

Simple.Data/Simple.Data.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
<Compile Include="ErrorCallback.cs" />
8585
<Compile Include="FunctionSignature.cs" />
8686
<Compile Include="InMemoryAdapter.cs" />
87+
<Compile Include="InMemoryAdapterIAdapterWithTransactions.cs" />
8788
<Compile Include="JoinType.cs" />
8889
<Compile Include="OfTypeEnumerable.cs" />
8990
<Compile Include="OptimizingDelegateFactory.cs" />

0 commit comments

Comments
 (0)