Permalink
Browse files

Added InMemory adapter project

  • Loading branch information...
1 parent 7b090eb commit 57b7695bb8d3b811824633281e81069924af8167 @markrendle committed Sep 30, 2011
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.InMemory
+{
+ using QueryPolyfills;
+
+ public class InMemoryAdapter : Adapter
+ {
+ private readonly Dictionary<string, List<IDictionary<string,object>>> _tables = new Dictionary<string, List<IDictionary<string, object>>>();
+ private readonly Dictionary<string,string> _autoIncrementColumns = new Dictionary<string, string>();
+ private readonly Dictionary<string, string[]> _keyColumns = new Dictionary<string, string[]>();
+
+ private List<IDictionary<string,object>> GetTable(string tableName)
+ {
+ tableName = tableName.ToLowerInvariant();
+ if (!_tables.ContainsKey(tableName)) _tables.Add(tableName, new List<IDictionary<string, object>>());
+ return _tables[tableName];
+ }
+
+ public override IEnumerable<IDictionary<string, object>> Find(string tableName, SimpleExpression criteria)
+ {
+ var whereClauseHandler = new WhereClauseHandler(new WhereClause(criteria));
+ return whereClauseHandler.Run(GetTable(tableName));
+ }
+
+ public override IEnumerable<IDictionary<string, object>> RunQuery(SimpleQuery query, out IEnumerable<SimpleQueryClauseBase> unhandledClauses)
+ {
+ unhandledClauses = query.Clauses.AsEnumerable();
+ return GetTable(query.TableName);
+ }
+
+ public override IDictionary<string, object> Insert(string tableName, IDictionary<string, object> data)
+ {
+ if (_autoIncrementColumns.ContainsKey(tableName))
+ {
+ object nextVal = GetTable(tableName).Select(d => d[_autoIncrementColumns[tableName]]).Max();
+ nextVal = ObjectMaths.Increment(nextVal);
+ data[_autoIncrementColumns[tableName]] = nextVal;
+ }
+ GetTable(tableName).Add(data);
+ return data;
+ }
+
+ public override int Update(string tableName, IDictionary<string, object> data, SimpleExpression criteria)
+ {
+ int count = 0;
+ foreach (var record in Find(tableName, criteria))
+ {
+ UpdateRecord(data, record);
+ ++count;
+ }
+ return count;
+ }
+
+ private static void UpdateRecord(IDictionary<string, object> data, IDictionary<string, object> record)
+ {
+ foreach (var kvp in data)
+ {
+ record[kvp.Key] = kvp.Value;
+ }
+ }
+
+ public override int Update(string tableName, IDictionary<string, object> data)
+ {
+ if (!_keyColumns.ContainsKey(tableName)) throw new InvalidOperationException("No key column(s) specified.");
+ IDictionary<string, object> row = null;
+ if (_keyColumns[tableName].Length == 1)
+ {
+ row =
+ GetTable(tableName).Single(
+ d => d[_keyColumns[tableName][0]] == data[_keyColumns[tableName][0]]);
+ }
+ else
+ {
+ IEnumerable<IDictionary<string, object>> rows = GetTable(tableName);
+ rows = _keyColumns[tableName].Aggregate(rows, (current, keyColumn) => current.Where(d => d[keyColumn] == data[keyColumn]));
+ row = rows.Single();
+ }
+ UpdateRecord(data, row);
+ return 1;
+ }
+
+ public override int Delete(string tableName, SimpleExpression criteria)
+ {
+ int count = 0;
+ foreach (var record in Find(tableName, criteria))
+ {
+ GetTable(tableName).Remove(record);
+ ++count;
+ }
+ return count;
+ }
+
+ public override bool IsExpressionFunction(string functionName, params object[] args)
+ {
+ return functionName.Equals("like", StringComparison.OrdinalIgnoreCase) && args.Length == 1 && args[0] is string;
+ }
+
+ public void SetAutoIncrementColumn(string tableName, string columnName)
+ {
+ _autoIncrementColumns.Add(tableName, columnName);
+ }
+
+ public void SetKeyColumn(string tableName, string columnName)
+ {
+ _keyColumns[tableName] = new[] { columnName };
+ }
+
+ public void SetKeyColumns(string tableName, params string[] columnNames)
+ {
+ _keyColumns[tableName] = columnNames;
+ }
+ }
+}
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.InMemory
+{
+ static class ObjectMaths
+ {
+ public static object Increment(object value)
+ {
+ if (value == null) throw new ArgumentNullException("value");
+ if (value is int) return (int) value + 1;
+ if (value is long) return (long) value + 1;
+ if (value is short) return (short) value + 1;
+ if (value is uint) return (uint)value + 1;
+ if (value is ulong) return (ulong)value + 1;
+ if (value is ushort) return (ushort)value + 1;
+ if (value is decimal) return (decimal)value + 1;
+ if (value is float) return (float)value + 1;
+ if (value is double) return (double)value + 1;
+ if (value is byte) return (byte)value + 1;
+ if (value is sbyte) return (sbyte)value + 1;
+
+ throw new ArgumentException("Cannot increment object type.");
+ }
+ }
+}
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Simple.Data.InMemory")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Simple.Data.InMemory")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7070e7d4-e1d2-498e-9b13-606ff91d7fa7")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{976ED1B4-04B7-489F-93B6-F99F587D49CB}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Simple.Data.InMemory</RootNamespace>
+ <AssemblyName>Simple.Data.InMemory</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="InMemoryAdapter.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Simple.Data\Simple.Data.csproj">
+ <Project>{148CEE80-2E84-4ABD-B5AB-20415B2BBD21}</Project>
+ <Name>Simple.Data</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.InMemoryTest
+{
+ using InMemory;
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class InMemoryTests
+ {
+ [Test]
+ public void InsertAndFindShouldWork()
+ {
+ Database.UseMockAdapter(new InMemoryAdapter());
+ var db = Database.Open();
+ db.Test.Insert(Id: 1, Name: "Alice");
+ var record = db.Test.FindById(1);
+ Assert.IsNotNull(record);
+ Assert.AreEqual(1, record.Id);
+ Assert.AreEqual("Alice", record.Name);
+ }
+ }
+}
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Simple.Data.InMemoryTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Simple.Data.InMemoryTest")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("2cc2c2fb-e08d-4770-9678-dff20d790899")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{1B6A87C0-4ACA-4411-8879-844537A52126}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Simple.Data.InMemoryTest</RootNamespace>
+ <AssemblyName>Simple.Data.InMemoryTest</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+ <HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.mocks, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+ <HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.mocks.dll</HintPath>
+ </Reference>
+ <Reference Include="pnunit.framework, Version=1.0.4109.34242, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\NUnit.2.5.10.11092\lib\pnunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="InMemoryTests.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Simple.Data.InMemory\Simple.Data.InMemory.csproj">
+ <Project>{976ED1B4-04B7-489F-93B6-F99F587D49CB}</Project>
+ <Name>Simple.Data.InMemory</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Simple.Data\Simple.Data.csproj">
+ <Project>{148CEE80-2E84-4ABD-B5AB-20415B2BBD21}</Project>
+ <Name>Simple.Data</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="NUnit" version="2.5.10.11092" />
+</packages>
Oops, something went wrong.

0 comments on commit 57b7695

Please sign in to comment.