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,16 +18,12 @@ 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)
{
Dictionary<string, Expression> expressions = new Dictionary<string, Expression>();
List<DocumentField> fields = new List<DocumentField>();
public static ConcurrentDictionary<string, Expression> PdfExpressionsFromCache(this DocumentTemplate dt, DiscoDataContext Database) string templateFilename = dt.RepositoryFilename(database);
{
string cacheModuleKey = string.Format(CacheTemplate, dt.Id);
var module = ExpressionCache.GetModule(cacheModuleKey);
if (module == null)
{
// Cache
string templateFilename = dt.RepositoryFilename(Database);
PdfReader pdfReader = new PdfReader(templateFilename); PdfReader pdfReader = new PdfReader(templateFilename);
int pdfFieldOrdinal = 0; int pdfFieldOrdinal = 0;
foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys) foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys)
@@ -48,14 +41,35 @@ namespace Disco.BI.Extensions
var position = pdfFieldPositions.First().position; var position = pdfFieldPositions.First().position;
pdfFieldPosition = new RectangleF(position.Left, position.Top, position.Width, position.Height); pdfFieldPosition = new RectangleF(position.Left, position.Top, position.Width, position.Height);
} }
var fieldTypeId = pdfReader.AcroFields.GetFieldType(pdfFieldKey);
var fieldType = DocumentFieldType.None;
if (fieldTypeId <= 8 && fieldTypeId > 0)
fieldType = (DocumentFieldType)fieldTypeId;
ExpressionCache.SetValue(cacheModuleKey, pdfFieldKey, Expression.Tokenize(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal, isRequired, isReadOnly, pdfFieldPosition)); 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++; pdfFieldOrdinal++;
} }
pdfReader.Close(); pdfReader.Close();
module = ExpressionCache.GetModule(cacheModuleKey, true);
return Tuple.Create(expressions, fields);
} }
return module;
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
+47 -63
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;
} }
}
public static Dictionary<string, Expression> GetOrCreateExpressions(string module, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{
if (cache.TryGetValue(module, out var result))
return result;
else else
return null; {
return Create(module, create).Item1;
} }
} }
private static Expression GetModuleValue(string Module, string Key, CreateValueDelegate CreateValue)
public static List<DocumentField> GetOrCreateFields(string module, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{ {
ConcurrentDictionary<string, Expression> moduleCache = GetModule(Module, (CreateValue != null)); if (fieldCache.TryGetValue(module, out var result))
if (moduleCache != null) return result;
{
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 else
moduleCache.TryAdd(Key, expression); {
return expression; return Create(module, create).Item2;
} }
} }
return null;
}
public static Expression GetValue(string Module, string Key, CreateValueDelegate CreateValue) public static void InvalidateCache(DocumentTemplate template)
{ {
return GetModuleValue(Module, Key, CreateValue); InvalidateCache(string.Format(DocumentTemplateCacheTemplate, template.Id));
} }
public static Expression GetValue(string Module, string Key) public static void InvalidateCache(string module)
{ {
return GetModuleValue(Module, Key, null); cache.TryRemove(module, out _);
fieldCache.TryRemove(module, out _);
} }
public static bool InvalidModule(string Module) public static void InvalidateSingleCache(string key)
{ {
ConcurrentDictionary<string, Expression> moduleCache; singleCache.TryRemove(key, out _);
return _Cache.TryRemove(Module, out moduleCache);
} }
public static bool InvalidateKey(string Module, string Key) public static Dictionary<string, Expression> GetOrCreateExpressions(DocumentTemplate template, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{ {
Expression expression; return GetOrCreateExpressions(string.Format(DocumentTemplateCacheTemplate, template.Id), create);
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
return false;
} }
public static bool SetValue(string Module, string Key, Expression Expression) public static List<DocumentField> GetOrCreateFields(DocumentTemplate template, Func<Tuple<Dictionary<string, Expression>, List<DocumentField>>> create)
{ {
ConcurrentDictionary<string, Expression> moduleCache = GetModule(Module, true); return GetOrCreateFields(string.Format(DocumentTemplateCacheTemplate, template.Id), create);
if (moduleCache.ContainsKey(Key))
{
Expression oldExpression;
if (moduleCache.TryGetValue(Key, out oldExpression))
{
return moduleCache.TryUpdate(Key, Expression, oldExpression);
}
}
return moduleCache.TryAdd(Key, Expression);
} }
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