Skip to content

Commit c42d4da

Browse files
Merge pull request #87 from DynamicsValue/feature/26-updates
2.6.x
2 parents 42711a6 + 90c023f commit c42d4da

File tree

58 files changed

+3313
-46
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3313
-46
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
### Added
44

5+
- Added new InMemoryFileDb implementation to support file and image storage - https://github.com/DynamicsValue/fake-xrm-easy/issues/157
56
- Added default max file size for file and image uploads - https://github.com/DynamicsValue/fake-xrm-easy/issues/157
67

78
### Changed
89

10+
- Resolves an issue in FetchXml queries when using arithmetic values and no early bound assemblies are used. It will now read from injected metadata in absence of proxy type assemblies - https://github.com/DynamicsValue/fake-xrm-easy/issues/158
911
- Resolves issue in MetadataGenerator where relationship properties were generated in the wrong order, also generates ManyToMany relationship properties - https://github.com/DynamicsValue/fake-xrm-easy/issues/135
1012
- Adds implementation of RelatedEntities in Update message , before it was implemented only for Create - https://github.com/DynamicsValue/fake-xrm-easy/issues/154
1113

src/FakeXrmEasy.Core/Db/InMemoryDb.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using FakeXrmEasy.Core.Db.Exceptions;
1+
using System;
2+
using FakeXrmEasy.Core.Db.Exceptions;
23
using FakeXrmEasy.Extensions;
34
using Microsoft.Xrm.Sdk;
45
using Microsoft.Xrm.Sdk.Metadata;
@@ -105,13 +106,30 @@ protected internal void AddOrUpdateMetadata(string logicalName, EntityMetadata e
105106

106107
protected internal void AddEntityRecord(Entity e)
107108
{
109+
InMemoryTable table;
108110
if (!ContainsTable(e.LogicalName))
109111
{
110-
InMemoryTable table;
111112
AddTable(e.LogicalName, out table);
112113
}
114+
else
115+
{
116+
table = GetTable(e.LogicalName);
117+
}
118+
119+
table.Add(e);
113120
}
114121

122+
protected internal bool ContainsEntityRecord(string logicalName, Guid id)
123+
{
124+
if (!ContainsTable(logicalName))
125+
{
126+
return false;
127+
}
128+
129+
var table = GetTable(logicalName);
130+
return table.Contains(id);
131+
}
132+
115133
protected internal void AddOrReplaceEntityRecord(Entity e)
116134
{
117135
InMemoryTable table = null;

src/FakeXrmEasy.Core/Db/InMemoryTable.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,14 @@ protected internal void SetMetadata(EntityMetadata entityMetadata)
126126
{
127127
_metadata._entityMetadata = entityMetadata.Copy();
128128
}
129+
130+
/// <summary>
131+
/// Returns the entity metadata associated to this column
132+
/// </summary>
133+
/// <returns></returns>
134+
protected internal EntityMetadata GetEntityMetadata()
135+
{
136+
return _metadata._entityMetadata;
137+
}
129138
}
130139
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.Exceptions.Query.FetchXml
4+
{
5+
/// <summary>
6+
/// Exception raised in a query when an attribute value type could not be determined correctly
7+
/// </summary>
8+
public class ArithmeticTypeConversionException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
/// <param name="entityName"></param>
14+
/// <param name="attributeName"></param>
15+
internal ArithmeticTypeConversionException(string entityName, string attributeName) :
16+
base($"When using arithmetic values in a condition of attribute '{attributeName}' of entity '{entityName}' in a Fetch a ProxyTypesAssembly must be used in order to know which types to cast values to. If you are using early bound types, please make sure the early bound type was generated for entity '{entityName}'")
17+
{
18+
19+
}
20+
}
21+
}

src/FakeXrmEasy.Core/Extensions/XmlExtensionsForFetchXml.cs

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Globalization;
88
using FakeXrmEasy.Abstractions;
99
using FakeXrmEasy.Abstractions.Exceptions;
10+
using FakeXrmEasy.Core.Exceptions.Query.FetchXml;
1011

1112
namespace FakeXrmEasy.Extensions.FetchXml
1213
{
@@ -898,6 +899,26 @@ public static bool ValueNeedsConverting(ConditionOperator conditionOperator)
898899
return !OperatorsNotToConvertArray.Contains(conditionOperator);
899900
}
900901

