示例#1
0
        public static TrackedUseCase UpdateFirms()
        {
            var operationIdentity = new StrictOperationIdentity(UpdateIdentity.Instance, new EntitySet(EntityTypeFirm.Instance));
            var changes           = new[]
            {
                ChangeDescriptor.Create(EntityTypeFirm.Instance, 12, ChangeKind.Updated),
                ChangeDescriptor.Create(EntityTypeFirm.Instance, 13, ChangeKind.Updated)
            };

            var operations = new[]
            {
                new OperationDescriptor(Guid.NewGuid(), operationIdentity, new OperationContext(DateTimeOffset.UtcNow, DateTime.UtcNow), new EntityChangesContext(changes))
            };

            var context = new UseCaseContext(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 0);
            var useCase = new TrackedUseCase(context, operations[0].Id, operations, new Dictionary <Guid, HashSet <Guid> >());

            return(useCase);
        }
示例#2
0
        public void AddToCache(long maxRowDate, CachedRoutine newCachedRoutine, string lastUpdateByHostName, out ChangeDescriptor changeDescriptor)
        {
            changeDescriptor = null;

            if (this.Id == null)
            {
                this.Id = ShortId.Generate();
            }
            if (this.CachedRoutineList == null)
            {
                this.CachedRoutineList = new List <CachedRoutine>();
            }

            lock (CachedRoutineList)
            {
                // look for an existing item
                var existing = this.CachedRoutineList.Where(e => newCachedRoutine.Equals(e)).FirstOrDefault();

                if (existing != null)
                {
                    // if existing is not deleted but the update IS
                    if (!existing.IsDeleted && newCachedRoutine.IsDeleted)
                    {
                        changeDescriptor = ChangeDescriptor.Create(lastUpdateByHostName, $"{newCachedRoutine.FullName} DROPPED");
                        this.CachedRoutineList.Remove(existing);               // will be added again below
                    }
                    else if (existing.IsDeleted && newCachedRoutine.IsDeleted) // still deleted then nothing to do
                    {
                        return;
                    }
                    else if (existing.IsDeleted && !newCachedRoutine.IsDeleted)
                    {                                            // "undeleted"
                        changeDescriptor = ChangeDescriptor.Create(lastUpdateByHostName, $"{newCachedRoutine.FullName} (RE)ADDED");
                        this.CachedRoutineList.Remove(existing); // will be added again below
                    }
                    else if (!newCachedRoutine.IsDeleted)
                    {
                        bool parametersUpdated    = newCachedRoutine.ParametersHash != existing.ParametersHash;
                        bool resultSetsUpdated    = newCachedRoutine.ResultSetHash != existing.ResultSetHash;
                        bool jsDALMetadataUpdated = false;

                        if (existing.jsDALMetadata == null && newCachedRoutine.jsDALMetadata != null)
                        {
                            jsDALMetadataUpdated = true;
                        }
                        else if (existing.jsDALMetadata != null && newCachedRoutine.jsDALMetadata == null)
                        {
                            jsDALMetadataUpdated = true;
                        }
                        else if (newCachedRoutine.jsDALMetadata != null)
                        {
                            var newMatchesExisting = newCachedRoutine.jsDALMetadata.Equals(existing.jsDALMetadata);
                            jsDALMetadataUpdated = newCachedRoutine.jsDALMetadata != null && !newMatchesExisting;
                        }

                        // no metadata related change
                        if (!parametersUpdated && !resultSetsUpdated && !jsDALMetadataUpdated)
                        {
                            return;
                        }

                        this.CachedRoutineList.Remove(existing); // will be added again below

                        var applicableChanges = new List <string>();

                        if (parametersUpdated)
                        {
                            applicableChanges.Add("PARAMETERS");
                        }
                        if (resultSetsUpdated)
                        {
                            applicableChanges.Add("RESULT SETS");
                        }
                        if (jsDALMetadataUpdated)
                        {
                            applicableChanges.Add("jsDAL metadata");
                        }

                        changeDescriptor = ChangeDescriptor.Create(lastUpdateByHostName, $"{newCachedRoutine.FullName} UPDATED {string.Join(", ", applicableChanges.ToArray())}");
                    }
                }
                else
                {
                    changeDescriptor = ChangeDescriptor.Create(lastUpdateByHostName, $"{newCachedRoutine.FullName} ADDED");
                }

                this.CachedRoutineList.Add(newCachedRoutine);
            }
        }
