initial
This commit is contained in:
commit
b789b367c2
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
# Autosave files
|
||||
*~
|
||||
|
||||
# build
|
||||
[Oo]bj/
|
||||
[Bb]in/
|
||||
packages/
|
||||
TestResults/
|
||||
|
||||
# globs
|
||||
Makefile.in
|
||||
*.DS_Store
|
||||
*.sln.cache
|
||||
*.suo
|
||||
*.cache
|
||||
*.pidb
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
config.log
|
||||
config.make
|
||||
config.status
|
||||
aclocal.m4
|
||||
install-sh
|
||||
autom4te.cache/
|
||||
*.user
|
||||
*.tar.gz
|
||||
tarballs/
|
||||
test-results/
|
||||
Thumbs.db
|
||||
.vs/
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# resharper
|
||||
*_Resharper.*
|
||||
*.Resharper
|
||||
|
||||
# dotCover
|
||||
*.dotCover
|
29
ObjectStorage.sln
Normal file
29
ObjectStorage.sln
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.ObjectStorage.Core", "PoweredSoft.ObjectStorage.Core\PoweredSoft.ObjectStorage.Core.csproj", "{81070762-4F21-402D-B10E-6285A46F0572}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.ObjectStorage.MongoDB", "PoweredSoft.ObjectStorage.MongoDB\PoweredSoft.ObjectStorage.MongoDB.csproj", "{D430A3A6-5D41-4B4D-9379-5761FB691619}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.ObjectStorage.MongoDB.Tests", "PoweredSoft.ObjectStorage.MongoDB.Tests\PoweredSoft.ObjectStorage.MongoDB.Tests.csproj", "{D8CB2E20-7298-4EEB-9694-C54654B1BD1C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{81070762-4F21-402D-B10E-6285A46F0572}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{81070762-4F21-402D-B10E-6285A46F0572}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{81070762-4F21-402D-B10E-6285A46F0572}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{81070762-4F21-402D-B10E-6285A46F0572}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D430A3A6-5D41-4B4D-9379-5761FB691619}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D430A3A6-5D41-4B4D-9379-5761FB691619}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D430A3A6-5D41-4B4D-9379-5761FB691619}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D430A3A6-5D41-4B4D-9379-5761FB691619}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D8CB2E20-7298-4EEB-9694-C54654B1BD1C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D8CB2E20-7298-4EEB-9694-C54654B1BD1C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D8CB2E20-7298-4EEB-9694-C54654B1BD1C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D8CB2E20-7298-4EEB-9694-C54654B1BD1C}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
9
PoweredSoft.ObjectStorage.Core/IObjectStorageClient.cs
Normal file
9
PoweredSoft.ObjectStorage.Core/IObjectStorageClient.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.Core
|
||||
{
|
||||
public interface IObjectStorageClient
|
||||
{
|
||||
IObjectStorageCollection<TEntity> GetCollection<TEntity>();
|
||||
}
|
||||
}
|
16
PoweredSoft.ObjectStorage.Core/IObjectStorageCollection.cs
Normal file
16
PoweredSoft.ObjectStorage.Core/IObjectStorageCollection.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.Core
|
||||
{
|
||||
public interface IObjectStorageCollection<TEntity>
|
||||
{
|
||||
string CollectionName { get; }
|
||||
|
||||
Task<TEntity> AddAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken));
|
||||
IQueryable<TEntity> AsQueryable();
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Class1.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using MongoDB.Driver;
|
||||
using PoweredSoft.ObjectStorage.MongoDB.Tests.Mock;
|
||||
using PoweredSoft.ObjectStorage.MongoDB.Tests.Mock.Dal;
|
||||
using Xunit;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.MongoDB.Tests
|
||||
{
|
||||
public class CollectionNameAttributeTests
|
||||
{
|
||||
[Fact]
|
||||
public void TestingGetCollection()
|
||||
{
|
||||
var objectStorageClient = MongoDatabaseFactory.GetObjectStorageClient();
|
||||
var collection = objectStorageClient.GetCollection<Contact>();
|
||||
Assert.NotNull(collection);
|
||||
Assert.NotNull(collection.CollectionName);
|
||||
}
|
||||
}
|
||||
}
|
37
PoweredSoft.ObjectStorage.MongoDB.Tests/CrudTests.cs
Normal file
37
PoweredSoft.ObjectStorage.MongoDB.Tests/CrudTests.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using PoweredSoft.ObjectStorage.MongoDB.Tests.Mock;
|
||||
using PoweredSoft.ObjectStorage.MongoDB.Tests.Mock.Dal;
|
||||
using Xunit;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.MongoDB.Tests
|
||||
{
|
||||
public class CrudTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task CreateUpdateThenDelete()
|
||||
{
|
||||
var osc = MongoDatabaseFactory.GetObjectStorageClient();
|
||||
var collection = osc.GetCollection<Contact>();
|
||||
var contact = await collection.AddAsync(new Contact
|
||||
{
|
||||
FirstName = "Chuck",
|
||||
LastName = "Not Norris"
|
||||
});
|
||||
Assert.NotNull(contact);
|
||||
|
||||
|
||||
contact.LastName = "Norris";
|
||||
var updatedContact = await collection.UpdateAsync(contact);
|
||||
Assert.Equal("Norris", updatedContact.LastName);
|
||||
|
||||
// delete the test.
|
||||
await collection.DeleteAsync(updatedContact);
|
||||
|
||||
// check that it was deleted.
|
||||
var shouldBeNull = collection.AsQueryable().FirstOrDefault(t => t.Id == updatedContact.Id);
|
||||
Assert.Null(shouldBeNull);
|
||||
}
|
||||
}
|
||||
}
|
17
PoweredSoft.ObjectStorage.MongoDB.Tests/Mock/Dal/Contact.cs
Normal file
17
PoweredSoft.ObjectStorage.MongoDB.Tests/Mock/Dal/Contact.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.MongoDB.Tests.Mock.Dal
|
||||
{
|
||||
[MongoCollection("contacts")]
|
||||
public class Contact
|
||||
{
|
||||
[BsonId, BsonElement("id")]
|
||||
public ObjectId Id { get; set; }
|
||||
[BsonElement("firstName")]
|
||||
public string FirstName { get; set; }
|
||||
[BsonElement("lastName")]
|
||||
public string LastName { get; set; }
|
||||
}
|
||||
}
|
14
PoweredSoft.ObjectStorage.MongoDB.Tests/Mock/Dal/Tag.cs
Normal file
14
PoweredSoft.ObjectStorage.MongoDB.Tests/Mock/Dal/Tag.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.MongoDB.Tests.Mock.Dal
|
||||
{
|
||||
[MongoCollection("tags")]
|
||||
public class Tag
|
||||
{
|
||||
[BsonId, BsonElement("id")]
|
||||
public ObjectId Id { get; set; }
|
||||
[BsonElement("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.MongoDB.Tests.Mock
|
||||
{
|
||||
public class MongoDatabaseFactory
|
||||
{
|
||||
public static IMongoDatabase GetDatabase()
|
||||
{
|
||||
var client = GetClient();
|
||||
var db = client.GetDatabase("acme");
|
||||
return db;
|
||||
}
|
||||
|
||||
public static MongoObjectStorageClient GetObjectStorageClient()
|
||||
{
|
||||
return new MongoObjectStorageClient(GetDatabase());
|
||||
}
|
||||
|
||||
public static IMongoClient GetClient()
|
||||
{
|
||||
var mongoClient = new MongoClient();
|
||||
return mongoClient;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
|
||||
<PackageReference Include="PoweredSoft.DynamicLinq" Version="1.1.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Mock\" />
|
||||
<Folder Include="Mock\Dal\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PoweredSoft.ObjectStorage.Core\PoweredSoft.ObjectStorage.Core.csproj" />
|
||||
<ProjectReference Include="..\PoweredSoft.ObjectStorage.MongoDB\PoweredSoft.ObjectStorage.MongoDB.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
namespace PoweredSoft.ObjectStorage.MongoDB
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class MongoCollectionAttribute : Attribute
|
||||
{
|
||||
public MongoCollectionAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using MongoDB.Driver;
|
||||
using PoweredSoft.ObjectStorage.Core;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.MongoDB
|
||||
{
|
||||
public class MongoObjectStorageClient : IObjectStorageClient
|
||||
{
|
||||
public MongoObjectStorageClient(IMongoDatabase database)
|
||||
{
|
||||
Database = database;
|
||||
}
|
||||
|
||||
public IMongoDatabase Database { get; }
|
||||
|
||||
public IObjectStorageCollection<TEntity> GetCollection<TEntity>()
|
||||
{
|
||||
var attribute = typeof(TEntity).GetCustomAttribute<MongoCollectionAttribute>();
|
||||
if (attribute == null)
|
||||
throw new Exception("Must add MongoCollectionAttribute on entity class to use this method.");
|
||||
|
||||
var mongoCollection = Database.GetCollection<TEntity>(attribute.Name);
|
||||
var ret = new MongoObjectStorageCollection<TEntity>(mongoCollection);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using MongoDB.Driver;
|
||||
using PoweredSoft.DynamicLinq.Helpers;
|
||||
using PoweredSoft.ObjectStorage.Core;
|
||||
|
||||
namespace PoweredSoft.ObjectStorage.MongoDB
|
||||
{
|
||||
public class MongoObjectStorageCollection<TEntity> : IObjectStorageCollection<TEntity>
|
||||
{
|
||||
public MongoObjectStorageCollection(IMongoCollection<TEntity> collection)
|
||||
{
|
||||
if (collection == null)
|
||||
throw new ArgumentNullException("collection");
|
||||
|
||||
Collection = collection;
|
||||
}
|
||||
|
||||
public string CollectionName => Collection.CollectionNamespace.CollectionName;
|
||||
|
||||
public IMongoCollection<TEntity> Collection { get; }
|
||||
|
||||
public async Task<TEntity> AddAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
await Collection.InsertOneAsync(entity, cancellationToken: cancellationToken);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public IQueryable<TEntity> AsQueryable()
|
||||
{
|
||||
return Collection.AsQueryable();
|
||||
}
|
||||
|
||||
protected virtual Expression<Func<TEntity, bool>> CreateEntityExpression(TEntity entity)
|
||||
{
|
||||
var objectKey = typeof(TEntity)
|
||||
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.FirstOrDefault(t => t.GetCustomAttribute<BsonIdAttribute>() != null);
|
||||
if (objectKey == null)
|
||||
throw new Exception("Must have a BsonIdAttribute on one of the properties.");
|
||||
|
||||
var constant = objectKey.GetValue(entity);
|
||||
var expression = QueryableHelpers.CreateConditionExpression<TEntity>(objectKey.Name,
|
||||
DynamicLinq.ConditionOperators.Equal, constant, DynamicLinq.QueryConvertStrategy.LeaveAsIs);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var expression = CreateEntityExpression(entity);
|
||||
await Collection.DeleteOneAsync(expression);
|
||||
}
|
||||
|
||||
public async Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var expression = CreateEntityExpression(entity);
|
||||
await Collection.ReplaceOneAsync(expression, entity);
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PoweredSoft.ObjectStorage.Core\PoweredSoft.ObjectStorage.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.7.3" />
|
||||
<PackageReference Include="PoweredSoft.DynamicLinq" Version="1.1.7" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user