902+
internal static object GetConditionExpressionBasedOnAttributeType(Type attributeType, string value, string sEntityName, string sAttributeName, ConditionOperator op)
903+
{
904+
try
905+
{
906+
if (ValueNeedsConverting(op))
907+
{
908+
return GetValueBasedOnType(attributeType, value);
909+
}
910+
911+
else
912+
{
913+
return int.Parse(value);
914+
}
915+
}
916+
catch (Exception e)
917+
{
918+
throw new Exception(string.Format("When trying to parse value for entity {0} and attribute {1}: {2}", sEntityName, sAttributeName, e.Message));
919+
}
920+
}
921+
901922
/// <summary>
902923
///
903924
/// </summary>
@@ -919,25 +940,18 @@ public static object GetConditionExpressionValueCast(string value, IXrmFakedCont
919940
var attributeType = ctx.FindReflectedAttributeType(reflectedType, sEntityName, sAttributeName);
920941
if (attributeType != null)
921942
{
922-
try
923-
{
924-
if (ValueNeedsConverting(op))
925-
{
926-
return GetValueBasedOnType(attributeType, value);
927-
}
928-
929-
else
930-
{
931-
return int.Parse(value);
932-
}
933-
}
934-
catch (Exception e)
935-
{
936-
throw new Exception(string.Format("When trying to parse value for entity {0} and attribute {1}: {2}", sEntityName, sAttributeName, e.Message));
937-
}
943+
return GetConditionExpressionBasedOnAttributeType(attributeType, value, sEntityName, sAttributeName, op);
938944
}
939945
}
940946
}
947+
else
948+
{
949+
var injectedAttributeType = ctx.FindAttributeTypeInInjectedMetadata(sEntityName, sAttributeName);
950+
if (injectedAttributeType != null)
951+
{
952+
return GetConditionExpressionBasedOnAttributeType(injectedAttributeType, value, sEntityName, sAttributeName, op);
953+
}
954+
}
941955

