go to post Joel Solon · Jun 30 One quick answer is a helper ObjectScript class with a wrapper classmethod for each macro. If the helper class can inherit from the class that provides the macros (for example: CustomPackage.TestCase extends %UnitTest.TestCase) then you can replace $$$Macro(args) with self.Macro(args). Otherwise, your helper class must include the INC file that defines the macros, and other classes can call the class methods directly: iris.CustomPackage.HelperClass.Macro(args).
go to post Joel Solon · Jun 16 @Harry Tong Would %vid help with this (https://docs.intersystems.com/irisforhealth20251/csp/docbook/DocBook.UI....)?
go to post Joel Solon · Jun 16 Suggestion: Since IRIS is the flagship product for 5+ years, calling the programming language "Caché ObjectScript" doesn't make much sense anymore. "ObjectScript" is enough.
go to post Joel Solon · Jun 6 I'd use LIKE and OR directly in the query. If there are more than 2-3 comparisons (which would make something like InLike() useful), I'd write a class method that uses Dynamic SQL to add an OR for each comparison to the final WHERE clause.
go to post Joel Solon · May 2 Are you asking this out of curiosity? Or is there another reason for the question? How would you like to use $this?
go to post Joel Solon · May 2 Clarification: you can't use * alone as a global mapping. If you want NS1 to get all of its globals from DB1, then the "Default database for globals" field should be DB1. You can then add mappings for certain globals (using * at the end if you want) to additional databases. (changing your question a little) If you add a mapping B* to DB1, and a mapping of BA* to DB2, BA* mapping takes precedence.
go to post Joel Solon · Apr 7 Can also be used as #include inside a method (applies only to that method)
go to post Joel Solon · Mar 12 ...and it makes sense that using $listbuild to add at the end would be better than the other two options, which are general purpose ("find the position in the list and put something there").
go to post Joel Solon · Feb 10 As @Yaron Munz and @Alexander Koblov correctly pointed out, you can use Embedded SQL or Dynamic SQL. You can also use Class Queries. Using Embedded SQL, host variables in IRIS (:varname) can be inputs or outputs, just like host variables in SQL Server and Oracle, but without any DECLARE statement. Host variables used as inputs are automatically sanitized. Examples: WHERE amount > :var1 INSERT INTO ... VALUES (:var1, :var2, :var3) SELECT ... INTO :var1, :var2 FROM ... Dynamic SQL allows ? placeholders for inputs only instead of host variables, also automatically sanitized. Examples: WHERE amount > ? INSERT INTO ... VALUES (?, ?, ?) Dynamic SQL returns output values in the result set object it returns, which you can access and copy into variables. Examples: set resultSet = ##class(%SQL.Statement).%ExecDirect(, sql, values for any placeholders) while resultSet.%Next() { set var1 = resultSet.column1 set var2= resultSet.column2 } Class queries use host variables (:varname) for inputs (like Embedded SQL), and return output values in the result set object (like Dynamic SQL).
go to post Joel Solon · Jan 10 I think the other commenters clarified it all, but I thought I'd add a little more. Try this variant, with the variable x intentionally undefined. write (1=0) && (x = 0)0 Since 1=0 is 0, you don't get an <UNDEFINED> for x, since the right-hand (x=0) expression is ignored, and the entire statement is 0. Now try this: write 1=0 && x=01 which, as @Roger Merchberger showed, is really write (((1=0) && x) = 0) Since 1=0 is 0, you again don't get an <UNDEFINED> for x, since the x expression (only) is ignored, and the ((1=0) && x) expression is 0. Finally, 0=0 is 1.
go to post Joel Solon · Nov 15, 2024 Thanks for the thoughts! To clarify, I was primarily asking about where to install IRIS itself. Within the context of that question, it's always good to include information about directories for the other important stuff, such as Journals and databases, so thanks for that.
go to post Joel Solon · Nov 11, 2024 Thanks for posting this Joel! I've been wondering about this for a while too! 🤣
go to post Joel Solon · Oct 29, 2024 As others in this thread have said, custom audit events from applications are added to the Audit Log using a call to $system.Security.Audit(). The events must be defined ahead of time in the Portal, using Configure User Events. All events (system and custom) have a 3-part name: Source, Type, and Name. I think of these parts as Main Category, Subcategory, and Name. The person(s) defining the custom events can choose all 3 parts of the name, in order to categorize all the custom events they're defining. So you could use Source = ABC, Type = DEF, and Name = XYZ. The names are totally up to you. Once defined, the event gets added by some code calling $system.Security.Audit("ABC", "DEF", "XYZ").
go to post Joel Solon · Oct 10, 2024 Thanks Robert! And there's another one! $LISTBUILD – Builds a list from elements or extracts elements from a list.
go to post Joel Solon · Oct 7, 2024 I have a comment on the sentence "I don't want to use Xecute because I am in need of really high performance code." I have always thought of Xecute and @ (indirection) as similar in performance characteristics. But I don't know what the current reality is. Is it possible that omer was told that Xecute is slow and indirection wasn't mentioned? Here are some quotes from the docs. I don't see anything here that indicates Xecute is slower or faster than indirection. Maybe someone else on this thread has more detailed knowledge on the difference if any. The execution time for code called within XECUTE can be slower than the execution time for the same code encountered in the body of a routine. This is because InterSystems IRIS compiles source code that is specified with the XECUTE command or that is contained in a referenced global variable each time it processes the XECUTE. You should use indirection only in those cases where it offers a clear advantage. Indirection can have an impact on performance because InterSystems IRIS performs the required evaluation at runtime, rather than during the compile phase. You can always duplicate the effect of indirection by other means, such as by using the XECUTE command.
go to post Joel Solon · Oct 2, 2024 I didn't even think to check if other %variables were handled automatically. I will add the request for %sqlcontext right away.
go to post Joel Solon · Jun 13, 2024 Common Table Expressions are now supported starting with v2024.1: https://docs.intersystems.com/irisforhealth20241/csp/docbook/DocBook.UI....
go to post Joel Solon · Apr 9, 2024 $increment is (or used to be) unique in that it was the only function that changed its argument. It reminded me of learning about "destructive functions" in LISP a long time ago. No matter where/how you use it, it increments. So "set a = $increment(a)" is redundant, but still OK to use. As you saw, developers started to use "if $increment(a)" alone, because that was shorter but also works fine, even thought it looks strange. I wasn't aware of "do $increment(a)" being allowed, which does look nicer, so I also learned something new from this thread, thanks. And let's not forget to mention the popular and useful "set a($increment(a)) = something"
go to post Joel Solon · Apr 9, 2024 I never encountered this issue. I assume it's because AutoSave is off by default, and Steve and others that have commented turned it on. I noticed that there IS a setting called "Auto Save When No Errors."
go to post Joel Solon · Apr 1, 2024 Very nice. Please remove "not" from "...its associated searches does not open up a world of opportunities..."