go to post Dan Pasco · Jul 27, 2022 I submitted some feedback to documentation regarding the content you cited. The line in question originated from something I wrote while implementing the %On*Finally set of methods. The "calling method" in this context refers to the method that invokes the %On*Finally() method. In this case, %Save() is the calling method. %Save may or may not initiate a transaction, depending on a few factors. If %Save does initiate a transaction then that transaction is complete prior to the %OnSaveFinally() call.
go to post Dan Pasco · Jun 1, 2022 %Library.ResultSet remains in the product for backward compatibility reasons but there are better ways to execute class queries. Any class query can be projected as a table valued function (TVF). TVF's can be executed if the class query also declares SQLPROC. A TVF can be included in the FROM item list, it can be joined with other FROM items, it can be ordered, restricted and a subset of available columns made available. Here is a simple example from the Sample.Person class: select id,name,dob from sample.SP_Sample_By_Name('Ad') order by dob desc I populated Sample.Person with some generated data and ran the above statement: ID Name DOB 855 Adams,Elvira X. 03/16/2021 1378 Adams,Ed L. 01/15/2018 477 Adams,Debra S. 10/01/2015 1341 Adam,Chad U. 10/20/2013 32 Adam,Dmitry N. 10/28/2010 1099 Adams,Pam Z. 10/20/1993 897 Adam,Joe Y. 02/23/1984 1469 Adam,Phyllis N. 04/20/1982 358 Adam,Liza H. 12/13/1980 1096 Adam,Belinda Z. 08/02/1975 1269 Adam,Charlotte P. 03/03/1974 1396 Adams,Robert E. 03/14/1973 1109 Adams,Quigley H. 01/01/1968 454 Adam,Amanda A. 01/22/1964 856 Adams,Lawrence A. 03/23/1961 1104 Adam,Stavros O. 02/24/1948 1179 Adam,Pam A. 05/16/1941 426 Adams,Brian M. 01/15/1928 18 row(s) affected And you can also execute this using a dynamic statement: USER>set result = $system.SQL.Execute("select id,name,dob from sample.SP_Sample_By_Name('Ad') order by dob desc") USER>write result.%Next() 1 USER>write result.Name Adams,Elvira X.
go to post Dan Pasco · Mar 24, 2022 There is a project that will be available soon (don't ask me to define "soon") that will allow the Java programmer to load and compile sources from the local system into an IRIS Server. The IRIS Server does not need to be running on the same system where the files are located. This example is slightly old as the current implementation of load() returns a list of items loaded and compile() returns a list of items compiled. There are load implementations that accept directories, individual files, any Java streamable, and also JAR files. SourceLoader sourceLoader = new SourceLoader(connection); Path path = Paths.get("path/to/samples/cls/Sample"); sourceLoader.load(path, null); sourceLoader.compile(true);
go to post Dan Pasco · Jan 12, 2022 Yes, of course "inverse" - sorry. Persistent vs RegisteredObject - not a problem but you are calling a simple class method so we don't need any super class. I used this implementation for the IRIS Class: Class Utils.CSW1JavaFunctions { ClassMethod IrisReturn(user = "user", pass = "pass") As %Stream.GlobalBinary { try { set cswStream=##class(%Stream.GlobalBinary).%New() set cswReturn = {"user":(user), "pass":(pass) } do cswReturn.%ToJSON(cswStream) return cswStream } catch exc { write !,"Caught Exception on server: ", exc.AsSQLMessage() } } } And this is a crude hack at the Java code - the anonymous InputStream class could use more work but it does run for this simple example. I'll leave the rest of the InputStream coding to you. package utils; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.intersystems.jdbc.*; import java.io.*; import java.sql.SQLException; public class Reader { public static final String CACHE_CLASS_NAME = "Utils.CSW1JavaFunctions"; public IRISConnection connection; public IRIS iris; public Reader(IRISConnection connection) throws SQLException { this.connection = connection; this.iris = IRIS.createIRIS(connection); } public static void main(String[] args) throws SQLException { IRISDataSource dataSource = new IRISDataSource(); dataSource.setServerName("localhost"); dataSource.setPortNumber(51776); dataSource.setDatabaseName("USER"); dataSource.setUser("_SYSTEM"); dataSource.setPassword("SYS"); IRISConnection connection = (IRISConnection) dataSource.getConnection(); Reader reader = new Reader(connection); try { JsonNode jsonNode = reader.execute("IrisReturn", "java", "jpass"); System.out.println(jsonNode.toString()); } catch (Exception exc) { exc.printStackTrace(); } } public JsonNode execute(String method, Object... args) throws Exception { ObjectMapper mapper = new ObjectMapper(); JsonNode jsonNode = null; try { IRISObject data = (IRISObject) iris.classMethodObject(CACHE_CLASS_NAME, method, args[0], args[1]); InputStream is = new InputStream() { byte[] buffer; int pos = 0; int len = -1; @Override public int read() throws IOException { if (pos >= len) { getBuffer(); } if (len == -1) { return -1; } return buffer[pos++]; } void getBuffer() { pos = 0; IRISReference readLen = new IRISReference(3200); String string = (String) data.invoke("Read", readLen); if (readLen.getLong() == -1) { buffer = null; len = -1; } else { buffer = string.getBytes(); len = buffer.length; } } }; jsonNode = (JsonNode) mapper.readTree(is); return jsonNode; } catch (Exception ex) { ex.printStackTrace(); } return null; } } Running this produces this output: /usr/lib/jvm/adoptopenjdk-11-hotspot-amd64/bin/java -javaagent:/home/...{"user":"java","pass":"jpass"} Process finished with exit code 0
go to post Dan Pasco · Jan 4, 2022 You can. Two different ways but both utilize the External Java Server with gateway connections. That is the same mechanism employed by LOAD DATA. If you have an example of what you want to do then I can provide you with a demo - using both options.
go to post Dan Pasco · Dec 24, 2021 Use the IRISList class: IRIS iris = IRIS.createIRIS(connection); IRISList list = new IRISList(); list.add("this is a string"); list.add(100); iris.set(list, "test",1); USER>zw ^test^test(1)=$lb("this is a string",100)
go to post Dan Pasco · Nov 26, 2021 I just saw this on the community: https://community.intersystems.com/post/intersystems-objectscript-101-en. Perhaps it will help?
go to post Dan Pasco · Mar 31, 2021 How are you purging this data? SQL? Or by calling a class method such as %DeleteExtent?
go to post Dan Pasco · Sep 16, 2020 You should not write %BuildIndices/%PurgeIndices. Can you provide the SQL map definition and the index definition of one of your indexes - just as an example? Perhaps we can start with a simple index on a table with a smaller number of rows?
go to post Dan Pasco · Sep 14, 2020 Let me focus on the last two items in your list. IRIS Native for Java, Node.js, DotNet, Python - these are all consistent implementations of the IRIS Native API and the communication is over TCP or shared memory. IRIS Native for ObjectScript is just another - consistent - implementation of the IRIS Native API. To get a connection to an IRIS server, the command is similar across all implementations of IRIS Native API: set connection = ##class(%Net.DB.DataSource).CreateConnection(host, port, namespace, user, pwd) Once you have a connection, you can get an IRIS object. set iris = connection.CreateIris() and from an iris object, you can invoke class methods, code implemented in routines, set/get globals, and so on.