refactor expression caching; add document fields

This commit is contained in:
Gary Sharp
2023-04-16 14:02:35 +10:00
parent d75663a219
commit cfe4c4b912
15 changed files with 182 additions and 144 deletions
@@ -6,12 +6,9 @@ using Disco.Services.Documents;
using Disco.Services.Documents.ManagedGroups; using Disco.Services.Documents.ManagedGroups;
using Disco.Services.Expressions; using Disco.Services.Expressions;
using Disco.Services.Interop.ActiveDirectory; using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Tasks;
using iTextSharp.text.pdf; using iTextSharp.text.pdf;
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Entity; using System.Data.Entity;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
@@ -21,41 +18,58 @@ namespace Disco.BI.Extensions
{ {
public static class DocumentTemplateExtensions public static class DocumentTemplateExtensions
{ {
internal const string CacheTemplate = "DocumentTemplate_{0}"; private static Tuple<Dictionary<string, Expression>, List<DocumentField>> CreateExpressions(DocumentTemplate dt, DiscoDataContext database)
public static ConcurrentDictionary<string, Expression> PdfExpressionsFromCache(this DocumentTemplate dt, DiscoDataContext Database)
{ {
string cacheModuleKey = string.Format(CacheTemplate, dt.Id); Dictionary<string, Expression> expressions = new Dictionary<string, Expression>();
var module = ExpressionCache.GetModule(cacheModuleKey); List<DocumentField> fields = new List<DocumentField>();
if (module == null)
string templateFilename = dt.RepositoryFilename(database);
PdfReader pdfReader = new PdfReader(templateFilename);
int pdfFieldOrdinal = 0;
foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys)
{ {
// Cache var pdfField = pdfReader.AcroFields.Fields[pdfFieldKey];
string templateFilename = dt.RepositoryFilename(Database); var pdfFieldPositions = pdfReader.AcroFields.GetFieldPositions(pdfFieldKey);
PdfReader pdfReader = new PdfReader(templateFilename); var pdfFieldFlags = pdfField.GetMerged(0).GetAsNumber(PdfName.FF)?.IntValue ?? 0;
int pdfFieldOrdinal = 0; var isRequired = (pdfFieldFlags & 2) == 2;
foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys) var isReadOnly = (pdfFieldFlags & 1) == 1;
var pdfFieldValue = pdfReader.AcroFields.GetField(pdfFieldKey);
var pdfFieldPosition = default(RectangleF?);
if (pdfFieldPositions != null && pdfFieldPositions.Count > 0)
{ {
var pdfField = pdfReader.AcroFields.Fields[pdfFieldKey]; var position = pdfFieldPositions.First().position;
var pdfFieldPositions = pdfReader.AcroFields.GetFieldPositions(pdfFieldKey); pdfFieldPosition = new RectangleF(position.Left, position.Top, position.Width, position.Height);
var pdfFieldFlags = pdfField.GetMerged(0).GetAsNumber(PdfName.FF)?.IntValue ?? 0;
var isRequired = (pdfFieldFlags & 2) == 2;
var isReadOnly = (pdfFieldFlags & 1) == 1;
var pdfFieldValue = pdfReader.AcroFields.GetField(pdfFieldKey);
var pdfFieldPosition = default(RectangleF?);
if (pdfFieldPositions != null && pdfFieldPositions.Count > 0)
{
var position = pdfFieldPositions.First().position;
pdfFieldPosition = new RectangleF(position.Left, position.Top, position.Width, position.Height);
}
ExpressionCache.SetValue(cacheModuleKey, pdfFieldKey, Expression.Tokenize(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal, isRequired, isReadOnly, pdfFieldPosition));
pdfFieldOrdinal++;
} }
pdfReader.Close(); var fieldTypeId = pdfReader.AcroFields.GetFieldType(pdfFieldKey);
module = ExpressionCache.GetModule(cacheModuleKey, true); var fieldType = DocumentFieldType.None;
if (fieldTypeId <= 8 && fieldTypeId > 0)
fieldType = (DocumentFieldType)fieldTypeId;
var fixedValues = default(List<string>);
if (fieldType == DocumentFieldType.RadioButton || fieldType == DocumentFieldType.Checkbox)
{
fixedValues = pdfReader.AcroFields.GetAppearanceStates(pdfFieldKey).ToList();
}
expressions[pdfFieldKey] = Expression.Tokenize(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal, isRequired, isReadOnly, pdfFieldPosition);
fields.Add(new DocumentField(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal, fieldType, isRequired, isReadOnly, fixedValues));
pdfFieldOrdinal++;
} }
return module; pdfReader.Close();
return Tuple.Create(expressions, fields);
}
public static Dictionary<string, Expression> PdfExpressionsFromCache(this DocumentTemplate dt, DiscoDataContext Database)
{
return ExpressionCache.GetOrCreateExpressions(dt, () => CreateExpressions(dt, Database));
}
public static List<DocumentField> PdfFieldsFromCache(this DocumentTemplate dt, DiscoDataContext Database)
{
return ExpressionCache.GetOrCreateFields(dt, () => CreateExpressions(dt, Database));
} }
public static List<Expression> ExtractPdfExpressions(this DocumentTemplate dt, DiscoDataContext Database) public static List<Expression> ExtractPdfExpressions(this DocumentTemplate dt, DiscoDataContext Database)
+1 -1
View File
@@ -214,7 +214,7 @@ namespace Disco.BI.Interop.Pdf
if (dt.FlattenForm) if (dt.FlattenForm)
FlattenFields = true; FlattenFields = true;
ConcurrentDictionary<string, Expression> expressionCache = dt.PdfExpressionsFromCache(Database); var expressionCache = dt.PdfExpressionsFromCache(Database);
string templateFilename = dt.RepositoryFilename(Database); string templateFilename = dt.RepositoryFilename(Database);
PdfReader pdfReader = new PdfReader(templateFilename); PdfReader pdfReader = new PdfReader(templateFilename);
+2
View File
@@ -68,6 +68,8 @@
<Compile Include="Services\Devices\Exporting\DeviceExportFieldMetadata.cs" /> <Compile Include="Services\Devices\Exporting\DeviceExportFieldMetadata.cs" />
<Compile Include="Services\Devices\Importing\IDeviceImportColumn.cs" /> <Compile Include="Services\Devices\Importing\IDeviceImportColumn.cs" />
<Compile Include="Services\Devices\Importing\IDeviceImportDataReader.cs" /> <Compile Include="Services\Devices\Importing\IDeviceImportDataReader.cs" />
<Compile Include="Services\Documents\DocumentField.cs" />
<Compile Include="Services\Documents\DocumentFieldType.cs" />
<Compile Include="Services\Documents\DocumentTemplatePackage.cs" /> <Compile Include="Services\Documents\DocumentTemplatePackage.cs" />
<Compile Include="Services\Documents\OnImportUserFlagRule.cs" /> <Compile Include="Services\Documents\OnImportUserFlagRule.cs" />
<Compile Include="Services\Jobs\LocationModes.cs" /> <Compile Include="Services\Jobs\LocationModes.cs" />
@@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace Disco.Models.Services.Documents
{
public class DocumentField
{
public string Name { get; }
public string Value { get; }
public int Ordinal { get; }
public DocumentFieldType Type { get; }
public bool IsRequired { get; }
public bool IsReadOnly { get; }
public List<string> FixedValues { get; }
public DocumentField(string name, string value, int ordinal, DocumentFieldType type, bool isRequired, bool isReadOnly, List<string> fixedValues)
{
Name = name;
Value = value;
Ordinal = ordinal;
Type = type;
IsRequired = isRequired;
IsReadOnly = isReadOnly;
FixedValues = fixedValues;
}
}
}
@@ -0,0 +1,14 @@
namespace Disco.Models.Services.Documents
{
public enum DocumentFieldType
{
None = 0,
PushButton = 1,
Checkbox = 2,
RadioButton = 3,
Text = 4,
List = 5,
Combo = 6,
Signature = 7,
}
}
+2 -6
View File
@@ -21,12 +21,8 @@ namespace Disco.Services
var deviceProfile = device.DeviceProfile; var deviceProfile = device.DeviceProfile;
Expression computerNameTemplateExpression = null; Expression computerNameTemplateExpression = null;
computerNameTemplateExpression = ExpressionCache.GetValue(DeviceProfileExtensions.ComputerNameExpressionCacheModule, deviceProfile.Id.ToString(), () => computerNameTemplateExpression = ExpressionCache.GetOrCreateSingleExpressions(string.Format(DeviceProfileExtensions.ComputerNameExpressionCacheTemplate, deviceProfile.Id),
{ () => Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0));
// Removed 2012-06-14 G# - Properties moved to DeviceProfile model & DB Migrated in DBv3.
//return Expressions.Expression.TokenizeSingleDynamic(null, deviceProfile.Configuration(context).ComputerNameTemplate, 0);
return Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0);
});
var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null, device); var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null, device);
string rendered; string rendered;
try try
@@ -18,11 +18,11 @@ namespace Disco.Services
{ {
public static class DeviceProfileExtensions public static class DeviceProfileExtensions
{ {
public const string ComputerNameExpressionCacheModule = "ComputerNameTemplate"; public const string ComputerNameExpressionCacheTemplate = "ComputerNameTemplate_{0}";
public static void ComputerNameInvalidateCache(this DeviceProfile deviceProfile) public static void ComputerNameInvalidateCache(this DeviceProfile deviceProfile)
{ {
ExpressionCache.InvalidateKey(ComputerNameExpressionCacheModule, deviceProfile.Id.ToString()); ExpressionCache.InvalidateSingleCache(string.Format(ComputerNameExpressionCacheTemplate, deviceProfile.Id));
} }
public static OrganisationAddress DefaultOrganisationAddressDetails(this DeviceProfile deviceProfile, DiscoDataContext Database) public static OrganisationAddress DefaultOrganisationAddressDetails(this DeviceProfile deviceProfile, DiscoDataContext Database)
@@ -8,8 +8,9 @@ namespace Disco.Services
{ {
public static string RepositoryFilename(this DocumentTemplate dt, DiscoDataContext Database) public static string RepositoryFilename(this DocumentTemplate dt, DiscoDataContext Database)
{ {
return Path.Combine(DataStore.CreateLocation(Database, "DocumentTemplates"), string.Format("{0}.pdf", dt.Id)); return Path.Combine(DataStore.CreateLocation(Database, "DocumentTemplates"), $"{dt.Id}.pdf");
} }
public static string SavePdfTemplate(this DocumentTemplate dt, DiscoDataContext Database, Stream TemplateFile) public static string SavePdfTemplate(this DocumentTemplate dt, DiscoDataContext Database, Stream TemplateFile)
{ {
string filePath = dt.RepositoryFilename(Database); string filePath = dt.RepositoryFilename(Database);
@@ -17,7 +18,7 @@ namespace Disco.Services
{ {
TemplateFile.CopyTo(fs); TemplateFile.CopyTo(fs);
} }
Expressions.ExpressionCache.InvalidModule(string.Format(DocumentTemplateExpressionExtensions.CacheTemplate, dt.Id)); Expressions.ExpressionCache.InvalidateCache(dt);
return filePath; return filePath;
} }
} }
@@ -10,19 +10,17 @@ namespace Disco.Services
{ {
public static class DocumentTemplateExpressionExtensions public static class DocumentTemplateExpressionExtensions
{ {
internal const string CacheTemplate = "DocumentTemplate_{0}";
public static Expression FilterExpressionFromCache(this DocumentTemplate dt) public static Expression FilterExpressionFromCache(this DocumentTemplate dt)
{ {
return ExpressionCache.GetValue("DocumentTemplate_FilterExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.FilterExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplate_FilterExpression_{dt.Id}", () => Expression.TokenizeSingleDynamic(null, dt.FilterExpression, 0));
} }
public static void FilterExpressionInvalidateCache(this DocumentTemplate dt) public static void FilterExpressionInvalidateCache(this DocumentTemplate dt)
{ {
ExpressionCache.InvalidateKey("DocumentTemplate_FilterExpression", dt.Id); ExpressionCache.InvalidateSingleCache($"DocumentTemplate_FilterExpression_{dt.Id}");
} }
public static bool FilterExpressionMatches(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState State) public static bool FilterExpressionMatches(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
{ {
if (!string.IsNullOrEmpty(dt.FilterExpression)) if (!string.IsNullOrEmpty(dt.FilterExpression))
{ {
@@ -51,12 +49,12 @@ namespace Disco.Services
public static Expression OnImportAttachmentExpressionFromCache(this DocumentTemplate dt) public static Expression OnImportAttachmentExpressionFromCache(this DocumentTemplate dt)
{ {
return ExpressionCache.GetValue("DocumentTemplate_OnImportExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.OnImportAttachmentExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplate_OnImportExpression_{dt.Id}", () => Expression.TokenizeSingleDynamic(null, dt.OnImportAttachmentExpression, 0));
} }
public static void OnImportAttachmentExpressionInvalidateCache(this DocumentTemplate dt) public static void OnImportAttachmentExpressionInvalidateCache(this DocumentTemplate dt)
{ {
ExpressionCache.InvalidateKey("DocumentTemplate_OnImportExpression", dt.Id); ExpressionCache.InvalidateSingleCache($"DocumentTemplate_OnImportExpression_{dt.Id}");
} }
public static string EvaluateOnAttachmentImportExpression(this DocumentTemplate dt, IAttachment Data, IAttachmentTarget AttachmentTarget, DiscoDataContext Database, User User, DateTime TimeStamp, List<DocumentUniqueIdentifier> PageIdentifiers) public static string EvaluateOnAttachmentImportExpression(this DocumentTemplate dt, IAttachment Data, IAttachmentTarget AttachmentTarget, DiscoDataContext Database, User User, DateTime TimeStamp, List<DocumentUniqueIdentifier> PageIdentifiers)
@@ -77,12 +75,12 @@ namespace Disco.Services
public static Expression OnGenerateExpressionFromCache(this DocumentTemplate dt) public static Expression OnGenerateExpressionFromCache(this DocumentTemplate dt)
{ {
return ExpressionCache.GetValue("DocumentTemplate_OnGenerateExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.OnGenerateExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplate_OnGenerateExpression_{dt.Id}", () => Expression.TokenizeSingleDynamic(null, dt.OnGenerateExpression, 0));
} }
public static void OnGenerateExpressionInvalidateCache(this DocumentTemplate dt) public static void OnGenerateExpressionInvalidateCache(this DocumentTemplate dt)
{ {
ExpressionCache.InvalidateKey("DocumentTemplate_OnGenerateExpression", dt.Id); ExpressionCache.InvalidateSingleCache($"DocumentTemplate_OnGenerateExpression_{dt.Id}");
} }
public static string EvaluateOnGenerateExpression(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State) public static string EvaluateOnGenerateExpression(this DocumentTemplate dt, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
@@ -73,12 +73,12 @@ namespace Disco.Services
public static Expression FilterExpressionFromCache(this DocumentTemplatePackage package) public static Expression FilterExpressionFromCache(this DocumentTemplatePackage package)
{ {
return ExpressionCache.GetValue("DocumentTemplatePackage_FilterExpression", package.Id, () => { return Expression.TokenizeSingleDynamic(null, package.FilterExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplatePackage_FilterExpression_{package.Id}", () => Expression.TokenizeSingleDynamic(null, package.FilterExpression, 0));
} }
public static void FilterExpressionInvalidateCache(this DocumentTemplatePackage package) public static void FilterExpressionInvalidateCache(this DocumentTemplatePackage package)
{ {
ExpressionCache.InvalidateKey("DocumentTemplatePackage_FilterExpression", package.Id); ExpressionCache.InvalidateSingleCache($"DocumentTemplatePackage_FilterExpression_{package.Id}");
} }
public static bool FilterExpressionMatches(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State) public static bool FilterExpressionMatches(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
@@ -111,12 +111,12 @@ namespace Disco.Services
public static Expression OnGenerateExpressionFromCache(this DocumentTemplatePackage package) public static Expression OnGenerateExpressionFromCache(this DocumentTemplatePackage package)
{ {
return ExpressionCache.GetValue("DocumentTemplatePackage_OnGenerateExpression", package.Id, () => { return Expression.TokenizeSingleDynamic(null, package.OnGenerateExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions($"DocumentTemplatePackage_OnGenerateExpression_{package.Id}", () => Expression.TokenizeSingleDynamic(null, package.OnGenerateExpression, 0));
} }
public static void OnGenerateExpressionInvalidateCache(this DocumentTemplatePackage package) public static void OnGenerateExpressionInvalidateCache(this DocumentTemplatePackage package)
{ {
ExpressionCache.InvalidateKey("DocumentTemplatePackage_OnGenerateExpression", package.Id); ExpressionCache.InvalidateSingleCache($"DocumentTemplatePackage_OnGenerateExpression_{package.Id}");
} }
public static string EvaluateOnGenerateExpression(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State) public static string EvaluateOnGenerateExpression(this DocumentTemplatePackage package, IAttachmentTarget Data, DiscoDataContext Database, User User, DateTime TimeStamp, DocumentState State)
-1
View File
@@ -9,7 +9,6 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Text; using System.Text;
namespace Disco.Services.Expressions namespace Disco.Services.Expressions
+62 -78
View File
@@ -1,99 +1,83 @@
using System.Collections.Concurrent; using Disco.Models.Repository;
using Disco.Models.Services.Documents;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace Disco.Services.Expressions namespace Disco.Services.Expressions
{ {
public static class ExpressionCache public static class ExpressionCache
{ {
private static ConcurrentDictionary<string, ConcurrentDictionary<string, Expression>> _Cache = new ConcurrentDictionary<string, ConcurrentDictionary<string, Expression>>(); private static ConcurrentDictionary<string, Expression> singleCache = new ConcurrentDictionary<string, Expression>();
private static ConcurrentDictionary<string, Dictionary<string, Expression>> cache = new ConcurrentDictionary<string, Dictionary<string, Expression>>();
private static ConcurrentDictionary<string, List<DocumentField>> fieldCache = new ConcurrentDictionary<string, List<DocumentField>>();
public delegate Expression CreateValueDelegate(); private const string DocumentTemplateCacheTemplate = "DocumentTemplate_{0}";
public static ConcurrentDictionary<string, Expression> GetModule(string Module, bool Create = false) public static Expression GetOrCreateSingleExpressions(string key, Func<Expression> create)
{ {
ConcurrentDictionary<string, Expression> moduleCache; if (singleCache.TryGetValue(key, out var result))
if (_Cache.TryGetValue(Module, out moduleCache)) return result;
return moduleCache;
else else
{ {
if (Create) result = create();
{ singleCache.TryAdd(key, result);
moduleCache = new ConcurrentDictionary<string, Expression>(); return result;
_Cache.TryAdd(Module, moduleCache);
return moduleCache;
}
else
return null;
} }
} }
private static Expression GetModuleValue(string Module, string Key, CreateValueDelegate CreateValue)
{
ConcurrentDictionary<string, Expression> moduleCache = GetModule(Module, (CreateValue != null));
if (moduleCache != null)
{
Expression expression;
if (moduleCache.TryGetValue(Key, out expression))
{
return expression;
}
if (CreateValue != null)
{
expression = CreateValue();
Expression oldExpression;
if (moduleCache.TryGetValue(Key, out oldExpression))
moduleCache.TryUpdate(Key, expression, oldExpression);
else
moduleCache.TryAdd(Key, expression);
return expression;
}
}
return null;
}
public static Expression GetValue(string Module, string Key, CreateValueDelegate CreateValue) public static Dictionary<string, Expression> GetOrCreateExpressions(string module, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{ {
return GetModuleValue(Module, Key, CreateValue); if (cache.TryGetValue(module, out var result))
} return result;
public static Expression GetValue(string Module, string Key)
{
return GetModuleValue(Module, Key, null);
}
public static bool InvalidModule(string Module)
{
ConcurrentDictionary<string, Expression> moduleCache;
return _Cache.TryRemove(Module, out moduleCache);
}
public static bool InvalidateKey(string Module, string Key)
{
Expression expression;
ConcurrentDictionary<string, Expression> moduleCache = GetModule(Module, false);
if (moduleCache != null)
{
bool removeResult = moduleCache.TryRemove(Key, out expression);
if (moduleCache.Count == 0)
InvalidModule(Module);
return removeResult;
}
else else
return false;
}
public static bool SetValue(string Module, string Key, Expression Expression)
{
ConcurrentDictionary<string, Expression> moduleCache = GetModule(Module, true);
if (moduleCache.ContainsKey(Key))
{ {
Expression oldExpression; return Create(module, create).Item1;
if (moduleCache.TryGetValue(Key, out oldExpression))
{
return moduleCache.TryUpdate(Key, Expression, oldExpression);
}
} }
return moduleCache.TryAdd(Key, Expression);
} }
public static List<DocumentField> GetOrCreateFields(string module, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{
if (fieldCache.TryGetValue(module, out var result))
return result;
else
{
return Create(module, create).Item2;
}
}
public static void InvalidateCache(DocumentTemplate template)
{
InvalidateCache(string.Format(DocumentTemplateCacheTemplate, template.Id));
}
public static void InvalidateCache(string module)
{
cache.TryRemove(module, out _);
fieldCache.TryRemove(module, out _);
}
public static void InvalidateSingleCache(string key)
{
singleCache.TryRemove(key, out _);
}
public static Dictionary<string, Expression> GetOrCreateExpressions(DocumentTemplate template, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{
return GetOrCreateExpressions(string.Format(DocumentTemplateCacheTemplate, template.Id), create);
}
public static List<DocumentField> GetOrCreateFields(DocumentTemplate template, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{
return GetOrCreateFields(string.Format(DocumentTemplateCacheTemplate, template.Id), create);
}
private static Tuple<Dictionary<string, Expression>, List<DocumentField>> Create(string module, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{
var results = create();
cache.TryAdd(module, results.Item1);
fieldCache.TryAdd(module, results.Item2);
return results;
}
} }
} }
+4 -4
View File
@@ -123,22 +123,22 @@ namespace Disco.Services.Jobs
public static Expression OnCreateExpressionFromCache(DiscoDataContext Database) public static Expression OnCreateExpressionFromCache(DiscoDataContext Database)
{ {
return ExpressionCache.GetValue("Job_OnCreateExpression", string.Empty, () => { return Expression.TokenizeSingleDynamic(null, Database.DiscoConfiguration.JobPreferences.OnCreateExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions("Job_OnCreateExpression", () => Expression.TokenizeSingleDynamic(null, Database.DiscoConfiguration.JobPreferences.OnCreateExpression, 0));
} }
public static void OnCreateExpressionInvalidateCache() public static void OnCreateExpressionInvalidateCache()
{ {
ExpressionCache.InvalidateKey("Job_OnCreateExpression", string.Empty); ExpressionCache.InvalidateSingleCache("Job_OnCreateExpression");
} }
public static Expression OnCloseExpressionFromCache(DiscoDataContext Database) public static Expression OnCloseExpressionFromCache(DiscoDataContext Database)
{ {
return ExpressionCache.GetValue("Job_OnCloseExpression", string.Empty, () => { return Expression.TokenizeSingleDynamic(null, Database.DiscoConfiguration.JobPreferences.OnCloseExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions("Job_OnCloseExpression", () => Expression.TokenizeSingleDynamic(null, Database.DiscoConfiguration.JobPreferences.OnCloseExpression, 0));
} }
public static void OnCloseExpressionInvalidateCache() public static void OnCloseExpressionInvalidateCache()
{ {
ExpressionCache.InvalidateKey("Job_OnCloseExpression", string.Empty); ExpressionCache.InvalidateSingleCache("Job_OnCloseExpression");
} }
} }
@@ -133,12 +133,12 @@ namespace Disco.Services
public static Expression OnAssignmentExpressionFromCache(this UserFlag uf) public static Expression OnAssignmentExpressionFromCache(this UserFlag uf)
{ {
return ExpressionCache.GetValue("UserFlag_OnAssignmentExpression", uf.Id.ToString(), () => { return Expression.TokenizeSingleDynamic(null, uf.OnAssignmentExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions($"UserFlag_OnAssignmentExpression_{uf.Id}", () => Expression.TokenizeSingleDynamic(null, uf.OnAssignmentExpression, 0));
} }
public static void OnAssignmentExpressionInvalidateCache(this UserFlag uf) public static void OnAssignmentExpressionInvalidateCache(this UserFlag uf)
{ {
ExpressionCache.InvalidateKey("UserFlag_OnAssignmentExpression", uf.Id.ToString()); ExpressionCache.InvalidateSingleCache($"UserFlag_OnAssignmentExpression_{uf.Id}");
} }
public static string EvaluateOnAssignmentExpression(this UserFlagAssignment ufa, DiscoDataContext Database, User AddingUser, DateTime TimeStamp) public static string EvaluateOnAssignmentExpression(this UserFlagAssignment ufa, DiscoDataContext Database, User AddingUser, DateTime TimeStamp)
@@ -158,12 +158,12 @@ namespace Disco.Services
public static Expression OnUnassignmentExpressionFromCache(this UserFlag uf) public static Expression OnUnassignmentExpressionFromCache(this UserFlag uf)
{ {
return ExpressionCache.GetValue("UserFlag_OnUnassignmentExpression", uf.Id.ToString(), () => { return Expression.TokenizeSingleDynamic(null, uf.OnUnassignmentExpression, 0); }); return ExpressionCache.GetOrCreateSingleExpressions($"UserFlag_OnUnassignmentExpression_{uf.Id}", () => Expression.TokenizeSingleDynamic(null, uf.OnUnassignmentExpression, 0));
} }
public static void OnUnassignmentExpressionInvalidateCache(this UserFlag uf) public static void OnUnassignmentExpressionInvalidateCache(this UserFlag uf)
{ {
ExpressionCache.InvalidateKey("UserFlag_OnUnassignmentExpression", uf.Id.ToString()); ExpressionCache.InvalidateSingleCache($"UserFlag_OnUnassignmentExpression_{uf.Id}");
} }
public static string EvaluateOnUnassignmentExpression(this UserFlagAssignment ufa, DiscoDataContext Database, User RemovingUser, DateTime TimeStamp) public static string EvaluateOnUnassignmentExpression(this UserFlagAssignment ufa, DiscoDataContext Database, User RemovingUser, DateTime TimeStamp)
@@ -1231,6 +1231,8 @@ namespace Disco.Web.Areas.API.Controllers
} }
} }
[HttpPost, ValidateAntiForgeryToken]
[DiscoAuthorizeAll(Claims.Config.DocumentTemplate.Configure, Claims.Config.UserFlag.Configure)]
public virtual ActionResult AddOnImportUserFlagRule([Required] string id, bool? addFlag = null, int? userFlagId = null, string comments = null) public virtual ActionResult AddOnImportUserFlagRule([Required] string id, bool? addFlag = null, int? userFlagId = null, string comments = null)
{ {
try try