示例#3
0
        public static void GenerateJsFileV2(string source, Endpoint endpoint, JsFile jsFile, Dictionary <string, ChangeDescriptor> fullChangeSet = null, bool rulesChanged = false)
        {
            var generateMetric = new Performance.ExecutionBase("GenerateJsFileV2");
            var noChanges      = false;

            try
            {
                // TODO: Figure out out casing on this property
                string jsNamespace = null;//endpoint.JsNamespace;
                if (string.IsNullOrWhiteSpace(jsNamespace))
                {
                    jsNamespace = endpoint.MetadataConnection.InitialCatalog;
                }

                var jsSafeNamespace = MakeNameJsSafe(jsNamespace);

                var routineContainerTemplate       = WorkSpawner.TEMPLATE_RoutineContainer;
                var routineTemplate                = WorkSpawner.TEMPLATE_Routine;
                var typescriptDefinitionsContainer = WorkSpawner.TEMPLATE_TypescriptDefinitions;

                endpoint.ApplyRules(jsFile);

                var includedRoutines = (from row in endpoint.CachedRoutines
                                        where !row.IsDeleted && (row.RuleInstructions[jsFile]?.Included ?? false == true)
                                        orderby row.FullName
                                        select row).ToList();

                List <KeyValuePair <string, ChangeDescriptor> > changesInFile = null;


                if (fullChangeSet != null)
                {
                    changesInFile = fullChangeSet.Where(change => includedRoutines.Count(inc => inc.FullName.Equals(change.Key, StringComparison.OrdinalIgnoreCase)) > 0).ToList();

                    // TODO: Consider if this is a good idea?
                    //       If we can reasonably say that there are no changes to routines that this JsFile cares about, why regenerate this file and why give it a new Version
                    if (changesInFile.Count == 0)
                    {
                        noChanges = true;
                        return;
                    }
                }

                var jsSchemaLookupForJsFunctions = new Dictionary <string, List <string> /*Routine defs*/>();
                var tsSchemaLookup = new Dictionary <string, List <string> /*Routine defs*/>();

                var typeScriptParameterAndResultTypesSB = new StringBuilder();

                var serverMethodPlugins = PluginLoader.Instance.PluginAssemblies
                                          .SelectMany(pa => pa.Plugins)
                                          .Where(p => p.Type == PluginType.ServerMethod && endpoint.Application.IsPluginIncluded(p.Guid.ToString()));

                var uniqueSchemas = new List <string>();

                var mainLoopMetric = generateMetric.BeginChildStage("Main loop");

                includedRoutines.ForEach(r =>
                {
                    try
                    {
                        if (r.TypescriptMethodStub == null)
                        {
                            r.PrecalculateJsGenerationValues(endpoint);
                        }

                        var jsSchemaName   = JsFileGenerator.MakeNameJsSafe(r.Schema);
                        var jsFunctionName = JsFileGenerator.MakeNameJsSafe(r.Routine);

                        if (!jsSchemaLookupForJsFunctions.ContainsKey(jsSchemaName))
                        {
                            jsSchemaLookupForJsFunctions.Add(jsSchemaName, new List <string>());
                        }

                        if (!tsSchemaLookup.ContainsKey(jsSchemaName))
                        {
                            tsSchemaLookup.Add(jsSchemaName, new List <string>());
                        }

                        if (!uniqueSchemas.Contains(r.Schema))
                        {
                            uniqueSchemas.Add(r.Schema);
                        }

                        var schemaIx = uniqueSchemas.IndexOf(r.Schema);

                        // .js
                        {
                            var jsFunctionDefLine = routineTemplate.Replace("<<FUNC_NAME>>", jsFunctionName).Replace("<<SCHEMA_IX>>", schemaIx.ToString()).Replace("<<ROUTINE>>", r.Routine);

                            if (r.Type.Equals(string.Intern("PROCEDURE"), StringComparison.OrdinalIgnoreCase))
                            {
                                jsFunctionDefLine = jsFunctionDefLine.Replace("<<CLASS>>", "S");
                            }
                            else
                            {
                                jsFunctionDefLine = jsFunctionDefLine.Replace("<<CLASS>>", "U");
                            }

                            jsSchemaLookupForJsFunctions[jsSchemaName].Add(jsFunctionDefLine);
                        }

                        // .tsd
                        {
                            typeScriptParameterAndResultTypesSB.AppendLine(r.TypescriptParameterTypeDefinition);
                            typeScriptParameterAndResultTypesSB.AppendLine(r.TypescriptOutputParameterTypeDefinition);
                            typeScriptParameterAndResultTypesSB.AppendLine(r.TypescriptResultSetDefinitions);
                            tsSchemaLookup[jsSchemaName].Add(r.TypescriptMethodStub);
                        }
                    }
                    catch (Exception ex)
                    {
                        SessionLog.Exception(ex);
                        // TODO: quit whole process
                    }
                });

                mainLoopMetric.End();

                var finalSBMetric = generateMetric.BeginChildStage("Final SB");

                var schemaAndRoutineDefs   = string.Join("\r\n", jsSchemaLookupForJsFunctions.Select(s => "\tx." + s.Key + " = {\r\n\t\t" + string.Join(",\r\n\t\t", s.Value.ToArray()) + "\r\n\t}\r\n").ToArray());
                var tsSchemaAndRoutineDefs = string.Join("\r\n", tsSchemaLookup.Select(s => "\t\tclass " + s.Key + " {\r\n" + string.Join(";\r\n", s.Value.ToArray()) + "\r\n\t\t}\r\n").ToArray());

                var finalSB = new StringBuilder(routineContainerTemplate);

                jsFile.IncrementVersion();

                // record changes against new version

                if (changesInFile != null && changesInFile.Count > 0)
                {
                    JsFileChangesTracker.Instance.AddUpdate(endpoint, jsFile, changesInFile.Select(kv => kv.Value).ToList());
                }

                if (rulesChanged)
                {
                    JsFileChangesTracker.Instance.AddUpdate(endpoint, jsFile, new List <ChangeDescriptor> {
                        ChangeDescriptor.Create("System", "One or more rules changed.")
                    });
                }

                finalSB.Replace("<<DATE>>", DateTime.Now.ToString("dd MMM yyyy, HH:mm"))
                .Replace("<<FILE_VERSION>>", jsFile.Version.ToString())
                .Replace("<<SERVER_NAME>>", Environment.MachineName)
                .Replace("<<ENDPOINT>>", endpoint.Pedigree)
                .Replace("<<UNIQUE_SCHEMAS>>", string.Join(',', uniqueSchemas.Select(k => $"'{k}'")))
                .Replace("<<Catalog>>", jsSafeNamespace)
                .Replace("<<ROUTINES>>", schemaAndRoutineDefs)
                ;

                var finalTypeScriptSB = new StringBuilder();

                finalTypeScriptSB = finalTypeScriptSB.Append(typescriptDefinitionsContainer);

                // Custom/User types
                if (endpoint.CustomTypeLookupWithTypeScriptDef.Count > 0)
                {
                    var customTSD = from kv in endpoint.CustomTypeLookupWithTypeScriptDef select $"\t\ttype {kv.Key} = {kv.Value};";
                    typeScriptParameterAndResultTypesSB.Insert(0, string.Join("\r\n", customTSD));
                }

                var resultAndParameterTypes = typeScriptParameterAndResultTypesSB.ToString();

                finalTypeScriptSB.Replace("<<DATE>>", DateTime.Now.ToString("dd MMM yyyy, HH:mm"))
                .Replace("<<FILE_VERSION>>", jsFile.Version.ToString())
                .Replace("<<SERVER_NAME>>", Environment.MachineName)
                .Replace("<<Catalog>>", jsSafeNamespace)
                .Replace("<<ResultAndParameterTypes>>", resultAndParameterTypes)
                .Replace("<<MethodsStubs>>", tsSchemaAndRoutineDefs)
                ;

                finalSBMetric.End();

                var toStringMetric = generateMetric.BeginChildStage("ToString");
                var typescriptDefinitionsOutput = finalTypeScriptSB.ToString();
                var finalOutput = finalSB.ToString();
                toStringMetric.End();

                var filePath          = endpoint.OutputFilePath(jsFile);
                var minfiedFilePath   = endpoint.MinifiedOutputFilePath(jsFile);
                var tsTypingsFilePath = endpoint.OutputTypeScriptTypingsFilePath(jsFile);

                var minifyMetric = generateMetric.BeginChildStage("Minify");

                var minifiedSource = Uglify.Js(finalOutput /*, { }*/).Code;

                minifyMetric.End();

                if (!Directory.Exists(endpoint.OutputDir))
                {
                    Directory.CreateDirectory(endpoint.OutputDir);
                }

                var fileOutputMetric = generateMetric.BeginChildStage("Write");

                var jsFinalBytes         = System.Text.Encoding.UTF8.GetBytes(finalOutput);
                var jsFinalMinifiedBytes = System.Text.Encoding.UTF8.GetBytes(minifiedSource);

                jsFile.ETag         = Controllers.PublicController.ComputeETag(jsFinalBytes);
                jsFile.ETagMinified = Controllers.PublicController.ComputeETag(jsFinalMinifiedBytes);

                File.WriteAllText(filePath, finalOutput);
                File.WriteAllText(minfiedFilePath, minifiedSource);
                File.WriteAllText(tsTypingsFilePath, typescriptDefinitionsOutput);

                fileOutputMetric.End();
            }
            finally
            {
                generateMetric.End();

                SessionLog.InfoToFileOnly($"{endpoint.Pedigree.PadRight(25, ' ')} - {generateMetric.DurationInMS.ToString().PadLeft(4)} ms {jsFile.Filename.PadRight(20)} (source={source};rulesChanged={rulesChanged};changes={!noChanges}); {generateMetric.ChildDurationsSingleLine()}");
            }
        }