942956
#if FAKE_XRM_EASY_9
943957
if(op == ConditionOperator.ContainValues || op == ConditionOperator.DoesNotContainValues)
@@ -976,7 +990,7 @@ public static object GetConditionExpressionValueCast(string value, IXrmFakedCont
976990

977991
if (bIsNumeric || bIsDateTime)
978992
{
979-
throw new Exception($"When using arithmetic values in a condition of attribute '{sAttributeName}' of entity '{sEntityName}' in a Fetch a ProxyTypesAssembly must be used in order to know which types to cast values to. If you are using early bound types, please make sure the early bound type was generated for entity '{sEntityName}'");
993+
throw new ArithmeticTypeConversionException(sEntityName, sAttributeName);
980994
}
981995

982996
//Default value

src/FakeXrmEasy.Core/FakeXrmEasy.Core.csproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,22 @@
102102
</ItemGroup>
103103

104104
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY'">
105-
<PackageReference Include="FakeXrmEasy.Abstractions.v2011" Version="[2.5.0-*,3.0)" />
105+
<PackageReference Include="FakeXrmEasy.Abstractions.v2011" Version="[2.6.0-*,3.0)" />
106106
</ItemGroup>
107107
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_2013'">
108-
<PackageReference Include="FakeXrmEasy.Abstractions.v2013" Version="[2.5.0-*,3.0)" />
108+
<PackageReference Include="FakeXrmEasy.Abstractions.v2013" Version="[2.6.0-*,3.0)" />
109109
</ItemGroup>
110110
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_2015'">
111-
<PackageReference Include="FakeXrmEasy.Abstractions.v2015" Version="[2.5.0-*,3.0)" />
111+
<PackageReference Include="FakeXrmEasy.Abstractions.v2015" Version="[2.6.0-*,3.0)" />
112112
</ItemGroup>
113113
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_2016'">
114-
<PackageReference Include="FakeXrmEasy.Abstractions.v2016" Version="[2.5.0-*,3.0)" />
114+
<PackageReference Include="FakeXrmEasy.Abstractions.v2016" Version="[2.6.0-*,3.0)" />
115115
</ItemGroup>
116116
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_365'">
117-
<PackageReference Include="FakeXrmEasy.Abstractions.v365" Version="[2.5.0-*,3.0)" />
117+
<PackageReference Include="FakeXrmEasy.Abstractions.v365" Version="[2.6.0-*,3.0)" />
118118
</ItemGroup>
119119
<ItemGroup Condition="'$(Configuration)'=='FAKE_XRM_EASY_9'">
120-
<PackageReference Include="FakeXrmEasy.Abstractions.v9" Version="[2.5.0-*,3.0)" />
120+
<PackageReference Include="FakeXrmEasy.Abstractions.v9" Version="[2.6.0-*,3.0)" />
121121
</ItemGroup>
122122

123123
<Target Name="PreparePackageReleaseNotesFromFile" BeforeTargets="GenerateNuspec">
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
4+
{
5+
/// <summary>
6+
/// Exception raised when InitializeFiles is called more than once.
7+
/// </summary>
8+
public class AlreadyInitializedFilesException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
public AlreadyInitializedFilesException() : base("InitializeFiles has been called more than once. Always initialize all the files you need in a single call to .InitializeFiles()")
14+
{
15+
16+
}
17+
18+
}
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
4+
{
5+
/// <summary>
6+
/// Exception raised when a file is uploaded and its file extension is blocked by the BlockedAttachment settings
7+
/// </summary>
8+
public class BlockedAttachmentException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
internal BlockedAttachmentException(string fileName) : base($"The attachment with file name '{fileName}' is not a valid file extension type")
14+
{
15+
16+
}
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
4+
{
5+
/// <summary>
6+
/// Exception raised when a file is uploaded and its file MIME type is blocked by either the BlockedMimeType or AllowedMimeType settings
7+
/// </summary>
8+
public class BlockedMimeTypeException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
internal BlockedMimeTypeException(string fileName, string mimeType) : base($"The MIME Type '{mimeType}' for file name '{fileName}' is not a valid")
14+
{
15+
16+
}
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
4+
{
5+
/// <summary>
6+
/// Internal exception used for internal testing only thrown when a file could not be added to the InMemoryFileDb
7+
/// </summary>
8+
public class CouldNotAddFileException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
internal CouldNotAddFileException(): base("A file could not be added")
14+
{
15+
16+
}
17+
}
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
4+
{
5+
/// <summary>
6+
/// Throws an exception when a file could not be committed due to an unknown error
7+
/// </summary>
8+
public class CouldNotCommitFileException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
/// <param name="fileUploadContinuationToken"></param>
14+
internal CouldNotCommitFileException(string fileUploadContinuationToken) : base($"The file associated to continuation token '{fileUploadContinuationToken}' could not be committed due to an unknown error")
15+
{
16+
17+
}
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
4+
{
5+
/// <summary>
6+
/// Exception thrown when a particular file could not be deleted or it doesn't exists
7+
/// </summary>
8+
public class CouldNotDeleteFileException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
/// <param name="fileId"></param>
14+
internal CouldNotDeleteFileException(string fileId) : base($"Could not delete file with Id '{fileId}'")
15+
{
16+
17+
}
18+
}
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
4+
{
5+
/// <summary>
6+
/// Exception raised when a block id already exists in the current file upload session
7+
/// </summary>
8+
public class DuplicateFileBlockException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
/// <param name="blockId">The block Id that already existed</param>
14+
/// <param name="fileUploadSessionId">The Id of the FileUploadSession where that block existed</param>
15+
internal DuplicateFileBlockException(string blockId, string fileUploadSessionId) : base($"A block was already uploaded with Id {blockId} against the current file continuation token: {fileUploadSessionId}")
16+
{
17+
18+
}
19+
}
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using Microsoft.Xrm.Sdk;
3+
4+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
5+
{
6+
/// <summary>
7+
/// Exception raised when downloading a file block for a database record and column that doesn't actually have a file against it
8+
/// </summary>
9+
public class FileToDownloadNotFoundException: Exception
10+
{
11+
/// <summary>
12+
/// Default constructor
13+
/// </summary>
14+
/// <param name="entityReference">An entity reference of the record</param>
15+
/// <param name="fileAttributeName">The column where a file was not found</param>
16+
internal FileToDownloadNotFoundException(EntityReference entityReference, string fileAttributeName)
17+
: base($"A file was not found for record with logical name '{entityReference.LogicalName}' and Id '{entityReference.Id.ToString()}' in column '{fileAttributeName}'")
18+
{
19+
20+
}
21+
}
22+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
3+
namespace FakeXrmEasy.Core.FileStorage.Db.Exceptions
4+
{
5+
/// <summary>
6+
/// Exception thrown when a file continuation token could not be found or invalid, either when initiating a file upload or a file download
7+
/// </summary>
8+
public class FileTokenContinuationNotFoundException: Exception
9+
{
10+
/// <summary>
11+
/// Default constructor
12+
/// </summary>
13+
/// <param name="fileContinuationTokenId">The file continuation token that could not be found</param>
14+
internal FileTokenContinuationNotFoundException(string fileContinuationTokenId)
15+
: base($"The file continuation token with Id '{fileContinuationTokenId}' could not be found or has already been committed")
16+
{
17+
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)