コード例 #1
0
        /// <summary>
        /// Gets the content of aggregate keys
        /// </summary>
        /// <param name="script"></param>
        /// <param name="keyBuffName"></param>
        /// <returns></returns>
        private string GetAggregateKeyExtraction(DonutScript script, string keyBuffName)
        {
            var rootIgn = script.GetRootIntegration();
            var ignKeys = rootIgn.AggregateKeys;

            if (ignKeys == null || !ignKeys.Any())
            {
                throw new Exception("Integration has no aggregate keys!");
            }
            var keys = ignKeys.Where(x => x.Operation != null);
//            if (keys == null || !keys.Any())
//            {
//                throw new Exception("Integration has no evaluable aggregate keys!");
//            }
            var buffer = new StringBuilder();
            int iKey   = 0;

            buffer.AppendLine($"var {keyBuffName} = new Dictionary<string, object>();");
            foreach (var key in keys)
            {
                var keyName    = $"aggKey{iKey}";
                var evalFnName = $"{keyName}_fn";
                var evalFn     = key.Operation.GetCallCode(evalFnName).ToString();
                //var keyVar = $"var {keyName} = {evalFnName}(document[\"{key.Arguments}\"]);";
                var keyLine = $"{keyBuffName}[\"{key.Name}\"] = {evalFnName}(document[\"{key.Arguments}\"]);";
                buffer.AppendLine(evalFn);
                buffer.AppendLine(keyLine);
                iKey++;
            }

            buffer.AppendLine($"var groupKey = Context.AddMetaGroup({keyBuffName});");
            return(buffer.ToString());
        }
コード例 #2
0
        /// <summary>
        /// Generates a donutfile context
        /// </summary>
        /// <param name="namespace"></param>
        /// <param name="script"></param>
        /// <returns></returns>
        public string GenerateContext(string @namespace, DonutScript script)
        {
            string ctxTemplate;

            _expVisitor.Clear();
            _expVisitor.SetScript(script);
            if (script.Type == null)
            {
                throw new ArgumentException("Script type is null!");
            }
            var baseName = script.Type.GetContextName();

            using (StreamReader reader = new StreamReader(GetTemplate("DonutContext.txt")))
            {
                ctxTemplate = reader.ReadToEnd();
                if (string.IsNullOrEmpty(ctxTemplate))
                {
                    throw new Exception("Template empty!");
                }
                ctxTemplate = ctxTemplate.Replace("$Namespace", @namespace);
                ctxTemplate = ctxTemplate.Replace("$ClassName", baseName);
                var cacheSetMembers = GetCacheSetMembers(script);
                ctxTemplate = ctxTemplate.Replace("$CacheMembers", cacheSetMembers);
                var dataSetMembers = GetDataSetMembers(script);
                ctxTemplate = ctxTemplate.Replace("$DataSetMembers", dataSetMembers);
                var mappers = GetContextTypeMappers(script);
                ctxTemplate = ctxTemplate.Replace("$Mappers", mappers);

                //Items: $Namespace, $ClassName, $CacheMembers, $DataSetMembers, $Mappers
            }
            return(ctxTemplate);
        }
コード例 #3
0
        private string GetContextTypeMappers(DonutScript dscript)
        {
            //Template:
            //RedisCacher.RegisterCacheMap<MapTypeName, TypeToMapNamme>
            var sb = new StringBuilder();

            return(sb.ToString());
        }
コード例 #4
0
 private static void GetIntegrationRecordVars(DonutScript script, StringBuilder fBuilder)
 {
     foreach (var integration in script.GetDatasetMembers())
     {
         var iName  = integration.GetPropertyName();
         var record = $"var rec{iName} = this.Context.{iName}.Records;";
         fBuilder.AppendLine(record);
     }
 }
コード例 #5
0
        private string GetDataSetMembers(DonutScript dscript)
        {
            var dtSources = dscript.GetDatasetMembers();
            var content   = new StringBuilder();

            foreach (var source in dtSources)
            {
                var sourceProperty = $"[SourceFromIntegration(\"{source.Name}\")]\n" +
                                     "public DataSet<BsonDocument> " + source.GetPropertyName() + " { get; set; }";
                content.AppendLine(sourceProperty);
            }
            return(content.ToString());
        }
