Skip to content

Commit 57b7695

Browse files
committed
Added InMemory adapter project
1 parent 7b090eb commit 57b7695

13 files changed

Lines changed: 428 additions & 16 deletions

File tree

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Simple.Data.InMemory
7+
{
8+
using QueryPolyfills;
9+
10+
public class InMemoryAdapter : Adapter
11+
{
12+
private readonly Dictionary<string, List<IDictionary<string,object>>> _tables = new Dictionary<string, List<IDictionary<string, object>>>();
13+
private readonly Dictionary<string,string> _autoIncrementColumns = new Dictionary<string, string>();
14+
private readonly Dictionary<string, string[]> _keyColumns = new Dictionary<string, string[]>();
15+
16+
private List<IDictionary<string,object>> GetTable(string tableName)
17+
{
18+
tableName = tableName.ToLowerInvariant();
19+
if (!_tables.ContainsKey(tableName)) _tables.Add(tableName, new List<IDictionary<string, object>>());
20+
return _tables[tableName];
21+
}
22+
23+
public override IEnumerable<IDictionary<string, object>> Find(string tableName, SimpleExpression criteria)
24+
{
25+
var whereClauseHandler = new WhereClauseHandler(new WhereClause(criteria));
26+
return whereClauseHandler.Run(GetTable(tableName));
27+
}
28+
29+
public override IEnumerable<IDictionary<string, object>> RunQuery(SimpleQuery query, out IEnumerable<SimpleQueryClauseBase> unhandledClauses)
30+
{
31+
unhandledClauses = query.Clauses.AsEnumerable();
32+
return GetTable(query.TableName);
33+
}
34+
35+
public override IDictionary<string, object> Insert(string tableName, IDictionary<string, object> data)
36+
{
37+
if (_autoIncrementColumns.ContainsKey(tableName))
38+
{
39+
object nextVal = GetTable(tableName).Select(d => d[_autoIncrementColumns[tableName]]).Max();
40+
nextVal = ObjectMaths.Increment(nextVal);
41+
data[_autoIncrementColumns[tableName]] = nextVal;
42+
}
43+
GetTable(tableName).Add(data);
44+
return data;
45+
}
46+
47+
public override int Update(string tableName, IDictionary<string, object> data, SimpleExpression criteria)
48+
{
49+
int count = 0;
50+
foreach (var record in Find(tableName, criteria))
51+
{
52+
UpdateRecord(data, record);
53+
++count;
54+
}
55+
return count;
56+
}
57+
58+
private static void UpdateRecord(IDictionary<string, object> data, IDictionary<string, object> record)
59+
{
60+
foreach (var kvp in data)
61+
{
62+
record[kvp.Key] = kvp.Value;
63+
}
64+
}
65+
66+
public override int Update(string tableName, IDictionary<string, object> data)
67+
{
68+
if (!_keyColumns.ContainsKey(tableName)) throw new InvalidOperationException("No key column(s) specified.");
69+
IDictionary<string, object> row = null;
70+
if (_keyColumns[tableName].Length == 1)
71+
{
72+
row =
73+
GetTable(tableName).Single(
74+
d => d[_keyColumns[tableName][0]] == data[_keyColumns[tableName][0]]);
75+
}
76+
else
77+
{
78+
IEnumerable<IDictionary<string, object>> rows = GetTable(tableName);
79+
rows = _keyColumns[tableName].Aggregate(rows, (current, keyColumn) => current.Where(d => d[keyColumn] == data[keyColumn]));
80+
row = rows.Single();
81+
}
82+
UpdateRecord(data, row);
83+
return 1;
84+
}
85+
86+
public override int Delete(string tableName, SimpleExpression criteria)
87+
{
88+
int count = 0;
89+
foreach (var record in Find(tableName, criteria))
90+
{
91+
GetTable(tableName).Remove(record);
92+
++count;
93+
}
94+
return count;
95+
}
96+
97+
public override bool IsExpressionFunction(string functionName, params object[] args)
98+
{
99+
return functionName.Equals("like", StringComparison.OrdinalIgnoreCase) && args.Length == 1 && args[0] is string;
100+
}
101+
102+
public void SetAutoIncrementColumn(string tableName, string columnName)
103+
{
104+
_autoIncrementColumns.Add(tableName, columnName);
105+
}
106+
107+
public void SetKeyColumn(string tableName, string columnName)
108+
{
109+
_keyColumns[tableName] = new[] { columnName };
110+
}
111+
112+
public void SetKeyColumns(string tableName, params string[] columnNames)
113+
{
114+
_keyColumns[tableName] = columnNames;
115+
}
116+
}
117+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Simple.Data.InMemory
7+
{
8+
static class ObjectMaths
9+
{
10+
public static object Increment(object value)
11+
{
12+
if (value == null) throw new ArgumentNullException("value");
13+
if (value is int) return (int) value + 1;
14+
if (value is long) return (long) value + 1;
15+
if (value is short) return (short) value + 1;
16+
if (value is uint) return (uint)value + 1;
17+
if (value is ulong) return (ulong)value + 1;
18+
if (value is ushort) return (ushort)value + 1;
19+
if (value is decimal) return (decimal)value + 1;
20+
if (value is float) return (float)value + 1;
21+
if (value is double) return (double)value + 1;
22+
if (value is byte) return (byte)value + 1;
23+
if (value is sbyte) return (sbyte)value + 1;
24+
25+
throw new ArgumentException("Cannot increment object type.");
26+
}
27+
}
28+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("Simple.Data.InMemory")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("Microsoft")]
12+
[assembly: AssemblyProduct("Simple.Data.InMemory")]
13+
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("7070e7d4-e1d2-498e-9b13-606ff91d7fa7")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6+
<ProductVersion>8.0.30703</ProductVersion>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{976ED1B4-04B7-489F-93B6-F99F587D49CB}</ProjectGuid>
9+
<OutputType>Library</OutputType>
10+
<AppDesignerFolder>Properties</AppDesignerFolder>
11+
<RootNamespace>Simple.Data.InMemory</RootNamespace>
12+
<AssemblyName>Simple.Data.InMemory</AssemblyName>
13+
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14+
<FileAlignment>512</FileAlignment>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<DebugType>pdbonly</DebugType>
27+
<Optimize>true</Optimize>
28+
<OutputPath>bin\Release\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
<ErrorReport>prompt</ErrorReport>
31+
<WarningLevel>4</WarningLevel>
32+
</PropertyGroup>
33+
<ItemGroup>
34+
<Reference Include="System" />
35+
<Reference Include="System.Core" />
36+
<Reference Include="System.Xml.Linq" />
37+
<Reference Include="System.Data.DataSetExtensions" />
38+
<Reference Include="Microsoft.CSharp" />
39+
<Reference Include="System.Data" />
40+
<Reference Include="System.Xml" />
41+
</ItemGroup>
42+
<ItemGroup>
43+
<Compile Include="InMemoryAdapter.cs" />
44+
<Compile Include="Properties\AssemblyInfo.cs" />
45+
</ItemGroup>
46+
<ItemGroup>
47+
<ProjectReference Include="..\Simple.Data\Simple.Data.csproj">
48+
<Project>{148CEE80-2E84-4ABD-B5AB-20415B2BBD21}</Project>
49+
<Name>Simple.Data</Name>
50+
</ProjectReference>
51+
</ItemGroup>
52+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
53+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
54+
Other similar extension points exist, see Microsoft.Common.targets.
55+
<Target Name="BeforeBuild">
56+
</Target>
57+
<Target Name="AfterBuild">
58+
</Target>
59+
-->
60+
</Project>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Simple.Data.InMemoryTest
7+
{
8+
using InMemory;
9+
using NUnit.Framework;
10+
11+
[TestFixture]
12+
public class InMemoryTests
13+
{
14+
[Test]
15+
public void InsertAndFindShouldWork()
16+
{
17+
Database.UseMockAdapter(new InMemoryAdapter());
18+
var db = Database.Open();
19+
db.Test.Insert(Id: 1, Name: "Alice");
20+
var record = db.Test.FindById(1);
21+
Assert.IsNotNull(record);
22+
Assert.AreEqual(1, record.Id);
23+
Assert.AreEqual("Alice", record.Name);
24+
}
25+
}
26+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("Simple.Data.InMemoryTest")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("Microsoft")]
12+
[assembly: AssemblyProduct("Simple.Data.InMemoryTest")]
13+
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("2cc2c2fb-e08d-4770-9678-dff20d790899")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6+
<ProductVersion>8.0.30703</ProductVersion>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{1B6A87C0-4ACA-4411-8879-844537A52126}</ProjectGuid>
9+
<OutputType>Library</OutputType>
10+
<AppDesignerFolder>Properties</AppDesignerFolder>
11+
<RootNamespace>Simple.Data.InMemoryTest</RootNamespace>
12+
<AssemblyName>Simple.Data.InMemoryTest</AssemblyName>
13+
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14+
<FileAlignment>512</FileAlignment>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<DebugType>pdbonly</DebugType>
27+
<Optimize>true</Optimize>
28+
<OutputPath>bin\Release\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
<ErrorReport>prompt</ErrorReport>
31+
<WarningLevel>4</WarningLevel>
32+
</PropertyGroup>
33+
<ItemGroup>
34+
<Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
35+
<HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll</HintPath>
36+
</Reference>
37+
<Reference Include="nunit.mocks, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
38+
<HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.mocks.dll</HintPath>
39+
</Reference>
40+
<Reference Include="pnunit.framework, Version=1.0.4109.34242, Culture=neutral, processorArchitecture=MSIL">
41+
<HintPath>..\packages\NUnit.2.5.10.11092\lib\pnunit.framework.dll</HintPath>
42+
</Reference>
43+
<Reference Include="System" />
44+
<Reference Include="System.Core" />
45+
<Reference Include="System.Xml.Linq" />
46+
<Reference Include="System.Data.DataSetExtensions" />
47+
<Reference Include="Microsoft.CSharp" />
48+
<Reference Include="System.Data" />
49+
<Reference Include="System.Xml" />
50+
</ItemGroup>
51+
<ItemGroup>
52+
<Compile Include="InMemoryTests.cs" />
53+
<Compile Include="Properties\AssemblyInfo.cs" />
54+
</ItemGroup>
55+
<ItemGroup>
56+
<None Include="packages.config" />
57+
</ItemGroup>
58+
<ItemGroup>
59+
<ProjectReference Include="..\Simple.Data.InMemory\Simple.Data.InMemory.csproj">
60+
<Project>{976ED1B4-04B7-489F-93B6-F99F587D49CB}</Project>
61+
<Name>Simple.Data.InMemory</Name>
62+
</ProjectReference>
63+
<ProjectReference Include="..\Simple.Data\Simple.Data.csproj">
64+
<Project>{148CEE80-2E84-4ABD-B5AB-20415B2BBD21}</Project>
65+
<Name>Simple.Data</Name>
66+
</ProjectReference>
67+
</ItemGroup>
68+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
69+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
70+
Other similar extension points exist, see Microsoft.Common.targets.
71+
<Target Name="BeforeBuild">
72+
</Target>
73+
<Target Name="AfterBuild">
74+
</Target>
75+
-->
76+
</Project>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="NUnit" version="2.5.10.11092" />
4+
</packages>

0 commit comments

Comments
 (0)