refactor expression caching; add document fields
This commit is contained in:
@@ -6,12 +6,9 @@ using Disco.Services.Documents;
|
||||
using Disco.Services.Documents.ManagedGroups;
|
||||
using Disco.Services.Expressions;
|
||||
using Disco.Services.Interop.ActiveDirectory;
|
||||
using Disco.Services.Tasks;
|
||||
using iTextSharp.text.pdf;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Entity;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
@@ -21,41 +18,58 @@ namespace Disco.BI.Extensions
|
||||
{
|
||||
public static class DocumentTemplateExtensions
|
||||
{
|
||||
internal const string CacheTemplate = "DocumentTemplate_{0}";
|
||||
|
||||
public static ConcurrentDictionary<string, Expression> PdfExpressionsFromCache(this DocumentTemplate dt, DiscoDataContext Database)
|
||||
private static Tuple<Dictionary<string, Expression>, List<DocumentField>> CreateExpressions(DocumentTemplate dt, DiscoDataContext database)
|
||||
{
|
||||
string cacheModuleKey = string.Format(CacheTemplate, dt.Id);
|
||||
var module = ExpressionCache.GetModule(cacheModuleKey);
|
||||
if (module == null)
|
||||
Dictionary<string, Expression> expressions = new Dictionary<string, Expression>();
|
||||
List<DocumentField> fields = new List<DocumentField>();
|
||||
|
||||
string templateFilename = dt.RepositoryFilename(database);
|
||||
PdfReader pdfReader = new PdfReader(templateFilename);
|
||||
int pdfFieldOrdinal = 0;
|
||||
foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys)
|
||||
{
|
||||
// Cache
|
||||
string templateFilename = dt.RepositoryFilename(Database);
|
||||
PdfReader pdfReader = new PdfReader(templateFilename);
|
||||
int pdfFieldOrdinal = 0;
|
||||
foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys)
|
||||
var pdfField = pdfReader.AcroFields.Fields[pdfFieldKey];
|
||||
var pdfFieldPositions = pdfReader.AcroFields.GetFieldPositions(pdfFieldKey);
|
||||
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 pdfField = pdfReader.AcroFields.Fields[pdfFieldKey];
|
||||
var pdfFieldPositions = pdfReader.AcroFields.GetFieldPositions(pdfFieldKey);
|
||||
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++;
|
||||
var position = pdfFieldPositions.First().position;
|
||||
pdfFieldPosition = new RectangleF(position.Left, position.Top, position.Width, position.Height);
|
||||
}
|
||||
pdfReader.Close();
|
||||
module = ExpressionCache.GetModule(cacheModuleKey, true);
|
||||
var fieldTypeId = pdfReader.AcroFields.GetFieldType(pdfFieldKey);
|
||||
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)
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace Disco.BI.Interop.Pdf
|
||||
if (dt.FlattenForm)
|
||||
FlattenFields = true;
|
||||
|
||||
ConcurrentDictionary<string, Expression> expressionCache = dt.PdfExpressionsFromCache(Database);
|
||||
var expressionCache = dt.PdfExpressionsFromCache(Database);
|
||||
|
||||
string templateFilename = dt.RepositoryFilename(Database);
|
||||
PdfReader pdfReader = new PdfReader(templateFilename);
|
||||
|
||||
@@ -68,6 +68,8 @@
|
||||
<Compile Include="Services\Devices\Exporting\DeviceExportFieldMetadata.cs" />
|
||||
<Compile Include="Services\Devices\Importing\IDeviceImportColumn.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\OnImportUserFlagRule.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,
|
||||
}
|
||||
}
|
||||
@@ -21,12 +21,8 @@ namespace Disco.Services
|
||||
|
||||
var deviceProfile = device.DeviceProfile;
|
||||
Expression computerNameTemplateExpression = null;
|
||||
computerNameTemplateExpression = ExpressionCache.GetValue(DeviceProfileExtensions.ComputerNameExpressionCacheModule, deviceProfile.Id.ToString(), () =>
|
||||
{
|
||||
// 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);
|
||||
});
|
||||
computerNameTemplateExpression = ExpressionCache.GetOrCreateSingleExpressions(string.Format(DeviceProfileExtensions.ComputerNameExpressionCacheTemplate, deviceProfile.Id),
|
||||
() => Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0));
|
||||
var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null, device);
|
||||
string rendered;
|
||||
try
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace Disco.Services
|
||||
{
|
||||
public static class DeviceProfileExtensions
|
||||
{
|
||||
public const string ComputerNameExpressionCacheModule = "ComputerNameTemplate";
|
||||
public const string ComputerNameExpressionCacheTemplate = "ComputerNameTemplate_{0}";
|
||||
|
||||
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)
|
||||
|
||||
@@ -8,8 +8,9 @@ namespace Disco.Services
|
||||
{
|
||||
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)
|
||||
{
|
||||
string filePath = dt.RepositoryFilename(Database);
|
||||
@@ -17,7 +18,7 @@ namespace Disco.Services
|
||||
{
|
||||
TemplateFile.CopyTo(fs);
|
||||
}
|
||||
Expressions.ExpressionCache.InvalidModule(string.Format(DocumentTemplateExpressionExtensions.CacheTemplate, dt.Id));
|
||||
Expressions.ExpressionCache.InvalidateCache(dt);
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,19 +10,17 @@ namespace Disco.Services
|
||||
{
|
||||
public static class DocumentTemplateExpressionExtensions
|
||||
{
|
||||
internal const string CacheTemplate = "DocumentTemplate_{0}";
|
||||
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
@@ -51,12 +49,12 @@ namespace Disco.Services
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@@ -77,12 +75,12 @@ namespace Disco.Services
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -73,12 +73,12 @@ namespace Disco.Services
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@@ -111,12 +111,12 @@ namespace Disco.Services
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -9,7 +9,6 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Disco.Services.Expressions
|
||||
|
||||
@@ -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
|
||||
{
|
||||
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 (_Cache.TryGetValue(Module, out moduleCache))
|
||||
return moduleCache;
|
||||
if (singleCache.TryGetValue(key, out var result))
|
||||
return result;
|
||||
else
|
||||
{
|
||||
if (Create)
|
||||
{
|
||||
moduleCache = new ConcurrentDictionary<string, Expression>();
|
||||
_Cache.TryAdd(Module, moduleCache);
|
||||
return moduleCache;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
result = create();
|
||||
singleCache.TryAdd(key, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (cache.TryGetValue(module, out var result))
|
||||
return result;
|
||||
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;
|
||||
if (moduleCache.TryGetValue(Key, out oldExpression))
|
||||
{
|
||||
return moduleCache.TryUpdate(Key, Expression, oldExpression);
|
||||
}
|
||||
return Create(module, create).Item1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,22 +123,22 @@ namespace Disco.Services.Jobs
|
||||
|
||||
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()
|
||||
{
|
||||
ExpressionCache.InvalidateKey("Job_OnCreateExpression", string.Empty);
|
||||
ExpressionCache.InvalidateSingleCache("Job_OnCreateExpression");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
ExpressionCache.InvalidateKey("Job_OnCloseExpression", string.Empty);
|
||||
ExpressionCache.InvalidateSingleCache("Job_OnCloseExpression");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -133,12 +133,12 @@ namespace Disco.Services
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@@ -158,12 +158,12 @@ namespace Disco.Services
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user