コード例 #6
0
        /// <summary>
        /// Generates the code that processes each incoming document, in order to gather information for features.
        /// </summary>
        /// <param name="script"></param>
        /// <returns></returns>
        private string ProcessFeaturePrepContent(string donutfileContent, DonutScript script)
        {
            string aggregateKeyContent = GetAggregateKeyExtraction(script, "aggKeyBuff");
            var    placeholder         = "$ExtractionBody";
            var    donutCV             = new DonutFeatureGeneratingExpressionVisitor(script);
            var    donutFeatureGen     = new DonutFeatureCodeGenerator(script, donutCV);
            var    donutFeatures       = script.Features.Where(x => x.IsDonutNativeFeature());

            donutFeatureGen.AddAll(donutFeatures);
            var donutFeatureCode = donutFeatureGen.GetScriptContent(donutfileContent);

            donutFeatureCode.PrepareScript = aggregateKeyContent + donutFeatureCode.PrepareScript;
            donutfileContent = donutfileContent.Replace(placeholder, donutFeatureCode.PrepareScript);
            return(donutfileContent);
        }
コード例 #7
0
        private string GetCacheSetMembers(DonutScript dscript)
        {
            var featureAssignments = dscript.Features;
            var content            = new StringBuilder();

            foreach (var fassign in featureAssignments)
            {
                var name     = fassign.Member.Name;
                var sName    = name.Replace(' ', '_');
                var typeName = "string";
                //Resolve the type name if needed
                var sourceProperty = $"public CacheSet<{typeName}> " + sName + " { get; set; }";
                content.AppendLine(sourceProperty);
            }
            return(content.ToString());
        }
コード例 #8
0
ファイル: CsCompiler.cs プロジェクト: sp0x/donut
        public string GenerateProjectDefinition(string assemblyName, DonutScript script)
        { 
            using (var template = new StreamReader(GetTemplate("Project.txt")))
            {
                var content = template.ReadToEnd();
                var referenceBuilder = new StringBuilder();
                foreach (var reference in References)
                {
                    var referenceTemplate = $"<PackageReference Incude=\"{reference.Display}\" />\n";
                    referenceBuilder.Append(referenceTemplate);
                    //<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.0.1" />
                }

                content = content.Replace("$References", referenceBuilder.ToString());
                return content;
            }
        }
