go to post Eduard Lebedyuk · Jan 25, 2017 Macros can eliminate using $method/dynamic dispatch here altogether.
go to post Eduard Lebedyuk · Jan 25, 2017 Macros for method names which compile into AmethodName or methodName depending on global var set for compilation then. Dynamic dispatch is a hit on speed anyway.
go to post Eduard Lebedyuk · Jan 25, 2017 Always call do a.AmethodName() And inside dynamic dispatch check global variable %debug (or global, or some IsDebug method etc.). If it exists call both annotation methods and target method, If it does not exist only call target method.
go to post Eduard Lebedyuk · Jan 25, 2017 Another approach would be using dynamic dispatch: Let's say you have this method: /// @NiceTest1 ClassMethod Test() { Write 1 } Using Class Generators you generate 2 additional methods: /// @NiceTest1 ClassMethod OnBeforeTest() { Write "Before NiceTest1" } /// @NiceTest1 ClassMethod OnAfterTest() { Write "After NiceTest1" } and you add dynamic dispatch method (and dynamic dispatch classmethod) to the class: /// Is used to implement an unknown method call. It is also used /// to resolve an unknown multidimensional property reference (to get the value /// of a property) because that syntax is identical to a method call. Method %DispatchMethod(Method As %String, Args...) [ ServerOnly = 1 ] { // Amethod -> method set Method = $e(Method, 2, *) do $method(, "OnBefore" _ Method, Args...) do $method(, Method, Args...) do $method(,"OnAfter" _ Method,Args...) } So, as a whole it can look like this: Class Utils.Annotations1 Extends %RegisteredObject { Method OnBeforeTest() { Write "Init NiceTest1",! } /// @NiceTest1 Method Test() { Write 1,! } Method OnAfterTest() { Write "End NiceTest1",! } /// Is used to implement an unknown method call. Method %DispatchMethod(Method As %String, Args...) [ ServerOnly = 1 ] { set Method = ..getMethodName(Method) do $method(, "OnBefore" _ Method, Args...) do $method(, Method, Args...) do $method(,"OnAfter" _ Method,Args...) } /// Is used to implement an unknown class method call ClassMethod %DispatchClassMethod(Class As %String, Method As %String, Args...) [ ServerOnly = 1 ] { set Method = ..getMethodName(Method) do $classmethod(, "OnBefore" _ Method, Args...) do $classmethod(, Method, Args...) do $classmethod(,"OnAfter" _ Method,Args...) } ClassMethod getMethodName(method As %String) As %String { // Amethod -> method set method = $e(method, 2, *) return method } } Works like this: USER>do a.ATest() Init NiceTest1 1 End NiceTest1 USER>do a.Test() 1
go to post Eduard Lebedyuk · Jan 24, 2017 You can modify method code during compilation (obviously dangerous) using generators. Here's the sample that annotates all methods, containing @ in description: Class Utils.Annotations { /// @NiceTest1 ClassMethod Test() { Write 1 } ClassMethod OnCompile() As %Status [ CodeMode = objectgenerator ] { #dim sc As %Status = $$$OK for i=1:1:%class.Methods.Count() { #dim method As %Dictionary.MethodDefinition = %class.Methods.GetAt(i) if method.Description [ "@" { set sc = ..annotate(method) quit:$$$ISERR(sc) } } quit:$$$ISERR(sc) sc set sc = %class.%Save() quit sc } ClassMethod annotate(method As %Dictionary.MethodDefinition) As %Status { #dim sc As %Status = $$$OK set code = method.Implementation.Read($$$MaxCacheInt) set code = ..cleadOldAnnotation(code) set code = ..addNewAnnotation(code, $e(method.Description, 2,*)) do method.Implementation.Clear() do method.Implementation.Write(code) quit sc } ClassMethod cleadOldAnnotation(code As %String) As %String { if $find(code, "//init annotation end") { set code = $e(code, $find(code, "//init annotation end") + 2, $find(code, "//complete annotation start") - $l("//complete annotation start") - 2) } return code } ClassMethod addNewAnnotation(code As %String, annotation As %String) As %String { #define Tab $c(9) set code = $$$Tab _ "Write ""Init " _ annotation _ """" _ $$$NL _ $$$Tab _ "//init annotation end" _ $$$NL _ code _ $$$Tab _ "//complete annotation start"_ $$$NL _ $$$Tab _ "Write ""End " _ annotation _ """" return code } } Compiles into: /// @NiceTest1 ClassMethod Test() { Write "Init NiceTest1" //init annotation end Write 1 //complete annotation start Write "End NiceTest1" } GitHub
go to post Eduard Lebedyuk · Jan 20, 2017 Yes, you can query everything you see in Message Viewer and Event Viewer. Their code is defined in EnsPortal.MessageViewer.zen and EnsPortal.EventLog.zen respectively. You can see the queries these pages use and adapt them, or inherit from them and publish it as another separate web application.Also, here's modification example - Ensemble Log Viewer with namespace support.
go to post Eduard Lebedyuk · Jan 19, 2017 You can specify Logfile setting for logging and these settings for debug:JavaDebug: Allow a Java debugger (such as Eclipse or JSwat) to attach. If True, enables Java debugging via TCP. The default is False.JavaDebugPort: Specify the port on which to listen. The default is 8000.JavaDebugSuspend: If Yes, suspend the JVM on start to wait for the debugger to attach. The default is No.Documentation.
go to post Eduard Lebedyuk · Jan 17, 2017 %DB_CACHESYS may also be required, because data for this table is stored in CACHESYS database.
go to post Eduard Lebedyuk · Jan 15, 2017 Are there any hardware differences?Are there differences in memory allocation?
go to post Eduard Lebedyuk · Jan 13, 2017 Thank you!Do you import code from GitHub repository into Ensemble instance automatically?
go to post Eduard Lebedyuk · Jan 9, 2017 you are entirely correct. Good to hear.$$$SIMSRCDOMENTIf I change algorithm to $$$SIMSRCDOMENT I don't receive any results (Results local is undefined).If I choose $$$SIMSRCEQUIVS or $$$SIMSRCSIMPLE I get Results local as expected.What may be the reason? I didn't modify the domain between runs.Method returns $$$OK and %objlasterror is empty using any algorithm.
go to post Eduard Lebedyuk · Jan 9, 2017 Yes, same as with studio, Caché supports Unit Tests. Documentation.
go to post Eduard Lebedyuk · Jan 9, 2017 write ##class(Config.CPF).Activate() Would read and activate current configuration file without system restart.
go to post Eduard Lebedyuk · Jan 9, 2017 You can search for the references in studio:Open StudioMenu -> Edit -> Search in filesFind: Dimension/Measure (for example [DateOfSale].[Actual].[DaySold])File type: *.dfiIt should find relevant entities.
go to post Eduard Lebedyuk · Jan 8, 2017 Hello. Thank you for this information. I started testing it and %iKnow.Queries.SourceAPI:GetSimilar() returned the following as a result local: result(1)=$lb(890,":SQL:2002:20020308X00320",.4737,.9606,57,27,686,.4737) The list is formed from these values: $lb(srcId, externalId, percentageMatched, percentageNew, nbOfTgtsInRefSrc, nbOfTgtsInCommon, nbOfTgtsInSimSrc, matchScore) What does that mean? srcId -sourceId of similar documentexternalId - external source id of similar documentpercentageMatched - number of targets common between source and similar documents divided by number of targets in source documentpercentageNew - number of targets in similar document that is not present in source document divided by total number of targets in similar documentnbOfTgtsInRefSrc - number of targets in source documentnbOfTgtsInCommon - number of targets common between source and similar documentsnbOfTgtsInSimSrc - number of targets in similar documentmatchScore - seems equal to percentageMatched Is that correct? Are there documentation on that?
go to post Eduard Lebedyuk · Jan 5, 2017 Cache Fileserver is an old project of mine which allows file upload/download. Files have IDs, but to download each client get's an unique link active only for his IP for a limited time. You can remove IDs altogether.