internal WriteCustomSettings(IDataLoaderContext execContext, KraftGlobalConfigurationSettings kraftGlobalConfigurationSettings) : base(execContext, kraftGlobalConfigurationSettings) { long? maxFilesSpacePerDashboardInMB = null; double?previewHeight = null; double?previewWidth = null; if (execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(MAXFILESPACEPERDASHBOARDINMB, out string maxFilesLengthAsString)) { if (long.TryParse(maxFilesLengthAsString, out long maxFilesLength)) { if (maxFilesLength < 0L) { throw new Exception($"{MAXFILESPACEPERDASHBOARDINMB} cannot be less than zero."); } maxFilesSpacePerDashboardInMB = maxFilesLength; } } MaxFilesSpacePerDashboardInMB = maxFilesSpacePerDashboardInMB; if (execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(PREVIEWHEIGHT, out string previewHeightAsString)) { previewHeight = ParseDouble(previewHeightAsString); } PreviewHeight = previewHeight; if (execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(PREVIEWWIDTHT, out string previewWidthAsString)) { previewWidth = ParseDouble(previewWidthAsString); } PreviewWidth = previewWidth; }
private string FindValue(string name, IDataLoaderContext execContext, bool isWrite) { ParameterResolverValue parameterReolverValue = execContext.Evaluate(name); if (parameterReolverValue.Value != null && parameterReolverValue.ValueDataType == EValueDataType.Text) { return(parameterReolverValue.Value.ToString()); } else { string value = execContext.CurrentNode.Parameters.FirstOrDefault(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase))?.Expression; if (isWrite) { if (value == default(string)) { value = execContext.CurrentNode.Write?.Parameters.FirstOrDefault(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase))?.Expression; } } else { if (value == default(string)) { value = execContext.CurrentNode.Read?.Parameters.FirstOrDefault(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase))?.Expression; } } return(value); } }
private void OnLoadRequested(IDataLoaderTrigger trigger, IDataLoaderContext context) { // This operation is not cancellable from the trigger itself. // The operation will be cancelled if the loader is disposed. context = context ?? new DataLoaderContext(); var cancellationToken = CancellationToken.None; var sequenceId = Interlocked.Increment(ref _sequenceId); PopulateContext(context); _ = LoadFromTrigger(cancellationToken, new DataLoaderRequest(sequenceId, trigger, context, _contextValues)); async Task LoadFromTrigger(CancellationToken ct, DataLoaderRequest request) { try { await InnerLoad(ct, request); } catch (Exception e) { if (_logger.IsEnabled(LogLevel.Error)) { _logger.LogError(e, "Caught unhandled exception during Load operation. Prefer injecting a strategy that handles all exceptions in your application code."); } } } }
protected string GetQuery(IDataLoaderContext ctx) { if (ctx.Action == ModelConstants.ACTION_READ) { var op = ctx.CurrentNode?.Read?.Select; if (op != null) { return(op.Query); } } else if (ctx.Action == ModelConstants.ACTION_WRITE) { switch (ctx.Operation) { case ModelConstants.OPERATION_INSERT: return(ctx.CurrentNode?.Write?.Insert?.Query); case ModelConstants.OPERATION_UPDATE: return(ctx.CurrentNode?.Write?.Update?.Query); case ModelConstants.OPERATION_DELETE: return(ctx.CurrentNode?.Write?.Delete?.Query); } } return(null); }
/// <summary> /// /// </summary> /// <param name="ctx"></param> /// <param name="args">(IPostedFile pf, string savepath)</param> /// <returns></returns> public ParameterResolverValue SaveFile(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 2) { throw new ArgumentException("Save file takes two arguments: file, save_path"); } IPostedFile file = args[0].Value as IPostedFile; string savepath = args[1].Value as string; if (savepath == null || file == null) { throw new ArgumentException("SaveFile: either file, path or both are null"); } if (!Path.IsPathFullyQualified(savepath)) { throw new ArgumentException("SaveFile the specified path is not fully qualified. Did you forget to combine paths?"); } using (var stream = new FileStream(savepath, FileMode.Create)) { file.OpenReadStream().CopyTo(stream); } var scope = Scope(ctx); scope.DeleteOnRollback(savepath); return(new ParameterResolverValue(true)); }
//public Task<object> ExecuteAsync(IDataLoaderContext execContext) //{ // object returnResult = null; // Configuration cfg = ReadConfiguration(execContext); // if (!string.IsNullOrEmpty(cfg.Statement)) { // returnResult = ProcessStatement(cfg.Statement, execContext); // } // return Task.FromResult(returnResult); //} private Dictionary <string, object> ProcessStatement(string statement, IDataLoaderContext execContext) { Dictionary <string, object> results = new Dictionary <string, object>(); Match m = _reg.Match(statement); while (m.Success) { if (m.Groups[2].Success) { string paramname = m.Groups[2].Value; string jsonkey = (m.Groups[4].Success) ? m.Groups[4].Value : m.Groups[2].Value; // if no alias specifyed we assume the paramname. var v = execContext.Evaluate(paramname); if ((int)v.ValueType >= 0) { var resolverValue = ResolverValueDataTypeMap(v.ValueDataType, v.Value); switch (v.ValueType) { case EResolverValueType.ValueType: bool resultIsCollection = (v.ValueDataType & EValueDataType.Collection) != 0; if (results.Any()) { if (resultIsCollection) { throw new Exception("Only the first expression is permited to return a collection"); } ReCodeResolverValue(resolverValue, ref results, jsonkey); } else { if (resultIsCollection) { ReCodeResolverValue(resolverValue, ref results, jsonkey); } else { results.Add(jsonkey, resolverValue); } } break; default: break; // We shouldn't fall into this case ? } } } else { throw new Exception("While parsing query we received match with invalid second group (which should be impossible)"); } m = m.NextMatch(); } return(results); }
public ParameterResolverValue IsPostedFile(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 1) { throw new ArgumentException("IsFile accepts single argument."); } return(new ParameterResolverValue(args[0].Value is IPostedFile)); }
private string GetAuthAccessToken(IDataLoaderContext execContext) { IHttpContextAccessor httpContextAccessor = execContext.PluginServiceManager.GetService <IHttpContextAccessor>(typeof(HttpContextAccessor)); Task <string> accessTokenTask = httpContextAccessor.HttpContext.GetTokenAsync(OpenIdConnectDefaults.AuthenticationScheme, OpenIdConnectParameterNames.AccessToken); return(accessTokenTask.Result); }
public ParameterResolverValue FileExists(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 1) { throw new ArgumentException("FileExists requies one argument - the path to the file"); } var path = Convert.ToString(args[0].Value); return(new ParameterResolverValue(File.Exists(path))); }
/// <inheritdoc cref="IDataLoader.Load(CancellationToken, IDataLoaderContext)"/> public Task <object> Load(CancellationToken ct, IDataLoaderContext context = null) { context = context ?? new DataLoaderContext(); _manualTrigger = _manualTrigger ?? new ManualDataLoaderTrigger($"{Name}.ManualTrigger"); var sequenceId = Interlocked.Increment(ref _sequenceId); PopulateContext(context); return(InnerLoad(ct, new DataLoaderRequest(sequenceId, _manualTrigger, context, _contextValues))); }
/// <summary> /// Produces a standard identification line for the location of the error /// </summary> /// <param name="ctx"></param> /// <param name="plugin">Must be supplied by the plugin in a human readable but concise manner.</param> /// <returns></returns> public static string LocationInfo(this IDataLoaderContext ctx, string plugin) { string module = ctx.ProcessingContext.InputModel.Module; string nodepath = ctx.ProcessingContext.InputModel.Nodepath; string nodeset = ctx.ProcessingContext.InputModel.NodeSet; string currentNode = ctx.CurrentNode.NodeKey; string action = ctx.Action; string operation = ctx.Operation; return($"Location: {module}:{nodeset}/{nodepath} ({currentNode}|{action}|{operation}) {plugin ?? ""}"); }
/// <summary> /// Gets the <see cref="SequenceDisposableGroup"/> of this <paramref name="context"/>. /// If none exists, it's automatically created and added. /// </summary> /// <param name="context">The context from which to retrieve the <see cref="SequenceDisposableGroup"/> object.</param> /// <returns>The <see cref="SequenceDisposableGroup"/> of this <paramref name="context"/>.</returns> public static SequenceDisposableGroup GetSequenceDisposableGroup(this IDataLoaderContext context) { if (context.TryGetValue(DisposeWithNextLoadKey, out var lifetime)) { return((SequenceDisposableGroup)lifetime); } else { var contextLifetime = new SequenceDisposableGroup(); context.Add(DisposeWithNextLoadKey, contextLifetime); return(contextLifetime); } }
/// <summary> /// File names will look like 345-somename.jpg /// </summary> /// <param name="ctx"></param> /// <param name="args">(sring basedir, int spread, long id, IPostedFile file)</param> /// <returns></returns> public ParameterResolverValue SaveFileToSpread(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 4) { throw new ArgumentException("SaveFileToSpread requires 4 arguments (sring basedir, int spread, long id, string filename)"); } string basedir; int spread; long id; IPostedFile file; try { basedir = args[0].Value as string; spread = Convert.ToInt32(args[1].Value); id = Convert.ToInt64(args[2].Value); file = args[3].Value as IPostedFile; if (file == null) { throw new ArgumentException("filename is not a posted file"); } } catch (Exception ex) { throw new ArgumentException("SaveFileToSpread has some invalid arguments", ex); } if (!Directory.Exists(basedir)) { Directory.CreateDirectory(basedir); } string subdir = (id % spread).ToString(); string filedir = Path.Combine(basedir, subdir); if (!Directory.Exists(filedir)) { Directory.CreateDirectory(filedir); } string filespreaddir = Path.Combine(subdir, $"{id}-{file.FileName}"); string filefullpath = Path.Combine(basedir, filespreaddir); // Saving using (var stream = new FileStream(filefullpath, FileMode.Create)) { file.OpenReadStream().CopyTo(stream); } var scope = Scope(ctx); scope.DeleteOnRollback(filefullpath); return(new ParameterResolverValue(filespreaddir)); }
public ParameterResolverValue PostedFileType(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 1) { throw new ArgumentException("PostedFileSize requires single argument"); } var pf = args[0].Value as IPostedFile; if (pf == null) { throw new ArgumentException("PostedFileSize argument is not a posted file"); } return(new ParameterResolverValue(pf.ContentType)); }
/// <summary> /// Performs the standard processing - extract parameters, replacing those that resolve to literals (ValueType == ContentType) /// and binding to the command the ValueType ones. /// To avoid potential discrepancies with DbCommand implementations the SQL is supplied separately and set only once to the command. /// </summary> /// <param name="cmd"></param> /// <param name="sql"></param> /// <param name="execContext"></param> protected virtual string ProcessCommand(DbCommand cmd, string sql, IDataLoaderContext execContext) { if (string.IsNullOrWhiteSpace(sql)) { return(null); // We just do nothing in this case. } Regex reg = new Regex(@"@([a-zA-Z_][a-zA-Z0-9_\$]*)", RegexOptions.None); // This should be configurable string result = reg.Replace(sql, m => { if (m.Groups[1].Success) { var paramname = m.Groups[1].Value; // Evaluate the parameter var v = execContext.Evaluate(paramname); if ((int)v.ValueType >= 0) { switch (v.ValueType) { case EResolverValueType.ValueType: if ((v.ValueDataType & EValueDataType.Collection) != 0 && SupportTableParameters == false) { throw new Exception("Loader doesn't support Table-Valued Parameters"); } // Bind value BindParameter(cmd, paramname, v); return("@" + paramname); case EResolverValueType.Skip: return("@" + paramname); default: // Replace text // We ignore all kinds of type info and we just use ToString(); string x = v.Value == null ? "" : v.Value.ToString(); return(x); } }// else skip the rest and leave them unbound. TODO: We will see if this is the correct default behavior. } else { throw new Exception("While parsing SQL we received match with invalid first group (which should be impossible)"); } return(m.Value); }); cmd.CommandText = result; return(result); }
public ParameterResolverValue FileResponse(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 1) { throw new ArgumentException("FileResponse accepts 1 argument (PostedFile)"); } var pf = args[0].Value as IPostedFile; if (pf == null) { throw new ArgumentException("FileResponse - argument is not IPostedFile. Use FileResponse(PostedFile(...))"); } ctx.ProcessingContext.ReturnModel.BinaryData = pf; return(new ParameterResolverValue(pf)); }
public override void Execute(IDataLoaderContext execContext) { // TODO: Needs a bit more effort to pack exception from the called methods if (execContext.Action == ACTION_READ) { ExecuteRead(execContext as IDataLoaderReadContext); } else if (execContext.Action == ACTION_WRITE) { ExecuteWrite(execContext as IDataLoaderWriteContext); } else { throw new Exception("Unknown action " + (execContext.Action ?? "null")); } }
internal WriteCustomSettings(IDataLoaderContext execContext, KraftGlobalConfigurationSettings kraftGlobalConfigurationSettings) : base(execContext, kraftGlobalConfigurationSettings) { Dictionary <string, long> fileRestrictions = new Dictionary <string, long>(); double?previewHeight = null; double?previewWidth = null; if (execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(MAXFILESPACEPERDASHBOARDINMB, out string parameters)) { long value; Regex keyValueRegex = new Regex(@"{(\s*(?<key>[a-zA-Z]+)\s*:\s*(?<value>[0-9]+)\s*)}"); MatchCollection matchCollection = keyValueRegex.Matches(parameters); foreach (Match match in matchCollection) { if (long.TryParse(match.Groups["value"].ToString(), out value)) { if (value < 0L) { throw new Exception("Invalid configuration for uploading files. Restriction cannot be less than zero."); } fileRestrictions.Add(match.Groups["key"].ToString(), value); } else { throw new Exception("Invalid configuration for uploading files."); } } } FileRestrictions = fileRestrictions; if (execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(PREVIEWHEIGHT, out string previewHeightAsString)) { previewHeight = ParseDouble(previewHeightAsString); } PreviewHeight = previewHeight; if (execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(PREVIEWWIDTHT, out string previewWidthAsString)) { previewWidth = ParseDouble(previewWidthAsString); } PreviewWidth = previewWidth; }
public ParameterResolverValue CreateDirectory(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 1) { throw new ArgumentException("CreateDirectory requires single parameter"); } var path = args[0].Value as string; if (path == null) { throw new ArgumentNullException("CreateDirectory argument is null or not a string"); } if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } return(new ParameterResolverValue(path)); }
public ParameterResolverValue CombinePaths(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 2) { throw new ArgumentException("CombinePaths accepts two arguments."); } var path = args[0].Value as string; var file = args[1].Value as string; if (path == null || file == null) { throw new ArgumentException("CombinePaths one or both of the parameters cannot convert to string."); } if (Path.IsPathFullyQualified(file)) { throw new ArgumentException("CombinePaths allows only partial paths for the second argument"); } return(new ParameterResolverValue(Path.Combine(path, file))); }
internal CustomSettings(IDataLoaderContext execContext, bool isWriteOperation) { if (execContext.OwnContextScoped.CustomSettings.TryGetValue(OPERATION, out string operation)) { OperationKey = operation; } ModuleKey = execContext.OwnContextScoped.CustomSettings[SETTING_MODULEKEY]; NodesetKey = execContext.OwnContextScoped.CustomSettings[SETTING_NODESETKEY]; NodepathKey = execContext.OwnContextScoped.CustomSettings[SETTING_NODEPATHKEY]; ValidateStringIsNotEmpty(ModuleKey, string.Format(REQUIRED_KEYVALUE_ERROR, SETTING_MODULEKEY)); ValidateStringIsNotEmpty(NodesetKey, string.Format(REQUIRED_KEYVALUE_ERROR, SETTING_NODESETKEY)); ValidateStringIsNotEmpty(NodepathKey, string.Format(REQUIRED_KEYVALUE_ERROR, SETTING_NODEPATHKEY)); if (!string.IsNullOrWhiteSpace(OperationKey)) { string operationValueAsString = FindValue(OperationKey, execContext); if (string.Equals(operationValueAsString, "write", StringComparison.OrdinalIgnoreCase)) { OperationValue = true; } else if (string.Equals(operationValueAsString, "read", StringComparison.OrdinalIgnoreCase)) { OperationValue = false; } } else { OperationValue = isWriteOperation; } ModuleValue = FindValue(ModuleKey, execContext); NodesetValue = FindValue(NodesetKey, execContext); NodepathValue = FindValue(NodepathKey, execContext); ValidateStringIsNotEmpty(ModuleValue, string.Format(REQUIRED_VALUE_ERROR, ModuleKey)); ValidateStringIsNotEmpty(NodesetValue, string.Format(REQUIRED_VALUE_ERROR, NodesetKey)); ValidateStringIsNotEmpty(NodepathValue, string.Format(REQUIRED_VALUE_ERROR, NodepathValue)); }
protected ActionBase Action(IDataLoaderContext execContext) { if (execContext.Action == ACTION_READ) { return(execContext.CurrentNode.Read.Select); } else if (execContext.Action == ACTION_WRITE) { switch (execContext.Operation) { case OPERATION_INSERT: return(execContext.CurrentNode.Write.Insert); case OPERATION_UPDATE: return(execContext.CurrentNode.Write.Update); case OPERATION_DELETE: return(execContext.CurrentNode.Write.Delete); } } return(null); }
/// <summary> /// Creates a PostedFile from a disk file. /// </summary> /// <param name="ctx"></param> /// <param name="args">(string filepath, string contentType)</param> /// <returns></returns> public ParameterResolverValue PostedFile(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length < 1) { throw new ArgumentException("PostedFile accepts 1 or 2 arguments (filepath[, contentType])"); } var filepath = args[0].Value as string; string contentType = null; if (args.Length > 1) { contentType = args[1].Value as string; // TODO: Calc if missing } if (contentType == null) { if (!(new FileExtensionContentTypeProvider().TryGetContentType(filepath, out contentType))) { contentType = "application/octet-stream"; } ; } if (string.IsNullOrWhiteSpace(filepath)) { throw new ArgumentException("PostedFile - filepath is empty or null"); } if (!File.Exists(filepath)) { throw new Exception("PostedFile - file does not exist"); } var fi = new FileInfo(filepath); var pf = new PostedFile(contentType, fi.Length, Path.GetFileName(filepath), filepath, path => { return(File.Open(path as string, FileMode.Open)); }, filepath); return(new ParameterResolverValue(pf)); }
public ParameterResolverValue PrependFileName(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 2) { throw new ArgumentException("PrependFileName requires two arguments (prefix, filename)"); } if (args[0].Value == null) { throw new ArgumentException("PrependFileName prefix argument is null"); } var prefix = args[0].Value.ToString(); var filename = args[1].Value as string; if (filename == null) { throw new ArgumentException("PrependFileName filename is null or not a string"); } var name = $"{prefix}-{Path.GetFileNameWithoutExtension(filename)}{Path.GetExtension(filename)}"; return(new ParameterResolverValue(name)); }
private string GetAuthUrl(IDataLoaderContext execContext, string action) { KraftGlobalConfigurationSettings kraftGlobalConfigurationSettings = execContext.PluginServiceManager.GetService <KraftGlobalConfigurationSettings>(typeof(KraftGlobalConfigurationSettings)); switch (action) //select, insert, update, delete { case "select": { return(kraftGlobalConfigurationSettings.GeneralSettings.Authority + "api/getuser"); } case "update": { return(kraftGlobalConfigurationSettings.GeneralSettings.Authority + "api/updateuser"); } case "delete": { return(kraftGlobalConfigurationSettings.GeneralSettings.Authority + "api/deleteuser"); } } return(null); }
public ParameterResolverValue DeleteFile(IDataLoaderContext ctx, ParameterResolverValue[] args) { if (args.Length != 1) { throw new ArgumentException("DeleteFile takes single argument: filepath"); } string savepath = args[1].Value as string; if (savepath == null) { throw new ArgumentException("DeleteFile: filepath is null or not a string"); } if (!Path.IsPathFullyQualified(savepath)) { throw new ArgumentException("DeleteFile the specified path is not fully qualified. Did you forget to combine paths?"); } if (File.Exists(savepath)) { var scope = Scope(ctx); scope.DeleteOnCommit(savepath); } return(new ParameterResolverValue(true)); }
internal ReadCustomSettings(IDataLoaderContext execContext, KraftGlobalConfigurationSettings kraftGlobalConfigurationSettings) { if (!execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(UPLOADFOLDER, out string uploadFolder)) { throw new Exception(string.Format(EXCEPTIONMESSAGE, UPLOADFOLDER)); } UploadFolder = uploadFolder.Replace(MODULEROOT, kraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolder(execContext.ProcessingContext.InputModel.Module)).Replace(MODULE, execContext.ProcessingContext.InputModel.Module); if (!execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(DEFAULTFOLDER, out string defaultFolder)) { throw new Exception(string.Format(EXCEPTIONMESSAGE, DEFAULTFOLDER)); } DefaultFolder = defaultFolder.Replace(MODULEROOT, kraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolder(execContext.ProcessingContext.InputModel.Module)).Replace(MODULE, execContext.ProcessingContext.InputModel.Module);; if (!execContext.DataLoaderContextScoped.CustomSettings.TryGetValue(FILENOTFOUNDICON, out string fileNotFoundIcon)) { throw new Exception(string.Format(EXCEPTIONMESSAGE, FILENOTFOUNDICON)); } FileNotFoundIcon = fileNotFoundIcon; }
/// <summary> /// /// </summary> /// <param name="execContext"></param> /// <returns></returns> protected Configuration ReadConfiguration(IDataLoaderContext execContext) { var cfg = new Configuration(); if (execContext.Action == ACTION_READ) { cfg.Statement = execContext.CurrentNode.Read.Select.HasStatement() ? execContext.CurrentNode.Read.Select.Query : null; } else if (execContext.Action == ACTION_WRITE) // TODO: Does this even make sense ? { switch (execContext.Operation) { case OPERATION_INSERT: if (execContext.CurrentNode.Write.Insert.HasStatement()) { cfg.Statement = execContext.CurrentNode.Write.Insert.Query; } break; case OPERATION_UPDATE: if (execContext.CurrentNode.Write.Update.HasStatement()) { cfg.Statement = execContext.CurrentNode.Write.Update.Query; } break; case OPERATION_DELETE: if (execContext.CurrentNode.Write.Delete.HasStatement()) { cfg.Statement = execContext.CurrentNode.Write.Delete.Query; } break; } } return(cfg); /////////////////////////////// }
public KeyedDataLoader(IDataLoaderContext context, Func <IEnumerable <TKey>, CancellationToken, Task <IReadOnlyDictionary <TKey, TReturn> > > fetch) { _context = context; _fetch = fetch; }
public DataLoader(IDataLoaderContext context, Func <CancellationToken, Task <TReturn> > fetch) { _context = context; _fetch = fetch; }