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