コード例 #9
0
        private string GetFeatureYieldsContent(DonutScript script)
        {
            var fBuilder        = new StringBuilder();
            var donutFnResolver = new DonutFunctions();

            foreach (var feature in script.Features)
            {
                IExpression accessor       = feature.Value;
                string      fName          = feature.Member.ToString();
                string      featureContent = "";
                var         featureFType   = accessor.GetType();
                if (featureFType == typeof(NameExpression))
                {
                    var member = (accessor as NameExpression).Member?.ToString();
                    //In some cases we might just use the field
                    if (string.IsNullOrEmpty(member))
                    {
                        member = accessor.ToString();
                    }
                    featureContent = $"yield return pair(\"{fName}\", doc[\"{member}\"]);";
                }
                else if (featureFType == typeof(CallExpression))
                {
                    if (donutFnResolver.IsAggregate(accessor as CallExpression))
                    {
                        //We're dealing with an aggregate call
                        //var aggregateContent = GenerateFeatureFunctionCall(accessor as CallExpression, feature);
                    }
                    else
                    {
                        //We're dealing with a function call
                        //featureContent = GenerateFeatureFunctionCall(accessor as CallExpression, feature).Content;
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
                if (!string.IsNullOrEmpty(featureContent))
                {
                    fBuilder.AppendLine(featureContent);
                }
            }
            return(fBuilder.ToString());
        }
コード例 #10
0
 public DonutFeatureCodeGenerator(DonutScript script, DonutFeatureGeneratingExpressionVisitor expVisitor) : base(script)
 {
     _donutFnResolver = new DonutFunctions();
     _rootIntegration = script.Integrations.FirstOrDefault();
     if (_rootIntegration == null)
     {
         throw new InvalidIntegrationException("Script has no integrations");
     }
     if (_rootIntegration.Fields == null || _rootIntegration.Fields.Count == 0)
     {
         throw new InvalidIntegrationException("Integration has no fields");
     }
     _rootDataMember   = script.GetDatasetMember(_rootIntegration.Name);
     _outputCollection = _rootIntegration.FeaturesCollection;
     if (string.IsNullOrEmpty(_outputCollection))
     {
         throw new InvalidOperationException("Root integration must have a features collection set.");
     }
     _expVisitor = expVisitor ?? throw new ArgumentNullException(nameof(expVisitor));
     _functions  = new List <IDonutFunction>();
 }
コード例 #11
0
ファイル: DonutSyntaxReader.cs プロジェクト: sp0x/donut
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public DonutScript ParseDonutScript(IIntegration ign)
        {
            _sourceIntegrations.Clear();
            DonutScript newScript = new DonutScript();

            Reader.DiscardToken(TokenType.Define);
            var newSymbolName = Reader.DiscardToken(TokenType.Symbol);

            newScript.Type      = new ScriptTypeInfo(newSymbolName.Value);
            _sourceIntegrations = ReadFrom();
            var orderBy     = ReadOrderBy();
            var expressions = ReadExpressions();

            newScript.StartingOrderBy = orderBy;
            foreach (var expression in expressions)
            {
                var expressionType = expression.GetType();
                if (expressionType == typeof(AssignmentExpression))
                {
                    newScript.Features.Add(expression as AssignmentExpression);
                }
                else if (expressionType == typeof(TargetExpression))
                {
                    var targetExpr   = expression as TargetExpression;
                    var targetFields = targetExpr.Attributes.Select(a => ign.Fields.FirstOrDefault(f => f.Name == a));
                    newScript.Targets = new List <ModelTarget>();
                    foreach (var targetField in targetFields)
                    {
                        ((List <ModelTarget>)newScript.Targets).Add(new ModelTarget(targetField));
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            newScript.AddIntegrations(_sourceIntegrations.Select(i => new Donut.Data.DataIntegration(i)).ToArray());

            return(newScript);
        }
コード例 #12
0
ファイル: DonutBuilder.cs プロジェクト: sp0x/donut
        public static IDonutBuilder Create <TData>(DonutScript script,
                                                   IIntegration integration, IServiceProvider serviceProvider)
            where TData : class, IIntegratedDocument
        {
            if (string.IsNullOrEmpty(script.AssemblyPath))
            {
                return(null);
            }
            if (!File.Exists(script.AssemblyPath))
            {
                throw new Exception("Donut assembly not found!");
            }
            var asm                = Assembly.LoadFrom(script.AssemblyPath);
            var donutTypes         = asm.GetTypes();
            var donutType          = donutTypes.FirstOrDefault(x => x.IsInstanceOfType(typeof(IDonutfile)));
            var donutContextType   = donutTypes.FirstOrDefault(x => x.IsInstanceOfType(typeof(IDonutContext)));
            var featureEmitterType = donutTypes.FirstOrDefault(x => x.IsInstanceOfType(typeof(IDonutFeatureEmitter)));
            var cacher             = serviceProvider.GetService(typeof(IRedisCacher)) as IRedisCacher;
            var builder            = Create <TData>(donutType, donutContextType, integration, cacher, serviceProvider);

            builder.SetEmitterType(featureEmitterType);
            return(builder);
        }
コード例 #13
0
        /// <summary>
        /// Generates a donutfile
        /// </summary>
        /// <param name="namespace"></param>
        /// <param name="script"></param>
        /// <returns></returns>
        public string GenerateDonut(string @namespace, DonutScript script)
        {
            string donutTemplate;
            var    baseName     = script.Type.GetClassName();
            var    conutextName = script.Type.GetContextName();

            _expVisitor.Clear();
            _expVisitor.SetScript(script);
            var encoding = System.Text.Encoding.UTF8;

            using (StreamReader reader = new StreamReader(GetTemplate("Donutfile.txt"), encoding))
            {
                donutTemplate = reader.ReadToEnd();
                if (string.IsNullOrEmpty(donutTemplate))
                {
                    throw new Exception("Template empty!");
                }
                var donutComment = $"//Generated on {DateTime.UtcNow} UTC\n";
                donutComment += $"//Root collection on {script.GetRootIntegration().Collection}\n";
                donutTemplate = $"{donutComment}\n" + donutTemplate;
                donutTemplate = donutTemplate.Replace("$Namespace", @namespace);
                donutTemplate = donutTemplate.Replace("$ClassName", baseName);
                donutTemplate = donutTemplate.Replace("$ContextTypeName", conutextName);
                var prepareScript = GeneratePrepareExtractionContent(script);
                donutTemplate = donutTemplate.Replace("$PrepareExtraction", prepareScript);
                donutTemplate = ProcessFeaturePrepContent(donutTemplate, script); //donutTemplate.Replace("$ExtractionBody", GetFeaturePrepContent(donutTemplate, script));
                donutTemplate = donutTemplate.Replace("$CompleteExtraction", GetFeatureExtractionCompletion(script));
                var propertiesContent = GenerateDonutPropertiesContent(!string.IsNullOrEmpty(prepareScript));
                donutTemplate  = donutTemplate.Replace("$DonutProperties", propertiesContent);
                donutTemplate  = donutTemplate.Replace("$OnFinished", GenerateOnDounutFinishedContent(script));
                donutTemplate += "\n\n" +
                                 "/* Donut script: \n" + script.ToString() +
                                 "\n*/";
                //Items: $ClassName, $ContextTypeName, $ExtractionBody, $OnFinished
            }
            return(donutTemplate);
        }
コード例 #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="script"></param>
        /// <returns></returns>
        private string GeneratePrepareExtractionContent(DonutScript script)
        {
            var fBuilder        = new StringBuilder();
            var rootIntegration = script.Integrations.FirstOrDefault();

            if (rootIntegration == null)
            {
                throw new InvalidIntegrationException("Script has no integrations");
            }
            if (rootIntegration.Fields == null || rootIntegration.Fields.Count == 0)
            {
                throw new InvalidIntegrationException("Integration has no fields");
            }
            //Get our record variables
            GetIntegrationRecordVars(script, fBuilder);
            var aggregates  = new AggregateFeatureCodeGenerator(script, _expVisitor);
            var aggFeatures = script.Features.Where(x => x.IsDonutAggregateFeature());

            aggregates.AddAll(aggFeatures);
            var aggregatePipeline = aggregates.GetScriptContent();

            fBuilder.Append(aggregatePipeline);
            return(fBuilder.ToString());
        }
コード例 #15
0
        public string GenerateFeatureGenerator(string @namespace, DonutScript script)
        {
            string fgenTemplate;
            var    donutName    = script.Type.GetClassName();
            var    conutextName = script.Type.GetContextName();

            _expVisitor.Clear();
            _expVisitor.SetScript(script);
            using (StreamReader reader = new StreamReader(GetTemplate("FeatureGenerator.txt")))
            {
                fgenTemplate = reader.ReadToEnd();
                if (string.IsNullOrEmpty(fgenTemplate))
                {
                    throw new Exception("Template empty!");
                }
                fgenTemplate = fgenTemplate.Replace("$Namespace", @namespace);
                fgenTemplate = fgenTemplate.Replace("$DonutType", donutName);
                fgenTemplate = fgenTemplate.Replace("$DonutContextType", conutextName);
                fgenTemplate = fgenTemplate.Replace("$ContextTypeName", conutextName);
                fgenTemplate = fgenTemplate.Replace("$FeatureYields", GetFeatureYieldsContent(script));
                //Items: $Namespace, $DonutType, $FeatureYields
            }
            return(fgenTemplate);
        }
コード例 #16
0
        private string GetFeatureExtractionCompletion(DonutScript script)
        {
            var code = "";

            return(code);
        }
コード例 #17
0
        //private DataIntegration _integration;

        public DonutScriptCodeGenerator(DonutScript script)
        {
            _expVisitor = new AggregateFeatureGeneratingExpressionVisitor(script);
            //_integration = integration;
        }
コード例 #18
0
ファイル: FeatureCodeGenerator.cs プロジェクト: sp0x/donut
 public FeatureCodeGenerator(DonutScript script)
 {
     this.Script = script;
 }
コード例 #19
0
 private string GenerateOnDounutFinishedContent(DonutScript script)
 {
     return(String.Empty);
 }
コード例 #20
0
 public DonutCompiler(DonutScript dscript)
 {
     _script        = dscript;
     _codeGen       = dscript.GetCodeGenerator() as DonutScriptCodeGenerator;
     _assembliesDir = Path.Combine(Environment.CurrentDirectory, "donutAssemblies");
 }
コード例 #21
0
 public void SetScript(DonutScript script)
 {
     _script = script;
 }